mysql主從復制

mysql主從復制

主從復制慨述

構建大型,高性能應用程序的基礎
主服務器復制負責更新,且將更新寫入二進制日志文件,并維護文件的一個索引以跟蹤日志循環
從服務器主動連接主庫,通知主服務器從日志中讀取的最后一次更新的位置(第一次的話就是開始位置)
從服務器接受從那時起發生的任何更新,任何封鎖并等待主庫通知新的更新
注意:任何數據更新都必須在主服務器上進行,主能讀寫,從只能讀

使用主從的好處

  1. 提高數據庫讀的性能,主庫專注寫操作,從可以多個,分散讀操作
  2. 提高數據安全,在從庫做備份不會影響主庫相關數據

能解決的問題

  1. 數據分布(data distribution)
  2. 負載均衡(load balancing)
  3. 備份(backups)
  4. 高可用性和容錯行 High availability and failover,故障切換

mysql支持的復制方法

  1. statement based replication(SBR) 基于SQL語句的復制: 主服務器上執行的sql,在從服務器上同樣執行,5.6默認使用SBR,
  2. row based replication(RBR) 基于行的復制: 把改變的內容復制過去,而不是把命令在從服務器上執行一遍,從5.0開始支持
  3. mixed based replication(MBR) 混合型的復制: 默認采用基于語句的復制,一旦發現基于語句的無法精確復制時,就采用基于行的復制
  4. 基于global transaction identifiers(GTIDs)來進行事務復制 5.6.5以后版本支持

mysql是異步復制,mysql cluster是同步復制。
mysql配置文件設置復制方法的變量為binlog_farmat,值為:

  • STATEMENT
  • ROW
  • MIXED

mysql主從復制模式:半同步模式(接近同步),異步模式(可以配置延遲時間),同步模式(延時小一點)
mysql主從架構:master --> slave, master --> slave --> slave, master <--> master

幾種復制的特點

SBR的特點

二進制日志記錄的是sql語句
優點:

  • 歷史悠久
  • 日志文件更小
  • 記錄了所有的語句,可以用來日后審計
    缺點:
  • 使用如下函數的語句不能被正確地復制:load_file(); uuid(), uuid_short(); user(); found_rows(); sysdate(); get_lock(); is_free_lock(); is_used_lock(); master_pos_wait(); rand(); release_lock(); sleep(); version();
  • 在日志中出現如下警告信息的不能正確復制:[Warning] Statement is not safe to log in statement format.
  • 或者在客戶端中出現show warnings
  • Insert … select語句會執行大量的行級鎖表
  • Update語句會執行大量的行級鎖表來掃描整個表
RBR的特點

主服務器把表的行變化作為事件寫入二進制日志
優點:

  • 所有的數據變化都是被復制,這是最安全的復制方式
  • 更少的行級鎖
    缺點:
  • 日志會很大
  • 不能通過查看日志來審計執行過的sql語句,不過可以通過mysqlbinlog --base64-output=decode-rows --verbose來查看數據的 變動
MBR

即使用SBR,又使用RBR,默認使用SBR

主從復制工作流程

  1. slave端的SLAVE_IO_RUNNING進程連接上master端,提交主庫二進制日志文件名及指定的位置(POS)
  2. master端負責復制的IO進程根據文件名及起始位置讀取起始位置及以后的數據,發送給slave端的IO線程。返回信息中除了日志所包含的信息之外,還包括本次返回的信息在master端的binary log文件的名稱以及在binary log中的位置
  3. slave端的IO線程收到信息(二進制日志事件,binary log events)后,將接收到的日志內容依次寫入到save端的relay log文件(mysql-relay-bin.xxxxxx)的最末端,并將讀取到的master端的bin-log的文件名及位置記錄到master-info(也可能是mysql.slave_master_info表)文件中
  4. slave端的SLAVE_SQL_RUNNING進程檢測到relay log 中新增加的內容后,會馬上解析改log文件的內容,slave端重做中繼日志中的事件,將改變反映它自己的數據。

下圖描述了復制的過程:

Paste_Image.png

該過程的第一部分就是master記錄二進制日志。在每個事務更新數據完成之前,master在二日志記錄這些改變。MySQL將事務串行的寫入二進制日志,即使事務中的語句都是交叉執行的。在事件寫入二進制日志完成后,master通知存儲引擎提交事務。
下一步就是slave將master的binary log拷貝到它自己的中繼日志。首先,slave開始一個工作線程——I/O線程。I/O線程在master上打開一個普通的連接,然后開始binlog dump process。Binlog dump process從master的二進制日志中讀取事件,如果已經跟上master,它會睡眠并等待master產生新的事件。I/O線程將這些事件寫入中繼日志。
SQL slave thread(SQL從線程)處理該過程的最后一步。SQL線程從中繼日志讀取事件,并重放其中的事件而更新slave的數據,使其與master中的數據一致。只要該線程與I/O線程保持一致,中繼日志通常會位于OS的緩存中,所以中繼日志的開銷很小。
此外,在master中也有一個工作線程:和其它MySQL的連接一樣,slave在master中打開一個連接也會使得master開始一個線程。復制過程有一個很重要的限制——復制在slave上是串行化的,也就是說master上的并行更新操作不能在slave上并行操作。
多級主從:

Paste_Image.png

主從復制參數

server-id = 11 #主從集群中不能重復,唯一ID
log_bin = mysql-bin #啟用二進制日志

binlog_format = row #配置二進制日志格式

log_timestamps = SYSTEM #主要是控制 error log、genera log,等等記錄日志的顯示時間參數

slave-parallel-workers=16 # 從庫啟用多線程同步,默認為0,并行執行被禁止
slave-parallel-type=LOGICAL_CLOCK # 針對slave-parallel-workers參數,多進程同步時,默認是每個庫同一時間只能有一個work進程來進行工作,如果只有一個庫,設置LOGICAL_CLOCK來解除這個限制,默認是DATABASE

log_slave_updates=true #從庫從主庫更新操作也記錄從的binlog日志(主 --> 從 --> 從)連級復制時中間的從庫必須啟用
binlog_checksum=CRC32 #binlog做認證
master_verify_checksum=1
slave_sql_verify_checksum=1
binlog_rows_query_log_events=1 #在RBS模式中,binlog日志及relay log日志中記錄具體行的變化內容,也會記錄原始的sql語句(注釋掉)

master_info_repository=TABLE #是否將主狀態和連接信息記錄到 FILE(master.info)或a TABLE (mysql.slave_master_info)

relay_log_info_repository=TABLE #取決于服務器的 relay_log_info_repository 設置(FILE或 TABLE)

如下三個參數控制mysql.slave_master_info與mysql.slave_relay_log_info表的刷新頻率
sync_master_info=1 #若master-info-repository為FILE,當設置為0,則每次sync_master_info事件都會刷新到磁盤,默認為10000次刷新到磁盤;若master-info-repository為TABLE,當設置為0,則表不做任何更新,設置為1,則每次事件會更新表 #默認為10000
sync_relay_log = 1 #默認為10000,即每10000次sync_relay_log事件會刷新到磁盤。為0則表示不刷新,交由OS的cache控制。
sync_relay_log_info = 1 #若relay_log_info_repository為FILE,當設置為0,交由OS刷新磁盤,默認為10000次刷新到磁盤;若relay_log_info_repository為TABLE,且為INNODB存儲,則無論為任何值,則都每次evnet都會更新表。

relay_log_recovery=ON #當slave從庫宕機后,假如relay-log損壞了,導致一部分中繼日志沒有處理,則自動放棄所有未執行的relay-log,并且重新從master上獲取日志,這樣就保證了relay-log的完整性。默認情況下該功能是關閉的

binlog-row-image=minimal #針對row模式,參數默認值是FULL,為minimal:binlog記錄的就只是影響后的行

server-id = ID
log_bin = mysql-bin
binlog_format = row
log_timestamps = SYSTEM
slave_parallel_workers=16
slave_parallel_type=LOGICAL_CLOCK
log_slave_updates=true
binlog_rows_query_log_events=1
master_info_repository=TABLE
relay_log_info_repository=TABLE
sync_master_info=1
sync_relay_log = 1
sync_relay_log_info = 1
relay_log_recovery=ON
binlog_row_image=minimal

復制過濾

兩種思路,一種是在主庫上過濾,一種是從庫上過濾

Paste_Image.png

主庫上面僅向二進制日志記錄有特定相關數據庫寫操作;
問題:即時點還原將無法全面恢復

  • binlog_do_db=
  • binlog_ignore_db=

從庫的SQL_THREAD僅在中繼日志中讀取特定數據相關的語句并應用到本地
問題: 會造成網絡帶寬及磁盤IO浪費

replicate_do_db=
replicate_ignre_db=

replicate_db_table=
replicate_ignore_table=

replicate_wild_do_table=
replicate_wild_ignore_table=

實例:

replicate-wild-do-table=xxx_db.%
replicate-wild-do-table=yxxx_db.%

replicate-wild-ignore-table =mysql.%
replicate-wild-ignore-table =sys.%
replicate-wild-ignore-table =information_schema.%
replicate-wild-ignore-table =performance_schema.%

主從復制配置

有很多種配置主從同步的方法,可以總結為如下的步驟:

  1. 在master端開啟二進制日志和配置獨立的ID
  2. 在每一個slave端配置一個唯一的ID,創建一個用來專門復制master端數據的賬號
  3. 在開始復制前,在master端上記錄二進制文件位置信息
  4. 如果在開始復制之前,master端中已經有數據,就必須先建一個數據快照
  5. 配置slave端要連接的master端的IP地址和登陸授權,二進制日志名稱及位置

在master端建主從復制專用用戶
CREATE USER 'userrepl'@'%' IDENTIFIED BY 'userpasswd';
GRANT REPLICATION SLAVE ON . TO 'userrepl'@'%';

基本配置參數
log-bin=mysql-bin
server-id=1 (每個主機的ID唯一)

slave-parallel-workers=16
slave-parallel-type=LOGICAL_CLOCK
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log_recovery=ON
binlog-row-image=minimal

傳統方式

從上配置連接主庫的信息
CHANGE MASTER TO
-> MASTER_HOST='Master_IP',
-> MASTER_USER='userrepl',
-> MASTER_PASSWORD='userpasswd',
-> MASTER_LOG_FILE='mysql-bin.000001',
-> MASTER_LOG_POS=xxx;

GTID方式

gtid事物復制 5.6版本出現 主和從都開啟還需要添加舊版本的配置
gtid_mode = on
enforce-gtid-consistency=true

change master to
-> master_host='192.168.1.102',
-> master_user='repuser',
-> master_password='reppasswd',
-> master_port=3306,
-> master_auto_position = 1,
-> master_delay=30; 配置同步延時

半同步方式

主節點:
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.05 sec)

MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%semi%';
+------------------------------------+-------+
| 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 |
+------------------------------------+-------+
4 rows in set (0.00 sec)

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)

從節點:
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.05 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)

如果從服務器已經啟動,還需要重啟IO_THREAD;

主從復制狀態

mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: xx.xx.xx.xx
Master_User: xxrepl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000061
Read_Master_Log_Pos: 48850622
Relay_Log_File: r430db02-relay-bin.000180
Relay_Log_Pos: 48850835
Relay_Master_Log_File: mysql-bin.000061
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table: y_db.%,yi_db.%,b_db.%,u_cms.%
Replicate_Wild_Ignore_Table: mysql.%,sys.%,information_schema.%,performance_schema.%
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 48850622
Relay_Log_Space: 48851092
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: 11
Master_UUID: a614d748-1cd6-11e6-a130-14187760f283
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set: 35e7d774-b8d1-11e5-948c-00163e0c1173:1-766221
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:

GTID

MySQL [(none)]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: xx.xx.xx.xx
Master_User: xxrepl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 12844624
Relay_Log_File: vm10-20-10-6-relay-bin.000002
Relay_Log_Pos: 12844837
Relay_Master_Log_File: mysql-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: mysql.%,sys.%,information_schema.%,performance_schema.%
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 12844624
Relay_Log_Space: 12845051
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: 68
Master_UUID: d5197ac0-5996-11e7-8f1d-fa163e7c7d02
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: d5197ac0-5996-11e7-8f1d-fa163e7c7d02:1-9459
Executed_Gtid_Set: d5197ac0-5996-11e7-8f1d-fa163e7c7d02:1-9459
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)

復制的監控及維護

清理日志:PURGE
復制監控:

  • SHOW MASTER STATUS
  • SHOW BINLOG EVENTS
  • SHOW BINARY LOGS
  • SHOW SLAVE STATUS

多源復制slave啟動和停止
啟動所有
START SLAVEthread_types;
啟動一個
start slave for channel "master50";
停止
STOP SLAVEthread_types;
stop slave for channel "master50";
查看
show slave status\G
show slave status for channel "master50"\G
重置
RESET SLAVE;
RESET SLAVE FOR CHANNELchannel;

如何判斷slave是否落后于master
Seconds_Behind_Master: 0

如何確定主從節點數據是否一致?
通過表自身的CHECKSUM檢查
使用percona-tools中pt-table-checksum

數據不一致的修復方法:重復復制;

參考資料:
http://wangwei007.blog.51cto.com/68019/965575
http://blog.csdn.net/hguisu/article/details/7325124
http://www.cnblogs.com/kylinlin/p/5258719.html
https://dev.mysql.com/doc/refman/5.7/en/replication-options-slave.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374

推薦閱讀更多精彩內容