1. 程式人生 > >MySQL復制以及調優

MySQL復制以及調優

控制 -i 混合 執行 很多 lob 有效 cti 最小

原文:MySQL復制以及調優

一. 簡介

MySQL自帶復制方案,帶來好處有:

數據備份。

負載均衡。

分布式數據。

概念介紹:

主機(master):被復制的數據庫。

從機(slave):復制主機數據的數據庫。

復制步驟:
(1). master記錄更改的明細,存入到二進制日誌(binary log)。
(2). master發送同步消息給slave。
(3). slave收到消息後,將master的二進制日誌復制到本地的中繼日誌(relay log)。
(4). slave重現中繼日誌中的消息,從而改變數據庫的數據。

下面放一張經典的圖片來說明這一過程:
技術分享圖片

二. 實現復制

實現復制有以下步驟:

1.設置MySQL主庫的二進制日誌以及server-id

MySQL配置文件一般存放在/etc/my.cnf

# 在[mysqld]下面添加配置選項
[mysqld]
server-id=1
log-bin=mysql-bin.log

server-id是數據庫在整個數據庫集群中的唯一標示,必須保持唯一。
重啟MySQL。
註:如果MySQL配置文件中已經配置過此文件,則可以跳過此步。

2.新建復制賬號

在主庫裏面新建用於從庫復制主庫數據的賬號,並授予復制權限。

mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO user_name@'host' IDENTIFIED BY 'password';

3.設置MySQL主庫server-id

和第二步配置一樣,要註意的地方有兩點:

  1. 如果不需要從庫作為別的從庫的主庫的話,則不需要配置二進制日誌。
  2. 很多時候復制並不需要復制主庫的全部數據庫(特別是mysql的信息配置庫)。因此可以配置replicate_do_db來指定復制的數據庫

4.從庫初始化主庫的數據

如果數據量不算大的情況下,可以使用mysqldump工具導出主庫數據,然後導入到從庫裏面。

mysqldump --single-transaction --triggers --master-data databasename > data.sql

如果數據量大的情況下應該使用Xtrabackup去進行數據庫的導出,此處不做介紹。
可能會有同學問,為什麽不直接使用二進制日誌進行初始化呢?

  1. 如果我們主庫運行了比較長的一段時間,並不太適合使用從庫根據二進制日誌進行復制數據,直接使用二進制日誌去初始化從庫會比較耗費時間和性能。
  2. 更多的情況下,主庫的二進制日誌的配置項沒有打開,因此也就不存在以前操作的二進制日誌。

5.開啟復制

從庫執行下面命令

mysql> CHANGE MASTER TO MASTER_HOST='host',
-> MASTER_USER='user',
-> MASTER_PASSWORD='password',
-> MASTER_LOG_FILE='mysql-bin.000001',
-> MASTER_LOG_POS=0;

註意最後的兩個命令:MASTER_LOG_FILE和MASTER_LOG_POS,表示從庫的從哪個二進制文件開始讀取,偏移量從那裏開始,這兩個參數可以從我們導入的SQL裏面找到。

技術分享圖片

開啟復制

start slave;

這時候就完成了復制,在主庫更新一個數據或者新增數據在從庫都可以查詢到結果。
技術分享圖片
在主庫上也可以查詢的到復制線程的狀態。
技術分享圖片

三. 復制的日誌格式

MySQL復制的日誌格式有三種,根據主庫存放數據的方式不同有以下三種:

復制方式 特點 優點 缺點
row 基於行的格式復制,記錄需要修改的每行的數據信息。 如果一個SQL修改了2w行的數據,那麽就會記錄2w行的日誌格式 保證了數據的強一致性,且由於記錄的是執行後的結果,在從庫上執行還原也會比較快 日誌記錄數量很多,主從之間的傳輸需要更多的時間。
statement 基於段的日誌格式復制,也就是記錄下更改的SQL記錄,而不是更改的行的記錄。 日誌記錄量最小。 對於一些輸出結果不確定的函數,在從庫上執行一遍很可能會出現問題,如uuid,從庫根據日誌還原主庫數據的時候需要執行一遍SQL,時間相對較慢。
mixed 混合上面兩種日誌格式記錄記錄日誌,至於什麽時候使用哪種日誌方式由MySQL本身決定。 可以平衡上面兩種日誌格式的優缺點。

mysql5.7以前默認使用statement格式。
設置方式,可以在配置文件設置(首選):

binlog_format=ROW

或臨時設置全局變量(當前mysql連接有效):

查看日誌格式
mysql > show variables like 'binlog_format';

設置日誌格式
mysql > set binlog_format='row';

由於兩個主從服務器一般都會放在同一個機房裏面,兩者之間同步的速度會會比較快,為保證強一致性,應該首選行的日誌格式記錄(row),保證傳輸素速度可以選擇混合方式(mixed)。
而行的日誌格式有下面三種記錄方式:

記錄方式 特點
minimal 只記錄被修改列的數據
full 記錄被修改的行的全部列的數據
noblob 特點同上,只是如果沒有修改blob和text類型的列的情況下,不會記錄這些列的數據(也就是大數據列)

mysql默認是full,最好修改成minimal。

binlog_row_image=minimal

四. 主從復制延遲

由於主庫和從庫之間不在同一個主機上,數據同步之間不可以避免地具有延遲,解決的方法有添加緩存,業務層的跳轉等待,如果非得從數據庫層面去減緩延遲問題,可以從復制時候的三大步驟(主庫產生日誌,主從傳輸日誌,從庫還原日誌內容)入手:
1.主庫寫入到日誌的速度
控制主庫的事務大小,分割大事務為多個小事務。
如插入20w的數據,改成插入多次5000行(可以利用分頁的思路)

2.二進制日誌在主從之間傳輸時間
主從之間盡量在同一個機房或地域。
日誌格式改用MIXED,且設置行的日誌格式未minimal,原理詳見上面的日誌格式介紹。

3.減少從庫還原日誌的時間
在MySQL5.7版本後可以利用邏輯時鐘方式分配SQL多線程。
設置邏輯時鐘:slave_parallel_type=‘logical_clock’;
設置復制線程個數:slave_parallel_workers=4;

五. 需要註意的地方

  1. 重啟MySQL最好切換未MySQL用戶再進行操作,不然文件啟動後會有權限問題。
  2. 搭建好MySQL的環境後就設置好配置裏的log-bin選項,這樣以後如果數據庫需要從庫的復制,就不需要重啟數據庫,打斷業務的進行。
  3. 需要打開主庫的防火墻的對應的mysql端口。
  4. 由於從庫同步主庫的方式,監聽主庫發送的信息,而不是輪詢,因此如果出現通信出現了故障,重新連接後如果主庫沒有進行數據更改的操作,從庫不會同步數據,因此可以通過插入空事務的方式同步數據。

歡迎各位來我博客查看本文

MySQL復制以及調優