26 | 备库为什么会延迟好几个小时?

导致备库延迟的原因。偶发性查询、备份,备库延迟影响分钟级,能追上来。

备库执行日志的速度持续低于主库生成日志的速度,延迟小时级别。压力持续高主库来说,永远都追不上


图 1 主备流程图

1、备库并行复制能力

黑色的两个箭头:写入主库(并行度高),备库上 sql_thread 执行中转日志(relay log)

    主库:各种锁影响并发度。支持行锁,除极端场,并发度好。并发压测线程 32 就比单线程时,总吞吐量高

    备库: sql_thread 更新数据 (DATA) 的逻辑。单线程主备延迟(5.6 之前),主库并发高、TPS 高严重主备延迟

图 2 多线程模型

2、复制机制:sql_thread拆成多个线程

coordinator 就是sql_thread, 不直接更新,只读中转日志和分发事务。真正更新日志worker 线程。个数slave_parallel_workers 8~16 之间最好(32 核物理机),备库提供读查询,不能把 CPU 都吃光。

3、coordinator 分发两个基本要求:

    1)不能更新覆盖更新同一行两个事务,分发同一worker 中。

    例:第二个比第一个事务先执行。主、备执行顺序相反,不一致

    2) 同一事务放同一个 worker 中

例:事务更新了表 t1 、2 各一行,分到不同 worker ,最终结果主备一致的, t1 执行完成瞬间,备库上有一个查询,看到事务“更新了一半的结果”,破坏隔离性。

一、MySQL 5.5 并行复制策略

不支持并行复制的。备库单线程复制。

1.1按表分发策略

两个事务更新不同表,可并行。如是跨表事务,放一起考虑。

图 3 按表并行复制程模型

每个 worker 线程对应一个 hash 表,保存当前正在这个 worker “执行队列”事务所涉及的表。hash 表 key 是“库名. 表名”,value 数字,队列多少个事务修改表。

有事务分配给 worker 时,事务里面涉及的表会被加到对应的 hash 表中。worker 执行完成后,这个表会被从 hash 表中去掉。

图 3 中,hash_table_1 表示,现在 worker_1 的“待执行事务队列”里,有 4 个事务涉及到 db1.t1 表,有1 涉及到 db2.t2 表;hash_table_2 worker_2 有一个事务会更新到表 t3 的数据。

coordinator 从中转日志中读入一个新事务 T,这个事务修改的行涉及到表 t1 和 t3。

事务 T 的分配流程,看分配规则。

1. 由于事务 T 中涉及修改表 t1,worker_1 队列中有事务在修改表 t1,事务 T 和队列中的某个事务要修改同一个表的数据,冲突。

2. 顺序判断事务 T 和每个 worker 队列的冲突关系,事务 T 跟 worker_2 也冲突。

3. T 跟多于一个 worker 冲突,coordinator 等待。

4.  每个 worker 继续执行,同时修改 hash_table。假设 hash_table_2里面涉及到修改表 t3 的事务先执行完成,从 hash_table_2中把 db1.t3 这一项去掉。

5.  冲突的 worker 只有 worker_1 了,因此就把它分配给 worker_1。

6.  coordinator 读下一个中转日志,分配事务。

worker 冲突关系包括以下三种情况:

1.  跟所有 worker 都不冲突,coordinator 分配给最空闲woker;

2.  跟多于一个 worker 冲突,coordinator 等待状态,直到只剩1 个

3.  只跟一个 worker 冲突,分配给这个 worker

负载均匀效果好。热点表,涉及某一个表的时候,所有事务都会被分配到同一个 worker 中,单线程复制。

1.2按行分发策略

没更新相同行,备库可并行。 binlog 格式 row。

这时候,我们判断一个事务 T 和 worker 是否冲突,用的就规则就不是“修改同一个表”,而是“修改同一行”。

数据结构差不多,为每个 worker, hash 表。key,“库名 + 表名 + 唯一键值”。

唯一键:除了主键,还有唯一索引 a:主库执行这两个事务:

图 4 唯一键冲突示例

更新的行主键值不同,分到不同的 worker,B 先执行。 id=1 行 a 值还是 1,唯一键冲突。

因此,基于行的策略,事务 hash 表中还需要考虑唯一键, key “库名 + 表名 + 索引 a 的名字 +a 的值”。

表 t1 上执行 update t1 set a=1 where id=2 语句, binlog 记录行修改前后各个字段值。

coordinator在解析这个语句的 binlog 时,hash 表三个项:

1. key=hash_func(db1+t1+“PRIMARY”+2), value=2; 修改前后行 id 值不变,出现两次

2.  key=hash_func(db1+t1+“a”+2), value=1,影响表 a=2 行

3.  key=hash_func(db1+t1+“a”+1), value=1,影响表 a=1 行

按行并行,消耗更多计算资源。约束条件:

1.  从 binlog 里解析出表名、主键值和唯一索引的值。主库 binlog 格式必须row;

2.  必须有主键

3.  不能有外键。级联更新行不记录 binlog 中,冲突检测不准确。

按行并行度高。大事务的话,两个问题:

1. 耗内存。删除 100 万行, hash 表记录 100 万项。

2. 耗CPU解析 binlog,计算 hash 值,成本高。

设置一个阈值,单个事务如果超过设置的行数阈值(比如,如果单个事务更新的行数超过 10 万行),退化为单线程模式:

1.  coordinator 暂时 hold 住事务;

2.  所有 worker 执行完,成空队列;

3.  coordinator 直接执行这个事务; 恢复并行模式。

二、MySQL 5.6 版本并行复制策略

并行复制,按库并行。理解了上面介绍的按表分发策略和按行分发策略,你就理解了,用于决定分发策略的 hash 表里,key 就是数据库名。

取决于压力模型。多个 DB压力均衡,效果好。

优势:

1. 构造 hash 值快,只要库名;实例上 DB 数不多,不会出现需要构造 100 万个项这种情况。

2.  不要求 binlog 格式。statement 格式binlog 很容易拿到库名。

没效果:主库上的表都放在同一个 DB 里面,;不同 DB 热点不同,一个是业务逻辑库,一个是系统配置库

创建不同的 DB,把相同热度的表均匀分到这些不同的 DB 中,强行用。由于需要特地移动数据,用得并不多。

三、MariaDB 的并行复制策略

第 23 篇文章中, redo log 组提交 (group commit) 优化, MariaDB 并行复制就是这个特性:

1.  同一组里提交的事务,不修改同一行

2.  主库上并行,备库也可

MariaDB 是这么做的:

1.  组里一起提交事务,相同commit_id

2.  commit_id 直接写binlog 里;

3.  传备库时,相同 commit_id 分发多个 worker 执行;

4.  执行完,coordinator 取下一批,commit_id+1。

之前都是“分析 binlog,拆分到 worker”上。MariaDB “模拟主库并行模式”。

问题:备库没真正并行。主库trx1、trx2 和 trx3 提交时,trx4、trx5 和 trx6 在执行的。提交完,下一组很快 commit

图 5 主库并行事务

MariaDB 并行复制策略,备库上执行如图 6

图 6 MariaDB 并行复制,备库并行效果

备库上,第一组完成,第二组才开始,吞吐量不够。

容易被大事务拖后腿。trx2超大事务,备库trx1 和 trx3 执行完成后,只能等 trx2完成,只有worker 工作,浪费。

四、MySQL 5.7 的并行复制策略

类似功能,参数slave-parallel-type 控制并行复制策略

1.   DATABASE, 5.6 并行策略;

2.   LOGICAL_CLOCKMariaDB 。做优化

“执行状态”所有事务不能同时并行锁冲突而等待,备库分配不同worker,不一致。

图 7 两阶段提交细化过程图

redo log prepare、 commit 状态,表示已通过锁冲突。并行思想:

1. 同时prepare 状态,备库可并行;

2.  prepare 、 commit 之间,备库也可并行。

 binlog 组提交两个参数,主库提交慢,让备库快。提升备库复制并发度:

1.  binlog_group_commit_sync_delay 延迟多少微秒后才调用fsync;

2.  binlog_group_commit_sync_no_delay_count 累积多少次调用 fsync。

五、MySQL 5.7.22 并行复制策略

基于WRITESET 并行复制。增加binlog-transaction-dependency-tracking控制是否启用新策略。参数三种:

1.  COMMIT_ORDER,同时进入 prepare 和 commit 判断可否并行

2.  WRITESET更新每行,计算 hash 值,组成集合 writeset。两个事务没有操作相同的行,writeset 没交集,可并行

3.  WRITESET_SESSION,WRITESET 多了约束,主库先后执行两事务,备库相同顺序

唯一标识 hash 值:“库名 + 表名 + 索引名 + 值”。还有其他唯一索引,每个唯一索引,insert 对应 writeset 多增加 hash 值

优势:

1.  writeset 主库生成后写入binlog 面,备库不需解析 binlog(event 里的行数据),省计算量

2.  不需扫一遍binlog 决定分发到哪个 worker,省内存

3.  备库分发策略不依赖binlog ,statement 也可

通用有保证。“表上没主键”和“外键约束”场景,WRITESET 策略没法并行,暂时退化为单线程

小结

MySQL各种多线程复制策略。不同策略优缺点

为什么要有多线程复制呢?单线程复制能力低,更新压力大主库,备库追不上主库。现象:备库seconds_behind_master 值越来越大

大事务不仅会影响主库,备库复制延迟。建议大事务拆小

MySQL5.7 备库并行策略,修改binlog,并不是向上兼容的,在主备切换、版本升级的时候需要把这个因素也考虑进去。

思考题

MySQL 5.7.22版本主库,单线程插入很多,3 小时后,给主库搭相同备库

更快追上主库并行复制binlog-transaction-dependency-tracking 参数 COMMIT_ORDER、WRITESET 和WRITE_SESSION 选择哪个?原因是?另外两个现象?

WRITESET。其他两个单线程。

评论1

同行更新几个事务, commit_id 相同,备库并行执行不一致?

同一行事务不可能同时commit。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容