MySQL 主從複製架構之單主模型與半同步複製
MySQL 集羣架構模型
單主模型特性:
- 主節點打開二進制日誌
- 從節點打開中繼日誌
- 從節點啓動兩個線程:IO線程用來向主節點申請主節點的二進制日誌並保存至本地的中繼日誌,SQL線程用來讀取中繼日誌的SQL語句並在本地執行,復現主節點的執行狀態
雙主模型特性:
- 兩個節點互爲主從
- 分別開啓二進制日誌和中繼日誌
- 分別啓用兩個線程:IO線程和SQL線程
一主多從架構實現示例:
假設主節點已經運行一段時間,其二進制日誌中已保存很多SQL語句條目,現在建立一個主從架構的數據庫
- 準備一個主節點和一個從節點,IP分別爲172.16.50.9和172.16.50.10,
#在兩臺主機上分別同步時間
ntpdate 172.16.0.1
在實際生產環境中,如果主服務器已經運行一段時間,其二進制日誌很大時,爲了能讓從服務器儘快追趕上主服務器,一般會對主節點服務器進行一次全量備份,將該全量備份在從節點服務器上恢復數據
主從服務器二者的MySQL程序版本不一致時:主服務器的MySQL版本可以低於從服務器,但不可以高於從服務器的MySQL版本
修改配置文件,對每個節點設置唯一的節點ID,主節點啓用二進制日誌,從節點啓用中繼日誌
- 主節點配置
#修改配置文件
vim /etc/my.cnf.d/server.cnf
#僅需修改mysqld配置段
[mysqld]
innodb_file_per_table=ON
skip_name_resolve=ON
#修改server_id
server_id=1
#主節點啓用二進制日誌
log_bin=master-log
#啓動mariadb服務
systemctl start mariadb;ss -tnl
- 從節點配置
假如該從節點有可能會在主節點宕機時成爲新的主節點,也應該開啓二進制日誌
從節點應該設置爲只讀,但是,此處設置的只讀僅對沒有特殊權限的普通用戶有效,對root等用戶來說依然可寫
#修改配置文件
vim /etc/my.cnf.d/server.cnf
#僅需修改mysqld配置段
[mysqld]
innodb_file_per_table=ON
skip_name_resolve=ON
#修改server_id
server_id=2
#從節點啓用中繼日誌
relay_log=relay-log
read_only=ON
主節點服務器登錄本地MySQL客戶端執行操作
- 在主節點創建一個具有讀取並請求二進制日誌內容權限的賬號供從節點登錄從而執行復制操作
#創建用戶
GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'repluser'@'172.16.50.%' IDENTIFIED BY 'replpass';
#刷新並查看權限
FLUSH PRIVILEGES;
SHOW GRANTS FOR 'repluser'@'172.16.50.%'\G;
- 查看當前的二進制日誌的名稱和位置
SHOW MASTER STATUS;
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-log.000006 | 497 | | |
+-------------------+----------+--------------+------------------+
從節點服務器登錄本地MySQL客戶端執行操作
- 在從節點服務器上指定主節點服務器的相關信息
CHANGE MASTER TO MASTER_HOST='172.16.50.9',MASTER_USER='repluser',MASTER_PASSWORD='replpass',MASTER_PORT=3306,MASTER_LOG_FILE='master-log.000006',MASTER_LOG_POS=497;
- 查看從節點信息
SHOW SLAVE STATUS\G;
#信息如下:
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 172.16.50.9 #主節點的主機名
Master_User: repluser #主節點上的具有複製權限的用戶
Master_Port: 3306 #連接主節點的端口
Connect_Retry: 60 #連接重試時間
Master_Log_File: master-log.000006 #主節點使用的二進制日誌名
Read_Master_Log_Pos: 497 #主節點的二進制日誌執行語句的位置
Relay_Log_File: relay-log.000001 #從節點中繼日誌名
Relay_Log_Pos: 4 #從節點中繼日誌位置
Relay_Master_Log_File: master-log.000006
Slave_IO_Running: No #是否啓動了IO線程
Slave_SQL_Running: No #是否啓動了SQL線程
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: 497
Relay_Log_Space: 245
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 #最後一次的IO線程的錯誤編號
Last_IO_Error: #最後一次IO線程的錯誤信息內容
Last_SQL_Errno: 0 #最後一次的SQL線程的錯誤編號
Last_SQL_Error: #最後一次SQL線程的錯誤信息內容
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0 #主節點的server_id
1 row in set (0.00 sec)
- 啓動從節點的IO線程和SQL線程,讓從節點連接至主節點
#啓用IO線程和SQL線程
START SLAVE;
#再次查看主從信息,注意與啓動線程前的狀態信息進行對比
SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.50.9
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-log.000006
Read_Master_Log_Pos: 497
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 530
Relay_Master_Log_File: master-log.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: 497
Relay_Log_Space: 818
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: 1
1 row in set (0.00 sec)
- 啓動兩個線程後查看mariadb程序錯誤日誌的記錄信息
tail /var/log/mariadb/mariadb.log
170716 0:21:11 [Note] /usr/libexec/mysqld: ready for connections.Version: '5.5.52-MariaDB' socket: '/var/lib/mysql/mysql.sock' port: 3306 MariaDB Server
170716 0:40:39 [Note] 'CHANGE MASTER TO executed'. Previous state master_host='', master_port='3306',master_log_file='', master_log_pos='4'. New state master_host='172.16.50.9',master_port='3306', master_log_file='master-log.000006', master_log_pos='497'.
170716 0:54:38 [Note] Slave SQL thread initialized, starting replication in log 'master-log.000006' at position497, relay log './relay-log.000001' position: 4
170716 0:54:38 [Note] Slave I/O thread: connected to master '[email protected]:3306',replication started in log 'master-log.000006' at position 497
至此,主從複製已配置完成。
複製時應該注意的問題:
1、從服務設定爲“只讀”;
在從服務器啓動read_only,但僅對非SUPER權限的用戶有效;
阻止所有用戶:
mysql> FLUSH TABLES WITH READ LOCK;
2、儘量確保複製時的事務安全
【可能導致服務啓動失敗】
在master節點啓用參數:
sync_binlog = ON
如果用到的是InnoDB存儲引擎:
innodb_flush_logs_at_trx_commit=ON
innodb_support_xa=ON
3、從服務器意外中止時儘量避免自動啓動複製線程
4、從節點:設置參數
【可能導致服務啓動失敗】
sync_master_info=ON
sync_relay_log_info=ON
主從架構的半同步複製
- 分別在主從節點上執行執行安裝插件命令
#在主節點服務器上登錄mysql客戶端,執行:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
#在從節點服務器上登錄mysql客戶端,執行:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
#查看插件的加載狀態
SHOW PLUGINS;
啓用插件
- 主節點
#查看插件運行狀態
SHOW GLOBAL VARIABLES LIKE '%semi_sync%';
+------------------------------------+-------+
| 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_no_slave | ON |
+------------------------------------+-------+
#啓用插件
SET @@global.rpl_semi_sync_master_enabled=ON;
- 從節點
#查看插件運行狀態
SHOW GLOBAL VARIABLES LIKE '%semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
#啓用插件
SET @@global.rpl_semi_sync_slave_enabled=ON;
- 在從節點重啓IO線程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;
- 在主節點導入一些數據,查看同步效果
ls /root/hellodb.sql;cd /root
mysql < hellodb.sql
#登錄mysql客戶端,查看同步效果
SHOW GLOBAL STATUS LIKE 'rpl%';
+--------------------------------------------+-------------+
| Variable_name | Value |
+--------------------------------------------+-------------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_net_avg_wait_time | 684 |
| Rpl_semi_sync_master_net_wait_time | 23974 |
| Rpl_semi_sync_master_net_waits | 35 |
| 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 | 907 |
| Rpl_semi_sync_master_tx_wait_time | 30838 |
| Rpl_semi_sync_master_tx_waits | 34 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 35 |
| Rpl_status | AUTH_MASTER |
+--------------------------------------------+-------------+