MySQL 5.7主從復制從零開始設置及全面詳解——實現多線程並行同步,解決主從復制延遲問題!
2017年06月15日 19:59:44 藍色-鳶尾 閱讀數:2062
版權聲明:本文為博主原創文章,如需轉載,請注明出處! https://blog.csdn.net/xzsfg6825/article/details/73302066
使用數據庫同步的方法解決數據傳輸的問題,但因為使用mysql 5.5版本時,設置的主從復制在數據量較大或者網絡擁塞的時候延遲會更高,而且經過查資料,老版本是無法從根本上改善這個問題的。最近了解了MySQL 5.7版本的特性,知道了5.7版本的基於組提交的並行復制可以更大的改善這個問題。接下來對相關的內容進行詳細的總結和概括。
一、Mysql 5.6 及更低版本的主從復制
(1) 在MySQL 5.6之前的版本里,有三個線程參與,都是單線程:Binlog Dump(主) ----->IO Thread (從) -----> SQL Thread(從)。其中IO Thread線程負責從主庫拿binlog並寫到relaylog,sql_thread 線程負責讀relaylog並執行。復制出現延遲一般出在兩個地方
a、SQL線程忙不過來(可能需要應用數據量較大,可能和從庫本身的一些操作有鎖和資源的沖突;)
雖然主庫可以並發寫,但Slave_SQL_Running線程不可以並發寫(主要原因)。
b、網絡抖動導致IO線程復制延遲(次要原因)。
(2) MySQL從5.6開始有了多線程的概念,可以並發還原數據,即並行復制技術。多線程的思路就是把sql_thread 變成分發線程,然后由一組worker_thread來負責執行。MySQL 5.6中,設置參數slave_parallel_workers = 4,即可有4個SQL Thread(coordinator線程)來進行並行復制,其狀態為:Waiting for an evant from Coordinator。但是其並行只是基於Schema的,也就是基於庫的。如果數據庫實例中存在多個Schema,這樣設置對於Slave復制的速度可以有比較大的提升。通常情況下單庫多表是更常見的一種情形,所以基於庫的並發一般是沒什么用的,不過其也有一定優勢:
對於可以按表分發的場景,可以通過將表遷到不同的庫,來應用此策略,有可操作性。
二、Mysql 5.7 的主從復制
(1)新版本增加了一種類型,變成了兩種類型
1、DATABASE 基於庫的並行復制 , 每個數據庫對應一個復制線程(5.6版本就有了,然並卵);
2、LOGICAL_CLOCK 基於組提交的並行復制方式,同一個數據庫下可以有多個線程(對大多數數據庫更實用)。
對於第二種類型,設置參數slave_parallel_workers>0並且global.slave_parallel_type=‘LOGICAL_CLOCK’,即可支持一個schema下,slave_parallel_workers中的worker線程並發執行relay log中主庫提交的事務。
(2)從MySQL官方文件看,其並行復制的要實現的目標是支持表級的並行復制和行級的並行復制,行級的並行復制通過解析ROW格式的二進制日志的方式來完成。
(3)5.7版本基於組提交的並行復制核心思想是:一個組提交的事務都是可以並行回放的,因為這些事務都已進入到事務的prepare階段,則說明事務之間沒有任何沖突(否則就不可能提交)。
三、具體的設置與操作
1、操作條件
主服務器:(1)系統:windows 7 (2)數據庫:MySQL 5.7.18
從服務器(虛擬機):(1)windows 7 (2)數據庫:mysql 5.7.18
2、主服務器配置
(1)在主服務器上建立需同步的數據庫 create database test; 並建立兩張表
CREATE TABLE `backup_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) CHARACTER SET utf8 NOT NULL,
`sex` varchar(2) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
CREATE TABLE `user` (
`User_ID` int(50) NOT NULL,
`User_Name` char(100) DEFAULT NULL,
PRIMARY KEY (`User_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
(2)對於windows系統,直接按鍵windows+R鍵彈出運行窗口,輸入地址C:\ProgramData\MySQL\MySQL Server 5.7,找到my.ini配置文件設置
<span style="font-size:18px;">[mysqld]
# 開啟log-bin日志
log-bin=mysql-bin
server-id=1
# 我這里要復制名為test的數據庫
binlog-do-db=test</span>
然后再找到參數或者添加參數設置如下(這兩個參數控制着二進制日志刷新的速度,先按下不表):
<span style="font-size:24px;">innodb_flush_log_at_trx_commit=1
sync_binlog=1</span>
(3)然后root用戶登錄數據庫,新建一個用戶並授權(我這里設置為testuser用戶,密碼也是testuser,IP找到主服務器的ip寫上)
<span style="font-size:18px;">CREATE USER 'testuser'@'192.168.0.%' IDENTIFIED BY 'testuser';
GRANT REPLICATION SLAVE ON *.* TO 'testuser'@'%';</span>
注釋:加了%則ip必須要用單引號括起來,%匹配任意。
(4)再開一個會話,連接mysql,執行 SHOW MASTER STATUS; 顯示如下,記住那個mysql-bin.000002和position的值
<span style="font-size:18px;">mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 412 | test | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)</span>
3、從服務器配置
(1)從服務器的server-id設置成2,且同樣要在目錄 C:\ProgramData\MySQL中找到my.ini文件打開進行設置 (ProgramData文件夾可能是隱藏的,直接輸入地址欄就能找到),后面的設置可直接寫在server-id后面,同樣是在該目錄下的my.ini中
server-id=2 #識別服務器的唯一值
replicate-do-db=test #要同步的數據庫
replicate-do-table=test.bakeup_table #要同步的表,改成自己的數據庫和表
replicate-do-table=test.user #要同步的第二個表
(2)在上面設置的參數之后緊隨下面的參數
<span style="font-size:18px;">skip-slave-start=true #跳過slave線程啟動
read_only=ON #開啟的只讀模式
relay-log=relay-bin
relay-log-index=relay-bin.index </span>
(3)配置尋找主服務器,然后啟動從服務器。先輸入start slave;然后執行如下命令:
CHANGE MASTER TO
MASTER_HOST='主服務器ip',
MASTER_USER='testuser', #新建的用戶
MASTER_PASSWORD='testuser', #我的用戶密碼
MASTER_LOG_FILE='mysql-bin.000002', #上圖查詢出的同步文件
MASTER_LOG_POS=412; #上圖查詢出的同步點(即:position下的值)
(4)接下來配置從服務器上並行復制的參數(開啟 Enhanced Multi-Threaded Slave)
A、master_info_repository
開啟MTS功能后,務必將參數master_info_repostitory設置為TABLE,這樣性能可以有50%~80%的提升。這是因為並 行復制開啟后對於元master.info這個文件的更新將會大幅提升,資源的競爭也會變大。在之前InnoSQL的版本中,添加了參數來控制刷新 master.info這個文件的頻率,甚至可以不刷新這個文件。因為刷新這個文件是沒有必要的,即根據master-info.log這個文件恢復本身就是不可靠的。在MySQL 5.7中,推薦將master_info_repository設置為TABLE,來減小這部分的開銷。
B、slave_parallel_workers
若將slave_parallel_workers設置為0,則MySQL 5.7退化為原單線程復制,但將slave_parallel_workers設置為1,則SQL線程功能轉化為coordinator線程,但是只有1 個worker線程進行回放,也是單線程復制。然而,這兩種性能卻又有一些的區別,因為多了一次coordinator線程的轉發,因此 slave_parallel_workers=1的性能反而比0還要差。
C、要開啟Enhanced Multi-Threaded Slave,只需要設置如下參數即可:
slave-parallel-type=LOGICAL_CLOCK
slave-parallel-workers=16 #16為設置的並發線程個數,之后根據項目對數據傳輸的具體要求再更改
#一個schema下,slave_parallel_workers中的worker線程並發執行relay log中主庫提交的事務
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log_recovery=ON
注:變量slave-parallel-type可以有兩個值
a、DATABASE 為默認值:基於庫的並行復制方式;
b、LOGICAL_CLOCK:基於組提交的並行復制方式
slave機器的relay log中 last_committed相同的事務(sequence_num不同)可以並發執行。
(5)最后保存my.ini並運行services.msc,重啟mysql服務。
(6)同樣,在從服務器上建立相同名的空數據庫test以及相同的表。
四、配置檢查及測試
1、啟動從服務器的mysql命令行界面
執行 start 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.193
Master_User: testuser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 412
Relay_Log_File: slave-relay-bin.000007
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes <<<--------------------------此處可以看到
Slave_SQL_Running: Yes <<<--------------------------這兩個線程都在運行
Replicate_Do_DB: test
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: 412
Relay_Log_Space: 951
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: ed1d6bc3-51a6-11e7-a527-083e8e9a4d6f
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more up
dates <<<<<<<<<<<<<<<<<<---------------------------此處可以看到這個線程正在等待接受數據
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:
1 row in set (0.00 sec)
2、執行命令show processlist;
查看一下正在執行等待接收數據的所有線程,結果如下:
所有線程都在等待接受數據,設置成功!
3、數據庫同步測試
接下來就可以在主數據庫中添加記錄了, 為方便添加數據,這里我選用navicat來添加數據
(1)在主數據庫中的兩個表中都添加數據,同時保存。
(2)然后在從數據庫中進行查找,結果如下:
至此,測試完成,配置成功!
參考文章:http://dinglin.iteye.com/blog/2272079
http://sky66.blog.51cto.com/2439074/1688047/
http://www.linuxidc.com/linux/2014-05/101450.htm——Linux公社
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝!
轉型人工智能 可以嗎?一個小測試就讓你知道怎么學
人工智能技術向前發展,也必然會出現一些崗位被人工智能取代,但我們相信,隨着人工智能的發展,會有更多的新的、屬於未來的工作崗位出現,是社會發展的必然產物,我們能做的也許只能是與時俱進了