MySQL數據庫支持單向、雙向、鏈式級聯、環狀等不一樣業務場景的複製。在複製過程當中,一臺服務器充當主服務器(Master),接收來自用戶的內容更新,而一個或多個其餘的服務器充當從服務器(Slave),接收來自主服務器 binlog文件的日誌內容,解析出SQL,從新更新到從服務器,使得主從服務器數據達到一致。
若是設置了鏈式級聯複製,那麼,從服務器( Slave)自己除了充當從服務器外,也會同時充當其下面從服務器的主服務器。鏈式級聯複製相似A→B→C的複製形式。前端
MySQL主從複製集羣功能使得 MySQL數據庫支持大規模高併發讀寫成爲可能,同時有效地保護了物理服務器宕機場景的數據備份。
應用場景1:從服務器做爲主服務器的實時數據備份
主從服務器架構的設置能夠大大增強 MySQL數據庫架構的健壯性。例如:當主服務器出現問題時,咱們能夠人工或設置自動切換到從服務器繼續提供服務,此時從服務器的數據與宕機時的主數據庫幾乎是一致的。
這相似NFS存儲數據經過 inotify+rsync同步到備份的NFS服務器,只不過 MySQL的複製方案是其自帶的工具。
利用 MySQL的複製功能進行數據備份時,在硬件故障、軟件故障的場景下,該數
據備份是有效的,但對於人爲地執行dop、 delete等語句刪除數據的狀況,從庫的備份功能就沒用了,由於從服務器也會執行刪除的語句。
應用場景2:主從服務器實現讀寫分離,從服務器實現負載均衡
主從服務器架構可經過程序(PHP、Java等)或代理軟件( mysql- proxy、 Amoeba)實現對用戶(客戶端)的請求讀寫分離,即讓從服務器僅僅處理用戶的 select查詢請求下降用戶查詢響應時間,以及同時讀寫在主服務器上帶來的訪問壓力。對於更新的數據(例如 update、 Insert、 delete語句),則仍然交給主服務器處理,確保主服務器和從服務器保持實時同步。
應用場景3:把多個從服務器根據業務重要性進行拆分訪問
能夠把幾個不一樣的從服務器,根據公司的業務進行拆分。例如:有爲外部用戶提供查詢服務的從服務器,有內部DBA用來數據備份的從服務器,還有爲公司內部人員提供訪問的後臺、腳本、日誌分析及供開發人員查詢使用的從服務器。這樣的拆分除了減
輕主服務器的壓力外,還可使數據庫對外部用戶瀏覽、內部用戶業務處理及DBA人員的備份等互不影響。mysql
(1)經過程序實現讀寫分離(性能和效率最佳,推薦)
PHP和Java程序均可以經過設置多個鏈接文件輕鬆地實現對數據庫的讀寫分離,即當語句關鍵字爲 select時,就去鏈接讀庫的鏈接文件,若爲 update、 Insert、delete時,則鏈接寫庫的鏈接文件。
經過程序實現讀寫分離的缺點就是須要開發人員對程序進行改造,使其對下層不透明,但這種方式更容易開發和實現,適合互聯網業務場景。
(2)經過開源的軟件實現讀寫分離
MySQL- proxy、 Amoeba等代理軟件也能夠實現讀寫分離功能,這些軟件的穩定性和功能通常,不建議生產使用。絕大多數公司經常使用的仍是在應用端發程序實現讀寫分離。
(3)大型門戶獨立開發DAL層綜合軟件
百度、阿里等大型門戶都有開發牛人,會花大力氣開發適合本身業務的讀寫分離、負載均衡、監控報警、自動擴容、自動收縮等一系列功能的DAL層軟件。web
MySQL的主從複製是一個異步的複製過程(雖然通常狀況下感受是實時的,數據將從一個 MySQL數據庫(咱們稱之爲 Master)複製到另外一個 MySQL數據庫(咱們稱之爲 Slave),在 Master與 Slave之間實現整個主從複製的過程是由三個線程參與完成的。其中有兩個線程(SQL線程和IO線程)在 Slave端,另一個線程(IO線程)在Master端要實現 MySQL的主從複製,首先必須打開 Master端的 binlog記錄功能,不然就沒法實現。由於整個複製過程實際上就是Save從 Master端獲取 binlog日誌,而後再在Slave上以相同順序執行獲取的 binlog日誌中所記錄的各類SQL操做。要打開 MySQL的 binlog記錄功能,可經過在 MySQL的配置文件 my.cnf中的mysqld模塊( [mysid]標識後的參數部分)增長"log-bin"參數選項來實現,具體信息以下:sql
[mysqld] log_bin = /data/mysql-bin
5、MySQL主從複製原理過程詳細描述下面簡單描述 MySQL Replication的複製原理過程。數據庫
1)在 Slave服務器上執行 start slave命令開啓主從複製開關,開始進行主從複製。vim
2)此時, Slave服務器的MO線程會經過在 Master上已經受權的複製用戶權限請求鏈接 Master服務器,並請求從指定 binlog日誌文件的指定位置(日誌文件名和位置就是在配置主從複製服務時執行 change master命令指定的)以後開始發送 binlog日誌內容。緩存
3) Master服務器接收到來自 Slave服務器的IO線程的請求後,其上負責複製的IO線程會根據 Slave服務器的Io線程請求的信息分批讀取指定 binlog日誌文件指定位置以後的 binlog日誌信息,而後返回給 Slave端的IO線程。返回的信息中除了 binlog日誌內容外,還有在 Master服務器端記錄的新的 binlog文件名稱,以及在新的 binlog中的下一個指定更新位置。安全
4)當 Slave服務器的IO線程獲取到 Master服務器上IO線程發送的日誌內容、日誌文件及位置點後,會將 binlog日誌內容依次寫到 Slave端自身的 Relay log(即中繼日誌)文件( MySQL-relay-bin.xxxx)的最末端,並將新的binlog文件名和位置記錄到master-info文件中,以便下一次讀取 Master端新 binlog日誌時可以告訴 Master服務器重新 binlog日誌的指定文件及位置開始請求新的 binlog日誌內容。服務器
5) Slave服務器端的SQL線程會實時檢測本地 Relay Log中IO線程新增長的日誌內容,而後及時地把 Relay log文件中的內容解析成SQL語句,並在自身 Slave服務器上按解析SQL語句的位置順序執行應用這些SQL語句,並在 relay- -log. info中記錄當前應用中繼日誌的文件名及位置點。
通過了上面的過程,就能夠確保在 Master端和 Slave端執行了一樣的SQL語句當複製狀態正常時, Master端和 Slave端的數據是徹底同樣的。固然, MySQL的複製機制也有一些特殊狀況,具體請參考官方的說明,大多數狀況下,你們不用擔憂。
下面針對 MySQL主從複製原理的重點進行小結:網絡
主從複製是異步的邏輯的SQL語句級的複製。
複製時,主庫有一個I/O線程,從庫有兩個線程,即I/O和SQL線程。
實現主從複製的必要條件是主庫要開啓記錄 binlog功能。
做爲複製的全部 MySQL節點的 server-id都不能相同。
binlog文件只記錄對數據庫有更改的SQL語句(來自主數據庫內容的變動),不記錄任何查詢(如 select、show)語句。
1)主從複製環境準備以下:
[root@master ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@test ~]# mysql -V
mysql Ver 14.14 Distrib 5.7.22, for Linux (x86_64) using EditLine wrapper
IP:192.168.200.103
[root@slave ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@test ~]# mysql -V
mysql Ver 14.14 Distrib 5.7.22, for Linux (x86_64) using EditLine wrapper
IP:192.168.200.104
2)、在主庫master上執行操做配置
設置server-id值並開啓binlog功能參數
設置server-id值並開啓binlog功能參數 [root@master mysql]# egrep "server-id|log-bin" /etc/my.cnf log-bin=mysql-bin server-id = 1 說明:server-id 服務器惟一標識,log_bin 啓動MySQL二進制日誌,上面的2行是添加在[mysqld]下面。 也能夠做以下設置: #不一樣步的數據庫,可設置多個 binlog-ignore-db=information_schema binlog-ignore-db=cluster binlog-ignore-db=mysql #指定須要同步的數據庫(和slave是相互匹配的),能夠設置多個 binlog-do-db=test 添加日誌存儲方式和規則(選填) #設置存儲模式不設置默認 binlog_format=MIXED #日誌清理時間 expire_logs_days=7 #日誌大小 max_binlog_size=100m #緩存大小 binlog_cache_size=4m #最大緩存大小 max_binlog_cache_size=521m 登陸數據庫檢查參數更改狀況 [root@master mysql]# mysql -pdm123 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.7.22-log Source distribution Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show variables like 'server_id'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | server_id | 1 | #server-id爲1 +---------------+-------+ 1 row in set (0.01 sec) mysql> show variables like 'log_bin'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | #binlog功能已開啓 +---------------+-------+ 1 row in set (0.01 sec)
在主庫上創建用於主從複製的帳號
mysql> grant replication slave on *.* to 'masterbackup' @'192.168.200.%' identified by 'masterbackup'; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> flush privileges; Query OK, 0 rows affected (0.01 sec) replication slave爲MySQL同步的必須權限,此處不要受權all權限 *.* 表示全部庫全部表,masterbackup爲同步帳號,192.168.200.%爲受權主機網段,使用了%號表示容許整個192.168.200.0網段以masterbackup用戶訪問 identified by 'masterbackup'; masterbackup爲密碼 檢查主庫建立的masterbackup複製帳號命令及結果 mysql> select user,host from mysql.user; +---------------+---------------+ | user | host | +---------------+---------------+ | masterbackup | 192.168.200.% | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | +---------------+---------------+ 4 rows in set (0.00 sec) mysql> select user,host from mysql.user where user='masterbackup'; +--------------+---------------+ | user | host | +--------------+---------------+ | masterbackup | 192.168.200.% | +--------------+---------------+ 1 row in set (0.01 sec) mysql> show grants for masterbackup@'192.168.200.%'; +------------------------------------------------------------------+ | Grants for masterbackup@192.168.200.% | +------------------------------------------------------------------+ | GRANT REPLICATION SLAVE ON *.* TO 'masterbackup'@'192.168.200.%' | +------------------------------------------------------------------+ 1 row in set (0.00 sec)
實現對主數據庫鎖表只讀
對主數據庫鎖表只讀(當前窗口不要關掉)的命令以下: mysql> flush table with read lock; Query OK, 0 rows affected (0.00 sec) 說明:在引擎不一樣的狀況下,這個鎖表命令的時間會受下面參數的控制。鎖表時,若是超過設置時間不操做會自動解鎖。 默認狀況下自動解鎖的時長參數值以下: mysql> show variables like '%timeout%'; +-----------------------------+----------+ | Variable_name | Value | +-----------------------------+----------+ | connect_timeout | 10 | | delayed_insert_timeout | 300 | | have_statement_timeout | YES | | innodb_flush_log_at_timeout | 1 | | innodb_lock_wait_timeout | 50 | | innodb_rollback_on_timeout | OFF | | interactive_timeout | 28800 | | lock_wait_timeout | 31536000 | | net_read_timeout | 30 | | net_write_timeout | 60 | | rpl_stop_slave_timeout | 31536000 | | slave_net_timeout | 60 | | wait_timeout | 28800 | +-----------------------------+----------+ 13 rows in set (0.00 sec) 鎖表後查看主庫狀態。可經過當前binlog日誌文件名和二進制binlog日誌偏移量來查看,結果以下。 注意,show master status;命令顯示的信息要記錄在案,後面的從庫導入全備後,繼續和主從複製是就是要從這個位置開始。 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000012 | 609 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) 或者新開個窗口用以下命令查看鎖標後的主庫binlog位置點信息: [root@master ~]# mysql -u root -pdm123 -e "show master status" mysql: [Warning] Using a password on the command line interface can be insecure. +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000012 | 609 | | | | +------------------+----------+--------------+------------------+-------------------+ 鎖表後,必定要單開一個新的ssh窗口,導數數據庫的全部數據,若是數據量很大(50G以上),而且容許停機,能夠停庫直接打包數據文件進行遷移,那樣更快。 [root@master ~]# mkdir /server/backup/ -p [root@master ~]# mysqldump -uroot -pdm123 --events -A -B |gzip >/server/backup/mysql_bak.$(date +%F).sql.gz mysqldump: [Warning] Using a password on the command line interface can be insecure. [root@master ~]# ls -l /server/backup/ 總用量 212 -rw-r--r-- 1 root root 215654 9月 9 22:13 mysql_bak.2018-09-09.sql.gz 爲了確保導出數據期間,數據庫沒有數據插入,導庫完畢能夠再次價差主庫狀態信息,結果以下: [root@master ~]# mysql -u root -pdm123 -e "show master status" mysql: [Warning] Using a password on the command line interface can be insecure. +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000012 | 609 | | | | +------------------+----------+--------------+------------------+-------------------+ 導出數據庫後,解鎖主庫,恢復可寫,命令以下: mysql> unlock tables; Query OK, 0 rows affected (0.00 sec) 把導出的數據庫遷移到從庫,可使用scp、rsync等將備份的數據拷貝到從庫。 [root@master ~]# scp -r /server/backup/mysql_bak.2018-09-09.sql.gz root@192.168.200.104:/server/backup/ The authenticity of host '192.168.200.104 (192.168.200.104)' can't be established. ECDSA key fingerprint is SHA256:dSlBmttAK+8cWnh7B/h7ywKYmicJrX0oba5StAR8F/U. ECDSA key fingerprint is MD5:2d:81:51:5b:1e:5f:d3:13:dd:f9:88:c9:3e:06:61:5c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.200.104' (ECDSA) to the list of known hosts. root@192.168.200.104's password: mysql_bak.2018-09-09.sql.gz 100% 211KB 58.4MB/s 00:00
3)、在MySQL從庫上執行以下操做
設置server-id值並關閉binlog功能參數
在my.cnf配置文件中的[mysqld]下面添加 vim /etc/my.cnf server-id = 5
登陸數據庫檢查參數的改變狀況
[root@slave ~]# mysql -uroot -pdm123 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.7.22 Source distribution Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show variables like 'server_id'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | server_id | 5 | +---------------+-------+ 1 row in set (0.01 sec) mysql> show variables like 'log_bin'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | OFF | +---------------+-------+ 1 row in set (0.00 sec)
把從主庫mysqldump導出的數據恢復到從庫
[root@slave ~]# cd /server/backup/ [root@slave backup]# ls mysql_bak.2018-09-09.sql.gz [root@slave backup]# gzip -d mysql_bak.2018-09-09.sql.gz #解壓目標數據庫備份,源文件會被刪除 [root@slave backup]# ll 總用量 784 -rw-r--r-- 1 root root 801238 9月 9 22:31 mysql_bak.2018-09-09.sql [root@slave backup]# mysql -uroot -pdm123 <mysql_bak.2018-09-09.sql #把數據還原到從庫的命令 mysql: [Warning] Using a password on the command line interface can be insecure.
登陸從庫配置複製參數
mysql> CHANGE MASTER TO -> MASTER_HOST='192.168.200.103', #主庫的IP -> MASTER_PORT=3306, #主庫的端口 -> MASTER_USER='masterbackup', #主庫上創建的用於複製的用戶masterbackup -> MASTER_PASSWORD='masterbackup', #這裏是masterbackup用戶的密碼 -> MASTER_LOG_FILE='mysql-bin.000012', #這裏是show master status時查看到的二進制日誌文件名稱 -> MASTER_LOG_POS=609; #這裏是show master status時查看到的二進制日誌偏移量 Query OK, 0 rows affected, 2 warnings (0.00 sec) 也能夠不登陸數據庫內部命令行,在Linux命令行快熟執行CHANGE MASTER的語句實現相應的功能,以下: [root@slave backup]# mysql -uroot -pdm123 << EOF > CHANGE MASTER TO > MASTER_HOST='192.168.200.103', > MASTER_PORT=3306, > MASTER_USER='masterbackup', > MASTER_PASSWORD='masterbackup', > MASTER_LOG_FILE='mysql-bin.000012', > MASTER_LOG_POS=609; > EOF 上述操做原理其實是吧用戶密碼等信息寫入到從庫新的額master.info文件中。 [root@slave backup]# cat /usr/local/mysql/ bin/ COPYING-test include/ man/ README share/ var/ COPYING docs/ lib/ mysql-test/ README-test support-files/ [root@slave backup]# cat /usr/local/mysql/var/ auto.cnf ibtmp1 mysql-bin.000003 mysql-bin.000008 slave.err ib_buffer_pool master.info mysql-bin.000004 mysql-bin.000009 slave.pid ibdata1 mysql/ mysql-bin.000005 mysql-bin.index slave-relay-bin.000001 ib_logfile0 mysql-bin.000001 mysql-bin.000006 performance_schema/ slave-relay-bin.index ib_logfile1 mysql-bin.000002 mysql-bin.000007 relay-log.info sys/ [root@slave backup]# cat /usr/local/mysql/var/master.info 25 mysql-bin.000012 #這裏是show master status時查看到的二進制日誌文件名稱 609 #這裏是show master status時查看到的二進制日誌偏移量 192.168.200.103 #主庫的IP masterbackup #主庫上創建的用於複製的用戶masterbackup masterbackup #這裏是masterbackup用戶的密碼 3306 #這是主庫的端口 60 0 0 30.000 0 86400 0
啓動從庫同步開關,測試主從複製配置狀況
啓動從庫主從複製開關,並查看複製狀態 [root@slave backup]# mysql -uroot -pdm123 -e "start slave;" mysql: [Warning] Using a password on the command line interface can be insecure. [root@slave backup]# mysql -uroot -pdm123 -e "show slave status\G;" mysql: [Warning] Using a password on the command line interface can be insecure. *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.200.103 Master_User: masterbackup Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000012 Read_Master_Log_Pos: 609 Relay_Log_File: slave-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000012 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: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 609 Relay_Log_Space: 527 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: 1 Master_UUID: 6fc3e9ed-b395-11e8-b3a4-000c29f2a33a Master_Info_File: /usr/local/mysql/var/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: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 主從複製是否成功,最關鍵的爲下面的3項狀態參數: [root@slave backup]# mysql -uroot -pdm123 -e "show slave status\G;"|egrep "Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master" mysql: [Warning] Using a password on the command line interface can be insecure. Slave_IO_Running: Yes Slave_SQL_Running: Yes Seconds_Behind_Master: 0 Slave_IO_Running:Yes,這個是I/O線程狀態,I/O線程負責從從庫到主庫讀取binlog日誌,並寫入從庫的中繼日誌,狀態爲Yes表示I/O線程工做正常。 Slave_SQL_Running:Yes,這個是SQL線程狀態,SQL線程負責讀取中繼日誌(relay-log)中的數據並轉換爲SQL語句應用到從數據庫中,狀態爲Yes表示I/O線程工做正常。 Seconds_Behind_Master:0,這個是複製過程當中從庫比主庫延遲的秒數,這個參數很重要,但企業裏更準確地判斷主從延遲的方法爲:在主庫寫時間戳,而後從庫讀取時間戳,和當前數據庫時間進行比較,從而認定是否延遲。
測試主從複製結果
在主庫上寫入數據而後觀察從庫的數據狀況 [root@master ~]# mysql -u root -pdm123 -e "create database test;" [root@master ~]# mysql -u root -pdm123 -e "show databases like 'test';" mysql: [Warning] Using a password on the command line interface can be insecure. +-----------------+ | Database (test) | +-----------------+ | test | +-----------------+ 在從庫查看主庫建立的數據庫是否同步過來,若是同步過來即說明同步成功。 [root@slave backup]# mysql -uroot -pdm123 -e "show databases like 'test';" mysql: [Warning] Using a password on the command line interface can be insecure. +-----------------+ | Database (test) | +-----------------+ | test | +-----------------+
1)、準備2臺數據庫環境和單臺多實例環境,確保能正常啓動和登陸
2)、配置my.cnf文件:主庫配置log-bin和server-id參數;從庫配置server-id,該值不能和主庫及其其餘從庫同樣,通常不開啓從庫log-bin功能.注意配置參數後要重啓才能生效.
3)、登陸主庫,增長從庫鏈接主庫同步的帳戶,例如:masterbackup,並受權 replication slave同步的權限。
4)、登陸主庫,整庫鎖表 flush table with read lock(窗口關閉後即失效,超時參數設置的時間到了,鎖表也失效),而後 show master status查看 binlog的位置狀態。
5)、新開窗口,在 Linux命令行備份導出原有的數據庫數據,並拷貝到從庫所在的服務器目錄。若是數據庫數據量很大,而且容許停機,能夠停機打包,而不用mysqldump。
6)、導出主庫數據後,執行 unlock tables解鎖主庫。
7)、把主庫導出的數據恢復到從庫。
8)、根據主庫的 show master status查看到的 binlog的位置狀態,在從庫執行 change master to..語句。
9)、從庫開啓複製開關,即執行 start slave;
10)、從庫 show slave status\G,檢查同步狀態,並在主庫進行更新測試。
步驟以下:
1)、安裝好要配置從庫的數據庫,配置好log-bin和 server-id參數。
2)、無需配置主庫 my.cnf文件,主庫的log-bin和 server-id參數默認就是配置好的。
3)、登陸主庫,增長從庫鏈接主庫同步的帳戶,例如:masterbackup,並受權 replication slave同步的權限。
4)、使用曾經在半夜經過 mysqldump帶-x和-- master-data=1的命令及參數定時備份的全備數據文件,把它恢復到從庫。
5)、在從庫執行 change master to...語句,無需 binlog文件及對應位置點。
6)、從庫開啓同步開關, start slave。
7)、從庫 show slave status,檢查同步狀態,並在主庫進行更新測試。
實施過程以下:
備份導出主庫數據 mysqldump -uroot -pdm123 -A --events -B -x --master-data=1|gzip >/opt/$(date +%F).sql.gz --master-data=1參數會在備份數據裏增長以下語句: -- Position to start replication or point-in-time recovery from CHANGE MASTER TO MASTER_LOG_FILE='musql-bin.000005',MASTER_LOG_POS=107; 在須要作複製的從庫上導入全備作從庫,命令以下: gzip -d /opt/2018-09-10.sql.gz mysql -uroot -pdm123 <<EOF CHANGE MASTER TO MASTER_HOST='192.168.20.104', MASTER_PORT=3306 MASTER_USER='masterbackup', MASTER_PASSWORD='masterbackup' EOF 這裏的CHANGE MASTER後面無需指定binlog文件名及具體位置,由於這部分已經在還原數據時提早應用到數據庫裏了(備份時 --master-data=1) start slave; #開啓主從複製開關 show slave status\G #查看主從複製狀態
MySQL主從複製主庫I/O線程狀態說明登陸主數據庫查看MySQL線程的同步狀態:
mysql> show processlist\G; *************************** 1. row *************************** Id: 2 User: masterbackup Host: 192.168.200.104:29639 db: NULL Command: Binlog Dump Time: 5985 State: Master has sent all binlog to slave; waiting for more updates Info: NULL *************************** 2. row *************************** Id: 3 User: root Host: localhost db: NULL Command: Query Time: 0 State: starting Info: show processlist 2 rows in set (0.01 sec) ERROR: No query specified
上面狀態的意思是線程已經從binlog日誌讀取全部更新,並已經發送到了從數據庫服務器.線程目前爲空閒狀態,等待有服務器上二進制日誌中的新事件更新.
主服務器的binlog Dump線程中State列的常見狀態以下:
主庫I/O線程工做狀態及其解釋說明 Sending binlog event to slave #線程已經從二進制binlog日誌讀取了一個事件而且正將它發送到服務器 Finished reading one binlog;switching to next binlog #線程已經讀完二進制binlog日誌文件,而且正在打開下一個要發送到從服務器的binlog日誌文件 Has sent all binlog to slave;waiting for binlog to be updated #線程已經從binlog日誌讀取全部更新並已經發送到了從數據庫服務器.線程目前爲空閒狀態,等待由服務器上二進制binlog日誌中的新事件更新 Waiting to finalize termination #線程中止時發生的一個很簡單的狀態
登陸從數據庫查看MySQL線程工做狀態
從庫有有2個線程,即I/O和SQL線程.從庫I/O線程的狀態以下:
mysql> show processlist\G; *************************** 1. row *************************** Id: 1 User: system user Host: db: NULL Command: Connect Time: 6093 State: Waiting for master to send event Info: NULL *************************** 2. row *************************** Id: 2 User: system user Host: db: NULL Command: Connect Time: 6093 State: Slave has read all relay log; waiting for more updates Info: NULL *************************** 3. row *************************** Id: 6 User: root Host: localhost db: NULL Command: Query Time: 0 State: starting Info: show processlist 3 rows in set (0.00 sec) ERROR: No query specified
從服務器的I/O線程的state列的常見狀態以下:
Connecting to master #線程正試圖鏈接主服務器 Checking master version #同主服務器之間創建鏈接後臨時出現的狀態 Requesting binlog dump #創建同主服務器之間的鏈接後臨時出現的狀態.線程向主服務器發送一個請求,索取從請求的二進制binlog日誌文件名和位置開始的二進制binlog日誌的內容 Waiting to reconnect after a failed binlog dump request #若是二進制binlog日誌轉儲請求失敗,線程進入睡眠狀態,而後按期嘗試從新鏈接.可使用--master-connect-retry選項指定重試之間的間隔 Reconnecting after a failed binlog dump request #線程正嘗試從新鏈接主服務器 Waiting for master to send event #線程已經鏈接上主服務器,正等待二進制binlog日誌事件達到 Queueing master event to the relay log #線程已經讀取一個事件,正將它複製到中繼日誌供SQL線程來處理 Waiting to reconnect after a failed master event read #讀取時(因爲沒有鏈接)出現錯誤.線程企圖從新鏈接前將睡眠master-connect-retry秒 Reconnecting after a failed master event read #線程正嘗試從新鏈接主服務器.當鏈接從新創建後,狀態變爲Waiting for master to send event
從庫SQL線程的狀態以下:
從服務器的SQL線程的state列的常見狀態: Reading event from the relay log #線程已經從中繼日誌讀取一個事件,能夠對事件進行處理了 Has read all relay log;Waiting for the slave I/O thread to update it #線程已經處理了中繼日誌文件中的全部事件,如今正等待I/O線程將新事件寫入中繼日誌 Waiting for slave mutex on exit #線程中止時發生的一個很簡單的狀態
查看MySQL線程同步狀態的用途
經過MySQL線程同步狀態能夠看到同步是否正常進行,故障的位置是什麼,另外還能夠查看數據庫是否同步完成,可用於主機宕機切換數據庫或人工數據庫主從切換遷移等.
例如:主庫宕機,要選擇最快的從庫將其提高爲主庫,就須要查看主從庫的線程狀態,若是主從庫複製在正常狀況下進行角色切換,也須要查看主從庫的線程狀態,根據複製狀態肯定更新是否完成.
1)、讓MySQL衝庫記錄binlog日誌的方法
當前的從庫還須要做爲其餘從庫的主庫,例如級聯複製或雙主互爲主從場景的狀況下,須要從庫記錄binlog日誌。 在從庫的my.cnf中加入以下參數,而後重啓服務生效便可。 log-slave-updates logbin = mysql-bin expire_logs_days = 7 #至關於find /usr/local/mysql/var/ -type f -name " mysql-bin.000*" -mtime +7 | xargs rm -f
2)、MySQL主從複製集羣架構的數據備份策略
若是主庫有語句級誤操做(例如:drop database dm;),從庫也會執行drop database dm;,這樣MySQL主從庫就都刪除了該數據。
高併發業務場景備份時須要在從庫開啓binlog功能,其邏輯圖以下:
步驟以下:
1)、選擇一個不對外提供服務的從庫,這樣能夠確保和主庫更新更接近,專門用於作數據備份。
2)、開啓從庫的binlog功能。
備份時能夠選擇只中止sql線程,中止應用SQL語句到數據庫,I/O線程保留工做狀態,執行命令爲 stop slave sql_thread;,備份方式能夠採起 mysqldump邏輯備份或直接物理備份,例如:使用cp、tar(針對mysql目錄)工具或 xtrabackup(第三方的物理備份軟件)進行備份,則邏輯備份和物理備份的選擇,通常是根據總的備份數據量的多少進行選擇的,數據量低於30G,建議選擇mysqldump邏輯備份方法,安全穩定,最後把全備和 binlog數據發送到備份服務器上留存。
問題一:主庫的從庫太多,致使複製延遲。
從庫數量以3~5個爲宜,要複製的從節點數量過多,會致使複製延遲。
問題二:從庫硬件比主庫差,致使複製延遲
查看 Master和 Slave的系統配置,可能會由於機器配置不當,包括磁盤I/O、CPU內存等各方面因素形成複製的延遲。這通常發生在高併發大數據量寫入場景中。
問題三:慢SQL語句過多。
假如一條SL語句執行時間是20秒,那麼從執行完畢到從庫上能查到數據至少須要20秒,這樣就延遲20秒了.
通常要把SQL語句的優化做爲常規工做,不斷地進行監控和優化,若是單個SQL的寫入時間長,能夠修改後分屢次寫入。經過查看慢查詢日誌或 show full processlist命令,找出執行時間長的查詢語句或大的事務
問題四:主從複製的設計問題。
例如,主從複製單線程,若是主庫寫併發太大,來不及傳送到從庫,就會致使延遲。
更高版本的 MySQL能夠支持多線程複製,門戶網站則會本身開發多線程同步功能。
問題五:主從庫之間的網絡延遲。
主從庫的網卡、網線、鏈接的交換機等網絡設備均可能成爲複製的瓶頸,致使複製延遲,另外,跨公網主從複製很容易致使主從複製延遲。
問題六:主庫讀寫壓力大,致使複製延遲。
主庫硬件要搞好一點,架構的前端要加 buffer及緩存層。
read-only參數選項可讓從服務器只容許來自從服務器線程或具備 SUPER權限的數據庫用戶進行更新,確保從服務器不接受來自用戶端的非法用戶更新。
read-only參數容許數據庫更新的條件爲:
具備 SUPER權限的用戶能夠更新,不受read-only參數影響,例如:管理員 root
來自從服務器線程能夠更新,不受read-only參數影響,例如:前面的masterbackup用戶。
在生產環境中,能夠在從庫 Slave中使用read-only參數,確保從庫數據不被非法更新。
read-only參數的配置方法以下。
在my.cnf裏[mysqld]模塊下加read-only參數重啓數據庫,配置以下:
[mysqld] read-only
專業的運維人員提供給開發人員讀寫分離的帳戶設置方法以下:
1)訪問主庫和從庫時使用一套用戶密碼,例如,用戶爲web,密碼爲dm123
2)即便訪問IP不一樣,端口也儘可能相同(3306)。例如:寫庫VIP爲192.168.200.103,讀庫VIP爲192.168.200.104。
除了IP沒辦法修改以外,要儘可能爲開發人員提供方便,若是數據庫前端有DAL層( DBProxy),還能夠只給開發人員一套用戶、密碼、IP、端口,這樣就更專業了,剩下
的都由運維人員搞定。
下面是受權Web鏈接用戶訪問的方案: MySQL主從複製讀寫分離集羣。
方法一:主庫和從庫使用不一樣的用戶,授予不一樣的權限。
主庫上對webw用戶受權以下:
用戶:web_w 密碼:dm123 端口3306 主庫VIP:192.168.200.103 權限:SELECT,INSERT,UPDATE,DELETE 命令:GRANT SELECT, INSERT, UPDATE, DELETE ON `web`.* TO 'web_w'@'192.168.200.%' identified by 'dm123';
從庫上對web_r用戶受權以下:
用戶:web_w 密碼:dm123 端口3306 主庫VIP:192.168.200.104 權限:SELECT 命令:GRANT SELECT ON `web`.* TO 'web_w'@'192.168.200.%' identified by 'dm123';
方法二:主庫和從庫使用相同的用戶,但授予不一樣的權限。
主庫上對web用戶受權以下:
用戶:web_w 密碼:dm123 端口3306 主庫VIP:192.168.200.103 權限:SELECT,INSERT,UPDATE,DELETE 命令:GRANT SELECT, INSERT, UPDATE, DELETE ON `web`.* TO 'web_w'@'192.168.200.%' identified by 'dm123';
主庫上對web用戶受權以下:
用戶:web_w 密碼:dm123 端口3306 主庫VIP:192.168.200.104 權限:SELECT 提示:用於從庫和主庫是同步複製的,因此從庫上的web用戶會自動和主庫保持一致,即沒法實現制度SELECT的受權
要實現方法二中的受權有以下2個方法:
一是在主庫上建立用戶和權限後,從庫上revoke收回對應更新權限(insert、update、delete)。命令爲:
REVOKE INSERT,UPDATE,DELETE on web.* FROM 'web'@192.168.200.%;
而是受權庫MySQL同步,主庫的配置參數以下:
binlog-ignore-db = mysql replicate-ignore-db = mysql
方法三:在從庫上設置read-only參數,讓從庫只讀。
主庫從庫:主庫和從庫使用相同的用戶,授予相同的權限(非ALL權限)。
用戶:web 密碼:dm123 端口:3306 主庫VIP:192.168.200.103,從庫VIP:192.168.200.104
權限:SELECT, INSERT, UPDATE, DELETE
命令:GRANT SELECT, INSERT, UPDATE, DELETE ON web.* TO 'web_w'@'192.168.200.%' identified by 'dm123';
因爲從庫設置了read-only,非super權限是沒法寫入的,所以,經過read-only參數就能夠很好的控制用戶,使其不能非法將數據寫入從庫。
生產工做場景的設置方案以下:
1)忽略受權庫MySQL同步,主庫配置參數以下:
binlog-ignore-db = mysql replicate-ignore-db = mysql
2)主庫和從庫使用相同的用戶,但授予不一樣的權限
主庫上對web用戶受權以下:
用戶:web 密碼:dm123 端口:3306 主庫VIP:192.168.200.103 權限:SELECT, INSERT, UPDATE, DELETE 命令:GRANT SELECT, INSERT, UPDATE, DELETE ON web.* TO 'web_w'@'192.168.200.%' identified by 'dm123';
從庫上對web用戶受權以下:
用戶:web 密碼:dm123 端口:3306 從庫VIP:192.168.200.104 權限:SELECT