MySQL複製的優勢主要包括如下3方面:html
{ 若是主服務器出現問題,能夠快速切換到從服務器提供服務;mysql
{ 能夠在從服務器上執行查詢操做,下降主服務器的訪問壓力;sql
{ 能夠在從服務器上執行備份,以免備份期間影響主服務器的服務。數據庫
因爲MySQL實現的是的複製,因此主從服務器之間存在必定的差距,在從服務器上進行的查詢操做須要考慮到這些數據的差別,通常只有更新不頻繁的數據或者對實時性要求不高的數據能夠經過從服務器查詢,實時性要求高的數據仍然須要從主數據庫得到。安全
(1) 確保主從服務器上安裝了相同版本的數據庫。由於複製的功能在持續的改進中,因此在可能的狀況下推薦安裝最新的穩定版本。bash
(2) 在主服務器上,設置一個複製使用的帳戶,並授予REPLICATION SLAVE權限。這裏建立一個複製用戶hollowJ,能夠與192.168.0.204:3307(從庫)的主機進行鏈接。服務器
grant replication slave on *.* to hollowJ@'192.168.0.204' identified by 'hollow';
注意,mysql有的命令必須在本地執行,比方說上面這個,不然即便使用root,也會提示網絡
Access denied for user 'root'@'%' (using password: YES) socket
(3) 修改主數據庫服務器的配置文件,my.cnf中[mysqld]段開啓BINLOG,並設置service-id的值。ide
# For advice on how to change settings please see # http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html # *** DO NOT EDIT THIS FILE. It's a template which will be copied to the # *** default location during install, and will be replaced if you # *** upgrade to a newer version of MySQL. [mysqld] # Remove leading # and set to the amount of RAM for the most important data # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%. # innodb_buffer_pool_size = 128M # Remove leading # to turn on a very important data integrity option: logging # changes to the binary log between backups. log-bin=mysql-bin //這裏開啓後,mysql的全部操做日誌都會記錄並同步到從屬節點上 # These are commonly set, remove the # and set as required. # basedir = ..... # datadir = ..... # port = ..... server_id =3306 //每一個實例的惟一標示,可用ip,這裏使用ip # socket = ..... # Remove leading # to set options mainly useful for reporting servers. # The server defaults are faster for transactions and fast SELECTs. # Adjust sizes as needed, experiment to find the optimal values. # join_buffer_size = 128M # sort_buffer_size = 2M # read_rnd_buffer_size = 2M sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
改完配置,請重啓主服務器!!不然下面的結果將沒法看到。
mysql>show master status;
上面咱們就獲得了主服務器上當前的二進制日誌名和偏移量值。這個操做的目的是爲了在從數據庫啓動之後,從這個點開始進行數據恢復。
(4) 修改從數據庫的配置文件my.cnf,增長servier-id參數。注意service-id的值必須是惟一的,不能和主數據庫的配置相同,若是有多個從數據庫服務器,每一個從數據庫服務器必須有本身惟一的server-id。
(5) 對從數據庫服務器作相應設置,指定複製使用的用戶,主數據庫服務器的IP、端口、以及開始執行復制的日誌文件和位置等。
關鍵的來了,前面的操做都是爲這一部作準備。在從節點執行下面命令:
mysql> change master to master_host='192.168.0.204',master_port=3306,master_user='hollowJ',master_password='hollow',master_log_file='mysql-bin.000001',master_log_pos=154; Query OK, 0 rows affected, 2 warnings (0.14 sec) mysql> start slave; Query OK, 0 rows affected (0.06 sec)
在從服務器上,啓動slave線程
(12) 這時slave上執行show slave status\G; 命令:
mysql> show slave status\G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.0.204 Master_User: hollowJ Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 154 Relay_Log_File: localhost-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes
這代表slave已經鏈接上master,等待主庫的發送事件。
快去主庫建立個表,插些數據,看看叢庫是否可以同步到。^_^
這個參數用來配置從服務器上的更新操做是否寫二進制日誌,默認是不打開的。可是若是這個從服務器同時也要做爲其餘服務器的主服務器搭建一個鏈式的複製,那麼就須要打開這個選項,這樣它的從服務器將得到它的二進制日誌以進行同步操做。
這個啓動參數要和--logs-bin參數一塊兒使用。
用來設置在主服務器的鏈接丟失的時候重試的時間間隔,默認是60秒。
設置從服務只能接受超級用戶的更新操做,從而限制應用程序錯誤的對從服務器的更新操做。
在主服務器上設置一個賬號,並使用此帳號在從服務器上登陸。
主:
mysql> grant all privileges on *.* to bai@'%' identified by '123456';
從:
使用read-only啓動從mysql
若是不關閉主服務器,從服務從新啓動後無需從新設置從服務與主服務器的主從關係。
可使用replicate-do-db、replicate-do-table、replicate-ignore-db、replicate-ignore-table或replicate-wild-do-table來指定從主數據庫複製到從數據庫的數據庫或者表。有些時候用戶只須要將關鍵表備份到從服務器上,或者只須要將提供查詢操做的表複製到從服務器上,這樣就能夠經過配置這幾個參數來篩選進行同步的數據庫和表。
replicate-do-table的演示:
首先在主數據庫的test數據庫中建立兩個表repl_test和repl_test1而後從數據庫啓動的時候指定replicate-do-table=test.repl_test,即只複製repl_test表。最後主數據庫更新兩張表,並檢查數據複製狀況。
(1) 首先檢查主從數據庫上的兩個表的記錄,主從數據庫是相同的
(2) 而後關閉從服務器,,而後從新啓動時指定複製其中一個表。
(3) 更新主數據庫上test.repl_test和test.repl_test1兩張表,並檢查從服務器。
在複製過程當中,因爲各類緣由,從服務器可能會遇到執行BINGLOG中的SQL出錯的狀況(好比主鍵衝突),在默認狀況下,從服務器將會中止複製進程,再也不進行同步,等等用戶介入處理。這種問題若是不能及時發現,將會對應用或者備份產生影響。此參數的做用就是用來定義複製過程當中從服務器能夠自動路過的錯誤號,這樣複製過程當中遇到定義中的錯誤號時,即可以自動路過,直接執行後面的SQL語句,以此來最大限度地減小人工干預。此參數能夠定義多個錯誤號,或者經過定義成all路過所有的錯誤。具體語法以下:
--slave-skip-errors=[err_code1,err_code2,…|all]
若是從數據庫主要是做爲主數據庫的備份,那麼就不該該使用這個啓動參數,設置不當,極可能形成主從數據庫的數據不一樣步。可是,若是從數據庫僅僅是爲了分擔主數據庫的查詢壓力,且對數據的完整性要求不是很嚴格,那麼這個選項的克能夠減輕數據庫管理員維護從數據庫的工做量。
複製環境配置完成後,數據庫管理員須要常常進行一些平常監控和管理維護工做,以便能及時發現一些複製中的問題,並儘快解決,以此來保持複製可以正常工做。
爲了防止複製過程當中出現故意從而致使複製進程中止,咱們須要常常檢查從服務器的複製狀態。通常用show slave status\G命令檢查。
在顯示的這此信息中,咱們主要關心「Slave_IO_Running」和「Slave_SQL_Running」
{ Slave_IO_Running:此進程負責slave從master上讀取BINGLOG日誌,並寫入slave上的中繼日誌中。
{ Slave_SQL_Running:此進程負責讀取而且執行中繼日誌中的BINLOG日誌。
只要其中有一個進程狀態是NO,則表示複製進程中止,錯誤緣由能夠從「Last_Errno」字段 的值中看到。
除了查看上面的信息。用戶還可能瞭解到從服務器的配置狀況以及當前和當服務器的同步狀況。
在某些繁忙的OLTP(在線事務處理)系統上,因爲主服務器更新頻繁,而從服務器因爲各類緣由(好比硬件性能較差)致使更新速度較慢,從而使得主從服務器之間的數據差距起來起大,最終對某些應用產生影響。在這種狀況下,咱們就須要按期地進行主從服務器的數據同步,使得從數據差距可以減到最小。經常使用的方法是:在負載較低的時候暫時阻塞主數據庫的更新,強制主從數據庫的更新同步。具體步驟以下
(1) 在主服務器上,執行如下語句(注意,會主數據庫的全部更新操做):
記錄SHOW語句輸出的日誌名和偏移量,這此是從服務器複製的目的座標。
(2) 在從服務器上執行下面語句,其中MASTER_POS_WAIT()函數的參數是前面步驟中獲得的複製座標值:
這個select語句會阻塞直到從服務器達到指定的日誌文件和偏移後,返回0,若是返回-1,則表示超時退出。查詢返回0時,則從服務器與主服務器同步。
(3) 主服務器上,解鎖表
UNLOCK TABLES;
首先須要肯定是不是從服務器的表與主服務器的不一樣形成的。若是是表結構不一樣致使,則修改從服務器的表與主服務器的相同,而後從新運行START SLAVE語句。
若是不是表結構不一樣致使的更新失敗,則須要確認手動更新是否安全,而後忽視來自主服務器的更新失敗的語句。路過來自主服務器的語句的命令爲
SET GLOBAL SQL_SLAVE_SKIP_SOUNTER=n
其中n的取值爲1或2。若是來自主服務器的更新語句不使用AUTO_INCREMENT或者LAST_INSERT_ID(),n值應爲1,不然爲2。緣由是使用AUTO_INCREMENT或者LAST_INSERT_ID()的語句須要從二進制日誌中取兩個事件。
如下例子就是在從服務器端模擬路過主服務器的兩個更新語句的效果。
(1) 首先,在從服務器端先中止複製進程,並設置路過兩個語句:
(2) 而後在主服務器插入三條記錄。
(3) 從服務器端啓動複製進程,檢查測試的表一,發現插入的兩條記錄被跳過了,只執行了第3條插入語句:
若是應用中使用大的BLOG列或者長字符串,那麼在從服務器上恢復的時候,可能會出現:log event entry exceeded max_allowed_packet的錯誤,這是由於含有大文本的記錄沒法經過網絡進行傳輸致使。解決的辦法就是在主從服務器上增長max_allowed_packet參數的大小,這個參數默認值爲1MB,能夠按照實際須要進行修改,好比下例中將其增大爲16M:
同時在my.cnf裏,設置max_allowed_packet=16M,保證下次數據庫從新啓動後參數繼續有效。
在多臺主服務器對一臺從服務器時,若是主服務器的表採用自動增加變量,那麼複製到從服務器的同一張表後極可能會引發主鍵衝突,同爲系統參數auto_incerment_incerment和auto_incerment_offset默認值爲1,這樣多臺主服務器的自增變量列早晚會發生衝突。在單主複製時,能夠採用默認設置,不會有主鍵衝突發生。可是使用多主複製時,就須要定製auto_incerment_incerment和auto_incerment_offset的設置,保證多主之間複製到從數據庫不會有重複衝突。好比。兩個master的狀況能夠按照如下設置。
{ Master1:auto_incerment_incerment=2,auto_incerment_offset=1;(1,3,5,7序列)
{ Master2:auto_incerment_incerment=2,auto_incerment_offset=0;(2,4,6,8序列)
首先在參數是默認值的時候往表中插入記錄:
而後把auto_incerment_incerment的值改爲10再插入記錄:
從測試的結果上看,新插入的記錄再也不連續了,每次增長10。接着再修改auto_increment_offset參數:
從插入記錄的結果上能夠了解,auto_increment_offset參數設置的是每次增長後的偏移量,也就是每次按照10累加以後,還須要增長5個偏移量。
經過這兩個參數能夠方便地設置不一樣的主服務器上的自動增加列的值的範圍,這樣在這此數據複製到從服務器上時能夠有交地避免主鍵的重複。
不少狀況下,咱們想要知道從服務器複製的進度如何。知道了這個差距,能夠幫助咱們判斷是否須要手工來作主從的同步工做,也能夠幫助咱們判斷從服務器上作統計的數據精度如何。這個值能夠經過SHOW PROCESSLIST列表中的Slave_SQL_Running線程的Time的值行到,它記錄了從服務器當前執行的SQL時間戳與系統時間之間的差距,單位是秒。
(1) 首先在主服務器上插入一個包含當前時間戳的記錄:
(2) 爲了方便模擬時間,這裏把從服務器上覆制的IO進程集下來,使得從服務器暫時不寫中繼日誌,也就是最後執行的SQL就是當前中繼日誌中最後一個SQL。
(3) 一段時間以後,再從服務器端查詢複製的狀況:
(4) 這時再查詢SQL線程的時間,顯示的Time值,單位是秒。這說明是多少秒之間的更新。
因爲MySQL複製的機制是執行主服務器傳輸過來的二進制日誌,二進制日誌中的每一個語句經過設置時間戳來保證執行時間和順序的正確性,因此每一個語句執行以前都會首先設置時間戳,而經過查詢這個進程的Time就能夠知道最後設置的時間戳和當前時間的差距。
(1) 首先要確保全部的從數據庫都已經執行了relay log中的所有更新,在每一個從服務器上執行STOP SLAVE IO_THERAD,而後檢查SHOW PROCESSLIST的輸出,直到盾到狀態是Has read all relay log,表示更新都很執行完畢。
(2) 在從S1數據庫上,執行STOP SLAVE中止從服務,而後RESET MASTER重置成主數據庫。
(3) 在S2上,中止從服務。而後更換主數據庫設置,而後再開啓複製(須要從新設置用戶以及二進制日誌文件?)
(4) 通知全部的客戶端將應用指向S1服務器。
(5) 刪除新的主數據庫服務器上的master.info和relay-log.info文件,不然下次重啓的時候還會按照從服務器啓動。
(6) 最後,若是M服務器能夠修復,則能夠按照S2的方法配置成S1的從服務器。
上面測試的步驟是默認S1是打開的log-bin選項的,這樣重置成數據庫後能夠將二進制日誌傳輸到期貨從服務器上。其次,S1上沒有打開log-slave-updates參數,不然重置成主數據庫後,可能會將已經執行過的二進制日誌重複傳輸給S2,致使S2的同步錯誤。