主從複製:MySQL5.6開始主從複製有兩種方式:基於日誌(binlog);基於GTID(全局事務標示符);mysql
1》基於日誌(binlog)主從複製原理:sql
Mysql的Replication是一個異步複製的過程,從一個Mysql instace(咱們稱成之爲:Master)複製另一個Mysqlinstance(咱們稱爲slave),在Master與 slave 之間實現整個複製的過程是由三個線程來完成的,其中兩個線程(sql線程和IO線程)在Slave端,另一個線程(IO線程0在Master端.)要實MysqlReplication
首先必須打開Master端的Binary Log(就是打開bin-log功能)不然沒法實現,整個的複製過程實際上就是Slave從Master端獲取binlog日誌而後再slave端順序執 行日誌中全部的記錄及各類操做;
Mysql複製基本過程以下:
1> Slave上面的IO線程鏈接上Master,而且請求從指定日誌文件的指定位置(或者從最開始的日誌)以後的日誌內容;
2>Master接收到來自Slave的IO線程請求後,經過負責複製的IO線程根據請求的信息指定日誌指定位置後的日誌信息,返回給Slave端的IO線程,返回的信 息當中除了日誌全部包含的信息外,還包括本次返回信息在Master段的Binary log(二進制)文件名稱以及Binary log(二進制)的位置.
3>Slave的IO 線程接收到master返回的信息後,將接收到的日誌內容一次寫入slave端的Relay log中繼日誌文件,(mysql-relay-bin.xx)的最末端,而且將 讀取到的Master端的bin-log的文件和位置記錄,紀錄到 master-info文件當中,以方便下一次讀取的時候可以清楚的告訴Master 我須要從某個bin-lo
g的哪一個位置開始日後的日誌內容,請發給我;
4>Slave的SQL線程檢測到Relay Log中心增長了內容後,會立刻解析Master 二進制日誌文件中的內容執行裏面的Query語句;vim
2》主從環境:服務器
Master IP: 192.168.1。106
Slave IP: 192.168.1。110
在Master和Slave上安裝Mysql
3》Master(主)操做異步
# : vim /etc/my.cnf
#log_slave_updates 註釋掉這行
server-id=1 將id號改成1
#mysql –uroot –p –h localhost
mysql>grant replication slave on *.* to 'admin'@'192.168.1.106' identified by '123456'; #給13slave進行受權複製
mysql>flush tables with read lock;
mysql>show master status;ide
mysql>unlock tables;post
4》Slave(從)操做測試
#:vim /etc/my.cnf
server-id=2 #將server_id改成2
#mysql –uroot –p –h localhost
mysql>stop slave;
mysql>change master to
master_host='192.168.100.160',
master_user='admin',
master_password='123456',
master_log_file='masterlog.000001',
master_log_pos=120;
mysql>start slave;
mysql>show slave status\G;線程
排錯:
若是show slave status\G;報錯是由於沒有找到正確的端口號,則能夠在這個直接添加定義
master_port=3306,
檢查從服務器複製功能狀態: 排錯:
若是show slave status\G;報錯是由於沒有找到正確的端口號,則能夠在這個直接添加定義
master_port=3306,
檢查從服務器複製功能狀態:日誌
注:Slave_IO及Slave_SQL進程必須正常運行,即YES狀態,不然都是錯誤的狀態(如:其中一個NO均屬錯誤)。
5》測試數據同步
1>在Master建立一個庫表插入一條數據
#mysql –uroot –p –h localhost
Mysql->create database zytest;
Mysql->create table aa(
User_id int,
User_name varchar(10));
Mysql->inster into aa values(‘11’,’alvin’);
2>在從上查看同步狀況
#mysql –uroot –p –h localhost
Mysql->show slave status\G;
Mysql->show databases;
6》常見故障解決
1>通常的異常只須要跳過一步便可恢復
模擬故障,建立主從複製以前.在主上建立一個CC庫,在開啓主從複製,從的IO都是爲YES後,在主上建立一個gongda庫,看看從庫是否同步成功?
若是成功,接下來模擬故障.在主上將CC刪除掉.在從看slave狀態是否是就開始報錯了??
解決方法以下:
> stop slave;
>SET GLOBAL sql_slave_skip_counter = 1; 遇到錯誤直接跳過,繼續恢復
> start slave;
2>斷電致使主從不能同步時,通主庫的最後一個bin-log日誌進行恢復
在主庫服務器上,mysqlbinlog mysql-bin.xxxx > binxxxx.txt
tail -n 100000 binxxxx.txt > tail-binxxxx.txt
vim tail-binxxxx.txt 打開tail-binxxxx.txt文件找到最後一個postion值
而後在從庫上,change host to 相應正確的值
>stop slave;
>change master to master_host='ip', master_user='username', master_password='password',
master_log_file='mysql-bin.xxxx', master_log_pos=xxxx;
>start slave;
>show slave status\G;
3>主鍵衝突、表已存在等錯誤代碼如1062,1032,1060等,能夠在mysql主配置文件指定
略過此類異常並繼續下條sql同步,這樣也能夠避免不少主從同步的異常中斷
[mysqld]
slave-skip-errors = 1062,1032,1060
======================常見錯誤場景描述以及解決方法
GTID複製模式手動跳過複製錯誤
1.場景描述:
A 服務器(Master)
B 服務器(Slave)
在A 服務器上建立一個庫叫作aatest
在B 服務器上查看是否同步,
2.錯誤場景描述開始:
在B 服務器(Slave)將aatest刪除掉.
在A 服務器(Master)將aatest刪除掉
在個時候到B服務器使用show slave status\G;發現SQL 線程阻塞.
3.開始嘗試恢復,使用binlog的跳過方式,嘗試跳過恢復(並未獲得解決,可是給出了提示)
當備庫複製出錯時,傳統的跳過錯誤的方法是設置sql_slave_skip_counter,而後再START SLAVE。但若是打開了GTID,就會設置失敗:
mysql> 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
提示的錯誤信息告訴咱們,能夠經過生成一個空事務來跳過錯誤的事務。
咱們手動產生一個備庫複製錯誤:
Last_SQL_Error: Error ‘Unknown table ‘test.t1」 on query. Default database: ‘test’. Query: ‘DROP TABLE `t1` /* generated by server */’
查看binlog中,該DDL對應的GTID爲7a07cd08-ac1b-11e2-9fcf-0010184e9e08:1131
4.經過GTID的方式跳過事務,獲得解決。
4.一、步驟1:
在備庫上執行:
mysql>show slave status\G; 查看一下
Master_Log_File: mysql-bin.000003 這裏獲得A 服務器(Master)的binlog日誌文件
4.二、步驟2:
在主庫上執行:
# mysqlbinlog mysql-bin.000003
找到drop database aatest這個語句動做的上下文,
咱們能夠看到有兩個SET @@SESSION.GTID_NEXT。
(1)第一個是drop database aatest之上的:SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:31
(2)第二個是drop database aatest之下的:SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:32
<< 咱們將第2個SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:32 複製一下>>
#160817 1:08:06 server id 1 end_log_pos 5484 CRC32 0x963858ea GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:31'/*!*/;
# at 5484
#160817 1:08:06 server id 1 end_log_pos 5565 CRC32 0x96ff64da Query thread_id=44exec_time=0 error_code=0
SET TIMESTAMP=1471367286/*!*/;
drop database aatest
/*!*/;
# at 5565
#160817 1:08:22 server id 1 end_log_pos 5613 CRC32 0x14d35459 GTID [commit=yes]
SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:32'/*!*/;
4.三、步驟3: 在備庫上執行: mysql> select @@GTID_NEXT 先查詢GTID_NEXT 的值 mysql> STOP SLAVE; 先中止掉SLAVE Query OK, 0 rows affected (0.00 sec) mysql> SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:32‘;將步驟2複製的粘貼運行, Query OK, 0 rows affected (0.00 sec) mysql> BEGIN; COMMIT; 給一個空的事務,而後在提交。 Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) mysql> SET SESSION GTID_NEXT = AUTOMATIC; 從新設置自動提交事務GTID。 Query OK, 0 rows affected (0.00 sec) mysql> START SLAVE; 再查看show slave status,就會發現錯誤事務已經被跳過了。這種方法的原理很簡單,空事務產生的GTID加入到GTID_EXECUTED中,這至關於告訴 備庫,這個GTID對應的事務已經處理了;