搜索
首页数据库mysql教程Binlog中table_map_id 的探究_MySQL

bitsCN.com

背景:

最近,线上Row Based Replication(下称RBR)环境中遇到了一个Bug。这个bug简单的描述就是:RBR对于DML需要通过table-map的event来标注每一个有更新的表。

而当一个DML同时操作多个表,且其中2个表的mapid相同时(通常为0),会导致slave执行这个event时crash,并重启mysqld实例

可见这个bug的毁灭性极大。

那么table-map-id 究竟从何而来?有什么办法知道每个表table-map-id,从而进行一些必要的监控呢?

下文将用几个例子来进行分析说明。

 

1. table-map-id 和 Innodb的table-id是否是同一个概念?

其实这个问题的答案是显而易见的。因为并非Innodb的表才支持RBR,如果这个问题答案为“是”,那么非innodb的表在RBR中的table-map-id从何而来呢?又怎么保证和innodb的map-id不重复呢?

所以,显然table-map-id和Innodb数据字典中的table-id是完全不同的两个概念。

即便如此,下面还是用一个实例进行验证

create table map_id_test (ID int primary key);insert into map_id_test values (1);show binlog events in 'log-prefix.000025';

输出结果:

Log_name             Pos     Event_type   Server_id    End_log_pos    Infolog-prefix.000025    2156    Query        15757        2224           BEGINlog-prefix.000025    2224    Table_map    15757        2274           table_id: 88 (test.map_id_test)log-prefix.000025    2274    Write_rows   15757        2308           table_id: 88 flags: STMT_END_Flog-prefix.000025    2308    Xid          15757        2335           COMMIT /* xid=346 */

查看Innodb的table-id:

select TABLE_ID from INNODB_SYS_TABLESTATS where `SCHEMA`='test' and NAME='map_id_test';

得到TABLE_ID = 170

 

 

2. table-map-id是否和物理文件有绑定关系

虽然table-map-id和Innodb的table-id是完全不同的概念。而我们知道Innodb中的table-id和物理文件有绑定关系,即rename table的操作不会改变dict-table中的table-id。

那么binlog中的table-map-id是不是有可能借鉴了这种实现方式,也有这个特性呢?

下面是具体测试过程

set global binlog_format='row';create table map_id_test1 (ID int primary key);create table map_id_test2 (ID int primary key);insert into map_id_test1 values (1);insert into map_id_test2 values (1);show binlog events in 'log-prefix.000025';

输出结果如下:此时table1 对应table_id:83 , tabl2 对应table_id:84 

Log_name             Pos     Event_type   Server_id End_log_pos    Infolog-prefix.000025    1157    Query        15757     1225           BEGINlog-prefix.000025    1225    Table_map    15757     1276           table_id: 83 (test.map_id_test1)log-prefix.000025    1276    Write_rows   15757     1310           table_id: 83 flags: STMT_END_Flog-prefix.000025    1310    Xid          15757     1337           COMMIT /* xid=327 */log-prefix.000025    1337    Query        15757     1405           BEGINlog-prefix.000025    1405    Table_map    15757     1456           table_id: 84 (test.map_id_test2)log-prefix.000025    1456    Write_rows   15757     1490           table_id: 84 flags: STMT_END_Flog-prefix.000025    1490    Xid          15757     1517           COMMIT /* xid=330 */

执行rename table,交换table1和table2

rename table map_id_test1 to map_id_test1_bak,map_id_test2 to map_id_test1, map_id_test1_bak to map_id_test2;

 查看binlog:此时table1 对应table_id:86 , tabl2 对应table_id:87。

Log_name             Pos     Event_type    Server_id    End_log_pos    Infolog-prefix.000025    1688    Query         15757        1756           BEGINlog-prefix.000025    1756    Table_map     15757        1807           table_id: 86 (test.map_id_test1)log-prefix.000025    1807    Write_rows    15757        1841           table_id: 86 flags: STMT_END_Flog-prefix.000025    1841    Xid           15757        1868           COMMIT /* xid=334 */log-prefix.000025    1868    Query         15757        1936           BEGINlog-prefix.000025    1936    Table_map     15757        1987           table_id: 87 (test.map_id_test2)log-prefix.000025    1987    Write_rows    15757        2021           table_id: 87 flags: STMT_END_Flog-prefix.000025    2021    Xid           15757        2048           COMMIT /* xid=335 */

从实验可以得出结论,RBR中的table_id 不仅和物理文件没有绑定关系,在MySQL实例的运行过程中也不是静态不变的。

因此,大胆猜测,table_id 和file handler有关系。下面的测试将进行验证。

 

3. table_id 和file handler是否有直接联系?

insert into map_id_test1 values (3);flush tables;insert into map_id_test1 values (4);show binlog events in 'log-prefix.000025';

执行结果: 从结果可以看出,flush table导致了,file handler的重新打开。同时也使table-map-id 发生了变化,且线性递增。

Log_name             Pos     Event_type    Server_id    End_log_pos    Infolog-prefix.000025    2424    Query         15757        2492           BEGINlog-prefix.000025    2492    Table_map     15757        2543           table_id: 89 (test.map_id_test1)log-prefix.000025    2543    Write_rows    15757        2577           table_id: 89 flags: STMT_END_Flog-prefix.000025    2577    Xid           15757        2604           COMMIT /* xid=383 */log-prefix.000025    2604    Query         15757        2679           use `test`; flush tableslog-prefix.000025    2679    Query         15757        2747           BEGINlog-prefix.000025    2747    Table_map     15757        2798           table_id: 90 (test.map_id_test1)log-prefix.000025    2798    Write_rows    15757        2832           table_id: 90 flags: STMT_END_Flog-prefix.000025    2832    Xid           15757        2859           COMMIT /* xid=385 */

 

结论:

1. RBR中的Table_ID 和Innodb中的table_id 没有关系,且和物理文件没有对应关系。

2. Flush Table 可以重置RBR中的Table_ID ,如果有表遇到了map_id=0 的情况,可以使用这个方法尝试解决问题。

3. 虽然和File Handler 有关,但是和 /proc/$PID/fd/ 中的fd数值没有直接联系

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

bitsCN.com
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
将用户添加到MySQL:完整的教程将用户添加到MySQL:完整的教程May 12, 2025 am 12:14 AM

掌握添加MySQL用户的方法对于数据库管理员和开发者至关重要,因为它确保数据库的安全性和访问控制。1)使用CREATEUSER命令创建新用户,2)通过GRANT命令分配权限,3)使用FLUSHPRIVILEGES确保权限生效,4)定期审计和清理用户账户以维护性能和安全。

掌握mySQL字符串数据类型:varchar vs.文本与char掌握mySQL字符串数据类型:varchar vs.文本与charMay 12, 2025 am 12:12 AM

chosecharforfixed-lengthdata,varcharforvariable-lengthdata,andtextforlargetextfield.1)chariseffity forconsistent-lengthdatalikecodes.2)varcharsuitsvariable-lengthdatalikenames,ballancingflexibilitibility andperformance.3)

MySQL:字符串数据类型和索引:最佳实践MySQL:字符串数据类型和索引:最佳实践May 12, 2025 am 12:11 AM

在MySQL中处理字符串数据类型和索引的最佳实践包括:1)选择合适的字符串类型,如CHAR用于固定长度,VARCHAR用于可变长度,TEXT用于大文本;2)谨慎索引,避免过度索引,针对常用查询创建索引;3)使用前缀索引和全文索引优化长字符串搜索;4)定期监控和优化索引,保持索引小巧高效。通过这些方法,可以在读取和写入性能之间取得平衡,提升数据库效率。

mysql:如何远程添加用户mysql:如何远程添加用户May 12, 2025 am 12:10 AM

ToaddauserremotelytoMySQL,followthesesteps:1)ConnecttoMySQLasroot,2)Createanewuserwithremoteaccess,3)Grantnecessaryprivileges,and4)Flushprivileges.BecautiousofsecurityrisksbylimitingprivilegesandaccesstospecificIPs,ensuringstrongpasswords,andmonitori

MySQL字符串数据类型的最终指南:有效的数据存储MySQL字符串数据类型的最终指南:有效的数据存储May 12, 2025 am 12:05 AM

tostorestringsefliceflicyInmySql,ChooSetherightDataTypeBasedyOrneOrneEds:1)USEcharforFixed-LengthStstringStringStringSlikeCountryCodes.2)UseVarcharforvariable-lengtthslikenames.3)USETEXTCONTENT.3)

mysql blob vs.文本:为大对象选择正确的数据类型mysql blob vs.文本:为大对象选择正确的数据类型May 11, 2025 am 12:13 AM

选择MySQL的BLOB和TEXT数据类型时,BLOB适合存储二进制数据,TEXT适合存储文本数据。1)BLOB适用于图片、音频等二进制数据,2)TEXT适用于文章、评论等文本数据,选择时需考虑数据性质和性能优化。

MySQL:我应该将root用户用于产品吗?MySQL:我应该将root用户用于产品吗?May 11, 2025 am 12:11 AM

No,youshouldnotusetherootuserinMySQLforyourproduct.Instead,createspecificuserswithlimitedprivilegestoenhancesecurityandperformance:1)Createanewuserwithastrongpassword,2)Grantonlynecessarypermissionstothisuser,3)Regularlyreviewandupdateuserpermissions

MySQL字符串数据类型说明了:选择适合您数据的合适类型MySQL字符串数据类型说明了:选择适合您数据的合适类型May 11, 2025 am 12:10 AM

mySqlStringDatatatPessHouldBechoseBeadeDataCharacteristicsAndUsecases:1)USECHARFORFIXED LENGTHSTRINGSTRINGSLIKECOUNTRYCODES.2)USEDES.2)usevarcharforvariable-lengtthstringstringstringstringstringstringstringslikenames.3)usebinaryorvarrinaryorvarinarydatalbonydatalgebgeenfopical.4)

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具