MySQL複製支持單向,異步複製。經過一臺主服務器將更新寫入二進制日誌文件,並維護文件的一個索引以跟蹤日誌循環。這些日誌能夠記錄發送到從服務器的更新。當一個從服務器鏈接主服務器時,它通知主服務器從服務器在日誌中讀取的最後一次成功更新的位置。從服務器接收從那時起發生的任何更新,而後封鎖並等待主服務器通知新的更新。MySQL主從複製是異步進行的。同步須要版本爲5.5,使用google提供的插件來實現。python
MySQL主從複製操做很靈活既能夠實現整個服務的級別的複製,也能夠實現對某個庫,甚至某個數據庫中的指定的某個對象進行復制。mysql
提升性能。經過一(多)主多從的部署方案,將涉及數據寫的操做放在Master端操做,而將數據讀的操做分散到衆多的Slave當中。下降了Master的負載,提升數據寫入的響應效率;多臺從服務器提供讀,分擔了請求,提升了讀的效率。sql
數據安全。數據複製到Slave節點,即便Master宕機,Slave節點還保存着完整數據。shell
數據分析。將數據分析,放在slave上。數據庫
MySQL的Replication是一個異步的複製過程,從一個MySQL實例(Master)複製到另外一臺MySQL實例上。在Master和Slave之間複製的整個過程主要由3個線程完成,其中兩個線程(SQL線程和IO線程)在Slave端,另一個線程(IO線程)在Master端。安全
要實現主從複製,首先要在Master端打開Binary Log功能。由於整個複製過程實際上就是Slave從Master上獲取二進制日誌,而後在本身身上徹底按照產生的順序一次執行日誌中記錄的各類操做的過程。服務器
複製的具體過程以下:網絡
Slave的IO線程連上Master,並請求日誌文件指定位置(或從開始的日誌)以後的日誌的內容。多線程
Master接收到來自Slave的IO線程請求後,負責複製IO線程根據請求的信息讀取指定日誌以後的日誌信息,返回給Slave端的IO線程。返回信息中除了日誌所包含的信息,還包含了包括本次返回的信息在Master端的Binary Log文件的名稱和位置。併發
Slave的IO線程接受到信息後,將日誌內容一次寫入Slave端的Relay Log文件(mysql-relay-bin.xxxx)的末端,並將讀取到的Master端的bin-log的文件和位置記錄到master-info文件中,以便在下一次讀取時可以清楚地告訴Master,下次從bin-log哪一個位置開始日後的日誌內容。
Slave的SQL線程檢測檢測到Relay Log中更新內容後,會立刻解析該Log文件中的內容,還原成在Master端真實執行時的可執行的SQL語句,並執行這些SQK語句。實際上Master和Slave執行一樣的語句。
Binary Log會記錄成每一行數據被修改的形式,而後在Slave端再對相同的數據進行修改。
優勢:在Row Level模式下,Binnary Log能夠不記錄執行的Query語句的上下文相關信息,只要記錄哪一行修改了,修改爲什麼樣子。Row Level會詳細的記錄下每一行數據的修改細節,並且不會出現某個特定狀況下的存儲過程,或Function,以及Trigger的調用和觸發沒法被正確複製問題。
缺點:產生大量的日誌內容。
每一條會修改的SQL語句都會記錄到Master的Binnary中。Slave端在複製的時候,SQL線程會解析成和原來Master端執行過相同的SQL語句,並再次執行。
優勢:首先,解決了Row Level下的缺點,不需要記錄每一行的數據變化,減小了Binnary Log日誌量,節約了IO成本,提升了性能。
缺點:因爲它是記錄的執行語句,爲了讓這些語句在Slave端也能正確執行。那麼它還必須記錄每條語句在執行時的一些相關信息,即上下文信息,以保證全部語句在Slave端被執行的時候可以獲得和在Master端執行時相同的結果。另外,因爲MySQL發展比較快,不少新功能不斷加入,使得MySQL複製遇到了不小的挑戰,複製時設計的內容岳父在,越容易出bug。在Statement Level下,目前已發現很多的狀況下會形成MySQL的複製問題。主要是在修改數據使用了某些特定的函數貨功能後,出現,好比:Sleep()函數在有些版本中就不能正確的複製,在存儲過程當中使用了last_insert_id()函數,可能會使Slave和Master的到不一致的ID,等等。
在Mixed模式下,MySQL會根據執行的每一條具體的SQL語句來區分對待記錄的日誌形式,也就是在Statement和Row之間選擇一種。除了MySQL認爲經過Statement方式可能形成複製過程當中Master和Slave之間產生不一致數據。(如特殊Procedure和Funtion的使用,UUID()函數的使用等特殊狀況)時,它會選擇ROW的模式來記錄變動以外,都會使用Statement方式。
mysql主從延時
有不少種緣由會形成mysql的主從延時,經過查看Seconds_Behind_Master:的值來肯定是否存在延遲問題,該值越大,延遲現象越明顯。衆所周知備庫relay-log和主庫的bin-log裏的內容同樣,真正和主庫有關兩的是io_thread,當主庫I/O負載很大或網絡阻塞時,io_thread不能及時複製binlog,而sql_thread直能跟上io_thread的腳步,這時seconds_behind_master的值是0,實際上卻不是,這時用該值做爲延遲參考則不許。咱們可使用pt-heartbeat來監控延時現象。該工具按期在主庫上不斷寫入時間戳,經過主從複製同步到從庫中去,此時從庫服務器的時間和主庫保持一致,經過比較從服務器上同步過來的主庫時間戳和從庫系統時間戳的差值的大小來肯定是否存在延遲現象。
主從延遲的主要緣由是:主庫多線程併發更新,從庫單線程串行更新。解決方法:將從庫變爲多線程更新,可使用mysql-transfer:是一個基於mysql的patch,用來加速主從同步速度。
通常來講,咱們遇到了主從延時的問題,若是不是高併發緣由的話,能夠手動臨時解決一下:
方法一:忽略錯誤後,繼續同步
該方法適用於主從庫數據相差不大,或者要求數據能夠不徹底統一的狀況,數據要求不嚴格的狀況
解決:
stop slave;
#表示跳過一步錯誤,後面的數字可變
set global sql_slave_skip_counter =1;
start slave;
以後再用mysql> show slave status\G 查看:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
ok,如今主從同步狀態正常了。。。
方式二:從新作主從,徹底同步
該方法適用於主從庫數據相差較大,或者要求數據徹底統一的狀況
解決步驟以下:
1.先進入主庫,進行鎖表,防止數據寫入
使用命令:
mysql> flush tables with read lock;
注意:該處是鎖定爲只讀狀態,語句不區分大小寫
2.進行數據備份
#把數據備份到mysql.bak.sql文件
[root@server01 mysql]#mysqldump -uroot -p -hlocalhost > mysql.bak.sql
這裏注意一點:數據庫備份必定要按期進行,能夠用shell腳本或者python腳本,都比較方便,確保數據萬無一失
3.把mysql備份文件傳到從庫機器,進行數據恢復
#使用scp命令
[root@server01 mysql]# scp mysql.bak.sql root@192.168.128.101:/tmp/
4.中止從庫的狀態
mysql> stop slave;
5.而後到從庫執行mysql命令,導入數據備份
mysql> source /tmp/mysql.bak.sql
6.設置從庫同步,注意該處的同步點,就是主庫show master status信息裏的| File| Position兩項
change master to master_host = '192.168.128.100', master_user = 'rsync', master_port=3306, master_password='', master_log_file = 'mysqld-bin.000001', master_log_pos=3260;
7.從新開啓從同步
mysql> stop slave;
8.查看同步狀態
mysql> show slave status\G 查看:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
好了,同步完成啦。