閱讀目錄 1.1 主從複製基礎概念 1.2 MySQL主從複製介紹 1.3 主從搭建配置 1.4 MySQL主從複製常見問題 1.5 【生產案例】主從複製事故 1.6 mysql半同步複製 1.7 主從複製架構的演變 1.8 參考文獻 回到頂部 1.1 主從複製基礎概念 在瞭解主從複製以前必需要了解的就是數據庫的二進制日誌(binlog),主從複製架構大多基於二進制日誌進行,二進制日誌相關信息參考:http://www.cnblogs.com/clsn/p/8087678.html#_label6 1.1.1 二進制日誌管理說明 二進制日誌在哪?如何設置位置和命名? 在my.cnf文件中使用 log-bin = 指定;命名規則爲 mysql-bin.000000 (後爲6位數字) 二進制日誌位置 複製代碼 mysql> show variables like '%log_bin%' ; +---------------------------------+-----------------------------------------+ | Variable_name | Value | +---------------------------------+-----------------------------------------+ | log_bin | ON | | log_bin_basename | /application/mysql/data/mysql-bin | | log_bin_index | /application/mysql/data/mysql-bin.index | | log_bin_trust_function_creators | OFF | | log_bin_use_v1_row_events | OFF | | sql_log_bin | ON | +---------------------------------+-----------------------------------------+ 6 rows in set (0.06 sec) 複製代碼 日誌命名 複製代碼 mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 2979 | | mysql-bin.000002 | 120 | +------------------+-----------+ 2 rows in set (0.00 sec) 複製代碼 二進制日誌記錄什麼? 二進制日誌中記錄的是一個個完成的事件 二進制日誌格式是怎樣的? 推薦使用row格式 查看當前使用的日誌 格式。 複製代碼 mysql> show variables like '%format%'; +--------------------------+-------------------+ | Variable_name | Value | +--------------------------+-------------------+ | binlog_format | ROW | | date_format | %Y-%m-%d | | datetime_format | %Y-%m-%d %H:%i:%s | | default_week_format | 0 | | innodb_file_format | Antelope | | innodb_file_format_check | ON | | innodb_file_format_max | Antelope | | time_format | %H:%i:%s | +--------------------------+-------------------+ 8 rows in set (0.00 sec) 複製代碼 二進制日誌如何滾動? 每次重啓都會刷新日誌,也能夠經過命令進行刷新 reset master; 二進制日誌用來幹嗎? 備份恢復 起始點的備份恢復 二進制日誌的操做命令? 查看都有哪些二進制日誌 複製代碼 mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 2979 | | mysql-bin.000002 | 167 | | mysql-bin.000003 | 120 | +------------------+-----------+ 3 rows in set (0.00 sec) 複製代碼 查看當前使用的二進制日誌文件 複製代碼 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000003 | 120 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) 複製代碼 binlog相關詳情參照:http://www.cnblogs.com/clsn/p/8087678.html#_label6 1.1.2 mysql傳統備份方式和缺陷 一、二進制日誌備份 二、mysqldump a)必須有數據庫服務器完成邏輯工做,須要更多地cpu週期 b)邏輯備份還原速度慢:須要MySQL加載和解釋語句、轉化存儲格式、重建引擎 三、xtrabackup a)文件大 b)不老是能夠跨平臺、操做系統和MySQL版本 1.1.3 MySQL主從複製能爲咱們作什麼 高可用、輔助備份、分擔負載 回到頂部 1.2 MySQL主從複製介紹 1.2.1 複製技術 做用 1.保證數據安全(異機實時備份) 2.保證服務持續運行(宕機接管) 主從複製實現基本原理 1.自帶功能,複製是 MySQL 的一項功能,容許服務器將更改從一個實例複製到另外一個實例。 2.主服務器將全部數據和結構更改記錄到二進制日誌中。 3.從屬服務器從主服務器請求該二進制日誌並在本地應用其內容。即經過把主庫的binlog傳送到從庫,重新解析應用到從庫。 1.2.2 複製架構 mysql複製的應用常見場景: 應用場景1:從服務器做爲主服務器的實時數據備份 應用場景2:主從服務器實現讀寫分離,從服務器實現負載均衡 應用場景3:把多個從服務器根據業務重要性進行拆分訪問 1.2.2.1 主–從複製 傳統的 MySQL 複製提供了一種簡單的主–從複製方法。 有一個主,以及一個或多個從。 主節點執行和提交事務,而後將它們(異步地)發送到從節點,以從新執行(在基於語句的複製中)或應用(在基於行的複製中)。 這是一個 shared-nothing 的系統,默認狀況下全部 server 成員都有一個完整的數據副本。 (圖)MySQL 異步複製 還有一個半同步複製,它在協議中添加了一個同步步驟。 這意味着主節點在提交時須要等待從節點確認它已經接收到事務。只有這樣,主節點才能繼續提交操做。 (圖)MySQL 異步複製 在上面的兩個圖片中,能夠看到傳統異步 MySQL 複製協議(以及半同步)的圖形展現。 藍色箭頭表示在不一樣 server 之間或者 server 與 client 應用之間的信息交互。 1.2.3 MySQL主從複製原理介紹 複製過程: 一、開啓binlog日誌,經過把主庫的binlog傳送到從庫,重新解析應用到從庫。 二、複製須要3個線程(dump、io、sql)完成,5.6從庫多個sql。 三、複製是異步的過程。主從複製是異步的邏輯的SQL語句級的複製。 複製前提: 一、主服務期必定要打開二進制日誌 二、必須兩臺服務器(或者是多個實例) 三、從服務器須要一次數據初始化 3.1若是主從服務器都是新搭建的話,能夠不作初始化 3.2若是主服務器已經運行了很長時間了,能夠經過備份將主庫數據恢復到從庫。 四、主庫必需要有對從庫複製請求的用戶。 五、從庫須要有relay-log設置,存放從主庫傳送過來的二進制日誌 show variables like '%relay%'; 六、在第一次的時候,從庫須要change master to 去鏈接主庫。 七、change master信息須要存放到master.info中 show variables like '%master_info%'; 八、從庫怎麼知道,主庫發生了新的變化?經過relay-log.info記錄的已經應用過的relay-log信息。 九、在複製過程當中涉及到的線程 從庫會開啓一個IO thread(線程),負責鏈接主庫,請求binlog,接收binlog並寫入relay-log。 從庫會開啓一個SQL thread(線程),負責執行relay-log中的事件。 主庫會開啓一個dump thrad(線程),負責響應從IO thread的請求。 主從怎麼實現的? 一、經過二進制日誌 二、至少兩臺(主、從) 三、主服務器的二進制日誌「拿」到從服務器上再運行一遍。 四、經過網絡鏈接兩臺機器,通常都會出現延遲的狀態。也能夠說是異步的。 1.2.4 執行原理--第一次開啓主從過程 一、 從庫經過手工執行change master to 語句鏈接主庫,提供了鏈接的用戶一切條件 (user、password、port、ip) 而且讓從庫知道,二進制日誌的起點位置(file名 position號) start slave 二、從庫的IO和主庫的dump線程創建鏈接 三、從庫根據change master to 語句提供的file名和position號,IO線程向主庫發起binlog的請求 四、主庫dump線程根據從庫的請求,將本地binlog以events的方式發給從庫IO線程 五、從庫IO線程接收binlog evnets,並存放到本地relay-log中,傳送過來的信息,會記錄到master.info中。 六、從庫SQL線程應用relay-log,而且把應用過的記錄到relay-log.info,默認狀況下,已經應用過的relay會自動被清理purge。 到此位置,一次主從複製就完成 一旦主從運行起來: 就不須要手工執行change master to, 由於信息都會被存放到master.info (user、password、port、ip,上次獲取過的binlog信息file和position)中 其餘的過程都是同樣的 1.2.4.1 詳細的mysql replication 過程 回到頂部 1.3 主從搭建配置 本次主從搭建使用mysql多實例進行實驗。多實例配置參考文檔進行配置:http://www.cnblogs.com/clsn/p/8038964.html#_label8 1.3.1 多實例數據庫slave配置 系統環境說明: 複製代碼 [root@db02 ~]# cat /etc/redhat-release CentOS release 6.9 (Final) [root@db02 ~]# uname -r 2.6.32-696.el6.x86_64 [root@db02 ~]# /etc/init.d/iptables status iptables: Firewall is not running. # 注意:務必關閉防火牆(iptables selinux) [root@db02 ~]# getenforce Disabled [root@db02 ~]# mysql --version mysql Ver 14.14 Distrib 5.6.36, for Linux (x86_64) using EditLine wrapper 複製代碼 一、啓動多實例數據庫 [root@db02 ~]# /data/3306/mysql start Starting MySQL... [root@db02 ~]# /data/3307/mysql start Starting MySQL... 二、配置文件說明: master 配置文件說明: 複製代碼 [root@db02 ~]# cat /data/3306/my.cnf [client] port = 3306 socket = /data/3306/mysql.sock [mysqld] user = mysql port = 3306 socket = /data/3306/mysql.sock basedir = /application/mysql datadir = /data/3306/data log-bin = /data/3306/mysql-bin server-id = 6 # server id 不能相同 skip_name_resolve = 0 # 跳過域名解析參數 [mysqld_safe] log-error=/data/3306/mysql_3306.err pid-file=/data/3306/mysqld.pid 複製代碼 slave 配置文件說明: 複製代碼 [root@db02 ~]# cat /data/3307/my.cnf [client] port = 3307 socket = /data/3307/mysql.sock [mysqld] user = mysql port = 3307 socket = /data/3307/mysql.sock basedir = /application/mysql datadir = /data/3307/data log-bin = /data/3307/mysql-bin server-id = 7 # server id 不能相同 skip_name_resolve = 0 # 跳過域名解析參數 read_only = 1 # 從庫只讀 (非root用戶 ) [mysqld_safe] log-error=/data/3307/mysql_3307.err pid-file=/data/3307/mysqld.pid 複製代碼 三、在主庫建立複製用戶 登錄到主數據庫中: mysql -uroot -p123 -S /data/3306/mysql.sock 建立受權用戶,注意是slave用戶。 grant replication slave on *.* to repl@'10.0.0.%' identified by '123'; 四、初始化從庫數據 備份主庫當前數據 mysqldump -uroot -p123 -A -B -F --master-data=2 -S /data/3306/mysql.sock >/tmp/full.sql 部分參數說明:(詳細參照http://www.cnblogs.com/clsn/p/8138015.html#_label2) -F 刷新二進制日誌 --master-data [=#]這會致使二進制日誌的位置和文件名被追加到輸出中。 若是等於1,則將其打印爲CHANGE MASTER命令; 若是等於2,那麼該命令將以註釋符號爲前綴。 到從庫進行恢復 mysql -uroot -p123 -S /data/3307/mysql.sock # 恢復備份的數據 set sql_log_bin=0; source /tmp/full.sql 五、開啓從庫複製 查看備份的當前使用的文件及POS號 複製代碼 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000012 | 120 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) 複製代碼 登入數據庫,進行slave配置。 複製代碼 mysql -uroot -p123 -S /data/3307/mysql.sock CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_USER='repl', MASTER_PASSWORD='123', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000012', MASTER_LOG_POS=120; start slave; # 啓動從庫複製 複製代碼 該配置想關說明能夠經過 help 得到。 複製代碼 mysql> help CHANGE MASTER TO CHANGE MASTER TO MASTER_HOST='master2.mycompany.com', MASTER_USER='replication', MASTER_PASSWORD='bigs3cret', MASTER_PORT=3306, MASTER_LOG_FILE='master2-bin.001', MASTER_LOG_POS=4, MASTER_CONNECT_RETRY=10; 複製代碼 1.3.2 測試主從同步 查看slave庫的狀態 主要查看 Slave_IO_Running 與 Slave_SQL_Running 是否都爲Yes 複製代碼 1 mysql> show slave status\G 2 *************************** 1. row *************************** 3 Slave_IO_State: Waiting for master to send event 4 Master_Host: 10.0.0.52 5 Master_User: repl 6 Master_Port: 3306 7 Connect_Retry: 60 8 Master_Log_File: mysql-bin.000010 9 Read_Master_Log_Pos: 842 10 Relay_Log_File: 3307-relay-bin.000018 11 Relay_Log_Pos: 283 12 Relay_Master_Log_File: mysql-bin.000010 13 Slave_IO_Running: Yes 14 Slave_SQL_Running: Yes 15 Replicate_Do_DB: 16 Replicate_Ignore_DB: 17 Replicate_Do_Table: 18 Replicate_Ignore_Table: 19 Replicate_Wild_Do_Table: 20 Replicate_Wild_Ignore_Table: 21 Last_Errno: 0 22 Last_Error: 23 Skip_Counter: 0 24 Exec_Master_Log_Pos: 842 25 Relay_Log_Space: 455 26 Until_Condition: None 27 Until_Log_File: 28 Until_Log_Pos: 0 29 Master_SSL_Allowed: No 30 Master_SSL_CA_File: 31 Master_SSL_CA_Path: 32 Master_SSL_Cert: 33 Master_SSL_Cipher: 34 Master_SSL_Key: 35 Seconds_Behind_Master: 0 36 Master_SSL_Verify_Server_Cert: No 37 Last_IO_Errno: 0 38 Last_IO_Error: 39 Last_SQL_Errno: 0 40 Last_SQL_Error: 41 Replicate_Ignore_Server_Ids: 42 Master_Server_Id: 6 43 Master_UUID: 4f344556-e0ab-11e7-9138-000c29d60ab3 44 Master_Info_File: /data/3307/data/master.info 45 SQL_Delay: 0 46 SQL_Remaining_Delay: NULL 47 Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it 48 Master_Retry_Count: 86400 49 Master_Bind: 50 Last_IO_Error_Timestamp: 51 Last_SQL_Error_Timestamp: 52 Master_SSL_Crl: 53 Master_SSL_Crlpath: 54 Retrieved_Gtid_Set: 55 Executed_Gtid_Set: 56 Auto_Position: 0 57 1 row in set (0.00 sec) 複製代碼 在主庫進行操做,在從庫驗證 複製代碼 [root@db02 ~]# mysql -uroot -p123 -S /data/3306/mysql.sock mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 4 rows in set (0.00 sec) mysql> create database clsn; Query OK, 1 row affected (0.00 sec) 複製代碼 在從庫上能夠看到該數據庫已建立 複製代碼 [root@db02 ~]# mysql -uroot -p123 -S /data/3307/mysql.sock mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | clsn | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.00 sec) 複製代碼 至此mysql主從複製就搭建完成 1.3.3 忘記數據庫密碼? shell> /application/mysql/bin/mysqld_safe --defaults-file=/data/3306/my.cnf --skip-grant-tables --skip-networking & mysql> update user set password=password('123') where user='root' and host='localhost'; mysql> flush privileges; 1.3.4 主從複製狀態失敗的緣由? Last_IO_Error: error reconnecting to master 'repl@10.0.0.52:3306' - retry-time: 60 retries: 1 緣由: 一、主機沒啓動,或者宕機,檢查主庫的狀態。 二、網絡通訊問題,使用ping命令進行檢查;或使用mysql命令進行shell端登錄測試 三、防火牆,selinux(務必檢查)。 四、複製用戶和密碼、端口號、地址有問題,使用mysql命令進行shell端登錄測試。 五、mysql自動解析,會將鏈接的IP解析成主機名(skip-name-resolve = 0)寫入my.cnf文件便可。 六、從庫IO異常關閉,經過show slave status \G 進行查看。 回到頂部 1.4 MySQL主從複製常見問題 1.4.1 從庫binlog落後主庫binlog? 從庫記錄的已經主庫已經給我傳送的binlog事件的座標,通常在繁忙的生產環境下會落後於主庫 show master status\G --- 主 show slave status \G --- 從 Master_Log_File: mysql-bin.000007 Read_Master_Log_Pos: 729 落後太遠的緣由: 硬件條件有關的,機器磁盤IO性能不足。 主要仍是網絡問題,網絡傳輸的性能。 主庫存放二進制日誌的存儲性能過低,建議binlog日誌存咋SSD中。 主庫DUMP線程太繁忙,主要發生在一主多從的環境下。 從庫IO線程太忙 人爲控制(delay節點、延時節點 ) 1.4.2 主庫update,從庫遲遲的沒有更新。 特殊狀況:日誌已經傳過來了,數據並無同步 通常狀況: 一、沒開啓SQL線程 二、傳的東西有問題(你要作的事情,我提早已經作了,不想重複作了,而後他就死了) 三、SQL線程忙。 四、人爲控制了【delay(從庫)節點、延時節點,通常生產設置爲3-6小時之間,能夠保證過去3-6小時之間的誤操做,能夠避免】。 1.4.3 主從複製延時配置(從庫配置) 中止從庫複製 mysql>stop slave; Query OK, 0 rows affected (0.01 sec) 修改延時參數,MASTER_DELAY,單位位S (秒)。 mysql>CHANGE MASTER TO MASTER_DELAY = 30; Query OK, 0 rows affected (0.07 sec) 啓動從庫複製 mysql>start slave; Query OK, 0 rows affected (0.07 sec) 查看配置是否生效 mysql> show slave status \G …… SQL_Delay: 30 1.4.4 從庫安全配置(其餘用戶只讀) 修改my.cnf配置文件,添加只讀參數 read_only = 1 ====> 控制普通用戶 innodb_read_only = 1 ====> 控制root用戶,正常狀況不要加 添加完成後重啓數據庫 複製代碼 mysql> show variables like '%read_only%'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | innodb_read_only | OFF | | read_only | ON | | tx_read_only | OFF | +------------------+-------+ 3 rows in set (0.00 sec) 複製代碼 延時從庫: delay節點、延時節點 1.4.5 主從複製故障及解決(跳過錯誤) 命令行設置 stop slave; #<==臨時中止同步開關。 set global sql_slave_skip_counter = 1 ; #<==將同步指針向下移動一個,若是屢次不一樣步,能夠重複操做。 start slave; 在配置文件修改,設置要跳過的pos /etc/my.cnf slave-skip-errors = 1032,1062,1007 在mysql中能夠跳過某些錯誤,可是最好的解決辦法,從新搭建主從複製。 1.4.6 延時節點概念 --> SQL線程延時? Last_SQL_Errno: 0 Last_SQL_Error: 緣由: 一、主庫作操做的對象,在從庫不存在 二、主庫作操做的對象屬性不一致。 三、主庫作操做的對象,從庫已經存在 …… 1.4.7 Slave_*_Running:? 一、Slave_IO_Running I/O 線程正在運行、未運行仍是正在運行但還沒有鏈接到主服務器。可能值分別爲Yes、No 或 Connecting。 二、Slave_SQL_Running SQL 線程當前正在運行、未運行,可能值分別爲 Yes、No 主服務器日誌座標: 三、Master_Log_File 和 Read_Master_Log_Pos 標識主服務器二進制日誌中 I/O 線程已經傳輸的最近事件的座標。 四、若是Master_Log_File和Read_Master_Log_Pos 的值遠遠落後於主服務器上的那些值,這表示主服務器與從屬服務器之間事件的網絡傳輸可能存在延遲。 1.4.8 中繼日誌座標 a) Relay_Log_File 和 Relay_Log_Pos 列標識從屬服務器中繼日誌中 SQL 線程已經執行的最近事件的座標。這些座標對應於 Relay_Master_Log_File 和 Exec_Master_Log_Pos 列標識的主服務器二進制日誌中的座標。 b) 若是 Relay_Master_Log_File 和 Exec_Master_Log_Pos 列的輸出遠遠落後於 Master_Log_File 和Read_Master_Log_Pos 列(表示 I/O 線程的座標),這表示 SQL 線程(而不是 I/O 線程)中存在延遲。即,它表示複製日誌事件快於執行這些事件。 1.4.9 單一主從須要改變的地方 從庫的做用 一、至關於實時備份 二、使用從庫備份 三、一主多從應對讀多的業務需求 若是,從庫只作備份服務器用,那麼主庫的壓力會不減反增。由於,全部的業務都在主庫實現,讀和寫,dump線程讀取並投遞binlog 解決方案: (1)可不能夠挪走一部分讀業務到從庫,讀寫分離 (2) 一主多從應對讀多的業務需求,一旦發展成這個架構,dump線程投遞binlog的壓力更大 (3) 多級主從,採用中間庫緩解主庫dump的壓力,會出現中間庫瓶頸的問題,選擇blackhole引擎,看性能與安全的權衡 (4)雙主模型:緩解,數據一致性難保證 (5)環裝複製 回到頂部 1.5 【生產案例】主從複製事故 1.5.1 發生背景 一、有一臺已經工做好久的單機mysql數據。在2017年12月24日的平安夜,我司購物網站宕機了。機器物損壞,系統硬盤報廢。 二、在接到一條短信告知服務器宕機,數據庫連不上。當時的我一臉懵逼的還在開party,誰能想到在這樣一個闔家歡樂的時刻發生這樣的事情。 三、隨之我火速趕回公司處理事故。首先更換硬盤,從備份服務器上拉取備份數據,用備份恢復宕機的時刻數據,經歷40分鐘後全部應用恢復正常。 四、經歷此次事故,決心修改數據庫架構,我跟領導承諾,保證改完以後,出現相似故障能在5-10分鐘恢復業務。把原來的停機時間縮短4-8倍。 1.5.2 搭建流程 1.5.2.1 架構設計 修改架構採用數據庫主從同步,能保證數據的安全,提升事故發生的恢復速度。 1.5.2.2 架構實施 (1)準備一臺新機器,配置、系統、環境等與原數據庫保持一致。 (2)在主庫檢查binlog開關,沒有開啓將其開啓 ,檢查server_id 與 auto.cnf文件中的uuid 是否惟一。 (3)主庫建立受權複製的用戶,受權 replication slave。 (4)備份主庫上現有數據,恢復到從庫中,推薦使用mysqldump,在訪問低谷的時候作。 (5)在從庫上開啓binlog和relaylog,server_id。 (6)在從庫配置change master to 信息:在第一次開啓主從的時候,告訴從庫user password host port,複製binlog的起點file、position。 (7)start slave 開啓主從複製。 到此歷經千辛萬苦主從複製搭建完成。 1.5.3 測試主從切換 (1) 主從的可用性測試:在主庫中插入數據,在從庫查看有沒有。 (2) 主從快速恢復演練 a) 在一個月黑風高夜選一個業務不繁忙時間點,人工宕掉主庫。 b) 將從庫定爲主庫,查看從庫的日誌量(master.info、relay-log.info) c) 判斷主從日誌的差距(master.info,show master status) d) 恢復後發現誤差,就人爲登陸到主庫(備份服務器也行)中,把截取差距的binlog日誌,並傳送到從庫進行數據補償。 e) 此時從庫數據如今已經和主庫一致。 f) reset master,reset slave g) 應用割接到從庫,將應用數據庫IP指向從庫IP,測試應用。 (3)小結:經歷裏此次測試,主從見的切換歷時6分32秒,比以前縮短許多,可是感受還差點什麼,之後再補吧。 回到頂部 1.6 mysql半同步複製 MySQL複製默認是異步複製,存在必定的機率備庫與主庫的數據是不對等的,若是Master宕機,事務在Master上已提交,但極可能這些事務沒有傳到任何的Slave上,此時Slave也可能會丟失事務。在半同步複製的架構下,當master在將本身binlog發給slave上的時候,要確保slave已經接受到了這個二進制日誌之後,纔會返回數據給客戶端。 半同步複製介於異步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是馬上返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才返回給客戶端。相對於異步複製,半同步複製提升了數據的安全性,同時它也形成了必定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。因此,半同步複製最好在低延時的網絡中使用。 半同步複製的原理圖 在5.6中加入了group commit特性以後,性能不比傳統的異步複製差。 1.6.1 半同步複製的潛在問題 客戶端事務在存儲引擎層提交後,在獲得從庫確認的過程當中,主庫宕機了,此時,可能的狀況有兩種 事務還沒發送到從庫上 此時,客戶端會收到事務提交失敗的信息,客戶端會從新提交該事務到新的主上,當宕機的主庫從新啓動後,以從庫的身份從新加入到該主從結構中,會發現,該事務在從庫中被提交了兩次,一次是以前做爲主的時候,一次是被新主同步過來的。 事務已經發送到從庫上 此時,從庫已經收到並應用了該事務,可是客戶端仍然會收到事務提交失敗的信息,從新提交該事務到新的主上。 1.6.2 半同步架構搭建 加載使用的插件 主庫: INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; 從從: INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; 查看是否加載成功 show plugins; 啓動半同步複製 主庫: SET GLOBAL rpl_semi_sync_master_enabled = 1; 從庫: SET GLOBAL rpl_semi_sync_slave_enabled = 1; 重啓從庫上的IO線程 STOP SLAVE IO_THREAD; START SLAVE IO_THREAD; 查看是否在運行 主庫: show status like 'Rpl_semi_sync_master_status'; 從庫: show status like 'Rpl_semi_sync_slave_status'; 測試半同步複製 查看延遲時間: show variables like '%rpl_semi_sync%'; 從庫: stop slave; 主庫: create database clsn; 若是建立庫的時間是設置的時間就成功了。 回到頂部 1.7 主從複製架構的演變 1.7.1 基本結構 (1)一主一從 (2)一主多從 (3)多級主從 (4)雙主 (5)多主一從(5.7以後開始支持) (6)循環複製 對於循環數據庫鏡像,就是多個數據庫A、B、C、D等,對其中任一個數據庫的修改,都要同時鏡像到其它的數據庫裏。 replicate-same-server-id = 0 1.7.2 高級應用架構演變 (1)讀寫分離——MySQL proxy、amoeba、xx-dbproxy等。 通常來講都是經過主從複製(Master-Slave)的方式來同步數據,再經過讀寫分離(MySQL-Proxy)來提高數據庫的併發負載能力這樣的方案來進行部署與實施的。 (2)分庫分表——cobar、自主研發等。 1) 系統對外提供的數據庫名是dbtest,而且其中有兩張表tb1和tb2。 2) tb1表的數據被映射到物理數據庫dbtest1的tb1上。 3) tb2表的一部分數據被映射到物理數據庫dbtest2的tb2上,另一部分數據被映射到物理數據庫dbtest3的tb2上。 (3)MMM架構——mysql-mmm(google)-使用極少 MMM(Master-Master replication manager for MySQL)是一套支持雙主故障切換和雙主平常管理的腳本程序。MMM使用Perl語言開發,主要用來監控和管理MySQL Master-Master(雙主)複製,能夠說是mysql主主複製管理器。 雖然叫作雙主複製,可是業務上同一時刻只容許對一個主進行寫入,另外一臺備選主上提供部分讀服務,以加速在主主切換時刻備選主的預熱,能夠說MMM這套腳本程序一方面實現了故障切換的功能,另外一方面其內部附加的工具腳本也能夠實現多個slave的read負載均衡。 關於mysql主主複製配置的監控、故障轉移和管理的一套可伸縮的腳本套件(在任什麼時候候只有一個節點能夠被寫入),這個套件也能對居於標準的主從配置的任意數量的從服務器進行讀負載均衡,因此你能夠用它來在一組居於複製的服務器啓動虛擬ip,除此以外,它還有實現數據備份、節點之間從新同步功能的腳本。 對於那些對數據的一致性要求很高的業務,很是不建議採用MMM這種高可用架構。 (4)MHA架構——mysql-master-ha(日本DeNa) MHA(Master High Availability)目前在MySQL高可用方面是一個相對成熟的解決方案,它由日本DeNA公司youshimaton(現就任於Facebook公司)開發,是一套優秀的做爲MySQL高可用性環境下故障切換和主從提高的高可用軟件。在MySQL故障切換過程當中,MHA能作到在0~30秒以內自動完成數據庫的故障切換操做,而且在進行故障切換的過程當中,MHA能在最大程度上保證數據的一致性,以達到真正意義上的高可用。 該軟件由兩部分組成:MHA Manager(管理節點)和MHA Node(數據節點)。 (5)MGR-- 5.7 新特性 MySQL Group replication 基於傳統異步複製和半同步複製的缺陷——數據的一致性問題沒法保證,MySQL官方在5.7.17版本正式推出組複製(MySQL Group Replication,簡稱MGR)。 由若干個節點共同組成一個複製組,一個事務的提交,必須通過組內大多數節點(N / 2 + 1)決議並經過,才能得以提交。如上圖所示,由3個節點組成一個複製組,Consensus層爲一致性協議層,在事務提交過程當中,發生組間通信,由2個節點決議(certify)經過這個事務,事務纔可以最終得以提交併響應。 (6)PXC、MySQL Cluster、galera cluster架構 在PXC中,一次數據寫入在各個節點間的驗證/回滾流程 PXC架構的優勢: a) 服務高可用; b) 數據同步複製(併發複製),幾乎無延遲; c) 多個可同時讀寫節點,可實現寫擴展,不過最好事先進行分庫分表,讓各個節點分別寫不一樣的表或者庫,避免讓galera解決數據衝突; d) 新節點能夠自動部署,部署操做簡單; e) 數據嚴格一致性,尤爲適合電商類應用; f) 徹底兼容MySQL; 1.7.3 分庫分表簡單實踐 實踐中使用的爲world數據庫,爲mysql官方提供,詳情參照:http://www.cnblogs.com/clsn/p/8087417.html#_label0 第一個里程碑:建立新表 複製代碼 CREATE TABLE `country_1` ( `Code` char(3) NOT NULL DEFAULT '', `Name` char(52) NOT NULL DEFAULT '', `Continent` enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL DEFAULT 'Asia', PRIMARY KEY (`Code`), KEY `name_idx` (`Name`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 複製代碼 第二個里程碑:從舊錶導入數據到新表 insert into country_1(code,name,continent) select code,name,continent from country; 第三個里程碑:橫向拆表 建立與導出表相同格式的新表1 create table country_1_p1 like country_1; 將數據的前100行插入到新表1中 insert into country_1_p1 select code,name,continent from country_1 order by code limit 100; 建立與新表1相同格式的新表2 create table country_1_p2 like country_1; 將100行以後的139行導入表2. insert into country_1_p2 select code,name,continent from country_1 order by code limit 139 offset 100; 回到頂部 1.8 參考文獻 [1] http://blog.csdn.net/hguisu/article/details/7325124 [2] https://www.cnblogs.com/ivictor/p/5735580.html [3] https://www.cnblogs.com/Aiapple/p/5792939.html [4] http://heylinux.com/archives/1004.html 讀寫分離 [5] http://hualong.iteye.com/blog/2102798 Cobar邏輯層次圖 [6] https://www.cnblogs.com/kevingrace/p/5662975.html MMM架構 [7] https://www.cnblogs.com/gomysql/p/3675429.html MHA架構 [8] http://blog.jobbole.com/70844/ MySQL在大型網站的應用架構演變 [9] https://www.cnblogs.com/dosmile/p/6681923.html MGR複製 [10] http://imysql.cn/tag/pxc PXC架構 [11] https://mp.weixin.qq.com/s/Ll0sdKS6Vbw1pXIKbW3-NQ 做者:慘綠少年 出處:http://www.nmtui.com 本文版權歸做者全部,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。