MySQL半同步複製資料最終一致性驗證

chenoracle發表於2022-12-29

所謂半同步,是指從庫完全接收到主庫傳來的binlog資料,並將資料寫入到realy log後,主庫才能提交事務,
那麼理論上,在主庫執行大事務並正常提交事務後出現當機,這時從庫雖然接收到了全部的binlog,
但是realy log可能還沒有解析重放完成,
導致從庫查詢的資料是滯後的,等realy log解析重放完成後,資料才會一致,
也就是半同步複製在某些場景下,資料不是強一致性的,而是弱一致性或最終一致性。

下面透過實驗來驗證這個猜想:

主庫:192.168.1.100  MySQL 5.7.22  Redhat7.5
從庫:192.168.1.200  MySQL 5.7.22  Redhat7.5

啟用半同步複製

主庫

準備測試資料

mysql> use cjc
Database changed
mysql> select count(*) from t1;
+----------+
| count(*) |
+----------+
| 11534336 |
+----------+
1 row in set (5.88 sec)
mysql> create table t2 like t1;
Query OK, 0 rows affected (0.33 sec)

從庫

檢查半同步狀態

mysql> show global status like '%semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.62 sec)

主從同步狀態

mysql> show slave status\G;

主庫、從庫執行指令碼,檢視t2表資料量和時間

準備指令碼

[mysql@cjc-db-01 ~]$ head -n 2 1.sh 
mysql -uroot -p1 -e "select now(),count(*) from cjc.t2;"
mysql -uroot -p1 -e "select now(),count(*) from cjc.t2;"
[mysql@cjc-db-01 ~]$ cat 1.sh |wc -l
12312

執行指令碼

[mysql@dcs02 ~]$ sh 1.sh > 1.log
[mysql@dcs02 ~]$ tail -10f 1.log

主庫:模擬大事務

mysql> insert into t2 select * from t1;
Query OK, 11534336 rows affected (6 min 57.18 sec)
Records: 11534336  Duplicates: 0  Warnings: 0

主庫:在10:39:40事務結束,查詢t2表資料量為11534336

2022-12-29 10:34:360
now()count(*)
2022-12-29 10:35:100
now()count(*)
2022-12-29 10:35:590
now()count(*)
2022-12-29 10:36:580
now()count(*)
2022-12-29 10:38:110
now()count(*)
2022-12-29 10:39:4011534336
now()count(*)
2022-12-29 10:39:4711534336
now()count(*)
2022-12-29 10:39:5411534336
now()count(*)

強制關閉主庫,模擬意外當機

[root@cjc-db-01 ~]# ps -ef|grep mysql
mysql     2318     1  5 09:10 pts/0    00:04:25 mysqld --defaults-file=/etc/my.cnf --user=mysql
[root@cjc-db-01 ~]# kill -9 2318

從庫:

在10:45:51查詢t2表資料量為11534336,比主庫慢了6分11秒,

也就是主庫10:40:00當機後,從庫切換為主庫,在10:40:00到10:45:50期間,t2表資料量和真實資料量不一致,

資料量為0,實際是11534336,5分鐘後,relay log完全解析入庫後,資料一致。

[mysql@dcs02 ~]$ sh 1.sh > 1.log
[mysql@dcs02 ~]$ tail -10f 1.log
now()count(*)
2022-12-29 10:43:000
now()count(*)
2022-12-29 10:43:510
now()count(*)
2022-12-29 10:44:520
now()count(*)
2022-12-29 10:45:5111534336
now()count(*)
2022-12-29 10:45:5811534336
now()count(*)
2022-12-29 10:46:0611534336
now()count(*)
2022-12-29 10:46:1211534336


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29785807/viewspace-2930047/,如需轉載,請註明出處,否則將追究法律責任。

相關文章