MySQL Replication--TABLE_ID与行格式复制
BINLOG中的TABLE_ID
在ROW格式的二进制中,事件信息中没有列的信息,需要通过Table_Map将表名对于的表信息加载到cache中,然后根据事件信息中的列下标来定位到数据列,每次表信息加载到Cache中时,会得到一个自增的ID值,即Table_ID:
# at 1794
#190717 13:08:44 server id 4294967295 end_log_pos 1855 GTID last_committed=5 sequence_number=6 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaa01:9'/*!*/;
# at 1855
#190717 13:08:44 server id 4294967295 end_log_pos 1919 Query thread_id=306 exec_time=0 error_code=0
SET TIMESTAMP=1563340124/*!*/;
BEGIN
/*!*/;
# at 1919
#190717 13:08:44 server id 4294967295 end_log_pos 1956 Rows_query
# delete from tb001
# at 1956
#190717 13:08:44 server id 4294967295 end_log_pos 2002 Table_map: `db001`.`tb001` mapped to number 108
# at 2002
#190717 13:08:44 server id 4294967295 end_log_pos 2069 Delete_rows: table id 108 flags: STMT_END_F BINLOG '
XK0uXR3/////JQAAAKQHAACAABFkZWxldGUgZnJvbSB0YjAwMQ==
XK0uXRP/////LgAAANIHAAAAAGwAAAAAAAEABWRiMDAxAAV0YjAwMQACAwMAAg==
XK0uXSD/////QwAAABUIAAAAAGwAAAAAAAEAAgAC//wIAAAAAQAAAPwPAAAAAQAAAPwWAAAAAQAA
APwdAAAAAQAAAA==
'/*!*/;
### DELETE FROM `db001`.`tb001`
### WHERE
### @1=8 /* INT meta=0 nullable=0 is_null=0 */
### @2=1 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM `db001`.`tb001`
### WHERE
### @1=15 /* INT meta=0 nullable=0 is_null=0 */
### @2=1 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM `db001`.`tb001`
### WHERE
### @1=22 /* INT meta=0 nullable=0 is_null=0 */
### @2=1 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM `db001`.`tb001`
### WHERE
### @1=29 /* INT meta=0 nullable=0 is_null=0 */
### @2=1 /* INT meta=0 nullable=1 is_null=0 */
# at 2069
#190717 13:08:44 server id 4294967295 end_log_pos 2096 Xid = 30
COMMIT/*!*/;
在基于行的复制模式下,为什么BINLOG中使用TABLE_ID而不直接使用表名:
1、如果某事务中一条SQL语句修改了100万行记录,那么会在该事务对应的BINLOG中记录这100万记录相应的信息,通过TABLE_ID方式来映射表名,那么仅需要存储一次表名即可,后面的使用TABLE_ID代替,可以有效降低BINLOG长度。
导致TABLE_ID发生变化的操作有:
1>DDL语句执行
2>Flush Tables语句执行
3>Table被加载到Table Cahche
MYSQL使用Table Cache来存放表定义信息,当Table Cache中无空闲空间来存放新的表信息后,会根据算法将一部分近期没有被使用的表信息换出Table Cache。如果TableCache设置过小,而数据库中存在大量的用户表需要加载到Table Cahche中,那么会导致表定义信息频繁地被换入换出,导致Table_ID急剧增大。
查看TABLE CACHE相关信息:
#查看TableCache的配置
SHOW VARIABLES LIKE '%table%cache%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| table_definition_cache | 16384 |
| table_open_cache | 16384 |
| table_open_cache_instances | 16 |
+----------------------------+-------+ #查看缓存的表定义信息
SHOW STATUS LIKE '%open%table%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| Com_show_open_tables | 0 |
| Open_table_definitions | 118 |
| Open_tables | 231 |
| Opened_table_definitions | 6 |
| Opened_tables | 100 |
| Slave_open_temp_tables | 0 |
+--------------------------+-------+
Open_table_definitions: The number of cached .frm files.
Opened_table_definitions : The number of .frm files that have been cached.
Open_tables: The number of tables that are open.
Opened_tables : The number of tables that have been opened. If Opened_tables is big, your table_open_cache value is probably too small.
如果Open_tables等于或接近table_open_cache,说明Table Cache已满或已快满。
如果Opened_tables值较大,则说明表定义信息被频繁换入换出Table Cache,参数table_open_cache可能设置过小。
TABLE_ID导致的BUG
在定义Table id时采用8byte的ulong类型列来存放,但在同步的SQL线程中使用4byte的uint类型列来存放,因此当同步的SQL线程中Table id值超过2^32的时,会导致应用SQL失败,即主库上的二进制可以同步到从库的中继日志中,但应用二进制日志日志失败,导致主从数据丢失。
PS1: 基于STATEMENT格式的二进制日志不需要使用table_id来查看表信息
PS2: 主库和从库上的Table ID没有任何关联关系,每个实例上的Table id都是独立生成的。
MySQL Replication--TABLE_ID与行格式复制的更多相关文章
- 17.1.2.1 Advantages and Disadvantages of Statement-Based and Row-Based Replication 基于语句和行的复制的优势和劣势
17.1.2.1 Advantages and Disadvantages of Statement-Based and Row-Based Replication 基于语句和行的复制的优势和劣势 每 ...
- 在Docker平台实现MySQL Replication(复制)
MySQL Replication提供了数据库之间复制数据的功能,通过这个功能可以让一个数据库的数据更改自动同步到另外一个数据库.通常用这个功能来实现数据备份.数据容灾.数据冗余,进一步实现数据的读写 ...
- 浅谈MySQL Replication(复制)基本原理
1.MySQL Replication复制进程MySQL的复制(replication)是一个异步的复制,从一个MySQL instace(称之为Master)复制到另一个MySQL instance ...
- 14.19 InnoDB and MySQL Replication InnoDB 和MySQL 复制:
14.19 InnoDB and MySQL Replication InnoDB 和MySQL 复制: MySQL 复制工作对于InnoDB 表和对于MyISAM表. 它是可能使用复制的方式 存储引 ...
- 转:MySQL Row Format(MySQL行格式详解)
MySQL Row Format(MySQL行格式详解) --转载自登博的博客
- MySQL 行格式
以 MySQL 默认的存储引擎 InnoDB 为例 InnoDB 包含以下四种行格式 Compact Redundant Dynamic Compressed 指定行格式 CREATE TABLE 表 ...
- 【大白话系列】MySQL 学习总结 之 COMPACT 行格式的设计原理
如果大家对我的 [大白话系列]MySQL 学习总结系列 感兴趣的话,可以点击关注一波. 一.回顾 MySQL 学习总结系列至此已经第七节了. 从大方向:我们已经学习了 MySQL 的架构设计.Inno ...
- Mysql之InnoDB行格式、数据页结构
Mysql架构图 存储引擎负责对表中的数据的进行读取和写入,常用的存储引擎有InnoDB.MyISAM.Memory等,不同的存储引擎有自己的特性,数据在不同存储引擎中存放的格式也是不同的,比如Mem ...
- 浅析 MySQL Replication(本文转自网络,非本人所写)
作者:卢飞 来源:DoDBA(mysqlcode) 0.导读 本文几乎涵盖了MySQL Replication(主从复制)的大部分知识点,包括Replication原理.binlog format.复 ...
随机推荐
- PHP 1000个进程同时利用file_put_contents的追加FILE_APPEND模式
1000个进程同时利用file_put_contents的追加FILE_APPEND模式,不会出现写入的数据被覆盖? <?php // fork出1000个进程查询,内存大,cpu屌,1000个 ...
- ElasticSearch集群状态查看命令大全(转)
原文地址: https://blog.csdn.net/pilihaotian/article/details/52460747 Elasticsearch中信息很多,同时ES也有很多信息查看命令,可 ...
- Python原生调试工具pdb实践小结
使用python -m pdb xxx.py进入单步调试模式,默认会在脚本的第一行可执行命令处停止.此时,通过 b function设置之后的函数断点会提示出错,从出错异常栈中可以看出,pdb是将fu ...
- 使用filebeat发送nginx日志到kafka
1.配置filebeat_nginx.yml filebeat.modules: - module: nginx access: enabled: true var.paths: ["/va ...
- hive的分桶原理
套话之分桶的定义: 分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储.对于 hive 中每一个表.分区都可以进一步进行分桶. 列的哈希值除以桶的个数来决定每条数据划分在哪个桶中.(网上其它定 ...
- Linux下安装.NET Core
环境 { "操作系统":"CentOS 7.5 64位", "CPU":"1核", "内存":&qu ...
- 大数据 -- kafka学习笔记:知识点整理(部分转载)
一 为什么需要消息系统 1.解耦 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 2.冗余 消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险.许多 ...
- elk使用记录
1.使用elk查询接口的时候 几个常用参数 http_host.raw 2.具体的接口名称:request_uri 3.想要把左边要查询的显示出来
- C# web项目乱码问题解决
在 web.config 文件中添加代码 <globalization requestEncoding="GB2312" responseEncoding="GB ...
- svg可视化制作工具
svg可视化制作工具直接ai里面用钢笔路径画好 然后右键建立复合路径 最后存储为svg即可 这样生成的svg就带path标签了