mysql主從同步的意思為備份,主庫(Master)將自己庫中的寫入同時同步給自己的從庫(Slave),當主庫發生某些不可預知的狀況,導致整個伺服器無法使用時,由於從庫中也有一份資料,所以資料可以做到快速恢復,不造成或者減少造成資料的損失。
當master(主)庫的資料發生變化的時候,變化會實時的同步到slave(從)庫。
資料是一個應用至關重要的一部分。從目的出發,主從同步有那麼點備份的意思,主庫(Master)將自己庫中的寫入同時同步給自己的從庫(Slave),當主庫發生某些不可預知的狀況,導致整個伺服器無法使用時,由於從庫中也有一份資料,所以資料可以做到快速恢復,不造成或者減少造成資料的損失。
當然,這只是第一個層面,如果主從庫的作用僅限於此,那麼我個人認為沒有必要分為兩個資料庫,只需要定期將資料庫內容作為快照傳送到另一臺伺服器,或者每次寫入時將寫入內容實時傳送到另一臺伺服器不就好了嗎,這樣不但可以節約資源,也可以起到容災備份的目的。
當然主從同步的作用絕不可能僅限於此,一旦我們設定了主從結構,我們通常不會讓從節點僅僅只作為備份資料庫,我們應該還會相應地設定上讀寫分離(可以使用MyCat或者其它中介軟體,可以自己瞭解一下,關於MyCat我在下一篇部落格中會說這個,篇幅可能會有點長,所以就再寫一篇吧)。
在實際環境下,對於資料庫的讀運算元目遠大於對資料庫的寫操作,所以我們可以讓Master只提供寫的功能,然後將所有的讀操作都移到從庫,這就是我們平時常說的讀寫分離,這樣不但可以減輕Master的壓力,還可以做容災備份,一舉兩得。
水平擴充套件資料庫的負載能力。
容錯,高可用。Failover(失敗切換)/High Availability
資料備份。
說完了主從同步的概念,下面來說說主從同步的原理,其實原理也非常簡單,沒有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和中繼紀錄檔。
本次搭建主從同步的環境: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之後再來設定就更加簡單了,但是更希望不要只侷限於會設定,設定出來的東西只能說你會設定了,但是在這層設定底下是前人做了相當多的工作,才能使我們通過簡單設定就能實現一些功能,應該要深入底層,瞭解設定下面的工作原理,這個才是最重要的,也是體現一個程式設計師水平的地方。
推薦教學:
以上就是mysql主從同步是什麼的詳細內容,更多請關注TW511.COM其它相關文章!