什麼是mysql主從同步

什麼是MySQL主從同步

數據是一個應用至關重要的一部分。從目的出發,主從同步有那麼點備份的意思,主庫(Master)將自己庫中的寫入同時同步給自己的從庫(Slave),當主庫發生某些不可預知的狀況,導致整個服務器無法使用時,由於從庫中也有一份數據,所以數據可以做到快速恢復,不造成或者減少造成數據的損失。

當然,這只是第一個層面,如果主從庫的作用僅限於此,那麼我個人認爲沒有必要分爲兩個數據庫,只需要定期將數據庫內容作爲快照發送到另一臺服務器,或者每次寫入時將寫入內容實時發送到另一臺服務器不就好了嗎,這樣不但可以節約資源,也可以起到容災備份的目的。

當然主從同步的作用絕不可能僅限於此,一旦我們配置了主從結構,我們通常不會讓從節點僅僅只作爲備份數據庫,我們應該還會相應地配置上讀寫分離(可以使用MyCat或者其它中間件,可以自己瞭解一下,關於MyCat我在下一篇博客中會說這個,篇幅可能會有點長,所以就再寫一篇吧)。

在實際環境下,對於數據庫的讀操作數目遠大於對數據庫的寫操作,所以我們可以讓Master只提供寫的功能,然後將所有的讀操作都移到從庫,這就是我們平時常說的讀寫分離,這樣不但可以減輕Master的壓力,還可以做容災備份,一舉兩得

MySQL主從同步的原理

說完了主從同步的概念,下面來說說主從同步的原理,其實原理也非常簡單,沒有Redis集羣那麼多的概念。

實際上當我們在MySQL中配置了主從之後,只要我們對Master節點進行了寫操作,這個操作將會被保存到MySQL的binary-log(bin-log)日誌當中,當slave連接到master的時候,master機器會爲slave開啓binlog dump線程。當master 的 binlog發生變化的時候,Master的dump線程會通知slave,並將相應的binlog內容發送給Slave。而Slave節點在主從同步開啓的時候,會創建兩個線程,一個I/O線程,一個SQL線程,這在我們後面的搭建中可以親眼看到。

  • I/0線程:該線程鏈接到master機器,master機器的binlog發送到slave的時候,IO線程會將該日誌內容寫在本地的中繼日誌(Relay log)中。

  • SQL線程:該線程讀取中繼日誌中的內容,並且根據中繼日誌中的內容對Slave數據庫做相應的操作。

  • 可能造成的問題:在寫請求相當多的情況下,可能會造成Slave數據和Master數據不一致的情況,這是因爲日誌傳輸過程中的短暫延遲、或者寫命令較多,系統速度不匹配造成的。

這大致就是MySQL主從同步的原理,真正在其中起到作用的實際上就是這兩個日誌文件,binlog和中繼日誌。

手動搭建MySQL主從同步

環境準備

本次搭建主從同步的環境:CentOS 7 ,MySQL 8.0.18(使用二進制包安裝)。

場景介紹

本次將會搭建MySQL的主從同步,其中一臺Master,兩臺Slave。

Master:IP :192.168.43.201 Port:3306
Slave1:IP:192.168.43.202 Port:3306
Slave2:IP:192.168.43.203 Port:3306

開始搭建

修改配置文件

當我們安裝好MySQL之後,在/etc/目錄下會有一個my.cnf文件,打開文件,加入如下內容(別忘了修改之前做好備份):

x

#該配置爲Master的配置
server-id=201 #Server id 每臺MySQL的必須不同
log-bin=/var/lib/mysql/mysql-bin.log #代表開啓binlog日誌
expire_logs_days=10 #日誌過期時間
max_binlog_size=200M #日誌最大容量
binlog_ignore_db=mysql #忽略mysql庫,表示不同步此庫

y

#該配置爲Slave的配置,第二臺Slave也是這麼配置,不過要修改一下server-id
server-id=202
expire_logs_days=10 #日誌的緩存時間
max_binlog_size=200M #日誌的最大大小
replicate_ignore_db=mysql #忽略同步的數據庫

新增Slave用戶

打開Master節點的客戶端 ,mysql -u root -p 密碼

創建用戶 create user 'Slave'@'%' identified by '123456';

給新創建的用戶賦權:grant replication slave on '*.*' to 'Slave'@'%';

查看Master節點狀態

以上操作都沒有問題後,我們在客戶端中輸入show master status查看master的binlog日誌。

配置兩個Slave節點

打開兩個Slave節點客戶端,在我們的另外兩個Slave節點中輸入如下命令:

change master to master_user='Slave',master_password='123456',master_host='192.168.43.201',master_log_file='mysql-bin.000005',master_log_pos=155,get_master_public_key=1;
#注意,這裏的master_log_file,就是binlog的文件名,輸入上圖中的mysql-bin.000005,每個人的都可能不一樣。
#注意,這裏的master_log_pos是binlog偏移量,輸入上圖中的155,每個人的都可能不一樣。

配置完成後,輸入start slave;開啓從節點,然後輸入show slave status\G;查看從節點狀態

可以看到,在兩臺Slave的狀態中,我們能親眼看到IO線程和SQL線程的運行狀態,這兩個線程必須都是yes,纔算配置搭建完成。

搭建完成

通過上述步驟,就完成了MySQL主從同步的搭建,相對Redis而言MySQL配置相當簡單。下面我們可以進行測試。

先看看三個MySQL的數據庫狀態:SHOW DATABASES;

可以看到現在數據庫都是初始默認狀態,沒有任何額外的庫。

在Master節點中創建一個數據庫,庫名可以自己設置。

CREATE DATABASE testcluster;

可以看到,在Slave中也出現了Master中創建的數據庫,說明我們的配置沒有問題,主從搭建成功。這裏就不再創建表了,大家可以自己試試,創建表再往表中插入數據,也是沒有任何問題的。

注意事項

如果出現IO線程一直在Connecting狀態,可以看看是不是三臺機器無法相互連接,如果可以相互連接,那麼有可能是Slave賬號密碼寫錯了,重新關閉Slave然後輸入上面的配置命令再打開Slave即可。

如果出現SQL線程爲NO狀態,那麼有可能是從數據庫和主數據庫的數據不一致造成的,或者事務回滾,如果是後者,先關閉Slave,然後先查看master的binlog和position,然後輸入配置命令,再輸入set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;,再重新start slave;即可,如通過是前者,那麼就排查一下是不是存在哪張表沒有被同步,是否存在主庫存在而從庫不存在的表,自己同步一下再重新配置一遍即可。

結語

在寫這篇文章之前自己也被一些計算機領域的“名詞”嚇到過,相信有不少同學都有一樣的體會,碰上某些高大上的名詞總是先被嚇到,例如像“分佈式”、“集羣”等等等等,甚至在沒接觸過nginx之前,連”負載均衡“、”反向代理“這樣的詞都讓人覺得,這麼高達上的詞,肯定很難吧,但其實自己瞭解了nginx、ribbon等之後才發現,其實也就那麼回事吧,沒有想象中的那麼難。

所以寫這篇文章的初衷是想讓大家對集羣化或者分佈式或者其他的一些技術或者解決方案不要有一種望而卻步的感覺(感覺計算機領域的詞都有這麼一種特點,詞彙高大上,但是其實思想是比較好理解的),其實自己手動配置出一個簡單的集羣並沒有那麼難。

如果學會docker之後再來配置就更加簡單了,但是更希望不要只侷限於會配置,配置出來的東西只能說你會配置了,但是在這層配置底下是前人做了相當多的工作,才能使我們通過簡單配置就能實現一些功能,應該要深入底層,瞭解配置下面的工作原理,這個纔是最重要的,也是體現一個程序員水平的地方。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章