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.复 ...
随机推荐
- row_number() over()分组排序功能 partition by 用于给结果集分组
select * from ( select row_number() over(partition by Gid order by Gid ASC) as RowN, * from( select ...
- Qt 一张图片显示在其他组件之上
图片放在QLabel上,注意设置QLable一些属性 QImage img("test.png"); img = img.scaledToWidth(,Qt::SmoothTran ...
- shell中函数的使用
函数是一个脚本代码块,你可以对它进行自定义命名,并且可以在脚本中任意位置使用这个函数.如果想要这个函数,只要调用这个函数的名称就可以了.使用函数的好处在于模块化以及代码可读性强. (1).函数的创建语 ...
- Windows 10 安装MySQL
1.下载MySQL官网:https://www.mysql.com/ 进入官网点击DOWNLOADS ->Community->DOWNLOADS (下载社区版) 2.安装MySQL 将下 ...
- notepad++之个性化配置
在Linux下,喜欢用vi做文件编辑(vim反倒没怎么用).在Windows系统下,用得最多的则是notepad++.开源大法好.. 之所以选择notepad++,是因为其不会强制你命名并保存文件,你 ...
- UltraISO制作启动U盘
使用UltraISO可以制作纯净版本启动U盘 下载 下载地址https://cn.ultraiso.net/ 打开ISO镜像 下载后双击安装完成以后打开软件 文件-打开-选择一个ISO镜像,例如win ...
- 解决SQL语句在Dapper执行超时比Query慢的问题
在语句结尾加上 Add OPTION (RECOMPILE) to the end https://stackoverflow.com/questions/10933366/sp-executesql ...
- Centos6 系统下源码方式安装Mysql 记录
在运维工作中经常部署各种运维环境,涉及mysql数据库的安装也是时常需要的.mysql数据库安装可以选择yum在线安装,但是这种安装的mysql一般是系统自带的,版本方面可能跟需求不太匹配. #### ...
- centos 7 下使用jexus 配置ASP.NET Core
1.安装jexus Jexus独立版(专业版)的安装 Jexus“独立版”指的是自带.net运行时(mono),不需要在客户服务器安装mono就能正常运行的Jexus版本,该版本只支持 64位Linu ...
- 分布式session一致性
实现思路:当客户端发送请求到服务端后,在后台生成一个token,将token作为key,用户状态信息作为value,存入redis缓存中,并设置过期时间,最后把token返回给客户端 客户端第会保存t ...