mysql 5.7主從半同步複製(無損)
目錄
指一臺服務器充當主數據庫服務器,另一臺或多臺服務器充當從數據庫服務器,主服務器中的數據自動複製到從服務器之中。對於多級複製,數據庫服務器即可充當主機,也可充當從機。MySQL主從複製的基礎是主服務器對數據庫修改記錄二進制日誌,從服務器通過主服務器的二進制日誌自動執行更新。
一句話表示就是,主數據庫做什麼,從數據庫就跟着做什麼。
- 基於語句的複製 :主庫把sql語句寫入到bin log中,完成複製
2.基於行數據的複製:主庫把每一行數據變化的信息作爲事件,寫入到bin log,完成複製
3.混合複製:上面兩個結合體,默認用語句複製,出問題時候自動切換成行數據複製
tip:和上面相對應的日誌格式也有三種:STATEMENT,ROW,MIXED。
1.STATEMENT模式(SBR)
每一條會修改數據的sql語句會記錄到binlog中。優點是並不需要記錄每一條sql語句和每一行的數據變化,減少了binlog日誌量,節約IO,提高性能。缺點是在某些情況下會導致master-slave中的數據不一致(如sleep()函數, last_insert_id(),以及user-defined functions(udf)等會出現問題)
ROW模式(RBR)
不記錄每條sql語句的上下文信息,僅需記錄哪條數據被修改了,修改成什麼樣了。而且不會出現某些特定情況下的存儲過程、或function、或trigger的調用和觸發無法被正確複製的問題。缺點是會產生大量的日誌,尤其是alter table的時候會讓日誌暴漲。
MIXED模式(MBR)
以上兩種模式的混合使用,一般的複製使用STATEMENT模式保存binlog,對於STATEMENT模式無法複製的操作使用ROW模式保存binlog,MySQL會根據執行的SQL語句選擇日誌保存方式。
- Master 數據庫只要發生變化,立馬記錄到Binary log 日誌文件中
2.Slave數據庫啓動一個I/O thread連接Master數據庫,請求Master變化的二進制日誌
3.Slave I/O獲取到的二進制日誌,保存到自己的Relay log 日誌文件中。
4.Slave 有一個 SQL thread定時檢查Realy log是否變化,變化那麼就更新數據
確保數據相同
– 從庫必須要有主庫上的數據。
配置主服務器
– 啓用 binlog 日誌及設置格式,設置 server_id, 授權用戶
配置從服務器
– 設置 server_id ,指定主數據庫服務器信息
測試配置
– 客戶端連接主庫,寫入的數據,在連接從庫的時候也確保數據一致
寫在主庫配置文件裏參數(對所有從庫都有效)
[mysqld]
server-id = 1 #節點ID,確保唯一
binlog_do_db=庫名列表 #允許同步的庫,逗號拼接,寫多行
binlog_ignore_db=庫名列表 #不允許同步的庫,逗號拼接,寫多行
# log config
log-bin = mysql-bin #開啓mysql的binlog日誌功能
sync_binlog = 1 #控制數據庫的binlog是否寫磁盤 , 0 不寫磁盤
binlog_format = mixed #binlog日誌格式,mysql默認採用statement,建議使用mixed
expire_logs_days = 7 #binlog過期清理時間
max_binlog_size = 100m #binlog每個日誌文件大小
binlog_cache_size = 4m #binlog緩存大小
max_binlog_cache_size= 512m #最大binlog緩存大
auto-increment-offset = 1 # 自增值的偏移量
auto-increment-increment = 1 # 自增值的自增量
slave-skip-errors = all #跳過從庫錯誤
寫在從庫配置文件裏參數(只針對從庫本機有效)
replicate_do_db=庫名列表 //指定只同步的庫
replicate_ignore_db=庫名列表 //指定不同步的庫
relay-log = mysql-relay-bin
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%
基本應用:
— 單項複製:一主一從
擴展應用:
— 一主多從
— 鏈式複製:主從從
— 主主(互爲主從)
vi /etc/my.cnf
server-id = 2108 #保障唯一
log-bin = mysql-bin2108 #開啓binlog日誌,設置格式
binlog_format = "mixed" #設置日誌格式
-
-
- 重啓A(主庫)mysql服務
-
systemctl restart mysqld
-
-
- 新增A(主庫)MySQL的同步用戶
-
[root@xiuba108 ~]# mysql -uroot -p
mysql> use mysql;
mysql> grant replication slave on *.* to 'replUser'@'%' identified by '123456';
mysql> flush privileges;
-
-
- 查看A(主庫)MySQL的日誌文件,已經位置
-
mysql> show master status ;
-
-
- 在服務器B(從庫)編輯my.cnf
-
vi /etc/my.cnf
server-id = 2109 #保障唯一
log_slave_updates #記錄從庫更新,允許鏈路複製
log-bin = mysql-bin2109 #開啓binlog日誌,設置格式
binlog_format = "mixed" #設置日誌格式
-
-
- 重啓服務器B(從庫)mysql服務
-
systemctl restart mysqld
-
-
- 在服務器B(從庫),配置同步進程
-
[root@xiuba109 ~]# mysql -uroot -p
mysql>change master to master_host='192.168.2.108',master_user='replUser',master_password='123456',master_log_file='mysql-bin2108.000002',master_log_pos=311;
mysql> start slave;
mysql> show slave status \G;
-
-
- 在服務器A(主庫),新建數據庫 db2;並插入數據
-
mysql> create database db2;
mysql> use db2;
mysql> create table test(a int);
mysql> insert into test(a) values(111);
mysql> select * from test;
-
-
- 在服務器B(從庫),查看mysql數據
-
-
-
- 把服務器B(從庫),還原成獨立的數據服務器
-
mysql> stop slave;
mysql> quit;
[root@xiuba109 data]# rm -rf /var/lib/mysql/master.info
[root@xiuba109 data]# rm -rf /var/lib/mysql/xiuba109-relay-bin.*
[root@xiuba109 data]# rm -rf /var/lib/mysql/relay-log.info
[root@xiuba109 data]# vi /etc/my.cnf
vi /etc/my.cnf
#server-id = 2109 #刪除
#log_slave_updates #刪除
#log-bin = mysql-bin2109 #刪除
#binlog_format = "mixed" #刪除
[root@xiuba109 data]# systemctl restart mysql
複製模式介紹
• 異步複製( Asynchronous replication )
– 主庫在執行完客戶端提交的事務後會立即將結果返給客戶端,並不關心從庫是否已經接收並處理。
• 全同步複製( Fully synchronous replication )
– 當主庫執行完一個事務,所有的從庫都執行了該事務才返回給客戶端。
• 半同步複製( Semisynchronous replication )
– 介於異步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到 relay log 中才返回給客戶端
- 查看當前的數據庫服務器是否支持動態加載模塊
mysql> show variables like 'have_dynamic_loading';
- 使用命令安裝模塊,服務器A(主),服務器B(從)都完全安裝
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
mysql> select plugin_name,plugin_status from information_schema.plugins where plugin_name like '%semi%';
- 啓用半同步複製
mysql> set global rpl_semi_sync_master_enabled = 1;
mysql> set global rpl_semi_sync_slave_enabled = 1;
mysql> show variables like 'rpl_semi_sync_%_enabled';
- 配置寫進配置文件使其永久生效
[root@xiuba110 ~]# vi /etc/my.cnf
### 配置半同步複製模式
plugin-load=rpl_semi_sync_master=semisync_master.so
rpl_semi_sync_master_enabled=ON #或者設置爲"1",即開啓半同步複製功能
rpl-semi-sync-master-timeout=1000 #超時時間爲1000ms,即1s
plugin-load=rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_slave_enabled=ON
[root@xiuba110 ~]# systemctl restart mysql
- 半同步複製的原理
- 存在丟失數據風險
- MySQL 5.7半同步複製的改進
支持無損複製(Loss-less Semi-Synchronous)
在Loss-less Semi-Synchronous模式下,master在調用binlog sync之後,engine層commit之前等待Slave ACK(需要收到至少一個Slave節點回復的ACK後)。這樣只有在確認Slave收到事務events後,master事務纔會提交,然後把結果返回給客戶端。此時此事務纔對其他事務可見。在這種模式下解決了after_commit模式帶來的幻讀和數據丟失問題,因爲主庫沒有提交事務。但也會有個問題,假設主庫在存儲引擎提交之前掛了,那麼很明顯這個事務是不成功的,但由於對應的Binlog已經做了Sync操作,從庫已經收到了這些Binlog,並且執行成功,相當於在從庫上多了數據,也算是有問題的,但多了數據,問題一般不算嚴重。這個問題可以這樣理解,作爲MySQL,在沒辦法解決分佈式數據一致性問題的情況下,它能保證的是不丟數據,多了數據總比丟數據要好。
無損複製其實就是對semi sync增加了rpl_semi_sync_master_wait_point參數,來控制半同步模式下主庫在返回給會話事務成功之前提交事務的方式。rpl_semi_sync_master_wait_point該參數有兩個值:AFTER_COMMIT和AFTER_SYNC
- 支持無損複製原理
參考文獻
https://www.cnblogs.com/kevingrace/p/10228694.html