mysql複製在業界裏有叫:mysql同步,ab複製等。專業名稱就是叫:複製
複製是單向的,只能從master複製到slave上,延時基本上是毫秒級別的。
一組複製結構中可以有多個slave,對於master一般場景推薦只有一個。
master用戶寫入數據,生成event記到binary log中
slave接收master上傳來的binlog,然後按順序應用,重現master上的用戶操作。
記錄最小的單位是一個event,日誌前4個字節是一個magic number,接下來19個字節記錄formatt desc event:FDE
MySQL5.6增加了GTID複製
classic主從配置
核心配置
[mysqld]
log-bin
server-id
gtid_mode=off #禁掉gtid
grantreplication slave on *.* to 'repl'@'%' identified by 'repl4slave';
flushprivileges;
級別 |
優點 |
缺點 |
statement |
binlog文件較小 日誌是包含用戶執行的原始SQL,方便統計和審計 出現最早,兼容較好 |
存在安全隱患,可能導致主從不一致 對一些系統函數不能準確複製或是不能複製 |
row |
相比statement更加安全的複製格式 在某些情況下複製速度更快(SQL複雜,表有主鍵) 系統的特殊函數也可以複製 更少的鎖 更新和刪除語句檢查是否有主鍵,如果有則直接執行,如果沒有,看是否有二級索引,如再沒有,則全表掃描 |
binlog比較大(myql5.6支持binlog_row_image) 單語句更新(刪除)表的行數過多,會形成大量binlog 無法從binlog看見用戶執行SQL(5.6中增加binlog_row_query_log_events記錄用戶的query) |
mixed |
混合使用row和statement格式,對於DDL記錄statument,對於table裏的行操作記錄爲row格式。 如果使用innodb表,事務級別使用了READ_COMMITTED or READ_UMCOMMITTED日誌級別只能使用row格式。 但是使用ROW格式中DDL語句還是會記錄成statement格式。 |
mixed模式中,那麼在以下幾種情況下自動將binlog模式由SBR模式改成RBR模式。 當DML語句更新一個NDB表 當函數中包含UUID時 2個及以上auto_increment字段的表被更新時 行任何insert delayed語句時 用UDF時 視圖中必須要求使用RBR時,例如創建視圖使用了UUID()函數 |
添加一個新的從庫
獲取主庫上一個帶binlog及pos偏移量的備份
在從庫上恢復後
>changemaster to
master_host='192.168.199.117',
master_user='slave',
master_port=7000,
master_password='slavepass',
master_log_file='mysql-bin.000008',
master_log_pos=896;
>startslave;
>showslave status\G;
錯誤跳過:
stopslave;
set globalsql_slave_skip_counter=1;
startslave;
show slavestatus\G;
GTID複製配置
一個事務對應一個唯一ID
一個GTID在一個服務器上只會執行一次
GTID是用來替代以前classic的複製方法
mysql5.62支持,mysql5.6.10後完善
優點:
相對於行復制來講數據安全性更高
故障切換更簡單
GTID
[mysqld]
#GTID:
gtid_mode=on
enforce-gtid-consistency=on
#binlog
log-bin=mysql-bin
log-slave-updates=1
GTID添加從庫有兩種方法:
1.如果master所有的binlog還在,安裝slave後,直接changemaster 到master
原理是直接獲取master所有的gtid並執行
優點是簡單
缺點是如果binlog太多,數據完全同步需要的時間較長,並且需要master一開始就啓用了GTID
總結:適用於master也是新建不久的情況
2.通過master或者其它slave的備份搭建新的slave.
原理:獲取master的數據和這些數據對應的GTID範圍,然後通過在slave設置@@GLOBAL.GTID_PURGED從而跳過備份包含的GTID
優點是可以避免第一種方法中的不足
缺點操作相對複雜
總結:適用於擁有較大數據集的情況
GTID添加從庫:
mysqldump
在備份的時候需要指定--master-data
導出的語句中包括:set @@GLOBAL.GTID_PURGED='c8d960f1-83ca-11e5-a8eb-000c29ea831c:1-745497';恢復時,需要先在slave上執行一個
reset master;再執行
changemaster to
perconaxtrabackup
xtrabackup_binlog_info包含了GTID在信息
做從庫恢復後,需要手工設置:
set@@GLOBAL.GTID_PURGED='c8d960f1-83ca-11e5-a8eb-000c29ea831c:1-745497';
恢復後,執行change master to
>changemaster to
master_host='192.168.199.117',
master_user='slave',
master_port=7000,
master_password='slavepass',
master_auto_position=1;
錯誤跳過
stopslave;
setgtid_next='xxxxxxxx:N';
begin;
commit;
setgtid_next='automatic';
startslave;
rpel |
change master |
error |
classic |
change master to master_host='192.168.199.117', master_user='slave', master_port=7000, master_password='slavepass', master_log_file='mysql-bin.000008', master_log_pos=896; |
stop slave; set global sql_slave_skip_counter=1; start slave; show slave status\G; |
GTID |
change master to master_host='192.168.199.117', master_user='slave', master_port=7000, master_password='slavepass', master_auto_position=1; |
stop slave; set gtid_next='xxxxxxxx:N'; begin; commit; set gtid_next='automatic'; start slave; |
GTID的限制:
不支持非事務引擎(從庫報錯,stopslave; start slave; 忽略)
不支持create table … select 語句複製(主庫直接報錯)
不允許在一個SQL同時更新一個事務引擎和非事務引擎的表
在一個複製組中,必須要求統一開啓CTID或是關閉GTID
開啓DTID需要重啓(5.7中可能不需要)
開啓DTID後,就不在使用原來的傳統的複製方式
對於createtemporary table 和drop temporary table語句不支持
不支持sql_slave_skip_counter
MySQL複製默認是異步複製,Master將事件寫入binlog,但並不知道Slave是否或何時已經接收且已處理。在異步複製的機制的情況下,如果Master宕機,事務在Master上已提交,但很可能這些事務沒有傳到任何的Slave上。假設有Master->Salve故障轉移的機制,此時Slave也可能會丟失事務。
官方半同步複製的概念:
1.當Slave主機連接到Master時,能夠查看其是否處於半同步複製的機制。
2.當Master上開啓半同步複製的功能時,至少應該有一個Slave開啓其功能。此時,一個線程在Master上提交事務將受到阻塞,直到得知一個已開啓半同步複製功能的Slave已收到此事務的所有事件,或等待超時。
3.當一個事務的事件都已寫入其relay-log中且已刷新到磁盤上,Slave纔會告知已收到。
4.如果等待超時,也就是Master沒被告知已收到,此時Master會自動轉換爲異步複製的機制。當至少一個半同步的Slave趕上了,Master與其Slave自動轉換爲半同步複製的機制。
5.半同步複製的功能要在Master,Slave都開啓,半同步複製纔會起作用;否則,只開啓一邊,它依然爲異步複製。
同步(社區增強半同步),異步,半同步複製的比較:
同步複製:Master提交事務,直到事務在所有的Slave都已提交,此時纔會返回客戶端,事務執行完畢。缺點:完成一個事務可能會有很大的延遲。
異步複製:當Slave準備好纔會向Master請求binlog。缺點:不能保證一些事件都能夠被所有的Slave所接收。
半同步複製:半同步複製工作的機制處於同步和異步之間,Master的事務提交阻塞,只要一個Slave已收到該事務的事件且已記錄。它不會等待所有的Slave都告知已收到,且它只是接收,並不用等其完全執行且提交。
半同步,開啓後嚴重影響性能
解決主庫不關心日誌是否被從庫讀到
半同步配置,在master和slave上都配置
master
[mysqld]
rpl_semi_sync_master_enabled=1
rp;_semi_sync_master_timeout=1000#1s
slave
[mysqld]
rpl_semi_sync_slave_enabled=1
複製參數
master |
slave |
log-bin=/data/mysql/mysql3316/logs/mysql-bin server-id=[ip]port log-bin-index=mysql-bin.index binlog_format=row binlog_cache_size=1M max_binlog_size=1G sync_binlog=0 expire_logs_days=7 log_bin_trust_function_creators=1 #使用存儲過程或函數打開
enforce-gtid-consistency=1 gtid-mode=on gtid-next gtid-purged gtid-execued 執行過的gtid
複製過濾 建議能不用就不用,如果必須用,在從庫上操作,不要在主庫上設置
==================== binlog-do-db binlog-ignore-db |
server-id log_slave_updates #會把複製的binlog也寫到binlog中 relay_log_recover=1 #在slave崩潰或正常啓動時,未應用完的relay_log會被刪掉,重新從master請求binlog再次生成relay_log skip-slave-start slave_transaction_retries #slave複製中,如果因爲innodb死鎖或者鎖超時導致複製線程執行的事務失敗重試次數,一般爲5 slave_parallel_workers #5.6引入基於庫計併發複製的功能,默認是關閉的 read-only #打開只讀,但對有super權限的用戶無效 slave_net_timeout = 10#默認3600s slave_skip_errors
log-slow-slave-statements #默認複製慢語句不會記錄到慢日誌中,啓動此功能,會把複製中超過long_query_time的語句記錄到慢日誌中 max_relay_log_size 設置relay_log的最大大小,建議不設置 relay-log-info-file #relay_log的索引文件 relay_log_purge 默認開啓,在relay_log使用完畢後,儘可能的清理掉 replicate-same-server-id 對於相同的server-id的binlog event默認不執行 slave_load_tmpdir 對於複製load data in file語句,slave指定創建臨時文件的目錄,默認是tmpdir relay_log_space_limit 限制relay_log戰勝磁盤的總大小
=========================== #slave to filter replicate-do-db replicate-ignore-db repicate-rewrite-db 如果master和slave有個庫同名了,可使用rewrite規則,將這個庫上的複製重寫到另一個新的庫上 replicate-do-table replicate-ignore-table replicate-wild-do-table replicate-wild-ignore-table |