一、主從同步複製
MySQL 5.6引入的GTID(Global Transaction IDs)使得其複製功能的配置、監控及管理變得更加易於實現,且更加健壯。
要在MySQL 5.6中使用複製功能,其服務配置段[mysqld]中應該定義如下選項:
binlog-format:二進制日誌的格式,有row、statement和mixed幾種類型;
需要注意的是:當設置隔離級別爲READ-COMMITED必須設置二進制日誌格式爲ROW,現在MySQL官方認爲STATEMENT這個已經不再適合繼續使用;但mixed類型在默認的事務隔離級別下,可能會導致主從數據不一致;
log-slave-updates、gtid-mode、enforce-gtid-consistency、report-port和report-host:用於啓動GTID及滿足附屬的其它需求;
master-info-repository和relay-log-info-repository:啓用此兩項,可用於實現在崩潰時保證二進制及從服務器安全的功能;
sync-master-info:啓用之可確保無信息丟失;
slave-paralles-workers:設定從服務器的SQL線程數;0表示關閉多線程複製功能;
binlog-checksum、master-verify-checksum和slave-sql-verify-checksum:啓用複製有關的所有校驗功能;
binlog-rows-query-log-events:啓用之可用於在二進制日誌記錄事件相關的信息,可降低故障排除的複雜度;
log-bin:啓用二進制日誌,這是保證複製功能的基本前提;
server-id:同一個複製拓撲中的所有服務器的id號必須惟一;
實驗環境:
系統:centos6.6
數據庫:mariadb-5.5.43
masterIP:192.168.43.113
slaveIP:192.168.43.110
1.修改master節點配置文件/etc/mysql/my.cnf
[mysqld]
binlog-format=ROW
log-bin=master-bin
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=2
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1
server-id=1
report-port=3306
port=3306
datadir=/mydata/data
socket=/tmp/mysql.sock
report-host=master.magedu.com
2.修改slave節點配置文件
[mysqld]
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=2
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1
server-id=11
report-port=3306
port=3306
log-bin=mysql-bin.log
datadir=/mydata/data
socket=/tmp/mysql.sock
report-host=slave.magedu.com
read-only = on
3.在主節點創建用於複製的用戶(最小權限原則,給予儘量少的權限)
MariaDB [(none)]> grant replication client,replication slave on *.* to 'copyuser'@'192.168.%.%' identified by 'copypass';
MariaDB [(none)]> flush privileges;
4.啓動從節點的複製線程
(1)查看主節點二進制日誌文件名稱和事件位置
MariaDB [(none)]> show master status;
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000001 | 245 | | |
+-------------------+----------+--------------+------------------+
(2)在從節點啓動複製線程
MariaDB [(none)]> change master to master_host='192.168.43.113', master_user='copyuser', master_password='copypass', master_log_file='master-bin.000001', master_log_pos=245;
MariaDB [(none)]> start slave;
MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.43.113
Master_User: copyuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 326
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 611
Relay_Master_Log_File: master-bin.000001
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: 326
Relay_Log_Space: 899
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 主從節點數據是否一致,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
可以看到:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
證明已經啓動成功
5.驗證主從同步結果
(1)在主節點修改數據庫數據
MariaDB [(none)]> create database xxx;
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| xxx |
+--------------------+
(2)在從節點查看數據是否同步
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| xxx |
+--------------------+
可以看到新建的數據庫“xxx”已經同步到從節點,試驗完成。
複製時應該注意的問題:
1、如何限制從服務器只讀?
在從服務器啓動read_only;但僅對非具有SUPER權限的用戶有效;
阻止所有用戶 :MariaDB> FLUSH TABLES WITH READ LOCK;
2、如何保證主從複製時的事務安全?
在master節點啓用參數:
sync_binlog = on
如果用到的爲InnoDB存儲引擎:
innodb_flush_logs_at_trx_commit
innodb_support_xa=on
在slave節點:
skip_slave_start 不自動啓動slave_start,應該手動啓動。
主節點:
sync_master_info = 1
從節點
sync_relay_log = 1
sync_relay_log_info = 1
二、半同步複製
基本原理:
客戶端發起數據庫修改操作之後,master服務器執行操作之後,不立即返回給客戶端結果,而是等待slave服務器複製master的二進制日誌文件執行同步操作,等slave執行完成同步操作返回給master同步完成信號,master纔將執行結果返回給客戶端。如果由於某種原因導致master在超時時間內沒有收到slave節點的同步完成信號,則master轉換爲異步模式,不在管slave是否同步,客戶端發起操作後,由master執行完成直接返回結果給客戶端
需要安裝兩個由谷歌開源的插件(插件目錄:/usr/local/mysql/lib/plugin)
(1)master服務器安裝插件semisync_master.so
MariaDB [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.12 sec)
MariaDB [(none)]> show global variables like '%semi%';
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled | OFF | 是否開啓半同步複製
| rpl_semi_sync_master_timeout | 10000 | 超時時長,超時後轉爲異步模式複製,默認10秒
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
+------------------------------------+-------+
4 rows in set (0.00 sec)
(2)設置全局變量,開啓半同步複製,縮短超時時長
MariaDB [(none)]> set global rpl_semi_sync_master_enabled=1;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> set global rpl_semi_sync_master_timeout=2000;
Query OK, 0 rows affected (0.00 sec)
(3)slave服務器安裝插件semisync_slave.so
MariaDB [(none)]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.03 sec)
MariaDB [(none)]> show global variables like '%semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
2 rows in set (0.00 sec)
MariaDB [(none)]> set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)
(4)重啓IO_THREAD
MariaDB [(none)]> stop slave io_thread;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)
(5)查看狀態
MariaDB [(none)]> show global status like '%semi%';
+--------------------------------------------+-------+
| 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 | 半同步狀態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 |
+--------------------------------------------+-------+
三、雙主模式(互爲主從)
雙主模型簡單介紹:
互爲主從需注意:
1、可能產生數據不一致;
2、自動增長id需要隔離開,否則害怕自動增長字段衝突
定義一個節點使用奇數id
auto_increment_offset=1 自動增長ID由1開始
auto_increment_increment=2 每次增長步長爲2
定義另一個節點使用偶數id
auto_increment_offset=2 自動增長ID由2開始
auto_increment_increment=2 每次增長步長爲2
簡單配置過程:
(1) 各自使用不同的server id
(2) 都啓用binlog和relay log
(3) 定義自動增長的id字段的增長方式
(4) 都授權有複製權限的用戶賬號
(5) 各自把對方指定爲主服務器
四、複製過濾器
讓slave僅複製有限的幾個數據庫,而非所有;
有兩種實現思路:
(1) 主服務器僅向二進制日誌中記錄有特定數據庫相關的寫操作;
問題:即時點還原將無法全面實現;
binlog_do_db= # 數據庫白名單
binlog_ignore_db= # 數據庫黑名單
(2)從服務器的SQL_THREAD僅在中繼日誌中讀取特定數據相關的語句並應用在本地;
問題:會造成網絡帶寬和磁盤IO的浪費;
Replicate_Do_DB= 執行中繼日誌的數據庫白名單
Replicate_Ignore_DB=
Replicate_Do_Table=
Replicate_Ignore_Table=
Replicate_Wild_Do_Table=
Replicate_Wild_Ignore_Table=
五、基於SSL的複製
前提:支持SSL
(1) 主服務器端配置證書和私鑰,並創建一個要求必須使用SSL連接的複製賬號(REQUIRE SSL);
(2) SLAV端連接master時,使用MASTER_SSL相關的選項來配置證書等信息;
六、跟複製功能相關的文件
master.info:用於保存slave連接至master時的相關信息;
relay-log.info:保存了當前slave節點上已經複製的當前二進制日誌和本地relay log日誌對應關係;
7、複製的監控和維護
(1) 清理日誌:PURGE
(2) 複製監控
SHOW MASTER STATUS
SHOW BINLOG EVENTS
SHOW BINARY LOGS
SHOW SLAVE STATUS
(3) 如何判斷slave是否落後於master(show slave status;)
Seconds_Behind_Master: 0
(4) 如何確定主從節點數據是否一致?
通過表自身的CHECKSUM檢查SHOW TABLE STATUS\G;
使用percona-tools中pt-table-checksum
(5) 數據不一致的修復方法:
重新複製