#371 PyCryptodome
Python 加密 2020-02-05和 PyCrypto 的关系
PyCrypto 是 Python 界最知名的加密模块,它提供了一系列的加密算法,包括对称加密、非对称加密、哈希算法、签名算法等。
不过有一个很大的问题:上一个版本 2.6.1 发布于 2013-10-18,已经很多年没有维护了。
PyCryptodome 是 PyCrypto 的分叉,该项目在统一套代码的基础上提供了两种包:pycryptodome 和 pycryptodomex:
- 前者保持对 PyCrypto 的兼容,所有的代码都在
Crypto名称下, -
后者丢掉了历史包袱,放弃对 PyCrypto 的兼容,所有代码都在
Cryptodome名称下。 - https://pypi.org/project/pycryptodomex/
- https://www.pycryptodome.org/en/latest/
- https://github.com/Legrandin/pycryptodome/
其他加密模块
- M2Crypto
其思路是在 libssl 库上做封装。PS: 因为其只是做封装,代码更新频率非常低。
但由于其有 C 库依赖,安装会相对复杂一些。 - https://gitlab.com/m2crypto/m2crypto
- https://github.com/m2crypto/m2crypto 可能是某个用户弄的,很久没有同步
- https://github.com/mcepl/m2crypto 项目维护者,主要开发者
- https://pypi.org/project/M2Crypto/
- cryptography https://github.com/pyca/cryptography
- pyOpenSSL https://github.com/pyca/pyopenssl 官方建议迁移到 cryptography
- PyNaCl https://github.com/pyca/pynacl
PyNaCl is a Python binding to libsodium, which is a fork of the Networking and Cryptography library.
- rsa https://pypi.org/project/rsa/ 纯 Python 实现
- https://github.com/sybrenstuvel/python-rsa/
示例
#370 公有云,私有云,混合云
云计算 2020-02-01公有云 Public Cloud
云计算厂商提供的公共服务,比如腾讯云、阿里云等。
私有云 Private Cloud
个人和组织自己搭建的(可能是厂商帮忙搭建),自用的云计算服务。机器由个人或组织持有(可能在云计算厂商的机房中)。
优点是数据完全掌握在自己手中。如果规模没有达到一定程度的话,这样做的成本会比较高(除了固定资产的投入之外,维护成本不可忽视)。
有一种形式,是一些利益相关的个体,对计算有着相同或相似的需求,然后共同搭建一个云服务平台。
比如 XX 市弄一个政务云,下属政府机构直接使用这个云服务平台。
又比如某地教育单位弄一个云服务平台,下属学校有啥服务的话,就都使用这个云服务平台。
专有云
有些厂商提供 “专有云” 的服务:整套设施就为单个客户专门提供服务。设备属于厂商所有。
感觉这个算公有云,私有云的交叉地带,只好单独算一类。
知乎上看到一个比喻:公有云是小姐,私有云是老婆,专有云是小三 (包养)。比较贴切。
混合云 Hybrid Cloud
一般意义上,混合云是指公有云和私有云的结合。
PS: 多个私有云之间,或多个公有云之间,相互共享资源,也可以叫做混合云。
应该是通过一些对接好了各大厂商(比如腾讯云,阿里云)和常见私有云平台(比如 OpenStack,CloudStack)的管理工具,对所有资源进行整合管理。
也可能部分二次开发过的私有云平台支持对接公有云,可以直接调度和整合公有云资源。
#369 ASN.1
开发者 ASN1 网络编程 2020-01-30我印象中曾在某个项目中接触到了这种格式,但是一时间竟也想不起来。
PS: 可能是有一次涉及 LDAP 协议的时候。
概念
ASN 全名 Abstract Syntax Notation, 翻译过来就是:抽象语法标记。
ASN.1 可能是第一版的意思(?)。
asn.1 是一套国际标准,用来定义一种通用的、严谨的数据表示(标记)方法,以及对应的数据编码格式。
PS:对数据 Scheme 的定义独立于硬件架构和编程语言。
- ITU-T Rec. X.680 (2015) | ISO/IEC 8824-1:2015
Specification of basic notation - ITU-T Rec. X.681 (2015) | ISO/IEC 8824-2:2015
Information object specification - ITU-T Rec. X.682 (2015) | ISO/IEC 8824-3:2015
Constraint specification - ITU-T Rec. X.683 (2015) | ISO/IEC 8824-4:2015
Parameterization of ASN.1 specifications - ITU-T Rec. X.690 (2015) | ISO/IEC 8825-1:2015
BER, CER and DER
PS:常见证书格式 der 就是来自这个 DER。 - ITU-T Rec. X.691 (2015) | ISO/IEC 8825-2:2015
PER (Packed Encoding Rules) - ITU-T Rec. X.692 (2015) | ISO/IEC 8825-3:2015
ECN (Extended Component Notation) - ITU-T Rec. X.693 (2015) | ISO/IEC 8825-4:2015
XER (XML Encoding Rules) - ITU-T Rec. X.694 (2015) | ISO/IEC 8825-5:2015
Mapping W3C XML schema definitions into ASN.1 - ITU-T Rec. X.695 (2015) | ISO/IEC 8825-6:2015
Registration and application of PER encoding instructions - ITU-T Rec. X.696 (2015) | ISO/IEC 8825-7:2015
OER (Octet Encoding Rules) - ITU-T Rec. X.697 (2017) | ISO/IEC 8825-8:2018
JER (JSON Encoding Rules)
一般又被称之为 X.680 系列,最早是 1995 年出第一版。最新的是 2018 年出的 5.4 版(X.680 (2015) Amd. 1)
PS:2021 年 X.680 出了第六版。
部分应用层的网络协议就使用了 ASN.1 格式,比如 X.500 Directory Services,LDAP,VoIP,PKCS,Kerberos,移动通信(2G/GSM,GRPS,一直到 5G)。
它和 JSON 这种通用数据交换格式完全不同,更加类似与 protobuf,msgpack,thrift 这样,提供一个完备的数据定义语法用来声明 Schema(ASN.1 称之为模块),然后基于二进制紧凑地表示数据。所以非常适合用在 C/S 架构的网络编程上,作为服务通讯协议的一部分,负责内外数据交换,也就是 TCP/UDP 服务的接口部分。
如果要将 ASN.1 归类的话,更贴切的应该是接口定义语言,或者叫协议定义语言。
要是了解到 ASN.1 出现的年份(1984)的话,对照它的竞争者出现的时间,会发现它的设计确实比较超前。不管怎么说,这些晚辈确实更加流行,作为国际标准的 ASN.1 不够卖座,肯定是也有不好的地方。
PS:可能是 ASN.1 历史包袱太重, 不够轻便 (我看到的一些评论和我的猜想比较符合)。
数据定义
先来一个示例(维基上找来的,感觉没啥意义):
FooProtocol DEFINITIONS ::= BEGIN
FooQuestion ::= SEQUENCE {
-- 跟踪编号,后面括号是限制值的范围
trackingNumber INTEGER(0..199),
-- 问题内容,字符串
question IA5String
}
FooAnswer ::= SEQUENCE {
-- 问题编号
questionNumber INTEGER(10..20),
-- 答案内容
answer BOOLEAN
}
FooHistory ::= SEQUENCE {
-- 问题数组
questions SEQUENCE(SIZE(0..10)) OF FooQuestion,
-- 答案数组
answers SEQUENCE(SIZE(1..10)) OF FooAnswer,
-- 一个整型数组
anArray SEQUENCE(SIZE(100)) OF INTEGER(0..1000),
...
}
END
基本语法
- 大小写字母,数字,短横杠,空格
标识符:小写字母开头
类型名称:大写字母开头 - 多个空白符号(空格、换行)会当作一个空格
- 数据类型都有一个 TagNumber
--注释
数据类型
简单类型
结构化类型
标记类型
其他类型:CHOICE,ANY
类别:
- 0 Universal 通用类型
- 1 Application 应用协议相关类型
- 2 Context-specific
- 3 Private 自定义
结构化:
原始类型:
| Type | Tag number | 备注 |
|---|---|---|
INTEGER |
2 | 整型 |
BIT STRING |
3 | |
OCTET STRING |
4 | |
NULL |
5 | NULL |
OBJECT IDENTIFIER |
6 | 对象 |
SEQUENCE andSEQUENCE OF |
16 | 数组 |
SET and SET OF |
17 | 集合 |
PrintableString |
19 | 字符串 |
T61String |
20 | |
IA5String |
22 | |
UTCTime |
23 | 时间 |
示例:
编码规则
- 基本编码规则(BER,Basic Encoding Rules)
- 规范编码规则(CER,Canonical Encoding Rules)
- 唯一编码规则(DER,Distinguished Encoding Rules)
- 压缩编码规则(PER,Packed Encoding Rules)
- XML 编码规则(XER,XML Encoding Rules)
Python
https://www.cnblogs.com/20175211lyz/p/12769883.html
https://github.com/etingof/pyasn1
上面的示例通过 asn1ate /tmp/foo.asn > /tmp/foo.py 生成 Python 代码:
PS:并不是一定需要定义成这样类的结构,只是 pyasn1 库适合这样用而已。
from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful
class FooAnswer(univ.Sequence):
pass
FooAnswer.componentType = namedtype.NamedTypes(
namedtype.NamedType('questionNumber', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(10, 20))),
namedtype.NamedType('answer', univ.Boolean())
)
class FooQuestion(univ.Sequence):
pass
FooQuestion.componentType = namedtype.NamedTypes(
namedtype.NamedType('trackingNumber', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, 199))),
namedtype.NamedType('question', char.IA5String())
)
class FooHistory(univ.Sequence):
pass
FooHistory.componentType = namedtype.NamedTypes(
namedtype.NamedType('questions', univ.SequenceOf(componentType=FooQuestion()).subtype(subtypeSpec=constraint.ValueSizeConstraint(0, 10))),
namedtype.NamedType('answers', univ.SequenceOf(componentType=FooAnswer()).subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 10))),
namedtype.NamedType('anArray', univ.SequenceOf(componentType=univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, 1000))).subtype(subtypeSpec=constraint.ValueSizeConstraint(100, 100)))
)
然后就可以使用了:
import foo
from pyasn1.codec.der.encoder import encode
fa = foo.FooAnswer()
fa['questionNumber'] = 10
fa['answer'] = False
fa_encoded = encode(fa)
print(fa_encoded) # b'0\x06\x02\x01\n\x01\x01\x00'
print(binascii.b2a_hex(fa_encoded).decode()) # 300602010a010100
from pyasn1.codec.der.decoder import decode
obj, rest = decode(fa_encoded)
print(obj)
# Sequence:
# field-0=10
# field-1=False
for k, v in obj.items():
print([k, v])
# ['field-0', <Integer value object, tagSet <TagSet object, tags 0:0:2>, payload [10]>]
# ['field-1', <Boolean value object, tagSet <TagSet object, tags 0:0:1>, subtypeSpec <ConstraintsIntersection object, consts <SingleValueConstraint object, consts 0, 1>>, namedValues <NamedValues object, enums False=0, True=1>, payload [False]>]
obj, rest = decode(fa_encoded, asn1Spec=foo.FooAnswer())
print(obj)
# FooAnswer:
# questionNumber=10
# answer=False
# print(dict(obj.items()))
print(dict([(k, str(v)) for k, v in obj.items()]))
# {'questionNumber': '10', 'answer': 'False'}
print(obj['questionNumber'].__dict__)
print(obj['questionNumber']._value) # 10
print(obj['answer'].__dict__)
print(obj['answer']._value) # 0
print([int(obj['questionNumber']), bool(obj['answer'])])
GitHub 找到的几个相关库:
- wbond/asn1crypto
Python ASN.1 library with a focus on performance and a pythonic API
- etingof/pyasn1
Generic ASN.1 library for Python
- eerimoq/asn1tools
ASN.1 parsing, encoding and decoding.
- P1sec/pycrate
A Python library to ease the development of encoders and decoders for various protocols and file formats; contains ASN.1
参考资料与拓展阅读
#368 武汉新型冠状病毒
时事 COVID19 2020-01-29具体的情况,网上不要太多,我说说我的经历和想法。
#367 MySQL help
MySQL 2020-01-25输入 help 之后,按照提示就会发现 MySQL 有一个主题树。
从头 help contents 开始:
Account ManagementALTER RESOURCE GROUPALTER USERCREATE RESOURCE GROUPCREATE ROLECREATE USERDROP RESOURCE GROUPDROP ROLEDROP USERGRANTRENAME USERREVOKESET DEFAULT ROLESET PASSWORDSET RESOURCE GROUPSET ROLEAdministrationBINLOGCACHE INDEXFLUSHHELP COMMANDKILLLOAD INDEXRESETRESET PERSISTRESTARTSETSET CHARACTER SETSET CHARSETSET NAMESSHOWSHOW BINARY LOGSSHOW BINLOG EVENTSSHOW CHARACTER SETSHOW COLLATIONSHOW COLUMNSSHOW CREATE DATABASESHOW CREATE EVENTSHOW CREATE FUNCTIONSHOW CREATE PROCEDURESHOW CREATE SCHEMASHOW CREATE TABLESHOW CREATE TRIGGERSHOW CREATE USERSHOW CREATE VIEWSHOW DATABASESSHOW ENGINESHOW ENGINESSHOW ERRORSSHOW EVENTSSHOW FIELDSSHOW FUNCTION CODESHOW FUNCTION STATUSSHOW GRANTSSHOW INDEXSHOW MASTER LOGSSHOW MASTER STATUSSHOW OPEN TABLESSHOW PLUGINSSHOW PRIVILEGESSHOW PROCEDURE CODESHOW PROCEDURE STATUSSHOW PROCESSLISTSHOW PROFILESHOW PROFILESSHOW RELAYLOG EVENTSSHOW REPLICA STATUSSHOW REPLICASSHOW SCHEMASSHOW SLAVE HOSTSSHOW SLAVE STATUSSHOW STATUSSHOW TABLE STATUSSHOW TABLESSHOW TRIGGERSSHOW VARIABLESSHOW WARNINGSSHUTDOWNComponentsCLONEINSTALL COMPONENTUNINSTALL COMPONENTUNINSTALL PLUGINCompound StatementsBEGIN ENDCASE STATEMENTCLOSEDECLARE CONDITIONDECLARE CURSORDECLARE HANDLERDECLARE VARIABLEFETCHGET DIAGNOSTICSIF STATEMENTITERATELABELSLEAVELOOPOPENREPEAT LOOPRESIGNALRETURNSIGNALWHILEContentsData DefinitionALTER DATABASEALTER EVENTALTER FUNCTIONALTER INSTANCEALTER LOGFILE GROUPALTER PROCEDUREALTER SCHEMAALTER SERVERALTER TABLEALTER TABLESPACEALTER VIEWCREATE DATABASECREATE EVENTCREATE FUNCTIONCREATE INDEXCREATE LOGFILE GROUPCREATE PROCEDURECREATE SCHEMACREATE SERVERCREATE SPATIAL REFERENCE SYSTEMCREATE TABLECREATE TABLESPACECREATE TRIGGERCREATE VIEWDROP DATABASEDROP EVENTDROP FUNCTIONDROP INDEXDROP PROCEDUREDROP SCHEMADROP SERVERDROP SPATIAL REFERENCE SYSTEMDROP TABLEDROP TABLESPACEDROP TRIGGERDROP VIEWFOREIGN KEYRENAME TABLETRUNCATE TABLEData ManipulationCALLDELETEDODUALHANDLERIMPORT TABLEINSERTINSERT DELAYEDINSERT SELECTJOINLOAD DATALOAD XMLPARENTHESIZED QUERY EXPRESSIONSREPLACESELECTTABLEUNIONUPDATEVALUES STATEMENTData TypesAUTO_INCREMENTBIGINTBINARYBITBLOBBLOB DATA TYPEBOOLEANCHARCHAR BYTEDATEDATETIMEDECDECIMALDOUBLEDOUBLE PRECISIONENUMFLOATINTINTEGERLONGBLOBLONGTEXTMEDIUMBLOBMEDIUMINTMEDIUMTEXTSET DATA TYPESMALLINTTEXTTIMETIMESTAMPTINYBLOBTINYINTTINYTEXTVARBINARYVARCHARYEAR DATA TYPEFunctionsAggregate Functions and ModifiersAVGBIT_ANDBIT_ORBIT_XORCOUNTCOUNT DISTINCTGROUP_CONCATJSON_ARRAYAGGJSON_OBJECTAGGMAXMINSTDSTDDEVSTDDEV_POPSTDDEV_SAMPSUMVARIANCEVAR_POPVAR_SAMP
Bit Functions&<<>>BIT_COUNT^|~
Cast Functions and OperatorsBINARY OPERATORCASTCONVERT
Comparison Operators!=<<=<=>=>>=BETWEEN ANDCOALESCEGREATESTININTERVALISIS NOTIS NOT NULLIS NULLISNULLLEASTNOT BETWEENNOT IN
Date and Time FunctionsADDDATEADDTIMECONVERT_TZCURDATECURRENT_DATECURRENT_TIMECURRENT_TIMESTAMPCURTIMEDATE FUNCTIONDATEDIFFDATE_ADDDATE_FORMATDATE_SUBDAYDAYNAMEDAYOFMONTHDAYOFWEEKDAYOFYEAREXTRACTFROM_DAYSFROM_UNIXTIMEGET_FORMATHOURLAST_DAYLOCALTIMELOCALTIMESTAMPMAKEDATEMAKETIMEMICROSECONDMINUTEMONTHMONTHNAMENOWPERIOD_ADDPERIOD_DIFFQUARTERSECONDSEC_TO_TIMESTR_TO_DATESUBDATESUBTIMESYSDATETIME FUNCTIONTIMEDIFFTIMESTAMP FUNCTIONTIMESTAMPADDTIMESTAMPDIFFTIME_FORMATTIME_TO_SECTO_DAYSTO_SECONDSUNIX_TIMESTAMPUTC_DATEUTC_TIMEUTC_TIMESTAMPWEEKWEEKDAYWEEKOFYEARYEARYEARWEEK
Encryption FunctionsAES_DECRYPTAES_ENCRYPTCOMPRESSMD5RANDOM_BYTESSHA1SHA2STATEMENT_DIGESTSTATEMENT_DIGEST_TEXTUNCOMPRESSUNCOMPRESSED_LENGTHVALIDATE_PASSWORD_STRENGTH
Enterprise Encryption FunctionsASYMMETRIC_DECRYPTASYMMETRIC_DERIVEASYMMETRIC_ENCRYPTASYMMETRIC_SIGNASYMMETRIC_VERIFYCREATE_ASYMMETRIC_PRIV_KEYCREATE_ASYMMETRIC_PUB_KEYCREATE_DH_PARAMETERSCREATE_DIGEST
Flow Control FunctionsCASE OPERATORIF FUNCTIONIFNULLNULLIF
GROUP BY Functions and ModifiersGTIDGTID_SUBSETGTID_SUBTRACTWAIT_FOR_EXECUTED_GTID_SETWAIT_UNTIL_SQL_THREAD_AFTER_GTIDS
Information FunctionsBENCHMARKCHARSETCOERCIBILITYCOLLATIONCONNECTION_IDCURRENT_ROLECURRENT_USERDATABASEFOUND_ROWSICU_VERSIONLAST_INSERT_IDROLES_GRAPHMLROW_COUNTSCHEMASESSION_USERSYSTEM_USERUSERVERSION
Internal FunctionsCAN_ACCESS_COLUMNCAN_ACCESS_DATABASECAN_ACCESS_TABLECAN_ACCESS_USERCAN_ACCESS_VIEWGET_DD_COLUMN_PRIVILEGESGET_DD_CREATE_OPTIONSGET_DD_INDEX_SUB_PART_LENGTHINTERNAL_AUTO_INCREMENTINTERNAL_AVG_ROW_LENGTHINTERNAL_CHECKSUMINTERNAL_CHECK_TIMEINTERNAL_DATA_FREEINTERNAL_DATA_LENGTHINTERNAL_DD_CHAR_LENGTHINTERNAL_GET_COMMENT_OR_ERRORINTERNAL_GET_ENABLED_ROLE_JSONINTERNAL_GET_HOSTNAMEINTERNAL_GET_USERNAMEINTERNAL_GET_VIEW_WARNING_OR_ERRORINTERNAL_INDEX_COLUMN_CARDINALITYINTERNAL_INDEX_LENGTHINTERNAL_IS_ENABLED_ROLEINTERNAL_IS_MANDATORY_ROLEINTERNAL_KEYS_DISABLEDINTERNAL_MAX_DATA_LENGTHINTERNAL_TABLE_ROWSINTERNAL_UPDATE_TIMEIS_VISIBLE_DD_OBJECT
Locking FunctionsGET_LOCKIS_FREE_LOCKIS_USED_LOCKRELEASE_ALL_LOCKSRELEASE_LOCK
Logical Operators!ANDASSIGN-EQUALASSIGN-VALUEORXOR
Miscellaneous FunctionsANY_VALUEBIN_TO_UUIDDEFAULTGROUPINGINET6_ATONINET6_NTOAINET_ATONINET_NTOAIS_IPV4IS_IPV4_COMPATIS_IPV4_MAPPEDIS_IPV6IS_UUIDMASTER_POS_WAITNAME_CONSTSLEEPSOURCE_POS_WAITUUIDUUID_SHORTUUID_TO_BINVALUES
Numeric Functions%*+- BINARY- UNARY/ABSACOSASINATANATAN2CEILCEILINGCONVCOSCOTCRC32DEGREESDIVEXPFLOORLNLOGLOG10LOG2MODPIPOWPOWERRADIANSRANDROUNDSIGNSINSQRTTANTRUNCATE
Performance Schema FunctionsFORMAT_BYTESFORMAT_PICO_TIMEPS_CURRENT_THREAD_IDPS_THREAD_ID
Spatial FunctionsGeometry ConstructorsGEOMCOLLECTIONGEOMETRYCOLLECTIONLINESTRINGMULTILINESTRINGMULTIPOINTMULTIPOLYGONPOINTPOLYGONGeometry Property FunctionsST_DIMENSIONST_ENVELOPEST_GEOMETRYTYPEST_ISEMPTYST_ISSIMPLEST_SRIDGeometry Relation FunctionsST_CONTAINSST_CROSSESST_DISJOINTST_DISTANCEST_EQUALSST_FRECHETDISTANCEST_HAUSDORFFDISTANCEST_INTERSECTSST_OVERLAPSST_TOUCHESST_WITHINGeometryCollection Property FunctionsST_BUFFERST_BUFFER_STRATEGYST_CONVEXHULLST_DIFFERENCEST_GEOMETRYNST_INTERSECTIONST_LINEINTERPOLATEPOINTST_LINEINTERPOLATEPOINTSST_NUMGEOMETRIESST_POINTATDISTANCEST_SYMDIFFERENCEST_TRANSFORMST_UNIONLineString Property FunctionsST_ENDPOINTST_ISCLOSEDST_LENGTHST_NUMPOINTSST_POINTNST_STARTPOINTMBR Functions->->>JSON_ARRAYJSON_ARRAY_APPENDJSON_ARRAY_INSERTJSON_CONTAINSJSON_CONTAINS_PATHJSON_DEPTHJSON_EXTRACTJSON_INSERTJSON_KEYSJSON_LENGTHJSON_MERGEJSON_MERGE_PATCH()JSON_MERGE_PRESERVE()JSON_OBJECTJSON_OVERLAPSJSON_PRETTYJSON_QUOTEJSON_REMOVEJSON_REPLACEJSON_SCHEMA_VALIDJSON_SCHEMA_VALIDATION_REPORTJSON_SEARCHJSON_SETJSON_STORAGE_FREEJSON_STORAGE_SIZEJSON_TABLEJSON_TYPEJSON_UNQUOTEJSON_VALIDJSON_VALUEMBRCONTAINSMBRCOVEREDBYMBRCOVERSMBRDISJOINTMBREQUALSMBRINTERSECTSMBROVERLAPSMBRTOUCHESMBRWITHINMEMBER OFST_ASGEOJSONST_COLLECTST_DISTANCE_SPHEREST_GEOHASHST_GEOMFROMGEOJSONST_ISVALIDST_LATFROMGEOHASHST_LONGFROMGEOHASHST_MAKEENVELOPEST_POINTFROMGEOHASHST_SIMPLIFYST_VALIDATEPoint Property FunctionsST_LATITUDEST_LONGITUDEST_XST_YPolygon Property FunctionsST_AREAST_CENTROIDST_EXTERIORRINGST_INTERIORRINGNST_NUMINTERIORRINGSWKB FunctionsST_ASBINARYST_ASTEXTST_GEOMCOLLFROMWKBST_GEOMFROMWKBST_LINEFROMWKBST_MLINEFROMWKBST_MPOINTFROMWKBST_MPOLYFROMWKBST_POINTFROMWKBST_POLYFROMWKBST_SWAPXYWKT FunctionsST_GEOMCOLLFROMTEXTST_GEOMFROMTEXTST_LINEFROMTEXTST_MLINEFROMTEXTST_MPOINTFROMTEXTST_MPOLYFROMTEXTST_POINTFROMTEXTST_POLYFROMTEXT
String FunctionsASCIIBINBIT_LENGTHCHAR FUNCTIONCHARACTER_LENGTHCHAR_LENGTHCONCATCONCAT_WSELTEXPORT_SETFIELDFIND_IN_SETFORMATFROM_BASE64HEXINSERT FUNCTIONINSTRLCASELEFTLENGTHLIKELOAD_FILELOCATELOWERLPADLTRIMMAKE_SETMATCH AGAINSTMIDNOT LIKENOT REGEXPOCTOCTET_LENGTHORDPOSITIONQUOTEREGEXPREGEXP_INSTRREGEXP_LIKEREGEXP_REPLACEREGEXP_SUBSTRREPEAT FUNCTIONREPLACE FUNCTIONREVERSERIGHTRPADRTRIMSOUNDEXSOUNDS LIKESPACESTRCMPSUBSTRSUBSTRINGSUBSTRING_INDEXTO_BASE64TRIMUCASEUNHEXUPPERWEIGHT_STRING
Window FunctionsCUME_DISTDENSE_RANKFIRST_VALUELAGLAST_VALUELEADNTH_VALUENTILEPERCENT_RANKRANKROW_NUMBER
XMLEXTRACTVALUEUPDATEXML
Geographic FeaturesGEOMETRY HIERARCHYSPATIAL COLUMNSSPATIAL INDEXESMBRWKTHelp MetadataHELP_DATEHELP_VERSIONLanguage StructureFALSETRUELoadable FunctionsCREATE FUNCTION LOADABLE FUNCTIONDROP FUNCTION LOADABLE FUNCTIONPluginsPrepared StatementsDEALLOCATE PREPAREDROP PREPAREEXECUTE STATEMENTPREPAREReplication StatementsCHANGE MASTER TOCHANGE REPLICATION FILTERCHANGE REPLICATION SOURCE TOPURGE BINARY LOGSPURGE MASTER LOGSRESET MASTERRESET REPLICARESET SLAVESET SQL_LOG_BINSTART REPLICASTART SLAVESTOP REPLICASTOP SLAVEStorage EnginesTable MaintenanceANALYZE TABLECHECK TABLECHECKSUM TABLEOPTIMIZE TABLEREPAIR TABLETransactionsBEGINCOMMITLOCK INSTANCE FOR BACKUPLOCK TABLESRELEASE SAVEPOINTROLLBACKROLLBACK TO SAVEPOINTSAVEPOINTSET TRANSACTIONSTART TRANSACTIONXAUtilityDESCDESCRIBEEXPLAINHELP STATEMENTUSE
#366 MySQL Error: Packet sequence number wrong
MySQL 2020-01-18多线程执行 MySQL 查询的时候会遇到 Packet sequence number wrong 错误。
Traceback (most recent call last):
File "/tmp/db.py", line 167, in _execute
rowcount = cur.execute(sql, args)
File "/usr/local/lib/python2.7/site-packages/pymysql/cursors.py", line 163, in execute
result = self._query(query)
File "/usr/local/lib/python2.7/site-packages/pymysql/cursors.py", line 321, in _query
conn.query(q)
File "/usr/local/lib/python2.7/site-packages/pymysql/connections.py", line 505, in query
self._affected_rows = self._read_query_result(unbuffered=unbuffered)
File "/usr/local/lib/python2.7/site-packages/pymysql/connections.py", line 724, in _read_query_result
result.read()
File "/usr/local/lib/python2.7/site-packages/pymysql/connections.py", line 1076, in read
self._read_result_packet(first_packet)
File "/usr/local/lib/python2.7/site-packages/pymysql/connections.py", line 1146, in _read_result_packet
self._read_rowdata_packet()
File "/usr/local/lib/python2.7/site-packages/pymysql/connections.py", line 1180, in _read_rowdata_packet
packet = self.connection._read_packet()
File "/usr/local/lib/python2.7/site-packages/pymysql/connections.py", line 660, in _read_packet
% (packet_number, self._next_seq_id))
InternalError: Packet sequence number wrong - got 51 expected 178
多个查询共用连接,并发查询的时候,现在的 MySQL 网络传输机制无法判断这个返回属于哪个查询。
所以每个线程应该使用不同的连接,或者在 execute 之前加一个锁。
#365 Python 打开文件的方式
Python 2020-01-10有同事排查 Python 项目问题的时候指出一处 open 没有关闭可能会导致句柄泄露 Handle Leak。
PS: 句柄泄漏的危害:大量资源占用可能导致性能下降,甚至由于可打开文件数达到极限,服务无法继续向外提供服务。
我看了之后告诉他,此处函数退出之后句柄会自动关闭,他还不信,下去自己研究了一会儿,可能是百度一下,过一会儿说好像确实是这样,不过他仍然很疑惑,那么 with open 的作用是什么呢?
一般我们常用上下文管理的方式(with open)来打开文件,这样可以自动关闭句柄,这是一个好的实践。
- 退出函数之后文件描述符的自动关闭是 CPython GC (垃圾回收机制) 的特性,非 Python 语言规范。
- 根据 CPython 的 GC 策略(引用计数),如果有引用,文件描述符不会被关闭,这是一个非常严重的潜在风险。
大部分时候我们可能没有引用文件描述符,但是不能排除可能性。
万一出现句柄泄漏,在代码库中排查可能的未关闭引用会比较麻烦。 - 上下文管理会自动处理异常,相当于我们的
close方法放在finally块中。
无关的事情:进程退出时的句柄
进程退出时如果有没有关闭的句柄,
- 如果程序正常退出,
- 语言可能会处理一道,清理相关数据
- 系统会处理一道
- 如果程序异常退出,则只有靠系统了
至少我看到 POSIX 中有相关规定,无论任何原因或任何方式的退出,都应该:
All of the file descriptors, directory streams, conversion descriptors, and message catalog descriptors open in the calling process shall be closed.
PS: 其中提到的:
- 文件描述符 File Descriptors
- 目录流 Directory Streams
- 转换描述符 Conversion Descriptors
- 消息编码描述符 Message Catalog Descriptors
后面三个是个啥?
#364 Shell 历史
Unix Linux Shell 2020-01-07参考: https://en.wikipedia.org/wiki/Comparison_of_command_shells
Linux Shell
- Thompson shell (sh), 1971, Unix v1 - v6
只存在历史中
在 Bourne shell 之前,贝尔实验室还出了一个 Mashey shell,只出现在 1976 年的 PWB UNIX 中(所以又叫 PWB shell),没有大范围使用 - Bourne shell (sh), 1977, Unix v7
- C shell (csh), 1978
- TENEX C shell (tcsh), 1983
是 TENEX 系统开发的 csh 兼容 Shell - Korn shell (ksh), 1983
- Bash, 1989
- Almquist shell (ash), 1989
- zsh, 1990
- Debian Almquist shell (dash), an ash fork, 1997
主体随 ash 是 BSD 协议,不过,可能是为了保持对 bash 的兼容,采用了 bash 项目的一个文件 - fish, 2005
分类
- ksh, bash, zsh, ash, dash 都是 Bourne shell 兼容。
- csh, tcsh 就是 csh 兼容。
- fish
说明
- Unix 上的 sh 有版权问题, 所以 BSD 和 Linux 上的
/bin/sh都指向某一种兼容 Shell (一般是默认 Shell) - RHEL/CentOS 上,默认 Shell 是 Bash
- Debian/Ubuntu 上,默认 Shell 是 Dash
- FreeBSD 上默认采用 tcsh, 基于 FreeBSD 的 GhostBSD 采用 fish
- OpenBSD 上默认采用 pdksh (pd: Public Domain), 不知道和 tsh 什么关系。可能是 OpenBSD 维护的 tsh 兼容 Shell。
- NetBSD 上默认采用 ash
- 由于 ash 非常轻量级,BusyBox 采用了 dash fork
然后 BusyBox 被 Alpine Linux, Tiny Core Linux 或者其他嵌入式 Linux (比如 OpenWrt) 采用,所以这些系统的默认 Shell 应该就是 ash
所以可能使用最广泛的 Shell 是 ash 和 bash。
其他:MacOS 上曾经默认采用 bash, 后来专向了 zsh
Windows 平台
- command.com, 1980
- cmd.exe, 1993
- PowerShell, 2006
#363 玩具总动员
影视 育儿 2020-01-06- 正片
Toy Story(1995)
巴斯光年,阿薛 - Toy Story Treats (1996) 电视剧
- 正片
Toy Story 2(1999)
公鸡人,翠丝 - Buzz Lightyear of Star Command (2000–2001) 电视剧
- Buzz Lightyear of Star Command: The Adventure Begins (2000)
- 正片
Toy Story 3(2010)
抱抱熊
故事的最后,玩具们都送给了邦妮 - Toy Story Toons (2011–2012) 玩具们在邦妮家的故事
- Hawaiian Vacation 短片:夏威夷假期
- Small Fry 短片:小玩具
- Partysaurus Rex 短片:派对恐龙
- Toy Story of Terror! (2013) 短片:惊魂夜
- Toy Story That Time Forgot (2014) 短片:遗忘时光
- Forky Asks a Question (2019–2020) 电视剧
- 正片
Toy Story 4(2019)
邦妮害怕上学,叉叉
胡迪最后跟宝贝走了 - Lamp Life (2020) 短片:牧羊女大冒险
- Pixar Popcorn (2021) 一分钟短片,其中有三部玩具总动员相关的短片。
- To Fitness and Beyond
- Fluffy Stuff with Ducky and Bunny: Love
- Fluffy Stuff with Ducky and Bunny: Three Heads
- Lightyear (2022)