0

0

再说MySQL中的 table_id

php中文网

php中文网

发布时间:2016-06-07 16:49:27

|

1513人浏览过

|

来源于php中文网

原创

最近线上一个实例出现了主从数据不一致的情况,也即从库丢失数据的情况。根本原因:由于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 Nginx\PHP5 (PHP-FPM)\MySQL

Ubuntu 14.04下搭建MySQL主从服务器

PHP简约自动发卡平台个人版
PHP简约自动发卡平台个人版

PHP自动发卡平台个人版是采用php+mysql进行开发的自动发卡支付平台。服务器环境:PHP5.2以上版本mysql5.1 或以上版本安装说明:安装 http://你的域名/install.php 进行安装,后台路径http://你的域名/admin 后台账号:admin 后台密码:yc88.net需要修改用户名,可以进入数据库进行修改faka_users把admin改成其他支持改成中文

下载

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

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

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

linux

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

19

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

6

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

1

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

2

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

1

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

61

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

53

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

26

2026.01.31

golang 循环遍历
golang 循环遍历

本专题整合了golang循环遍历相关教程,阅读专题下面的文章了解更多详细内容。

31

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 5.1万人学习

PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号