Heim > Datenbank > MySQL-Tutorial > Hauptteil

Binlog中table_map_id 的探究_MySQL

WBOY
Freigeben: 2016-06-01 13:48:14
Original
1108 Leute haben es durchsucht

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';
Nach dem Login kopieren

输出结果:

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 */
Nach dem Login kopieren

查看Innodb的table-id:

select TABLE_ID from INNODB_SYS_TABLESTATS where `SCHEMA`='test' and NAME='map_id_test';
Nach dem Login kopieren

得到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';
Nach dem Login kopieren

输出结果如下:此时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 */
Nach dem Login kopieren

执行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;
Nach dem Login kopieren

 查看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 */
Nach dem Login kopieren

从实验可以得出结论,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';
Nach dem Login kopieren

执行结果: 从结果可以看出,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 */
Nach dem Login kopieren

 

结论:

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
Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage