MariaDB GTID複製

一.環境信息
主庫:168.24.65.30
從庫:168.24.65.31、168.24.65.32
mariadb 10.1.16

二,搭建傳統複製(可選)
先在主庫上查看:
mysql -uroot -p --socket=/tmp/mysql3306.sock
(product)root@localhost [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 |      343 |              |                  |
+------------------+----------+--------------+------------------+

從庫上執行:
change master to
master_host='168.24.65.30',
master_port=3306,
master_user='rep',
master_password='xxxx',
master_log_file='mysql-bin.000002',
master_log_pos=343;
start slave;

三.搭建GTID複製
目前我們生產環境主要是由兩種方式進行備份:
1、mydumper備份
可以到備份目錄文件下獲取備份完成時主庫最後執行的事務的GTID.
Started dump at: 2017-06-17 10:55:40
SHOW MASTER STATUS:
Log: mysql-bin.000056
Pos: 9637
GTID:0-64236-299476
GTID:0-64236-299476 就是後面從庫導入備份數據後,從這個GTID開始進行復制的位置。
2、xtrabackup備份
more xtrabackup_binlog_info 
mysql-bin.000104 95830984 0-691253306-60596652
0-691253306-60596652 是後面從庫數據導入後進行復制的起始位置。
從庫導入備份數據(mydumper或者xtrabackup備份)後,執行以下步驟
a. set global gtid_slave_pos='0-64236-299476';
b. show variables like 'gtid%';確認gtid_slave_pos位置有效。
MariaDB [jira]> show variables like 'gtid%'; 
+------------------------+----------------+
| Variable_name | Value |
+------------------------+----------------+
| gtid_binlog_pos | |
| gtid_binlog_state | |
| gtid_current_pos | 0-64236-299476 |
| gtid_domain_id | 0 |
| gtid_ignore_duplicates | OFF |
| gtid_seq_no | 0 |
| gtid_slave_pos | 0-64236-299476 |
| gtid_strict_mode | OFF |
+------------------------+----------------+
c. change master to master_host='168.24.65.30',master_user='rep',master_password='xxx',master_use_gtid=slave_pos;
d.start slave; show slave status\G 確認複製搭建成功。
MariaDB [jira]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 168.24.65.30
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000056
Read_Master_Log_Pos: 9637
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 670
Relay_Master_Log_File: mysql-bin.000056
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
Master_Server_Id: 64236
Master_SSL_Crl: 
Master_SSL_Crlpath: 
Using_Gtid: Slave_Pos
Gtid_IO_Pos: 0-64236-299476


四,傳統與GTID複製切換
1、傳統複製切換到GTID複製
stop slave;
change master to master_use_gtid=slave_pos;或者執行 change master to master_use_gtid=current_pos
start slave;
show slave status\G 確認複製已經切換成功
2.GTID複製切換到傳統複製
stop slave;
change master to master_use_gtid=no;
start slave;
shwo slave status\G Using_Gtid: No 可以確認已經由GTID複製切換到傳統複製。

五、主從GTID複製結構中Master切換
A(M)-->B(S) 切換爲 A(S)<--B(M) 結構
主從GTID複製結構中Master切換非常簡單。
1、先確認從庫B已經完全追上主庫A
Master_Log_File: mysql-bin.000002 = Relay_Master_Log_File:mysql-bin.000002 && Read_Master_Log_Pos:343 = Exec_Master_Log_Pos: 343 
2、A 上執行
change master to master_host='B',master_port=,master_user='xxxx',master_password='xxx',master_use_gtid=current_pos;start slave;
這裏把 master_use_gtid 配置成 current_pos。
因爲該主庫沒有做過其他數據庫的從庫,所以slave_pos爲空,需要用current_pos。二者區別可以看後面的定義。
3、B 上執行 stop slave;
一主多從結構的主庫切換和一主一從切換類似,只要把原來的從庫直接change到新的主庫上面就好。

六、在使用GTID的從服務器中跳過事務
場景:
在從庫某表中刪掉某條記錄,然後在主庫上執行同樣的刪除動作。
從庫上操作:
(product)root@localhost > delete from abc where id=2;
Query OK, 1 row affected (0.00 sec)

主庫操作:
delete from abc  where id=2;

這時從庫會報錯如下:
Last_Errno: 1032
Last_Error: Could not execute Delete_rows_v1 event on table abc; Can't find record in 'abc', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000002, end_log_pos 906

從庫找不到需要刪除的記錄,這時可以手動跳過這個錯誤。
方法1:
show slave status\G
Gtid_IO_Pos: 0-303306-27108734


stop slave; set global gtid_slave_pos='0-303306-27108734';start slave; 
show slave status\G 確認主從複製恢復正常。
方法2:
stop slave;set global sql_slave_skip_counter=1;start slave;
show slave status\G 確認主從複製恢復正常。

七、GTID使用限制
1、slave的本地寫入,需要注意,因爲跟master不是同一個GTID範圍,寫入binlog的值,複製到後續從庫,容易失敗,需要使用
set sql_log_bin=0,來禁止binlog的寫入。
生產環境所有從庫已經設置爲read_only(普通用戶只有select權限,有all/super權限的都不在這個範圍內)。如果因爲特殊情況需要在從庫
寫入數據,則先臨時關閉binlog寫入。
2、切換主庫前,必須保證主庫數據已經全部複製到將要作爲新主庫的從庫。
3、不能在事務中創建和刪除臨時表;
4、無法在事務中對非事務存儲引擎進行更新;
5、限制mysql_upgrade的執行;
八、常見覆制錯誤處理
1、主庫進行update,delete操作,從庫發現沒有相應記錄,導致複製中斷。
Last_SQL_Error: Could not execute Delete_rows_v1 event on table test.tt; Can't find record in 'tt', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000056, end_log_pos 10508
處理方式:
根據複製報錯的binlog位置,在主庫上解析相應的binlog,確認從庫具體因爲哪些數據確失導致複製中斷。
找出從庫缺失的記錄之後手動從主庫導出,再導入從庫。導入的時候,切記要先關閉binlog寫入。
set sql_log_bin=0;導入數據;set sql_log_bin=1; 然後重啓複製。
2、主庫上執行 insert操作,從庫已經有相應的記錄,導致複製中斷。
從庫報錯如下:
Last_SQL_Error: Could not execute Write_rows_v1 event on table test.tt; Duplicate entry '12' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000056, end_log_pos 10907
處理方式:
根據報錯信息可以知道從庫已經存在ID=12的記錄,因此複製再次插入同樣主鍵ID記錄時,報1062錯誤。
爲了驗證這一點,可以解析主庫相應位置的binlog。
因此我們可以直接刪除從庫ID=12的記錄,重啓複製。
以上錯誤除了主庫delete操作,從庫因記錄缺失報錯可以跳過。其他錯誤都不能直接跳過,會導致主從數據不一致。
七、GTID有關的三個全局變量
select @@global.gtid_slave_pos, @@global.gtid_binlog_pos,@@global.gtid_current_pos;
gtid_slave_pos:
This variable is the GTID of the last event group replicated on a slave server, for each replication domain.
gtid_binlog_pos:
This variable is the GTID of the last event group written to the binary log, for each replication domain.
gtid_current_pos:
This variable is the GTID of the last change to the database for each replication domain. Such changes can either be master events (ie. local changes made by user or application), or replicated events originating from another master server.
總結
MariaDB10.0.2之後的GTID複製搭建與管理非常方便,整體比MySQL官方版本好用很多。
主要有以下優勢:
1、MariaDB GTID可以有間斷,支持 set global sql_slave_skip_counter=1 跳過錯誤的語法。
MySQL的GTID是連續的,不支持直接跳過錯誤的語法,只能採取插入空事務來跳過相應的GTID.
2、MariaDB 複製結構中可以同時混雜傳統複製從庫和GTID複製從庫。但是MySQL不行,必須所有數據庫都開啓GTID複製。
3、MariaDB GTID和傳統複製間的切換是非常方便的無需其他配置。而MySQL就繁瑣很多,無法做到平滑過渡,需要修改主庫配置並重啓。
MariaDB官方文檔也推薦使用GTID複製。後續會琢磨一下GTID複製下的高可用工具,目標使MariaDB GTID複製在主庫失敗的情況下能自動切換,同時不丟失數據。
可支持create table tablename as select語句,測試如下:

CREATE TABLE bak_170728901_go (`_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',PRIMARY KEY (`_id`))
AS
   SELECT * FROM  go;

Query OK, 43499 rows affected (3.83 sec)
Records: 43499  Duplicates: 0  Warnings: 0
發佈了197 篇原創文章 · 獲贊 23 · 訪問量 48萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章