-
Notifications
You must be signed in to change notification settings - Fork 683
/
Copy pathMySQL 主从复制 半同步复制.md.html
975 lines (878 loc) · 51.4 KB
/
MySQL 主从复制 半同步复制.md.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
<!DOCTYPE html>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>MySQL 主从复制 半同步复制.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- theme css & js -->
<meta name="generator" content="Hexo 4.2.0">
</head>
<body>
<div class="book-container">
<div class="book-sidebar">
<div class="book-brand">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<ul class="uncollapsible">
<li><a href="/" class="current-tab">首页</a></li>
</ul>
<ul class="uncollapsible">
<li><a href="../">上一级</a></li>
</ul>
<ul class="uncollapsible">
<li>
<a href="/文章/AQS 万字图文全面解析.md.html">AQS 万字图文全面解析.md.html</a>
</li>
<li>
<a href="/文章/Docker 镜像构建原理及源码分析.md.html">Docker 镜像构建原理及源码分析.md.html</a>
</li>
<li>
<a href="/文章/ElasticSearch 小白从入门到精通.md.html">ElasticSearch 小白从入门到精通.md.html</a>
</li>
<li>
<a href="/文章/JVM CPU Profiler技术原理及源码深度解析.md.html">JVM CPU Profiler技术原理及源码深度解析.md.html</a>
</li>
<li>
<a href="/文章/JVM 垃圾收集器.md.html">JVM 垃圾收集器.md.html</a>
</li>
<li>
<a href="/文章/JVM 面试的 30 个知识点.md.html">JVM 面试的 30 个知识点.md.html</a>
</li>
<li>
<a href="/文章/Java IO 体系、线程模型大总结.md.html">Java IO 体系、线程模型大总结.md.html</a>
</li>
<li>
<a href="/文章/Java NIO浅析.md.html">Java NIO浅析.md.html</a>
</li>
<li>
<a href="/文章/Java 面试题集锦(网络篇).md.html">Java 面试题集锦(网络篇).md.html</a>
</li>
<li>
<a href="/文章/Java-直接内存 DirectMemory 详解.md.html">Java-直接内存 DirectMemory 详解.md.html</a>
</li>
<li>
<a href="/文章/Java中9种常见的CMS GC问题分析与解决(上).md.html">Java中9种常见的CMS GC问题分析与解决(上).md.html</a>
</li>
<li>
<a href="/文章/Java中9种常见的CMS GC问题分析与解决(下).md.html">Java中9种常见的CMS GC问题分析与解决(下).md.html</a>
</li>
<li>
<a href="/文章/Java中的SPI.md.html">Java中的SPI.md.html</a>
</li>
<li>
<a href="/文章/Java中的ThreadLocal.md.html">Java中的ThreadLocal.md.html</a>
</li>
<li>
<a href="/文章/Java线程池实现原理及其在美团业务中的实践.md.html">Java线程池实现原理及其在美团业务中的实践.md.html</a>
</li>
<li>
<a href="/文章/Java魔法类:Unsafe应用解析.md.html">Java魔法类:Unsafe应用解析.md.html</a>
</li>
<li>
<a href="/文章/Kafka 源码阅读笔记.md.html">Kafka 源码阅读笔记.md.html</a>
</li>
<li>
<a href="/文章/Kafka、ActiveMQ、RabbitMQ、RocketMQ 区别以及高可用原理.md.html">Kafka、ActiveMQ、RabbitMQ、RocketMQ 区别以及高可用原理.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB Buffer Pool.md.html">MySQL · 引擎特性 · InnoDB Buffer Pool.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB IO子系统.md.html">MySQL · 引擎特性 · InnoDB IO子系统.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB 事务系统.md.html">MySQL · 引擎特性 · InnoDB 事务系统.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB 同步机制.md.html">MySQL · 引擎特性 · InnoDB 同步机制.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB 数据页解析.md.html">MySQL · 引擎特性 · InnoDB 数据页解析.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · InnoDB崩溃恢复.md.html">MySQL · 引擎特性 · InnoDB崩溃恢复.md.html</a>
</li>
<li>
<a href="/文章/MySQL · 引擎特性 · 临时表那些事儿.md.html">MySQL · 引擎特性 · 临时表那些事儿.md.html</a>
</li>
<li>
<a class="current-tab" href="/文章/MySQL 主从复制 半同步复制.md.html">MySQL 主从复制 半同步复制.md.html</a>
</li>
<li>
<a href="/文章/MySQL 主从复制 基于GTID复制.md.html">MySQL 主从复制 基于GTID复制.md.html</a>
</li>
<li>
<a href="/文章/MySQL 主从复制.md.html">MySQL 主从复制.md.html</a>
</li>
<li>
<a href="/文章/MySQL 事务日志(redo log和undo log).md.html">MySQL 事务日志(redo log和undo log).md.html</a>
</li>
<li>
<a href="/文章/MySQL 亿级别数据迁移实战代码分享.md.html">MySQL 亿级别数据迁移实战代码分享.md.html</a>
</li>
<li>
<a href="/文章/MySQL 从一条数据说起-InnoDB行存储数据结构.md.html">MySQL 从一条数据说起-InnoDB行存储数据结构.md.html</a>
</li>
<li>
<a href="/文章/MySQL 地基基础:事务和锁的面纱.md.html">MySQL 地基基础:事务和锁的面纱.md.html</a>
</li>
<li>
<a href="/文章/MySQL 地基基础:数据字典.md.html">MySQL 地基基础:数据字典.md.html</a>
</li>
<li>
<a href="/文章/MySQL 地基基础:数据库字符集.md.html">MySQL 地基基础:数据库字符集.md.html</a>
</li>
<li>
<a href="/文章/MySQL 性能优化:碎片整理.md.html">MySQL 性能优化:碎片整理.md.html</a>
</li>
<li>
<a href="/文章/MySQL 故障诊断:一个 ALTER TALBE 执行了很久,你慌不慌?.md.html">MySQL 故障诊断:一个 ALTER TALBE 执行了很久,你慌不慌?.md.html</a>
</li>
<li>
<a href="/文章/MySQL 故障诊断:如何在日志中轻松定位大事务.md.html">MySQL 故障诊断:如何在日志中轻松定位大事务.md.html</a>
</li>
<li>
<a href="/文章/MySQL 故障诊断:教你快速定位加锁的 SQL.md.html">MySQL 故障诊断:教你快速定位加锁的 SQL.md.html</a>
</li>
<li>
<a href="/文章/MySQL 日志详解.md.html">MySQL 日志详解.md.html</a>
</li>
<li>
<a href="/文章/MySQL 的半同步是什么?.md.html">MySQL 的半同步是什么?.md.html</a>
</li>
<li>
<a href="/文章/MySQL中的事务和MVCC.md.html">MySQL中的事务和MVCC.md.html</a>
</li>
<li>
<a href="/文章/MySQL事务_事务隔离级别详解.md.html">MySQL事务_事务隔离级别详解.md.html</a>
</li>
<li>
<a href="/文章/MySQL优化:优化 select count().md.html">MySQL优化:优化 select count().md.html</a>
</li>
<li>
<a href="/文章/MySQL共享锁、排他锁、悲观锁、乐观锁.md.html">MySQL共享锁、排他锁、悲观锁、乐观锁.md.html</a>
</li>
<li>
<a href="/文章/MySQL的MVCC(多版本并发控制).md.html">MySQL的MVCC(多版本并发控制).md.html</a>
</li>
<li>
<a href="/文章/QingStor 对象存储架构设计及最佳实践.md.html">QingStor 对象存储架构设计及最佳实践.md.html</a>
</li>
<li>
<a href="/文章/RocketMQ 面试题集锦.md.html">RocketMQ 面试题集锦.md.html</a>
</li>
<li>
<a href="/文章/SnowFlake 雪花算法生成分布式 ID.md.html">SnowFlake 雪花算法生成分布式 ID.md.html</a>
</li>
<li>
<a href="/文章/Spring Boot 2.x 结合 k8s 实现分布式微服务架构.md.html">Spring Boot 2.x 结合 k8s 实现分布式微服务架构.md.html</a>
</li>
<li>
<a href="/文章/Spring Boot 教程:如何开发一个 starter.md.html">Spring Boot 教程:如何开发一个 starter.md.html</a>
</li>
<li>
<a href="/文章/Spring MVC 原理.md.html">Spring MVC 原理.md.html</a>
</li>
<li>
<a href="/文章/Spring MyBatis和Spring整合的奥秘.md.html">Spring MyBatis和Spring整合的奥秘.md.html</a>
</li>
<li>
<a href="/文章/Spring 帮助你更好的理解Spring循环依赖.md.html">Spring 帮助你更好的理解Spring循环依赖.md.html</a>
</li>
<li>
<a href="/文章/Spring 循环依赖及解决方式.md.html">Spring 循环依赖及解决方式.md.html</a>
</li>
<li>
<a href="/文章/Spring中眼花缭乱的BeanDefinition.md.html">Spring中眼花缭乱的BeanDefinition.md.html</a>
</li>
<li>
<a href="/文章/Vert.x 基础入门.md.html">Vert.x 基础入门.md.html</a>
</li>
<li>
<a href="/文章/eBay 的 Elasticsearch 性能调优实践.md.html">eBay 的 Elasticsearch 性能调优实践.md.html</a>
</li>
<li>
<a href="/文章/不可不说的Java“锁”事.md.html">不可不说的Java“锁”事.md.html</a>
</li>
<li>
<a href="/文章/互联网并发限流实战.md.html">互联网并发限流实战.md.html</a>
</li>
<li>
<a href="/文章/从ReentrantLock的实现看AQS的原理及应用.md.html">从ReentrantLock的实现看AQS的原理及应用.md.html</a>
</li>
<li>
<a href="/文章/从SpringCloud开始,聊微服务架构.md.html">从SpringCloud开始,聊微服务架构.md.html</a>
</li>
<li>
<a href="/文章/全面了解 JDK 线程池实现原理.md.html">全面了解 JDK 线程池实现原理.md.html</a>
</li>
<li>
<a href="/文章/分布式一致性理论与算法.md.html">分布式一致性理论与算法.md.html</a>
</li>
<li>
<a href="/文章/分布式一致性算法 Raft.md.html">分布式一致性算法 Raft.md.html</a>
</li>
<li>
<a href="/文章/分布式唯一 ID 解析.md.html">分布式唯一 ID 解析.md.html</a>
</li>
<li>
<a href="/文章/分布式链路追踪:集群管理设计.md.html">分布式链路追踪:集群管理设计.md.html</a>
</li>
<li>
<a href="/文章/动态代理种类及原理,你知道多少?.md.html">动态代理种类及原理,你知道多少?.md.html</a>
</li>
<li>
<a href="/文章/响应式架构与 RxJava 在有赞零售的实践.md.html">响应式架构与 RxJava 在有赞零售的实践.md.html</a>
</li>
<li>
<a href="/文章/大数据算法——布隆过滤器.md.html">大数据算法——布隆过滤器.md.html</a>
</li>
<li>
<a href="/文章/如何优雅地记录操作日志?.md.html">如何优雅地记录操作日志?.md.html</a>
</li>
<li>
<a href="/文章/如何设计一个亿级消息量的 IM 系统.md.html">如何设计一个亿级消息量的 IM 系统.md.html</a>
</li>
<li>
<a href="/文章/异步网络模型.md.html">异步网络模型.md.html</a>
</li>
<li>
<a href="/文章/当我们在讨论CQRS时,我们在讨论些神马?.md.html">当我们在讨论CQRS时,我们在讨论些神马?.md.html</a>
</li>
<li>
<a href="/文章/彻底理解 MySQL 的索引机制.md.html">彻底理解 MySQL 的索引机制.md.html</a>
</li>
<li>
<a href="/文章/最全的 116 道 Redis 面试题解答.md.html">最全的 116 道 Redis 面试题解答.md.html</a>
</li>
<li>
<a href="/文章/有赞权限系统(SAM).md.html">有赞权限系统(SAM).md.html</a>
</li>
<li>
<a href="/文章/有赞零售中台建设方法的探索与实践.md.html">有赞零售中台建设方法的探索与实践.md.html</a>
</li>
<li>
<a href="/文章/服务注册与发现原理剖析(Eureka、Zookeeper、Nacos).md.html">服务注册与发现原理剖析(Eureka、Zookeeper、Nacos).md.html</a>
</li>
<li>
<a href="/文章/深入浅出Cache.md.html">深入浅出Cache.md.html</a>
</li>
<li>
<a href="/文章/深入理解 MySQL 底层实现.md.html">深入理解 MySQL 底层实现.md.html</a>
</li>
<li>
<a href="/文章/漫画讲解 git rebase VS git merge.md.html">漫画讲解 git rebase VS git merge.md.html</a>
</li>
<li>
<a href="/文章/生成浏览器唯一稳定 ID 的探索.md.html">生成浏览器唯一稳定 ID 的探索.md.html</a>
</li>
<li>
<a href="/文章/缓存 如何保证缓存与数据库的双写一致性?.md.html">缓存 如何保证缓存与数据库的双写一致性?.md.html</a>
</li>
<li>
<a href="/文章/网易严选怎么做全链路监控的?.md.html">网易严选怎么做全链路监控的?.md.html</a>
</li>
<li>
<a href="/文章/美团万亿级 KV 存储架构与实践.md.html">美团万亿级 KV 存储架构与实践.md.html</a>
</li>
<li>
<a href="/文章/美团点评Kubernetes集群管理实践.md.html">美团点评Kubernetes集群管理实践.md.html</a>
</li>
<li>
<a href="/文章/美团百亿规模API网关服务Shepherd的设计与实现.md.html">美团百亿规模API网关服务Shepherd的设计与实现.md.html</a>
</li>
<li>
<a href="/文章/解读《阿里巴巴 Java 开发手册》背后的思考.md.html">解读《阿里巴巴 Java 开发手册》背后的思考.md.html</a>
</li>
<li>
<a href="/文章/认识 MySQL 和 Redis 的数据一致性问题.md.html">认识 MySQL 和 Redis 的数据一致性问题.md.html</a>
</li>
<li>
<a href="/文章/进阶:Dockerfile 高阶使用指南及镜像优化.md.html">进阶:Dockerfile 高阶使用指南及镜像优化.md.html</a>
</li>
<li>
<a href="/文章/铁总在用的高性能分布式缓存计算框架 Geode.md.html">铁总在用的高性能分布式缓存计算框架 Geode.md.html</a>
</li>
<li>
<a href="/文章/阿里云PolarDB及其共享存储PolarFS技术实现分析(上).md.html">阿里云PolarDB及其共享存储PolarFS技术实现分析(上).md.html</a>
</li>
<li>
<a href="/文章/阿里云PolarDB及其共享存储PolarFS技术实现分析(下).md.html">阿里云PolarDB及其共享存储PolarFS技术实现分析(下).md.html</a>
</li>
<li>
<a href="/文章/面试最常被问的 Java 后端题.md.html">面试最常被问的 Java 后端题.md.html</a>
</li>
<li>
<a href="/文章/领域驱动设计在互联网业务开发中的实践.md.html">领域驱动设计在互联网业务开发中的实践.md.html</a>
</li>
<li>
<a href="/文章/领域驱动设计的菱形对称架构.md.html">领域驱动设计的菱形对称架构.md.html</a>
</li>
<li>
<a href="/文章/高效构建 Docker 镜像的最佳实践.md.html">高效构建 Docker 镜像的最佳实践.md.html</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
<div class="sidebar-toggle-inner"></div>
</div>
<script>
function add_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.add('show')
}
function remove_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.remove('show')
}
function sidebar_toggle() {
let sidebar_toggle = document.querySelector('.sidebar-toggle')
let sidebar = document.querySelector('.book-sidebar')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.remove('show')
overlay.classList.remove('show')
}
</script>
<div class="off-canvas-content">
<div class="columns">
<div class="column col-12 col-lg-12">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>MySQL 主从复制 半同步复制</h1>
<h1>1.半同步复制</h1>
<p>半同步复制官方手册:<a href="https://dev.mysql.com/doc/refman/5.7/en/replication-semisync.html">https://dev.mysql.com/doc/refman/5.7/en/replication-semisync.html</a></p>
<p>默认情况下,MySQL的复制是异步的,master将新生成的binlog发送给各slave后,无需等待slave的ack回复(slave将接收到的binlog写进relay log后才会回复ack),直接就认为这次DDL/DML成功了。</p>
<p>半同步复制(semi-synchronous replication)是指master在将新生成的binlog发送给各slave时,只需等待一个(默认)slave返回的ack信息就返回成功。</p>
<p><img src="assets/733013-20180524205148967-868029789-1623083552625.png" alt="img" /></p>
<p>MySQL 5.7对半同步复制作了大改进,新增了一个master线程。在MySQL 5.7以前,master上的binlog dump线程负责两件事:dump日志给slave的io_thread;接收来自slave的ack消息。它们是串行方式工作的。在MySQL 5.7中,新增了一个专门负责接受ack消息的线程ack collector thread。这样master上有两个线程独立工作,可以同时发送binlog到slave和接收slave的ack。</p>
<p>还新增了几个变量,其中最重要的是 <em>rpl_semi_sync_master_wait_point</em> ,它使得MySQL半同步复制有两种工作模型。解释如下。</p>
<h1>2.半同步复制的两种类型</h1>
<p>从MySQL 5.7.2开始,MySQL支持两种类型的半同步复制。这两种类型由变量 <em>rpl_semi_sync_master_wait_point</em> (MySQL 5.7.2之前没有该变量)控制,它有两种值:AFTER_SYNC和AFTER_COMMIT。在MySQL 5.7.2之后,默认值为AFTER_SYNC,在此版本之前,等价的类型为AFTER_COMMIT。</p>
<p>这个变量控制的是master何时提交、何时接收ack以及何时回复成功信息给客户端的时间点。</p>
<ol>
<li><code>AFTER_SYNC</code>模式:master将新的事务写进binlog(buffer),然后发送给slave,再sync到自己的binlog file(disk)。之后才允许接收slave的ack回复,接收到ack之后才会提交事务,并返回成功信息给客户端。</li>
<li><code>AFTER_COMMIT</code>模式:master将新的事务写进binlog(buffer),然后发送给slave,再sync到自己的binlog file(disk),然后直接提交事务。之后才允许接收slave的ack回复,然后再返回成功信息给客户端。</li>
</ol>
<p>画图理解就很清晰。(前提:已经设置了<code>sync_binlog=1</code>,否则binlog刷盘时间由操作系统决定)</p>
<p><img src="assets/733013-20180610220640867-571552886.png" alt="img" /></p>
<p><img src="assets/733013-20180610220716676-859240378.png" alt="img" /></p>
<p>再来分析下这两种模式的优缺点。</p>
<ul>
<li>AFTER_SYNC
<ul>
<li>对于所有客户端来说,它们看到的数据是一样的,因为它们看到的数据都是在接收到slave的ack后提交后的数据。</li>
<li>这种模式下,如果master突然故障,不会丢失数据,因为所有成功的事务都已经写进slave的relay log中了,slave的数据是最新的。</li>
</ul>
</li>
<li>AFTER_COMMIT
<ul>
<li>不同客户端看到的数据可能是不一样的。对于发起事务请求的那个客户端,它只有在master提交事务且收到slave的ack后才能看到提交的数据。但对于那些非本次事务的请求客户端,它们在master提交后就能看到提交后的数据,这时候master可能还没收到slave的ack。</li>
<li>如果master收到ack回复前,slave和master都故障了,那么将丢失这个事务中的数据。</li>
</ul>
</li>
</ul>
<p>在MySQL 5.7.2之前,等价的模式是 <em>AFTER_COMMIT</em> ,在此版本之后,默认的模式为 <em>AFTER_SYNC</em> ,该模式能最大程度地保证数据安全性,且性能上并不比 <em>AFTER_COMMIT</em> 差。</p>
<h1>3.半同步复制插件介绍</h1>
<p>MySQL的半同步是通过加载google为MySQL提供的半同步插件 <em>semisync_master.so</em> 和 <em>semisync_slave.so</em> 来实现的。其中前者是master上需要安装的插件,后者是slave上需要安装的插件。</p>
<p>MySQL的插件位置默认存放在<code>$basedir/lib/plugin</code>目录下。例如,yum安装的mysql-server,插件目录为/usr/lib64/mysql/plugin。</p>
<pre><code>[<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="84f6ebebf0c4fcf1e1fced">[email protected]</a> ~]# find / -type f -name "semisync*"
/usr/lib64/mysql/plugin/debug/semisync_master.so
/usr/lib64/mysql/plugin/debug/semisync_slave.so
/usr/lib64/mysql/plugin/semisync_master.so
/usr/lib64/mysql/plugin/semisync_slave.so
</code></pre>
<p>因为要加载插件,所以应该保证需要加载插件的MySQL的全局变量 <em>have_dynamic_loading</em> 已经设置为YES(默认值就是YES),否则无法动态加载插件。</p>
<pre><code>mysql> select @@global.have_dynamic_loading;
+-------------------------------+
| @@global.have_dynamic_loading |
+-------------------------------+
| YES |
+-------------------------------+
</code></pre>
<h2>3.1 MySQL中安装插件的方式</h2>
<p>安装插件有两种方式:1.在mysql环境中使用<code>INSTALL PLUGIN</code>语句临时安装;2.在配置文件中配置永久生效。</p>
<p>INSTALL安装插件的语法为:</p>
<pre><code>Syntax:
INSTALL PLUGIN plugin_name SONAME 'shared_library_name'
UNINSTALL PLUGIN plugin_name
</code></pre>
<p>例如,使用INSTALL语句在master上安装 <em>semisync_master.so</em> 插件。</p>
<pre><code class="language-mysql">mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
</code></pre>
<p>配置文件中加载插件的方式为:</p>
<pre><code>[mysqld]
plugin-load='plugin_name=shared_library_name'
</code></pre>
<p>例如,配置文件中加载<code>semisync_master.so</code>插件。</p>
<pre><code>[mysqld]
plugin-load="rpl_semi_sync_master=sermisync_master.so"
</code></pre>
<p>如果需要加载多个插件,则插件之间使用分号分隔。例如,在本节的slave1既是slave,又是master,需要同时安装两个半同步插件。</p>
<pre><code>[mysqld]
plugin-load="rpl_semi_sync_master=semisync_master.so;rpl_sync_slave=semisync_slave.so"
</code></pre>
<p>安装插件后,应该使用<code>show plugins</code>来查看插件是否真的激活。</p>
<pre><code class="language-mysql">mysql> show plugins;
+----------------------+--------+-------------+--------------------+---------+
| Name | Status | Type | Library | License |
+----------------------+--------+-------------+--------------------+---------+
......
| rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL |
+----------------------+--------+-------------+--------------------+---------+
</code></pre>
<p>或者查看<code>information_schema.plugins</code>表获取更详细的信息。</p>
<pre><code>mysql> select * from information_schema.plugins where plugin_name like "%semi%"\G
*************************** 1. row ***************************
PLUGIN_NAME: rpl_semi_sync_master
PLUGIN_VERSION: 1.0
PLUGIN_STATUS: ACTIVE
PLUGIN_TYPE: REPLICATION
PLUGIN_TYPE_VERSION: 4.0
PLUGIN_LIBRARY: semisync_master.so
PLUGIN_LIBRARY_VERSION: 1.7
PLUGIN_AUTHOR: He Zhenxing
PLUGIN_DESCRIPTION: Semi-synchronous replication master
PLUGIN_LICENSE: GPL
LOAD_OPTION: ON
1 row in set (0.00 sec)
</code></pre>
<p>插件装载完成后,半同步功能还未开启,需要手动设置它们启动,或者写入配置文件永久生效。</p>
<pre><code># 开启master的半同步
mysql> set @@global.rpl_semi_sync_master_enabled=1;
# 开启slave半同步
mysql> set @@globale.rpl_semi_sync_slave_enabled=1;
</code></pre>
<p>或者配合插件加载选项一起写进配置文件永久开启半同步功能。</p>
<pre><code>[mysqld]
rpl_semi_sync_master_enabled=1
[mysqld]
rpl_semi_sync_slave_enabled=1
</code></pre>
<h2>3.2 半同步插件相关的变量</h2>
<p>安装了 <em>semisync_master.so</em> 和 <em>semisync_slave.so</em> 后,这两个插件分别提供了几个变量。</p>
<pre><code>mysql> show global variables like "%semi%";
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
+-------------------------------------------+------------+
</code></pre>
<p>下面还多给了两个和半同步相关的状态变量的解释,可以通过<code>show status like %semi%;</code>查看它们。</p>
<ol>
<li>
<p>master相关的变量:</p>
<ul>
<li>
<p>①.<code>Rpl_semi_sync_master_clients</code>:(状态变量)master所拥有的半同步复制slave的主机数量。</p>
</li>
<li>
<p>②.<code>Rpl_semi_sync_master_status</code> :(状态变量)master当前是否以半同步复制状态工作(ON),OFF表示降级为了异步复制。</p>
</li>
<li>
<p>③.<code>rpl_semi_sync_master_enabled</code>:master上是否启用了半同步复制。</p>
</li>
<li>
<p>④.<code>rpl_semi_sync_master_timeout</code>:等待slave的ack回复的超时时间,默认为10秒。</p>
</li>
<li>
<p>⑤.<code>rpl_semi_sync_master_trace_level</code>:半同步复制时master的调试级别。</p>
</li>
<li>
<p>⑥.<code>rpl_semi_sync_master_wait_for_slave_count</code>:master在超时时间内需要收到多少个ack回复才认为此次DML成功,否则就降级为异步复制。该变量在MySQL5.7.3才提供,在此之前的版本都默认为收到1个ack则确认成功,且不可更改。MySQL 5.7.3之后该变量的默认值也是1。</p>
</li>
<li>
<p>⑦.<code>rpl_semi_sync_master_wait_no_slave</code>:值为ON(默认)或者OFF。ON表示master在超时时间内如果未收到指定数量的ack消息,则会一直等待下去直到收满ack,即一直采用半同步复制方式,不会降级;OFF表示如果在超时时间内未收到指定数量的ack,则超时时间一过立即降级为异步复制。</p>
<p>更官方的解释是:当设置为ON时,即使状态变量Rpl_semi_sync_master_clients中的值小于rpl_semi_sync_master_wait_for_slave_count,Rpl_semi_sync_master_status依旧为ON;当设置为OFF时,如果clients的值小于count的值,则Rpl_semi_sync_master_status立即变为OFF。通俗地讲,就是在超时时间内,如果slave宕机的数量超过了应该要收到的ack数量,master是否降级为异步复制。</p>
<p>该变量在MySQL 5.7.3之前似乎没有效果,因为默认设置为ON时,超时时间内收不到任何ack时仍然会降级为异步复制。</p>
</li>
<li>
<p>⑧.<code>rpl_semi_sync_master_wait_point</code>:控制master上commit、接收ack、返回消息给客户端的时间点。值为 <em>AFTER_SYNC</em> 和 <em>AFTER_COMMIT</em> ,该选项是MySQL5.7.2后引入的,默认值为 <em>AFTER_SYNC</em> ,在此版本之前,等价于使用了 <em>AFTER_COMMIT</em> 模式。关于这两种模式,见前文对两种半同步类型的分析。</p>
</li>
</ul>
</li>
<li>
<p>slave相关的变量:</p>
<ul>
<li>①.<code>rpl_semi_sync_slave_enabled</code>:slave是否开启半同步复制。</li>
<li>②.<code>rpl_semi_sync_slave_trace_level</code>:slave的调试级别。</li>
</ul>
</li>
</ol>
<h1>4.配置半同步复制</h1>
<p>需要注意的是,"半同步"是同步/异步类型的一种情况,<strong>既可以实现半同步的传统复制,也可以实现半同步的GTID复制</strong>。其实半同步复制是基于异步复制的,它是在异步复制的基础上通过加载半同步插件的形式来实现半同步性的。</p>
<p>此处以全新的环境进行配置,方便各位道友"依葫芦画瓢"。</p>
<p>本文实现如下拓扑图所示的半同步传统复制。如果要实现半同步GTID复制,也只是在gtid复制的基础上改改配置文件而已。</p>
<p><img src="assets/733013-20180611095458324-817021379.png" alt="img" /></p>
<p>具体环境:</p>
<table>
<thead>
<tr>
<th align="center">称呼</th>
<th align="center">主机IP</th>
<th align="center">MySQL版本</th>
<th align="center">OS</th>
<th align="center">角色(master/slave)</th>
<th align="center">数据库状态</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">master</td>
<td align="center">192.168.100.21</td>
<td align="center">MySQL 5.7.22</td>
<td align="center">CentOS 7.2</td>
<td align="center">master</td>
<td align="center">全新实例</td>
</tr>
<tr>
<td align="center">salve1</td>
<td align="center">192.168.100.22</td>
<td align="center">MySQL 5.7.22</td>
<td align="center">CentOS 7.2</td>
<td align="center">semi_slave for master semi_master for other slaves</td>
<td align="center">全新实例</td>
</tr>
<tr>
<td align="center">slave2</td>
<td align="center">192.168.100.23</td>
<td align="center">MySQL 5.7.22</td>
<td align="center">CentOS 7.2</td>
<td align="center">semi_slave for slave1</td>
<td align="center">全新实例</td>
</tr>
<tr>
<td align="center">slave3</td>
<td align="center">192.168.100.24</td>
<td align="center">MySQL 5.7.22</td>
<td align="center">CentOS 7.2</td>
<td align="center">semi_slave for slave1</td>
<td align="center">全新实例</td>
</tr>
</tbody>
</table>
<p>因为都是全新的实例环境,所以无需考虑基准数据和binlog坐标的问题。如果开始测试前,已经在master上做了一些操作,或者创建了一些新数据,那么请将master上的数据恢复到各slave上,并获取master binlog的坐标,具体操作方法可参见前文:将slave恢复到master指定的坐标。</p>
<h2>4.1 半同步复制的配置文件</h2>
<p>首先提供各MySQL Server的配置文件。</p>
<p>以下是master的配置文件。</p>
<pre><code>[mysqld]
datadir=/data
socket=/data/mysql.sock
log-error=/data/error.log
pid-file=/data/mysqld.pid
log-bin=/data/master-bin
sync-binlog=1
server-id=100
plugin-load="rpl_semi_sync_master=semisync_master.so"
rpl_semi_sync_master_enabled=1
</code></pre>
<p>以下是slave1的配置文件,注意slave1同时还充当着slave2和slave3的master的角色。</p>
<pre><code>[mysqld]
datadir=/data
socket=/data/mysql.sock
log-error=/data/error.log
pid-file=/data/mysqld.pid
log-bin=/data/master-bin
sync-binlog=1
server-id=110
relay-log=/data/slave-bin
log-slave-updates
plugin-load="rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
rpl_semi_sync_slave_enabled=1
rpl_semi_sync_master_enabled=1
</code></pre>
<p>以下是slave2和slave3的配置文件,它们配置文件除了<em>server-id</em>外都一致。</p>
<pre><code>[mysqld]
datadir=/data
socket=/data/mysql.sock
log-error=/data/error.log
pid-file=/data/mysqld.pid
server-id=120 # slave3的server-id=130
relay-log=/data/slave-bin
plugin-load="rpl_semi_sync_slave=semisync_slave.so"
rpl_semi_sync_slave_enabled=1
read-only=on
</code></pre>
<h2>4.2 启动复制线程</h2>
<p>现在master上创建一个专门用于复制的用户。</p>
<pre><code>mysql> create user <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="80f2e5f0ecc0">[email protected]</a>'192.168.100.%' identified by '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bfefffccccc8d0cddb8e">[email protected]</a>!';
mysql> grant replication slave on *.* to <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="265443564a66">[email protected]</a>'192.168.100.%';
</code></pre>
<p>因为master和所有的slave都是全新的实例,所以slave上指定的binlog坐标可以从任意位置开始。不过刚才master上创建了一个用户,也会写binlog,所以建议还是从master的第一个binlog的position=4开始。</p>
<p>以下是slave1上的<code>change master to</code>参数:</p>
<pre><code>mysql> change master to
master_host='192.168.100.21',
master_port=3306,
master_user='repl',
master_password='<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2575655656524a574114">[email protected]</a>!',
master_log_file='master-bin.000001',
master_log_pos=4;
</code></pre>
<p>以下是slave2和slave3的<code>change master to</code>参数:</p>
<pre><code>mysql> change master to
master_host='192.168.100.22',
master_port=3306,
master_user='repl',
master_password='<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="de8e9eadada9b1acbaef">[email protected]</a>!',
master_log_file='master-bin.000001',
master_log_pos=4;
</code></pre>
<p>启动各slave上的两个SQL线程。</p>
<pre><code>mysql> start slave;
</code></pre>
<p>一切就绪后,剩下的事情就是测试。在master上对数据做一番修改,然后查看是否会同步到slave1、slave2、slave3上。</p>
<h1>5.半同步复制的状态信息</h1>
<p>首先是semisync相关的可修改变量,这几个变量在<a href="https://www.cnblogs.com/f-ck-need-u/p/9166452.html#blog3.2">前文</a>已经解释过了。</p>
<p>例如以下是开启了半同步复制后的master上的semisync相关变量。</p>
<pre><code>mysql> show global variables like "%semi%";
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+-------------------------------------------+------------+
</code></pre>
<p>关于半同步复制,还有几个状态变量很重要。</p>
<p>例如,以下是master上关于semi_sync的状态变量信息。</p>
<pre><code>mysql> show status like "%semi%";
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 | # 注意行1
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 5 |
| Rpl_semi_sync_master_no_times | 1 |
| Rpl_semi_sync_master_no_tx | 1 |
| Rpl_semi_sync_master_status | ON | # 注意行2
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 384 |
| Rpl_semi_sync_master_tx_wait_time | 1537 |
| Rpl_semi_sync_master_tx_waits | 4 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 4 |
+--------------------------------------------+-------+
</code></pre>
<p>除了上面标注"注意行"的变量,其他都无需关注,而且其中有一些是废弃了的状态变量。</p>
<p><code>Rpl_semi_sync_master_clients</code>是该master所连接到的slave数量。</p>
<p><code>Rpl_semi_sync_master_status</code>是该master的半同步复制功能是否开启。在有些时候半同步复制会降级为异步复制,这时它的值为OFF。</p>
<p>以下是slave1上关于semi_sync的状态变量信息。</p>
<pre><code>mysql> show status like "%semi%";
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 2 | # 注意行1
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 8 |
| Rpl_semi_sync_master_no_times | 2 |
| Rpl_semi_sync_master_no_tx | 4 |
| Rpl_semi_sync_master_status | ON | # 注意行2
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 399 |
| Rpl_semi_sync_master_tx_wait_time | 1199 |
| Rpl_semi_sync_master_tx_waits | 3 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 3 |
| Rpl_semi_sync_slave_status | ON | # 注意行3
+--------------------------------------------+-------+
</code></pre>
<p>此外,从MySQL的错误日志、<code>show slave status</code>也能获取到一些半同步复制的状态信息。下一节测试半同步复制再说明。</p>
<h1>6.测试半同步复制(等待、降级问题)</h1>
<p>前面已经搭建好了下面的半同步复制结构。</p>
<pre><code> |------> slave2
master ---> slave1 ---
|------> slave3
</code></pre>
<p>下面来测试半同步复制降级为异步复制的问题,借此来观察一些semisync的状态变化。</p>
<p>首先,只停掉slave2或slave3中其中一个io线程的话,slave1是不会出现降级的,因为默认的半同步复制只需等待一个ack回复即可返回成功信息。</p>
<p>如果同时停掉slave2和slave3的io线程,当master更新数据后,slave1在10秒(默认)之后将降级为异步复制。如下:</p>
<p>在slave2和slave3上执行:</p>
<pre><code>mysql> stop slave io_thread;
</code></pre>
<p>在master上执行:</p>
<pre><code>create database test1;
create table test1.t(id int);
insert into test1.t values(33);
</code></pre>
<p>在slave1上查看(在上面的步骤之后的10秒内查看):</p>
<pre><code>mysql> show status like "%semi%";
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 | # clients=0
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 8 |
| Rpl_semi_sync_master_no_times | 2 |
| Rpl_semi_sync_master_no_tx | 4 |
| Rpl_semi_sync_master_status | ON | # status=ON
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 399 |
| Rpl_semi_sync_master_tx_wait_time | 1199 |
| Rpl_semi_sync_master_tx_waits | 3 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 1 |
| Rpl_semi_sync_master_yes_tx | 3 |
| Rpl_semi_sync_slave_status | ON |
+--------------------------------------------+-------+
</code></pre>
<p>可以看到在这一小段时间内,slave1还是半同步复制。此时用<code>show slave status</code>查看slave1。</p>
<pre><code># slave1上执行
mysql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.100.21
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000004
Read_Master_Log_Pos: 1762
Relay_Log_File: slave-bin.000005
Relay_Log_Pos: 1729
Relay_Master_Log_File: master-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
................................................
Slave_SQL_Running_State: Waiting for semi-sync ACK from slave
................................................
</code></pre>
<p>此时slave的<strong>SQL线程</strong>状态是<code>Waiting for semi-sync ACK from slave</code>。</p>
<p>但10秒之后再查看。</p>
<pre><code>mysql> show status like "%semi%";
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 8 |
| Rpl_semi_sync_master_no_times | 3 |
| Rpl_semi_sync_master_no_tx | 5 |
| Rpl_semi_sync_master_status | OFF |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 399 |
| Rpl_semi_sync_master_tx_wait_time | 1199 |
| Rpl_semi_sync_master_tx_waits | 3 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 3 |
| Rpl_semi_sync_slave_status | ON |
+--------------------------------------------+-------+
</code></pre>
<p>发现slave1已经关闭半同步功能了,也就是说降级为异步复制了。</p>
<p>此时查看slave1的错误日志。</p>
<pre><code>2018-06-11T03:43:21.765384Z 4 [Warning] Timeout waiting for reply of binlog (file: master-bin.000001, pos: 2535), semi-sync up to file master-bin.000001, position 2292.
2018-06-11T03:43:21.765453Z 4 [Note] Semi-sync replication switched OFF.
</code></pre>
<p>它先记录了当前slave2/slave3中已经同步到slave1的哪个位置。然后将Semi-sync复制切换为OFF状态,即降级为异步复制。</p>
<p>在下次slave2或slave3启动IO线程时,<strong>slave1将自动切换回半同步复制</strong>,并发送那些未被复制的binlog。</p>
</div>
</div>
<div>
<div style="float: left">
<a href="/文章/MySQL · 引擎特性 · 临时表那些事儿.md.html">上一页</a>
</div>
<div style="float: right">
<a href="/文章/MySQL 主从复制 基于GTID复制.md.html">下一页</a>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
</div>
<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70997fe278e38b66","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-NPSEEVD756');
var path = window.location.pathname
var cookie = getCookie("lastPath");
console.log(path)
if (path.replace("/", "") === "") {
if (cookie.replace("/", "") !== "") {
console.log(cookie)
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
}
} else {
setCookie("lastPath", path)
}
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
}
return "";
}
</script>
</html>