(一、主從復制)
一、mysql主從復制原理
mysql的默認復制方式是主從復制。Mysql內建的復制功能是構建大型,高性能應用程序的基礎。將Mysql的數據分布到多個系統上去,這種分布的機制,是通過將Mysql的某一台主機的數據復制到其它主機(slaves)上,並重新執行一遍來實現的。復制過程中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。主服務器將更新寫入二進制日志文件,並維護文件的一個索引以跟蹤日志循環。這些日志可以記錄發送到從服務器的更新。當一個從服務器連接主服務器時,它通知主服務器從服務器在日志中讀取的最后一次成功更新的位置。從服務器接收從那時起發生的任何更新,然后封鎖並等待主服務器通知新的更新。
注意:進行復制的時候,對復制的表的更新操作必須在master中完成。若是對從服務器上的表進行更新,將會導致主從服務器的數據庫數據不一致,繼而產生沖突。
二、mysql支持復制的類型
1)基於語句的復制:在主服務器中執行的語句,在從服務器中再執行一遍。(默認為基於語句的復制)
2)基於行復制:把改變的內容復制過去,而不是在從服務器上再執行一遍主服務器上的命令。(從mysql5.0后開始支持)
3)混合型的復制:默認采用語句復制,若發現語句不能精准定位,則會執行行的復制。
三、復制的具體步驟
1)首先master將改變記錄到二進制日志(binary log)中。
2)slave中的IO線程將master中的日至信息拷貝到中繼日志(relay log)。
3)slave中的sql線程將中繼日至的記錄再執行一遍。(這樣就達到了mysql的復制)
第一個過程中,master在每個事務(操作)完成數據更新之后,把這些改變記錄到二進制日志中。MySQL將事務串行的寫入二進制日志,即使事務中的語句都是交叉執行的。在事件寫入二進制日志完成后,master通知存儲引擎提交事務。
在slave將master的binary log拷貝到它自己的中繼日志過程中,首先,slave開始一個工作線程——I/O線程。I/O線程在master上打開一個普通的連接,然后開始binlog dump process。Binlog dump process從master的二進制日志中讀取事件,如果已經跟上master,它會睡眠並等待master產生新的事件。I/O線程將這些事件寫入中繼日志。
SQL slave thread(SQL從線程)處理該過程的最后一步。SQL線程從中繼日志讀取事件,並重放其中的事件而更新slave的數據,使其與master中的數 據一致。只要該線程與I/O線程保持一致,中繼日志通常會位於OS的緩存中,所以中繼日志的開銷很小。
此外,在master中也有一個工作線程:和其它 MySQL的連接一樣,slave在master中打開一個連接也會使得master開始一個線程。復制過程有一個很重要的限制——復制在slave上是 串行化的,也就是說master上的並行更新操作不能在slave上並行操作。
四、操作步驟
環境:rhel6.5 Server2:master Server3:slave
1)在server2上安裝mysql服務,作為master。
---> yum install -y mysql-community-client-5.7.17-1.el6.x86_64.rpm
mysql-community-common-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-compat-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-5.7.17-1.el6.x86_64.rpm
mysql-community-server-5.7.17-1.el6.x86_64.rpm
---> vim /etc/my.cnf # 添加如下(服務器id和二進制文件)
---> /etc/init.d/mysqld start # 打開數據庫(得等一會)
---> grep password /var/log/mysqld.log # 在日志中查看生成的隨機密碼
---> mysql_secure_installation # 進行數據庫初始化
# 此處填寫上面生成的隨機密碼
# 填寫自己設置的密碼。格式必須要注意:由大小寫字母、數字、特殊字符組成。例如:Xniu+123
---> mysql -p # 進行密碼登陸(並查看數據庫,如下表示安裝成功)
mysql > grant replication slave on *.* To repl@’172.25.2.%’ identified by ‘Xniu-123’;
mysql > flush privileges;
2)在srver3檢查授權是否成功;並進行mysql的安裝,作為slave。
---> mysql -u xniu -p -h 172.25.2.2 # 查看授權是否成功
---> vim /etc/my.cnf # 在最后一行給slave設置id
Server-id=2
# 接下來啟動mysql服務,設置密碼server2中步驟相同。
---> /etc/init.d/mysqld start
---> grep password /var/log/mysqld.log
---> mysql_secure_installation
---> mysql -p # 此時server3也可登陸成功
3)在srever2中查看master的狀態
---> show master status;
4)在server3中給建立slave並查看狀態
mysql> change master to master_host='172.25.2.2',master_user='repl',master_password='Xniu+123', master_log_file='mysql-bin.000003',master_log_pos=842; # 在slave中添加master主機的信息(注意,此處的master_log_file和master_log_pos要和master中的一致)
mysql> start slave;
mysql> show slave status\G; # 此時當io和sql狀態均為yes的時候,表示正常
5)測試。當我們在master中進行數據庫和表的建立,此時slave中可以查看到master中建立的信息。
# 在server2中建立數據庫xniu;
# 在server3中查看:
(二、基於GTID的主從復制)
一、什么是GTID
全稱Global transaction identifiers;包含兩部分,一部分為服務的UUid(保存在mysql數據目錄的auto.cnf文件中); 另一部分為事物ID。在整個復制架構中,GTID是不會變化的,即是在多個連環主從中也不會變。
二、GTID的工作原理
1、master更新數據時,會在事務前產生GTID,一同記錄到binlog日志中。
2、slave端的i/o 線程將變更的binlog,寫入到本地的relay log中。
3、sql線程從relay log中獲取GTID,然后對比slave端的binlog是否有記錄。
4、如果有記錄,說明該GTID的事務已經執行,slave會忽略。
5、如果沒有記錄,slave就會從relay log中執行該GTID的事務,並記錄到binlog。
6、在解析過程中會判斷是否有主鍵,如果有就用二級索引,如果沒有就用全部掃描。
注意:與mysql5.7默認的主從復制不同之處在與,從服務器在中繼日志中執行語句的時候,只需要根據uuid來判斷新的變更信息,從而執行;不需挨個進行查找。
三、環境搭建
在主從同步的基礎上進行添加GTID的模塊,具體步驟如下:(注意,當配置文件修改之后)
1)在master中修改配置文件
---> vim /etc/my.cnf # 開啟gtid模式
---> /etc/init.d/mysqld restart
# 登陸mysql之后,修改root用戶密碼,並授權復制用戶
2)在slave中進行如下配置
---> vim /etc/my.cnf
---> /etc/init.d/mysqld restart
3)在server3中,登陸mysql並修改master相關信息
mysql> stop salve;
mysql> change master to master_host=’172.25.2.2’,master_user=’repl’,master_password=’Xniu+123’,
MASTER_AUTO_POSITION=1;
mysql> start slave;
mysql> show slave status\G;
3)測試時,我們在master中對之前建立的數據庫進行修改,在slave中可以看到已經修改的數據庫。此時,達到了主從復制的效果。
# 在master中對對創建的數據庫插入信息
# 在server3中進行查看
(三、基於GTID的並行復制)
一、什么是並行復制
由於master是多線程的,而slave是單線程的,所以在復制的時候,會出現讀取和執行速度不一致。此時,我們可以通過設置sql線程的個數來實現,進行線程的優化;當master中把數據庫的更改寫入二進制文件中,並通知slave來進行讀取;然后slave的io進程把讀取到的數據存儲在中繼日志中;最后slave的多個線程對中繼日志進行回放並執行命令,從而達到了並行復制。
二、環境搭建
1)在GTID的基礎上,對slave中配置文件進行。
---> vim /etc/my.conf # 如下圖所示,添加16個worker線程。
注意:若將slave_parallel_workers設置為0,則MySQL 5.7退化為原單線程復制,但將slave_parallel_workers設置為1,則SQL線程功能轉化為coordinator線程,但是只有1個worker線程進行回放,也是單線程復制。然而,這兩種性能卻又有一些的區別,因為多了一次coordinator線程的轉發,因此slave_parallel_workers=1的性能反而比0還要差。開啟MTS功能后,務必將參數master_info_repostitory設置為TABLE,這樣性能可以有50%~80%的提升。這是因為並行復制開啟后對於元master.info這個文件的更新將會大幅提升,資源的競爭也會變大。在之前InnoSQL的版本中,添加了參數來控制刷新master.info這個文件的頻率,甚至可以不刷新這個文件。因為刷新這個文件是沒有必要的,即根據master-info.log這個文件恢復本身就是不可靠的。在MySQL 5.7中,Inside君推薦將master_info_repository設置為TABLE,來減小這部分的開銷。
2)查看slave中sql線程數
mysql > show processlist; # 此時會產稱16個sql線程。(只截取部分)
(四、GTID一主多從的復制)
一、環境搭建
server2 master A
server3 slave、master B
server4 slave C
當有多台從服務器時,向如:A --> B --> C,A是B的master,B是C的master。此時,B既是master又是slave。在上述配置的基礎上,再多加一台server4作為slave。
1)server4中配置文件內容如下:(首先安裝mysql,再這就不多加闡述了)
---> vim /etc/my.conf
---> /etc/init.d/mysqld start # 啟動mysql服務
2)設置server3的配置文件,並進行用戶授權。
---> vim /etc/my.cnf
---> /etc/init.d/mysqld restart
---> mysql -p
mysql> grant replication slave on *.* to repl@'172.25.2.%' identified by 'Xniu+123';
3)完成之后,我們要進行數據庫的復制。在server2中進行數據備份。
---> mysqldump -p xniu > xniu.sql
---> scp xniu.sql server4:/root/
4)在server4中對xniu.sql進行修改。
---> vim /root/xniu.sql #在drop語句上面添加兩條語句。
create database xniu;
user xniu;
---> msyql -p < xniu.sql # 把xniu.sql拷貝到mysql中
5)server4中進行數據庫的登陸。在mysql中添加master信息(此時master設置為B)。
mysql> stop slave;
mysql> change master to master_host='172.25.2.3',master_user='repl',master_password='Xniu+123',master_auto_position=1;
mysql> start slave;
mysql> show slave status\G; # 此時狀態都是可以的
6)此時可以進行測試。在server2中插入數據,在server3和server4中均可以看到。
