專職DBA-MySQL主從半同步複製 MySQL複製的多種工做方式: 1.異步複製 async replication 默認狀況下,MySQL的複製就是異步的,在master上將全部的更新操做都寫入binlog以後並不關心全部的更新是否都複製了slave服務器的中繼日誌中,以及是否應用到了slave數據庫裏主庫也不關心。 異步複製的明顯優點就是複製效率很高,可是其缺點也十分明顯,那就是不一樣的服務器進行復制時可能會存在數據不一致的問題,甚至還可能會丟失數據;異步複製合適於常規普通的互聯網應用場景。 2.全同步複製 full sync replication 全同步複製是指當主庫執行完一個事務後,須要確保全部的從庫都執行了該事務才返回給客戶端。由於須要等待全部的從庫都執行完該事務才能返回,因此全同步複製的性能必然會受到全部從庫更新的拖累。 同步複製的優勢是可以確保將數據實時複製到全部的從庫,可是主庫須要等待全部從庫的寫入完成,這會影響主庫的更新效率,可能還會致使主庫的更新延遲,適合於對數據一致性要求比較高的應用場景。 3.半同步複製 semi-sync replication 半同步複製介於異步複製和全同步複製之間,主庫在執行完客戶端提交的事務以後不是馬上返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才能返回給客戶端。相對於異步複製,半同步複製提升了數據的安全性,同時它也形成了必定程度的延遲,半同步複製最好在低延時的複製節點之間使用。 引入半同步複製的目的是爲了保證在master出現故障的時候,至少有一臺slave數據庫是完整的。在超時的狀況下半同步複製也會轉換爲異步複製,以確保主庫業務的正常更新。 半同步複製模式在必定程度上能夠保證所提交的事務至少會發送給一個從庫,但僅僅是保證事務已經發送到了從庫,並不能確保已經在從庫上應用完成。 MySQL主從半同步複製實驗 本次實驗環境延用MySQL主從異步複製的搭建環境 主機規劃 ---------------------------------------------------------------- 數據庫角色 主機名 bond0(SSH鏈接IP) bond1(內網通訊IP) ---------------------------------------------------------------- 主庫1(master) db01 10.0.0.11 192.168.10.11 ---------------------------------------------------------------- 主庫2(slave) db02 10.0.0.12 192.168.10.12 ---------------------------------------------------------------- 半同步的插件在MySQL的安裝目錄下 [root@db01 ~]# ls -l /u01/app/mysql/mysql-5.7.26-linux-glibc2.12-x86_64/lib/plugin/semisync_* -rwxr-xr-x 1 mysql mysql 708906 Apr 13 22:11 /u01/app/mysql/mysql-5.7.26-linux-glibc2.12-x86_64/lib/plugin/semisync_master.so -rwxr-xr-x 1 mysql mysql 152309 Apr 13 22:11 /u01/app/mysql/mysql-5.7.26-linux-glibc2.12-x86_64/lib/plugin/semisync_slave.so [root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf & [root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p Enter password: Master [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so'; Query OK, 0 rows affected (0.01 sec) Master [(none)]> select * from mysql.plugin; +----------------------+--------------------+ | name | dl | +----------------------+--------------------+ | rpl_semi_sync_master | semisync_master.so | +----------------------+--------------------+ 1 row in set (0.01 sec) Master [(none)]> show plugins; +----------------------------+----------+--------------------+--------------------+---------+ | Name | Status | Type | Library | License | +----------------------------+----------+--------------------+--------------------+---------+ | binlog | ACTIVE | STORAGE ENGINE | NULL | GPL | | mysql_native_password | ACTIVE | AUTHENTICATION | NULL | GPL | | sha256_password | ACTIVE | AUTHENTICATION | NULL | GPL | | CSV | ACTIVE | STORAGE ENGINE | NULL | GPL | | MyISAM | ACTIVE | STORAGE ENGINE | NULL | GPL | | MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL | GPL | | PERFORMANCE_SCHEMA | ACTIVE | STORAGE ENGINE | NULL | GPL | | MEMORY | ACTIVE | STORAGE ENGINE | NULL | GPL | | InnoDB | ACTIVE | STORAGE ENGINE | NULL | GPL | | INNODB_TRX | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_LOCKS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_LOCK_WAITS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMPMEM | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMPMEM_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP_PER_INDEX | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP_PER_INDEX_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_BUFFER_PAGE | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_BUFFER_PAGE_LRU | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_BUFFER_POOL_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_TEMP_TABLE_INFO | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_METRICS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_DEFAULT_STOPWORD | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_BEING_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_CONFIG | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_INDEX_CACHE | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_INDEX_TABLE | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_TABLES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_TABLESTATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_INDEXES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_COLUMNS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_FIELDS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_FOREIGN | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_FOREIGN_COLS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_TABLESPACES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_DATAFILES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_VIRTUAL | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | partition | ACTIVE | STORAGE ENGINE | NULL | GPL | | ARCHIVE | ACTIVE | STORAGE ENGINE | NULL | GPL | | FEDERATED | DISABLED | STORAGE ENGINE | NULL | GPL | | BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL | GPL | | ngram | ACTIVE | FTPARSER | NULL | GPL | | rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL | +----------------------------+----------+--------------------+--------------------+---------+ 45 rows in set (0.00 sec) Master [(none)]> show global variables like "%rpl_%"; +-------------------------------------------+------------+ | 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_stop_slave_timeout | 31536000 | +-------------------------------------------+------------+ 7 rows in set (0.01 sec) Master [(none)]> set global rpl_semi_sync_master_enabled = on; Query OK, 0 rows affected (0.00 sec) Master [(none)]> show global variables like "%rpl_%"; +-------------------------------------------+------------+ | 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 | | rpl_stop_slave_timeout | 31536000 | +-------------------------------------------+------------+ 7 rows in set (0.01 sec) 超時時間默認是10秒 若是你想永久生效能夠my.cnf配置文件裏 [mysqld]下面 rpl_semi_sync_master_enabled = on rpl_semi_sync_master_timeout = 10000 可是我不建議寫在配置文件裏,我要的是數據庫可控性強。 查看主庫半同步複製狀態 Master [(none)]> show global status like "%rpl_%"; +--------------------------------------------+-------+ | 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 | 0 | | Rpl_semi_sync_master_no_times | 0 | | Rpl_semi_sync_master_no_tx | 0 | | Rpl_semi_sync_master_status | ON | | Rpl_semi_sync_master_timefunc_failures | 0 | | Rpl_semi_sync_master_tx_avg_wait_time | 0 | | Rpl_semi_sync_master_tx_wait_time | 0 | | Rpl_semi_sync_master_tx_waits | 0 | | Rpl_semi_sync_master_wait_pos_backtraverse | 0 | | Rpl_semi_sync_master_wait_sessions | 0 | | Rpl_semi_sync_master_yes_tx | 0 | +--------------------------------------------+-------+ 14 rows in set (0.01 sec) Master [(none)]> 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 | +-------------------------------------------+------------+ 6 rows in set (0.00 sec) [root@db02 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf & [root@db02 ~]# mysql -S /data/mysql/3306/mysql.sock -p Enter password: Slave [(none)]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; Query OK, 0 rows affected (0.02 sec) Slave [(none)]> select * from mysql.plugin; +---------------------+-------------------+ | name | dl | +---------------------+-------------------+ | rpl_semi_sync_slave | semisync_slave.so | +---------------------+-------------------+ 1 row in set (0.01 sec) Slave [(none)]> show plugins; +----------------------------+----------+--------------------+-------------------+---------+ | Name | Status | Type | Library | License | +----------------------------+----------+--------------------+-------------------+---------+ | binlog | ACTIVE | STORAGE ENGINE | NULL | GPL | | mysql_native_password | ACTIVE | AUTHENTICATION | NULL | GPL | | sha256_password | ACTIVE | AUTHENTICATION | NULL | GPL | | CSV | ACTIVE | STORAGE ENGINE | NULL | GPL | | MyISAM | ACTIVE | STORAGE ENGINE | NULL | GPL | | MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL | GPL | | PERFORMANCE_SCHEMA | ACTIVE | STORAGE ENGINE | NULL | GPL | | MEMORY | ACTIVE | STORAGE ENGINE | NULL | GPL | | InnoDB | ACTIVE | STORAGE ENGINE | NULL | GPL | | INNODB_TRX | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_LOCKS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_LOCK_WAITS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMPMEM | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMPMEM_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP_PER_INDEX | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP_PER_INDEX_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_BUFFER_PAGE | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_BUFFER_PAGE_LRU | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_BUFFER_POOL_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_TEMP_TABLE_INFO | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_METRICS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_DEFAULT_STOPWORD | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_BEING_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_CONFIG | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_INDEX_CACHE | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_INDEX_TABLE | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_TABLES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_TABLESTATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_INDEXES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_COLUMNS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_FIELDS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_FOREIGN | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_FOREIGN_COLS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_TABLESPACES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_DATAFILES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_SYS_VIRTUAL | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | partition | ACTIVE | STORAGE ENGINE | NULL | GPL | | ARCHIVE | ACTIVE | STORAGE ENGINE | NULL | GPL | | FEDERATED | DISABLED | STORAGE ENGINE | NULL | GPL | | BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL | GPL | | ngram | ACTIVE | FTPARSER | NULL | GPL | | rpl_semi_sync_slave | ACTIVE | REPLICATION | semisync_slave.so | GPL | +----------------------------+----------+--------------------+-------------------+---------+ 45 rows in set (0.00 sec) Slave [(none)]> show global variables like "%rpl%"; +---------------------------------+----------+ | Variable_name | Value | +---------------------------------+----------+ | rpl_semi_sync_slave_enabled | OFF | | rpl_semi_sync_slave_trace_level | 32 | | rpl_stop_slave_timeout | 31536000 | +---------------------------------+----------+ 3 rows in set (0.01 sec) Slave [(none)]> set global rpl_semi_sync_slave_enabled = on; Query OK, 0 rows affected (0.00 sec) Slave [(none)]> show global variables like "%rpl%"; +---------------------------------+----------+ | Variable_name | Value | +---------------------------------+----------+ | rpl_semi_sync_slave_enabled | ON | | rpl_semi_sync_slave_trace_level | 32 | | rpl_stop_slave_timeout | 31536000 | +---------------------------------+----------+ 3 rows in set (0.00 sec) 固然你也能夠寫到my.cnf配置文件裏 Slave [(none)]> stop slave io_thread; Query OK, 0 rows affected (0.01 sec) Slave [(none)]> start slave io_thread; Query OK, 0 rows affected (0.01 sec) 查看從庫半同步複製狀態 Slave [(none)]> show global status like "%rpl_%"; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Rpl_semi_sync_slave_status | ON | +----------------------------+-------+ 1 row in set (0.01 sec) 查看從庫半同步複製插件的參數 Slave [(none)]> show variables like '%rpl_%'; +---------------------------------+----------+ | Variable_name | Value | +---------------------------------+----------+ | rpl_semi_sync_slave_enabled | ON | #on表示已激活半同步插件 | rpl_semi_sync_slave_trace_level | 32 | #從不半同步複製的調試級別 | rpl_stop_slave_timeout | 31536000 | +---------------------------------+----------+ 3 rows in set (0.00 sec) Master [(none)]> show global status like "%rpl_%"; +--------------------------------------------+-------+ | 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 | 0 | | Rpl_semi_sync_master_no_times | 0 | | Rpl_semi_sync_master_no_tx | 0 | | Rpl_semi_sync_master_status | ON | | Rpl_semi_sync_master_timefunc_failures | 0 | | Rpl_semi_sync_master_tx_avg_wait_time | 0 | | Rpl_semi_sync_master_tx_wait_time | 0 | | Rpl_semi_sync_master_tx_waits | 0 | | Rpl_semi_sync_master_wait_pos_backtraverse | 0 | | Rpl_semi_sync_master_wait_sessions | 0 | | Rpl_semi_sync_master_yes_tx | 0 | +--------------------------------------------+-------+ 14 rows in set (0.03 sec) Master [(none)]> show global variables like "%rpl_%"; +-------------------------------------------+------------+ | 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 | | rpl_stop_slave_timeout | 31536000 | +-------------------------------------------+------------+ 7 rows in set (0.01 sec) 測試主從半同步複製 Slave [(none)]> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.10.11 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000006 Read_Master_Log_Pos: 194 Relay_Log_File: db02-relay-bin.000006 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000006 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 194 Relay_Log_Space: 739 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 113306 Master_UUID: 7c145945-a680-11e9-baea-000c29a14cf7 Master_Info_File: /data/mysql/3306/data/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: 7c145945-a680-11e9-baea-000c29a14cf7:1-11 Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.01 sec) Master [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | app | | app01 | | app02 | | app03 | | app04 | | mysql | | performance_schema | | shenzhen | | sys | +--------------------+ 10 rows in set (0.00 sec) Master [shenzhen]> use shenzhen; Database changed Master [shenzhen]> show tables; +--------------------+ | Tables_in_shenzhen | +--------------------+ | t1 | +--------------------+ 1 row in set (0.00 sec) Master [shenzhen]> desc t1; +-------+---------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | +-------+---------+------+-----+---------+-------+ 1 row in set (0.00 sec) Master [shenzhen]> select * from t1; +------+ | id | +------+ | 1 | | 2 | +------+ 2 rows in set (0.00 sec) Master [shenzhen]> insert into t1(id) values(3); Query OK, 1 row affected (0.01 sec) Master [shenzhen]> insert into t1(id) values(4); Query OK, 1 row affected (0.02 sec) Master [shenzhen]> select * from t1; +------+ | id | +------+ | 1 | | 2 | | 3 | | 4 | +------+ 4 rows in set (0.00 sec) Master [shenzhen]> show global status like "%rpl_%"; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients | 1 | | Rpl_semi_sync_master_net_avg_wait_time | 0 | | Rpl_semi_sync_master_net_wait_time | 0 | | Rpl_semi_sync_master_net_waits | 2 | | Rpl_semi_sync_master_no_times | 0 | | Rpl_semi_sync_master_no_tx | 0 | | Rpl_semi_sync_master_status | ON | | Rpl_semi_sync_master_timefunc_failures | 0 | | Rpl_semi_sync_master_tx_avg_wait_time | 4897 | | Rpl_semi_sync_master_tx_wait_time | 9794 | | Rpl_semi_sync_master_tx_waits | 2 | | Rpl_semi_sync_master_wait_pos_backtraverse | 0 | | Rpl_semi_sync_master_wait_sessions | 0 | | Rpl_semi_sync_master_yes_tx | 2 | +--------------------------------------------+-------+ 14 rows in set (0.03 sec) Slave [shenzhen]> select * from t1; +------+ | id | +------+ | 1 | | 2 | | 3 | | 4 | +------+ 4 rows in set (0.00 sec) 測試半同步複製超時等待 Slave [shenzhen]> stop slave io_thread; Query OK, 0 rows affected (0.00 sec) 半同步複製與IO線程直接相關,與SQL線程無關。 Master [shenzhen]> insert into t1(id) values(5); Query OK, 1 row affected (10.01 sec) 等待了十秒鐘 半同步複製狀態自動轉換爲異步複製了,因此再次更新數據就很快了。 Master [shenzhen]> insert into t1(id) values(6); Query OK, 1 row affected (0.02 sec) Master [shenzhen]> insert into t1(id) values(7); Query OK, 1 row affected (0.00 sec) Master [shenzhen]> show global status like "%rpl_%"; +--------------------------------------------+-------+ | 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 | 2 | | Rpl_semi_sync_master_no_times | 1 | | Rpl_semi_sync_master_no_tx | 3 | | Rpl_semi_sync_master_status | OFF | | Rpl_semi_sync_master_timefunc_failures | 0 | | Rpl_semi_sync_master_tx_avg_wait_time | 4897 | | Rpl_semi_sync_master_tx_wait_time | 9794 | | Rpl_semi_sync_master_tx_waits | 2 | | Rpl_semi_sync_master_wait_pos_backtraverse | 0 | | Rpl_semi_sync_master_wait_sessions | 0 | | Rpl_semi_sync_master_yes_tx | 2 | +--------------------------------------------+-------+ 14 rows in set (0.00 sec) 開啓從庫的io線程複製,恢復半同步複製狀態。 Slave [shenzhen]> start slave io_thread; Query OK, 0 rows affected (0.00 sec) 再次查看主庫的半同步複製狀態 Master [shenzhen]> show global status like "%rpl_%"; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients | 1 | | Rpl_semi_sync_master_net_avg_wait_time | 0 | | Rpl_semi_sync_master_net_wait_time | 0 | | Rpl_semi_sync_master_net_waits | 3 | | Rpl_semi_sync_master_no_times | 1 | | Rpl_semi_sync_master_no_tx | 3 | | Rpl_semi_sync_master_status | ON | | Rpl_semi_sync_master_timefunc_failures | 0 | | Rpl_semi_sync_master_tx_avg_wait_time | 4897 | | Rpl_semi_sync_master_tx_wait_time | 9794 | | Rpl_semi_sync_master_tx_waits | 2 | | Rpl_semi_sync_master_wait_pos_backtraverse | 0 | | Rpl_semi_sync_master_wait_sessions | 0 | | Rpl_semi_sync_master_yes_tx | 2 | +--------------------------------------------+-------+ 14 rows in set (0.00 sec) Slave [shenzhen]> select * from t1; +------+ | id | +------+ | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | +------+ 7 rows in set (0.00 sec) 主從複製故障時的半同步複製測試 Slave [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | app | | app01 | | app02 | | app03 | | app04 | | mysql | | performance_schema | | shenzhen | | sys | +--------------------+ 10 rows in set (0.00 sec) Slave [(none)]> create database app05; Query OK, 1 row affected (0.00 sec) Slave [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | app | | app01 | | app02 | | app03 | | app04 | | app05 | | mysql | | performance_schema | | shenzhen | | sys | +--------------------+ 11 rows in set (0.00 sec) Master [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | app | | app01 | | app02 | | app03 | | app04 | | mysql | | performance_schema | | shenzhen | | sys | +--------------------+ 10 rows in set (0.00 sec) Master [(none)]> create database app05; Query OK, 1 row affected (0.01 sec) Master [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | app | | app01 | | app02 | | app03 | | app04 | | app05 | | mysql | | performance_schema | | shenzhen | | sys | +--------------------+ 11 rows in set (0.00 sec) Slave [(none)]> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.10.11 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000006 Read_Master_Log_Pos: 1661 Relay_Log_File: db02-relay-bin.000007 Relay_Log_Pos: 1143 Relay_Master_Log_File: mysql-bin.000006 Slave_IO_Running: Yes Slave_SQL_Running: No Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 1007 Last_Error: Error 'Can't create database 'app05'; database exists' on query. Default database: 'app05'. Query: 'create database app05' Skip_Counter: 0 Exec_Master_Log_Pos: 1499 Relay_Log_Space: 2199 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: NULL Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 1007 Last_SQL_Error: Error 'Can't create database 'app05'; database exists' on query. Default database: 'app05'. Query: 'create database app05' Replicate_Ignore_Server_Ids: Master_Server_Id: 113306 Master_UUID: 7c145945-a680-11e9-baea-000c29a14cf7 Master_Info_File: /data/mysql/3306/data/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: 190717 02:16:19 Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 7c145945-a680-11e9-baea-000c29a14cf7:12-17 Executed_Gtid_Set: 7c145945-a680-11e9-baea-000c29a14cf7:1-16 Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec) 此時再查看主庫的半同步複製狀態 發現仍是on,可見半同步複製和從庫的SQL線程沒有關係。 Master [(none)]> show global status like "%rpl%"; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients | 1 | | Rpl_semi_sync_master_net_avg_wait_time | 0 | | Rpl_semi_sync_master_net_wait_time | 0 | | Rpl_semi_sync_master_net_waits | 4 | | Rpl_semi_sync_master_no_times | 1 | | Rpl_semi_sync_master_no_tx | 3 | | Rpl_semi_sync_master_status | ON | | Rpl_semi_sync_master_timefunc_failures | 0 | | Rpl_semi_sync_master_tx_avg_wait_time | 3918 | | Rpl_semi_sync_master_tx_wait_time | 11756 | | 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 | +--------------------------------------------+-------+ 14 rows in set (0.01 sec) 處理從庫的複製故障 Slave [(none)]> stop slave; Query OK, 0 rows affected (0.00 sec) Slave [(none)]> set global sql_slave_skip_counter = 1; ERROR 1858 (HY000): sql_slave_skip_counter can not be set when the server is running with @@GLOBAL.GTID_MODE = ON. Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction 你開啓了gtid,他執行過了gtid是不會在執行的。 百度翻譯: 錯誤1858(hy000):當服務器以@@global.gtid_mode=on運行時,沒法設置SQL_slave_skip_計數器。相反,對於要跳過的每一個事務,生成一個與該事務具備相同GTID的空事務。 注入空事物的方法: Slave [(none)]> set gtid_next='7c145945-a680-11e9-baea-000c29a14cf7:17'; Query OK, 0 rows affected (0.00 sec) Slave [(none)]> begin;commit; Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.02 sec) 這裏的xxxxx:N 也就是你的slave sql thread報錯的GTID,或者說是你想要跳過的GTID。 最好的解決方案:從新構建主從環境 Slave [(none)]> set gtid_next='AUTOMATIC'; Query OK, 0 rows affected (0.00 sec) 注入空事物完成 Slave [(none)]> start slave; Query OK, 0 rows affected (0.01 sec) Slave [(none)]> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.10.11 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000006 Read_Master_Log_Pos: 1661 Relay_Log_File: db02-relay-bin.000008 Relay_Log_Pos: 360 Relay_Master_Log_File: mysql-bin.000006 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 1661 Relay_Log_Space: 1717 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 113306 Master_UUID: 7c145945-a680-11e9-baea-000c29a14cf7 Master_Info_File: /data/mysql/3306/data/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 7c145945-a680-11e9-baea-000c29a14cf7:12-17 Executed_Gtid_Set: 7c145945-a680-11e9-baea-000c29a14cf7:1-17 Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec) 最後查看主庫半同步的狀態 Master [(none)]> show global status like "%rpl%"; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients | 1 | | Rpl_semi_sync_master_net_avg_wait_time | 0 | | Rpl_semi_sync_master_net_wait_time | 0 | | Rpl_semi_sync_master_net_waits | 4 | | Rpl_semi_sync_master_no_times | 1 | | Rpl_semi_sync_master_no_tx | 3 | | Rpl_semi_sync_master_status | ON | | Rpl_semi_sync_master_timefunc_failures | 0 | | Rpl_semi_sync_master_tx_avg_wait_time | 3918 | | Rpl_semi_sync_master_tx_wait_time | 11756 | | 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 | +--------------------------------------------+-------+ 14 rows in set (0.00 sec) 查看從庫的半同步狀態 Slave [(none)]> show global status like "%rpl%"; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Rpl_semi_sync_slave_status | ON | +----------------------------+-------+ 1 row in set (0.01 sec) 線網環境半同步複製建議及其餘方案: 對於常規的互聯網應用,主從複製就夠用了,對於主從一致性要求較高的應用能夠使用半同步複製方案。可是半同步複製方案也會有缺點,那就是會致使主庫更新性能的降低。尤爲是在從庫網絡不穩定時會對主庫更新帶來更大的性能降低。 參考解決辦法: 1.將主庫半同步超時調短(1~2秒) 2.半同步複製的從庫硬件與主庫之間的網絡配置要更好。 3.半同步的從庫不要提供任何業務服務(包括讀業務都不要給) 除了半同步複製技術以外,還有一些方案能夠用於解決數據一致性問題: 1.客戶端程序實現雙寫數據庫。 2.客戶端程序在寫數據庫的同時,寫一段時間數據到磁盤上或內存中(redis)