再说MySQL中的 table_id

最近线上一个实例出现了主从数据不一致的情况,也即从库丢失数据的情况。根本原因:由于table_list-gt;table_id为uint,而m_table

【背景】
最近线上一个实例出现了主从数据不一致的情况,也即从库丢失数据的情况。根本原因:”由于table_list->table_id为uint,而m_table_id为ulong,主库上assign的table map id 总是一直递增的
当超过2^32后,备库出现溢出,,导致row模式下备库对应table id的事件全部丢失,产生主备不一致。”
【问题分析】
一 table_id 介绍
当mysql 开启日志模式时,binlog会记录所有对数据库的变更操作。binlog 分两种模式 statement 模式和row 模式。
当数据库的binlog format 是statement 模式时
例子:数据库中执行 一条语句
root@rac2 [yangyi]> insert into t1 values(9);
query ok, 1 row affected (0.00 sec)
root@rac2 [yangyi]> show binlog events in ‘mysql-bin.000003’;
+——————+—–+————-+———–+————-+—————————————-+
| log_name | pos | event_type | server_id | end_log_pos | info |
+——————+—–+————-+———–+————-+—————————————-+
| mysql-bin.000003 | 4 | format_desc | 2 | 106 | server ver: 5.1.68-log, binlog ver: 4 |
| mysql-bin.000003 | 106 | query | 2 | 176 | begin |
| mysql-bin.000003 | 176 | query | 2 | 265 | use `yangyi`; insert into t1 values(8) |
| mysql-bin.000003 | 265 | xid | 2 | 292 | commit /* xid=12 */ |
| mysql-bin.000003 | 292 | query | 2 | 369 | use `yangyi`; flush tables |
| mysql-bin.000003 | 369 | query | 2 | 439 | begin |
| mysql-bin.000003 | 439 | query | 2 | 528 | use `yangyi`; insert into t1 values(9) |
| mysql-bin.000003 | 528 | xid | 2 | 555 | commit /* xid=15 */ |
+——————+—–+————-+———–+————-+—————————————-+
8 rows in set (0.00 sec)
binlog 的log event 记录如下:
#140511 14:44:12 server id 2 end_log_pos 439 query thread_id=1 exec_time=0 error_code=0
set timestamp=1399790652/*!*/;
begin
/*!*/;
# at 439
#140511 14:44:12 server id 2 end_log_pos 528 query thread_id=1 exec_time=0 error_code=0
set timestamp=1399790652/*!*/;
insert into t1 values(9)
/*!*/;
# at 528
#140511 14:44:12 server id 2 end_log_pos 555 xid = 15
commit/*!*/;
从日志分析来看 ,dml会记录为原始的sql,也就是记录在query_event中。

当数据库的binlog format 是row模式时
执行insert 操作
root@rac2 [yangyi]> insert into t1 values(6);
query ok, 1 row affected (0.00 sec)
root@rac2 [yangyi]> show binlog events in ‘mysql-bin.000002’;
+——————+—–+————-+———–+————-+—————————————+
| log_name | pos | event_type | server_id | end_log_pos | info |
+——————+—–+————-+———–+————-+—————————————+
| mysql-bin.000002 | 4 | format_desc | 2 | 106 | server ver: 5.1.68-log, binlog ver: 4 |
| mysql-bin.000002 | 106 | query | 2 | 176 | begin |
| mysql-bin.000002 | 176 | table_map | 2 | 219 | table_id: 18 (yangyi.t1) |
| mysql-bin.000002 | 219 | write_rows | 2 | 253 | table_id: 18 flags: stmt_end_f |
| mysql-bin.000002 | 253 | xid | 2 | 280 | commit /* xid=61 */ |
+——————+—–+————-+———–+————-+—————————————+
5 rows in set (0.00 sec)
binlog中记录的信息:
begin
/*!*/;
# at 176
# at 219
#140511 14:31:43 server id 2 end_log_pos 219 table_map: `yangyi`.`t1` mapped to number 18
#140511 14:31:43 server id 2 end_log_pos 253 write_rows: table id 18 flags: stmt_end_f
binlog ‘
txlvuxmcaaaakwaaansaaaaaabiaaaaaaaeabnlhbmd5aqacddeaaqmaaq==
txlvuxccaaaaigaaap0aaaaaabiaaaaaaaeaaf/+bgaaaa==
‘/*!*/;
### insert into `yangyi`.`t1`
### set
### @1=6 /* int meta=0 nullable=1 is_null=0 */
# at 253
#140511 14:31:43 server id 2 end_log_pos 280 xid = 61
commit/*!*/;
从解析的binlog中可以看出row模式下,dml操作会记录为:table_map_event+row_log_event(包括write_rows_event ,update_rows_event,delete_rows_event).
为什么一个update在row模式下需要分解成两个event:一个table_map,一个update_rows。我们想象一下,一个update如果更新了10000条数据,那么对应的表结构信息是否需要记录10000次?其实是对同一个表的操作,所以这里binlog只是记录了一个table_map用于记录表结构相关信息,而后面的update_rows记录了更新数据的行信息。他们之间是通过table_id来联系的。

二 table_id 的特性
1 table_id 并不是固定的,它是当表被载入内存(table_definition_cache)时,临时分配的,是一个不断增长的变量。
2 当有新的table变更时,在cache中没有,就会触发一次load table def的操作,此时就会在原先最后一次table_id基础上+1,做为新的table def的id。
3 flush tables,之后对表的更新操作也会触发table_id 的增长。
4 如果table def cache过小,就会出现频繁的换入换出,从而导致table_id增长比较快。
例子
root@rac2 [yangyi]> show binlog events in ‘mysql-bin.000002’;
+——————+—–+————-+———–+————-+—————————————+
| log_name | pos | event_type | server_id | end_log_pos | info |
+——————+—–+————-+———–+————-+—————————————+
| mysql-bin.000002 | 4 | format_desc | 2 | 106 | server ver: 5.1.68-log, binlog ver: 4 |
| mysql-bin.000002 | 106 | query | 2 | 176 | begin |
| mysql-bin.000002 | 176 | table_map | 2 | 219 | table_id: 18 (yangyi.t1) |
| mysql-bin.000002 | 219 | write_rows | 2 | 253 | table_id: 18 flags: stmt_end_f |
| mysql-bin.000002 | 253 | xid | 2 | 280 | commit /* xid=61 */ |
| mysql-bin.000002 | 280 | query | 2 | 357 | use `yangyi`; flush tables |
| mysql-bin.000002 | 357 | query | 2 | 427 | begin |
| mysql-bin.000002 | 427 | table_map | 2 | 470 | table_id: 19 (yangyi.t1) |
| mysql-bin.000002 | 470 | write_rows | 2 | 504 | table_id: 19 flags: stmt_end_f |
| mysql-bin.000002 | 504 | xid | 2 | 531 | commit /* xid=65 */ |
+——————+—–+————-+———–+————-+—————————————+
10 rows in set (0.00 sec)

Ubuntu 14.04下安装MySQL

《MySQL权威指南(原书第2版)》清晰中文扫描版 PDF

Ubuntu 14.04 LTS 安装 LNMP NginxPHP5 (PHP-FPM)MySQL

Ubuntu 14.04下搭建MySQL主从服务器

Ubuntu 12.04 LTS 构建高可用分布式 MySQL 集群

Ubuntu 12.04下源代码安装MySQL5.6以及Python-MySQLdb

更多详情见请继续阅读下一页的精彩内容:

linux

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/1973181.html

(0)
上一篇 2025年2月23日 08:18:45
下一篇 2025年2月23日 08:19:03

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • navicat怎么添加数据

    打开Navicat。 打开数据表所在的数据库,右击需要新增记录的数据库表,然后点击“打开表”。 相关推荐:《Navicat for mysql使用图文教程》 此时显示数据库表已有数据,例中并无记录。 直接在表中输入第一条记录的信息,一般字段…

    2025年2月23日 数据库
    100
  • navicat怎么导出数据

    当我们对mysql数据库进行了误操作,造成某个数据表中的部分数据丢失时,肯定就要利用备份的数据库,对丢失部分的数据进行导出、导入操作了。Navicat工具正好给我们提供了一个数据表的导入导出功能。 导出数据表 Navicat导出数据表的格式…

    2025年2月23日 数据库
    100
  • Excel数据如何批量导入navicat

    打开电脑上的Navicat,点击左上角的“连接”。 选择数据库类型。 填写相关的信息。 创建好之后就会显示存在的数据库名。 相关推荐:《Navicat for mysql使用图文教程》 选择指定的数据库名,右键单击,选择导入向导。 选择文件…

    2025年2月23日 数据库
    100
  • 不同备份策略不兼容引起的磁盘空间故障解决实例

    最近接收一个系统,上线运维一年余。交接时候,业务部门反映曾经出现磁盘空间占满故障。当时引起整个系统瘫痪,最后联系开发商介 应用系统生命周期是一个整体,除了最开始的需求调研、开发测试和上线,更长的时期是在运维方面。应用系统的价值体现也就是在运…

    数据库 2025年2月23日
    100
  • Oracle并行执行特性应用初探

    在历史数据转出测试过程中,通过不断的优化,包括SQL调整和数据库调整,从AWR中看到,基本上难以进行更多的性能提升,于是准备试 1. 序 在历史数据转出测试过程中,通过不断的优化,包括sql调整和数据库调整,从awr中看到,基本上难以进行更…

    数据库 2025年2月23日
    100
  • Oracle生产环境RMAN备份脚本

    题记:这里分享一下我们Oracle的备份脚本,这些脚本均在生产库运行,正确无误! 环境:SUSE Linux 10sp2 + Oracle 11gR1 说明:小 题记:这里分享一下我们oracle的备份脚本,这些脚本均在生产库运行,正确无误…

    数据库 2025年2月23日
    100
  • xtraBackup备份原理剖析

    xtrabackup作为innodb的hotbackup工具,由percona公司开发,因开源,热备份和物理备份而在mysql中部署广泛,详情的说明可见之前的 xtrabackup作为innodb的hotbackup工具,由percona公…

    数据库 2025年2月23日
    100
  • 更改Oracle数据库连接端口

    Oracle数据库默认数据库监听与连接端口是1521, 但是有时候项目中需要更改默认端口,这样做很多时候客户要求,基于安全考虑. 以Ora oracle数据库默认数据库监听与连接端口是1521, 但是有时候项目中需要更改默认端口,,这样做很…

    数据库 2025年2月23日
    200
  • ORA-04030错误解决过程一例

    综合分析,报了04030的错误,而下面又分别报了27302及27301的错误。根据报错的意思,一方面,创建会话失败,另一方面,无法找到映 今天客户说从数据库后台发现报错,具体如下: Errors in file /Oracle/linuxi…

    数据库 2025年2月23日
    200
  • Linux中Mysql相关配置

    在Linux中安装好Mysql之后,要进行一些相关配置。根据需要修改 /etc/my.cnf,参考配置:[mysqld]# 设置默认为 INNODB 表,支持事务,支持行锁 在Linux中安装好Mysql之后,要进行一些相关配置。 根据需要…

    数据库 2025年2月23日
    200

发表回复

登录后才能评论