00 -表_映射_日志_事件
Table_map_log_Event是行格式Binlog中的一种事件。它记录了表的元数据信息。如数据库名、表名和字段类型。从机执行行事件时,表映射日志事件的功能如下:
-根据数据库名和表名,在从机上打开相应的表
-检查从属设备上的表的字段类型是否与主设备上的表的字段类型兼容。如果没有,从机将报告错误。
-将数据转换为从属表上的字段类型。然而,转换仅限于从机和主机的场类型兼容的情况。
01-生成table _ map _ log _ event
Table_map_log_event的单位是语句。在语句记录第一行事件之前,将为每个要更新的表生成一个表映射日志事件。因此,binlog中的Table_map_log_event具有以下特征:
-Table_map_log_event先于所有行事件
语句的行格式事件如下所示:
Query_log_event("BEGIN ")
db1.t1的Table_map_log_event //表
db1.t2的Table_map_log_event //表
db1.t1的Update_rows_log_event //更新
db1.t2的Update_rows_log_event //更新
Xid_log_event
-当语句不生成行事件时,不会生成Table_map_log_event。
这是因为在生成第一行事件时,会生成Table_map_log_event。这确保了当语句不产生任何更新时,binlog中不会记录任何事件。
-也可以记录Table_map_log_event,而不是生成row事件
记录Table_map_log_event时,无法确定表是否会更新数据。因此,将为所有具有写锁定的表生成Table_map_log_event。当您看到以下binlog内容时,不要感到惊讶:
Query_log_event("BEGIN ")
db1.t1的Table_map_log_event //表
db1.t2的Table_map_log_event //表
db1.t1的Update_rows_log_event //更新
Xid_log_event
-参考代码
在sql/handler.cc中写入_ locked _ table _ maps()和binlog_log_row()..
02-table_map_log_event格式
table_map_log_event格式如下图所示:
-包装_长度
首先,介绍了常用的术语pack_length。是一种数值存储方式,常用于二进制日志和MySQL的通讯包中。为了减少存储和传输过程中占用的空,长度字段和整形值以可变长度的方式存储。具体算法是:
-小于251的值
用1个字节直接存储该值
-251或以上和65535或以下(0xff)
首先,一个字节用于存储值252,然后两个字节用于存储值。
-大于65535且小于或等于16777215(0xFFF)的值
首先,将值253存储在1字节中,然后将值存储在3字节中。
-大于16777215的值
值254首先存储在一个字节中,然后存储在八个字节中。
在大多数情况下,如果该值小于251,这种存储方法可以保存空。同时可以支持数值大的情况。
-参考代码
SQL-common/pack.c中的net_store_length()
-事件标题
和其他事件一样。
-表格id
表id就像表的主键,它唯一地标识了一个table_map_log_event。要保存空,数据库名和表名不会记录在row事件中,但只会记录一个表id。通过将table_map_log_event与表id相关联,您可以知道生成了哪个表。
旗帜
当前未使用,内容始终为0,占2字节。
-数据库名称长度
数据库名称的长度,不包括“0”。使用包装长度进行储存。
-数据库名称
数据库的名称以“0”结尾,因此空之间占用的空间是数据库名称长度+1字节。
-表名长度
表名长度,不包括“0”。使用包装长度进行储存。
-表名
表的名称以“0”结尾,因此空之间占用的空间是表名长度+1字节。
-列数
字段数量。使用包装长度进行储存。
-列类型
这里的字段类型不是SQL语句中的类型,而是MySQL内部的数据类型。后面会详细介绍。每个字段的类型占用一个字节,总长度等于字段数。类型存储的顺序是根据主表中字段的顺序生成的。因此,如果从表上的字段顺序发生变化,将会导致错误。
-元数据长度
字段的元数据长度。使用包装长度进行储存。
-元数据
除了类型,字段还有长度等属性。这些属性信息存储在元数据中,这将在后面详细描述。
-空标志
字段是否可以是空的属性,每个字段占用一位。因为日志是以字节为最小单位记录的,所以当尾部小于1字节时,它被存储为1字节。比如有9个字段,前8个字段占用一个字节,后一个字段也需要占用一个字节,总共2个字节。存储顺序如下:第一个字节存储主机上第1-8个字段的null属性,第二个字节存储第9-16个字段的null属性,依次推送。在一个字节中,8个字段的空属性按字段顺序从低到高排列。例如:01010101,左边第一位是第一个字段的null属性,依次推送。代码在log_event.cc的Table_map_log_event()中..如下图所示:
03-table _ map _ log _ event中的字段类型
table_map_log_event中存储的字段类型是MySQL内部类型。了解内部类型和SQL数据类型的关系,可以帮助我们更好的理解MySQL的实现。下图显示了SQL数据类型和MySQL内部类型的对应关系:
- TINYINT/BOOL
BOOL只是TINYINT的别名。
- CHAR/BINARY
除了不同的字符集之外,CHAR和BINARY具有相同的特性。因此,它们使用相同的内部类型,并通过字符集属性进行区分。BINARY(N)等价于CHAR(N) CHARSET binary。
-VARCHAR/VARBINIC
类似于CHAR/BINARY
-枚举/设置
应该特别注意这一点。Table_map_log_event中的ENUM/SET与CHAR的类型相同,是MYSQL_TYPE_STRING。实际类型信息存储在元数据中。这三种类型可以通过元数据中的类型信息来区分。
-TINYBOB/BLOB/
-MEDIUMBLOB/long lob/
- TINYTEXT/TEXT/
-MEDIUMTExt/LOTEXT
文本和BLOB之间的关系类似于CHAR和BINARY。不同BLOB/TEXT类型之间的唯一区别是最大长度。因此,所有BLOB/TEXT字段在内部都由相同的类型表示。这种类型的字符集属性可以区分BLOB和TEXT。该类型还有一个最大长度属性,可以区分TINYBLOB和其他BLOB。信息的最大长度存储在元数据中。
04-不同字段的元数据
元数据按照主文档中字段的顺序记录字段的元数据(属性)信息。元数据信息具有以下特征:
-不同类型的字段可能有不同的属性信息和不同的长度。
-某些类型没有属性信息。
-任何类型的元数据信息的长度总是固定的。
根据列类型中的类型信息,我们可以知道每种类型的元数据信息。元数据中的元数据格式如下图所示:
C1的元数据占用2字节,C2的类型没有元数据,所以不占用空。C3的元数据只有一个字节,C4占用两个字节。
除以下类型外,所有其他类型都没有元数据。
- MYSQL_TYPE_FLOAT
1字节,内容:sizeof(浮点)。
- MYSQL_TYPE_DOUBLE
1字节,内容:sizeof(double)。
- MYSQL_TYPE_NEWDECIMAL
2字节,第一个字节是精度,第二个字节存储小数位。
- MYSQL_TYPE_BIT
2字节,第一个字节为(位长)/8,第二个字节为(位长)%8。
- MYSQL_TYPE_VARCHAR
2字节,存储长度。- MYSQL_TYPE_BLOB
1字节,存储blob的最大长度,单位字节。内容:1、2、3或4。
- MYSQL_TYPE_JSON
- MYSQL_TYPE_GOMETRY
这两种类型都是从BLOB继承的,所以元数据内容和MYSQL_TYPE_BLOB是一样的。
- MYSQL_TYPE_STRING
2字节。
-当实际类型为ENUM或SET时,第一个字节存储实类型MYSQL_TYPE_ENUM或MYSQL_TYPE_SET,第二个字节存储长度。
-当实际类型为CHAR时,使用2个字节来存储长度。为了避免与ENUM/SET的第一个字节冲突,采用了一种特殊的编码方法。
-参考代码
函数do_save_field_metadata()在sql/field.cc中
注意:本文代码参考的是MySQL-5.7中的代码,其他版本可能不一致。
推荐订阅原作者宋立兵在微信官方账号的MySQL代码研究
1.《mediumblob Table_map_log_event内容详解》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《mediumblob Table_map_log_event内容详解》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/jiaoyu/819683.html