Mysql主从复制之异步与半同步以及主从切换(实验)
什么是異步,半同步:
一、異步復制(Asynchronous replication)
1、邏輯上
MySQL默認的復制即是異步的,主庫在執行完客戶端提交的事務后會立即將結果返給給客戶端,并不關心從庫是否已經接收并處理,這樣就會有一個問題,主如果crash掉了,此時主上已經提交的事務可能并沒有傳到從庫上,如果此時,強行將從提升為主,可能導致新主上的數據不完整。
2、技術上
主庫將事務 Binlog 事件寫入到 Binlog 文件中,此時主庫只會通知一下 Dump 線程發送這些新的 Binlog,然后主庫就會繼續處理提交操作,而此時不會保證這些 Binlog 傳到任何一個從庫節點上。
二、半同步復制(Semisynchronous replication)
介于異步復制和全同步復制之間,主庫在執行完客戶端提交的事務后不是立刻返回給客戶端,而是等待至少一個從庫接收到并寫到relay log中才返回給客戶端。相對于異步復制,半同步復制提高了數據的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步復制最好在低延時的網絡中使用。
實驗:
項目環境: 2臺centos7、MySQL5.7.26(編譯安裝)
項目描述: 搭建2臺MySQL服務器,實現主從復制、為后面的讀寫分離做前期的準備,構建一個簡單的MySQL集群。
項目步驟:
操作步驟:
1.修改mysql的配置文件,啟動二進制日志功能vim /etc/my.cnf在主服務器上開啟二進制日志,server_id=1#binary loglog_binserver_id = 1在從服務器上也可以開啟二進制日志,server_id=2#binary loglog_binserver_id = 22.在主服務器上新建并且授權一個用戶,只給予復制權限用于復制二進制日志root@(none) 15:04 mysql>grant replication slave on *.* to '用戶名'@'從服務器的IP地址' identified by '密碼'; Query OK, 0 rows affected, 1 warning (0.02 sec)3.備份出主服務器上的數據,然后到導入到從服務器上[root@sc-mysql-master ~]# mysqldump -uroot -p'密碼#' --all-databases > /backup/all_db.sql [root@sc-mysql-master backup]# scp all_db.sql root@1從服務器ip地址:/root 100% 11MB 21.0MB/s 00:00 在從服務器上導入數據[root@sc-mysql-slave ~]# mysql -uroot -p'密碼' <all_db.sql mysql: [Warning] Using a password on the command line interface can be insecure.4.在從服務器上配置master 的信息在主服務器上查看當前的二進制日志的文件和位置號root@(none) 15:12 mysql>show master status; +----------------------------+----------+--------------+------------------+-------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |+----------------------------+----------+--------------+------------------+-------------------+| sc-mysql-master-bin.000001 | 449 | | | |+----------------------------+----------+--------------+------------------+-------------------+1 row in set (0.00 sec)root@(none) 15:19 mysql> root@(none) 15:19 mysql>flush logs; 刷新二進制日志文件 Query OK, 0 rows affected (0.02 sec)root@(none) 15:20 mysql>show master status; +----------------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +----------------------------+----------+--------------+------------------+-------------------+ | sc-mysql-master-bin.000002 | 154 | | | | +----------------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.01 sec) 在從服務器上配置master的信息[root@sc-mysql-slave ~]# mysql -uroot -p'密碼'root@(none) 15:26 mysql>CHANGE MASTER TO MASTER_HOST='master地址' ,MASTER_USER='slave',MASTER_PASSWORD='密碼',MASTER_PORT=3306,MASTER_LOG_FILE='mysql-bin.000020',MASTER_LOG_POS=154; Query OK, 0 rows affected, 2 warnings (0.04 sec)root@(none) 15:27 mysql> root@(none) 15:27 mysql>show slave status \G; 查看slave的狀態信息 *************************** 1. row ***************************Slave_IO_State: Master_Host: master地址Master_User: slaveMaster_Port: 3306Connect_Retry: 60Master_Log_File: sc-mysql-master-bin.000002Read_Master_Log_Pos: 154Relay_Log_File: sc-mysql-slave-relay-bin.000001Relay_Log_Pos: 4Relay_Master_Log_File: sc-mysql-master-bin.000002Slave_IO_Running: NoSlave_SQL_Running: No5.在master和slave上關閉防火墻和selinux主服務器[root@sc-mysql-master backup]# service firewalld stopRedirecting to /bin/systemctl stop firewalld.service[root@sc-mysql-master backup]# getenforce Permissive[root@sc-mysql-master backup]#從服務器[root@sc-mysql-slave ~]# service firewalld stopRedirecting to /bin/systemctl stop firewalld.service[root@sc-mysql-slave ~]# getenforce Disabled[root@sc-mysql-slave ~]#6.在slave上啟動復制功能 root@(none) 15:33 mysql>start slave; Query OK, 0 rows affected (0.01 sec)root@(none) 15:33 mysql> root@(none) 15:33 mysql>show slave status \G; *************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: master地址Master_User: slaveMaster_Port: 3306Connect_Retry: 60Master_Log_File: sc-mysql-master-bin.000002Read_Master_Log_Pos: 154Relay_Log_File: sc-mysql-slave-relay-bin.000002Relay_Log_Pos: 330Relay_Master_Log_File: sc-mysql-master-bin.000002Slave_IO_Running: Yes --》是yesSlave_SQL_Running: Yes --》是yes表示主從復制已經配置成功了 7.驗證主從復制的效果 在master上新建庫 root@(none) 15:36 mysql>create database zouweicheng; Query OK, 1 row affected (0.00 sec)root@(none) 15:36 mysql>use zouweicheng Database changed root@zouweicheng 15:37 mysql>show tables; Empty set (0.00 sec)root@zouweicheng 15:37 mysql>create table t1(id int); Query OK, 0 rows affected (0.06 sec)root@zouweicheng 15:38 mysql>insert into t1 values(1),(2); Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0root@zouweicheng 15:38 mysql>8.到slave上去看master.info 和relay-log.info [root@sc-mysql-slave ~]# cd /data/mysql/ 到數據目錄下查看 [root@sc-mysql-slave mysql]# cat master.info 25 sc-mysql-master-bin.000002 782 master ip地址 oudi Sanchuang123# 3306 60 0[root@sc-mysql-slave mysql]# cat relay-log.info 7 ./sc-mysql-slave-relay-bin.000002 958 sc-mysql-master-bin.000002 782 0 0 1 啟用半同步復制 在主服務器上執行安裝 root@localhost [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so'; Query OK, 0 rows affected (0.00 sec)root@(none) 15:45 mysql>set global rpl_semi_sync_master_enabled=1; Query OK, 0 rows affected (0.00 sec)啟用半同步 root@(none) 15:46 mysql>show global variables like '%rpl_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.01 sec)在從服務器上執行安裝插件 root@localhost [(none)]>install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; Query OK, 0 rows affected (0.01 sec)從庫上啟用半同步功能 root@(none) 15:59 mysql>set global rpl_semi_sync_slave_enabled=1; Query OK, 0 rows affected (0.00 sec)root@(none) 16:00 mysql>show global variables like '%rpl_semi%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | rpl_semi_sync_slave_enabled | ON | | rpl_semi_sync_slave_trace_level | 32 | +---------------------------------+-------+ 2 rows in set (0.01 sec)root@(none) 16:01 mysql> 三、半同步測試 從庫停止復制以后在主庫建表測試slave: root@localhost [(none)]>stop slave; Query OK, 0 rows affected (0.01 sec) master root@localhost [(none)]>use xucl; Database changed root@localhost [xucl]>create table t1(id int); Query OK, 0 rows affected (10.01 sec) 可以看到,主庫在10秒內沒有收到應答后自動改為異步復制,然后再引擎層提交事務。如何知道當前主從復制的狀態是半同步還是異步? root@xiongda 16:39 mysql>show status like 'Rpl_semi_sync_master_status'; +-----------------------------+-------+ | Variable_name | Value | +-----------------------------+-------+ | Rpl_semi_sync_master_status | ON | 表示是半同步 +-----------------------------+-------+ 1 row in set (0.00 sec)root@xiongda 16:41 mysql> 在從服務器上stop slave; root@xiongda 16:39 mysql>stop slave; Query OK, 0 rows affected (0.01 sec)root@xiongda 16:42 mysql>在主服務器上執行數據插入或者建表、數據修改等操作,觸發半同步,如果半同步失敗,主服務器會切換到異步 root@xiongda 16:41 mysql>create table t6(id int); Query OK, 0 rows affected (10.09 sec) 所花費的時間超過10秒root@xiongda 16:42 mysql> root@xiongda 16:42 mysql>show status like 'Rpl_semi_sync_master_status'; +-----------------------------+-------+ | Variable_name | Value | +-----------------------------+-------+ | Rpl_semi_sync_master_status | OFF | 半同步關閉 +-----------------------------+-------+ 1 row in set (0.00 sec)root@xiongda 16:43 mysql> 在從服務器那邊啟用start slave ; root@xiongda 16:42 mysql>start slave; Query OK, 0 rows affected (0.01 sec)root@xiongda 16:44 mysql> root@xiongda 16:44 mysql>show tables; 查看同步情況 +-------------------+ | Tables_in_xiongda | +-------------------+ | t1 | | t3 | | t4 | | t5 | | t6 | +-------------------+ 5 rows in set (0.00 sec)root@xiongda 16:45 mysql>在主服務器上查看狀態 root@xiongda 16:43 mysql>show status like 'Rpl_semi_sync_master_status'; +-----------------------------+-------+ | Variable_name | Value | +-----------------------------+-------+ | Rpl_semi_sync_master_status | ON | +-----------------------------+-------+ 1 row in set (0.01 sec)root@xiongda 16:44 mysql>主從切換
mysql主從關系中,如果master宕機了,則要提升slave為主,等原來的主庫恢復之后,則要把老的主庫變為從庫,這樣才能盡最大可能的保證應用層面的業務高可用性和數據的完整性。
## mysql主從切換為從主: 從庫變主庫 old slave: show processlist;# 確保Slave has read all relay log; STOP SLAVE IO_THREAD show slave status \G;檢查IO及SQL線程是否正常,如果為NO表明同步不一致stop slave; reset master; reset slave all;(看版本號)grant replication slave on *.* repl@'IP' identified by 'replpwd'; show master status;#記住這里列出的log_file和log_pos信息 ------------------------------------------------------------------------------ ## 主庫變從庫 old master: Reset master;(新的slave,老的master) Reset slave;change master to master_host="IP", master_port=3306, master_user="repl", master_password="replpwd", master_log_file="...",#上一步中列出的log_file master_log_pos="...";#上一部中列出的log_posstart slave; show slave status\G;總結
以上是生活随笔為你收集整理的Mysql主从复制之异步与半同步以及主从切换(实验)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [LeetCode]Buy and Se
- 下一篇: AD出现 “Net Tie failed