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

本文討論了使用MySQL的Alter Table語句修改表,包括添加/刪除列,重命名表/列以及更改列數據類型。

文章討論了為MySQL配置SSL/TLS加密,包括證書生成和驗證。主要問題是使用自簽名證書的安全含義。[角色計數:159]

文章討論了流行的MySQL GUI工具,例如MySQL Workbench和PhpMyAdmin,比較了它們對初學者和高級用戶的功能和適合性。[159個字符]

本文討論了使用Drop Table語句在MySQL中放下表,並強調了預防措施和風險。它強調,沒有備份,該動作是不可逆轉的,詳細介紹了恢復方法和潛在的生產環境危害。

本文討論了在PostgreSQL,MySQL和MongoDB等各個數據庫中的JSON列上創建索引,以增強查詢性能。它解釋了索引特定的JSON路徑的語法和好處,並列出了支持的數據庫系統。

文章討論了使用準備好的語句,輸入驗證和強密碼策略確保針對SQL注入和蠻力攻擊的MySQL。(159個字符)


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

Atom編輯器mac版下載
最受歡迎的的開源編輯器