什麼是MySQL主從複製
簡單來說,就是保證主SQL(Master)和從SQL(Slave)的資料是一致性的,向Master插入資料後,Slave會自動從Master把修改的資料同步過來(有一定的延遲),通過這種方式來保證資料的一致性,就是主從複製。
MySQL主從能解決什麼問題
一、高可用
因為資料都是相同的,所以當Master掛掉後,可以指定一臺Slave充當Master繼續保證服務執行,因為資料是一致性的(如果當插入Master就掛掉,可能不一致,因為同步也需要時間),當然這種配置不是簡單的把一臺Slave充當Master,畢竟還要考慮後續的Salve同步Master,當然本文並不是將高可用的配置,所以這裡就不多講了。
二、負載均衡
因為讀寫分離也算是負載均衡的一種,所以就不單獨寫了,因為一般都是有多臺Slave的,所以可以將讀操作指定到Slave伺服器上(需要程式碼控制),然後再用負載均衡來選擇那臺Slave來提供服務,同時也可以吧一些大量計算的查詢指定到某臺Slave,這樣就不會影響Master的寫入以及其他查詢
三、資料備份
一般我們都會做資料備份,可能是寫定時任務,一些特殊行業可能還需要手動備份,有些行業要求備份和原資料不能在同一個地方,所以主從就能很好的解決這個問題,不僅備份及時,而且還可以多地備份,保證資料的安全
四、業務模組化
可以一個業務模組讀取一個Slave,再針對不同的業務場景進行資料庫的索引建立和根據業務選擇MySQL儲存引擎
五、高擴充套件(硬體擴充套件)
主從複製支援2種擴充套件方式
1、scale-up
向上擴充套件或者縱向擴充套件,主要是提供比現在伺服器更好效能的伺服器,比如增加CPU和記憶體以及磁碟陣列等,因為有多臺伺服器,所以可擴充套件性比單臺更大
2、scale-out
向外擴充套件或者橫向擴充套件,是指增加伺服器數量的擴充套件,這樣主要能分散各個伺服器的壓力
主從複製的缺點
一、成本增加
無可厚非的是搭建主從肯定會增加成本,畢竟一臺伺服器和兩臺伺服器的成本完全不同,另外由於主從必須要開啟二進位制日誌,所以也會造成額外的效能消耗
二、資料延遲
Slave從Master複製過來肯定是會有一定的資料延遲的,所以當剛插入就出現查詢的情況,可能查詢不出來,當然如果是插入者自己查詢,那麼可以直接從Master中查詢出來,當然這個也是需要用程式碼來控制的
三、寫入更慢
主從複製主要是針對讀遠大於寫或者對資料備份實時性要求較高的系統中,因為Master在寫中需要更多操作,而且只有一臺寫入的Master(因為我目前只會配置一臺寫入Master,最多就是有從Master的Slave,用來在Master掛掉後替換成Master,平時不對外進行服務),所以寫入的壓力並不能被分散,當然如果直接怎麼解決這個問題的話,歡迎留言指教
複製方式
MySQL5.6開始主從複製有兩種方式:基於日誌(binlog)、基於GTID(全域性事務標示符)。
本文只涉及基於日誌binlog的主從配置
複製原理
1、Master將資料改變記錄到二進位制日誌(binary log)中,也就是配置檔案log-bin指定的檔案,這些記錄叫做二進位制日誌事件(binary log events)
2、Slave通過I/O執行緒讀取Master中的binary log events並寫入到它的中繼日誌(relay log)
3、Slave重做中繼日誌中的事件,把中繼日誌中的事件資訊一條一條的在本地執行一次,完成資料在本地的儲存,從而實現將改變反映到它自己的資料(資料重放)
要求
1、主從伺服器作業系統版本和位數一致
2、Master和Slave資料庫的版本要一致
3、Master和Slave資料庫中的資料要一致
4、Master開啟二進位制日誌,Master和Slave的server_id在區域網內必須唯一
具體配置
硬體需求
兩臺或兩臺以上安裝了相同版本的MySQL(我沒有試過不同版本會不會有問題,有興趣的可以試試),當然這個可以用虛擬機器或者Docker代替,個人推薦用Docker,比虛擬機器消耗少太多了,當然用起來可能沒有虛擬機器那麼方便,但是卻不用挨個環境配置了
配置Master
一、安裝資料庫
二、配置my.cnf
不同的系統my.cnf路徑不同,所以我們只講解牽扯修改的地方。新增配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[mysqld] ## 設定server_id,一般設定為IP,注意要唯一 server_id=100 ## 複製過濾:也就是指定哪個資料庫不用同步(mysql庫一般不同步) binlog-ignore-db=mysql ## 開啟二進位制日誌功能,可以隨便取,最好有含義(關鍵就是這裡了) log-bin=edu-mysql-bin ## 為每個session 分配的記憶體,在事務過程中用來儲存二進位制日誌的快取 binlog_cache_size=1M ## 主從複製的格式(mixed,statement,row,預設格式是statement) binlog_format=mixed ## 二進位制日誌自動刪除/過期的天數。預設值為0,表示不自動刪除。 expire_logs_days=7 ## 跳過主從複製中遇到的所有錯誤或指定型別的錯誤,避免slave端複製中斷。 ## 如:1062錯誤是指一些主鍵重複,1032錯誤是因為主從資料庫資料不一致 slave_skip_errors=1062 |
配置完成後重啟mysql
關於複製過濾
複製過濾可以讓你只複製伺服器中的一部分資料,有兩種複製過濾:
1、在Master上過濾二進位制日誌中的事件
2、在Slave上過濾中繼日誌中的事件。
複製型別
1、基於語句的複製
在Master上執行的SQL語句,在Slave上執行同樣的語句。MySQL預設採用基於語句的複製,效率比較高。一旦發現沒法精確複製時,會自動選著基於行的複製
2、基於行的複製
把改變的內容複製到Slave,而不是把命令在Slave上執行一遍。從MySQL5.0開始支援
3、混合型別的複製
預設採用基於語句的複製,一旦發現基於語句的無法精確的複製時,就會採用基於行的複製
三、建立資料同步使用者
1 2 3 |
CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%'; |
這裡主要是要授予使用者REPLICATION SLAVE許可權和REPLICATION CLIENT許可權
配置Slave
一、安裝資料庫
二、配置my.cnf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[mysqld] ## 設定server_id,一般設定為IP,注意要唯一 server_id=101 ## 複製過濾:也就是指定哪個資料庫不用同步(mysql庫一般不同步) binlog-ignore-db=mysql ## 開啟二進位制日誌功能,以備Slave作為其它Slave的Master時使用 log-bin=edu-mysql-slave1-bin ## 為每個session 分配的記憶體,在事務過程中用來儲存二進位制日誌的快取 binlog_cache_size=1M ## 主從複製的格式(mixed,statement,row,預設格式是statement) binlog_format=mixed ## 二進位制日誌自動刪除/過期的天數。預設值為0,表示不自動刪除。 expire_logs_days=7 ## 跳過主從複製中遇到的所有錯誤或指定型別的錯誤,避免slave端複製中斷。 ## 如:1062錯誤是指一些主鍵重複,1032錯誤是因為主從資料庫資料不一致 slave_skip_errors=1062 ## relay_log配置中繼日誌 relay_log=edu-mysql-relay-bin ## log_slave_updates表示slave將複製事件寫進自己的二進位制日誌 log_slave_updates=1 ## 防止改變資料(除了特殊的執行緒) read_only=1 |
如果Slave為其它Slave的Master時,必須設定bin_log。配置完成後重啟mysql
完成Master和Slave連結
一、初始化資料
保證Master和Slave除不同步的資料庫,其他庫的資料一致
二、查詢Master狀態
在Master中執行
1 |
show master status; |
記錄下返回結果的File列和Position列的值
三、Slave中設定Master資訊
在Slave中執行
1 |
change master to master_host='192.168.1.100', master_user='slave', master_password='123456', master_port=3306, master_log_file='edu-mysql-bin.000001', master_log_pos=1389, master_connect_retry=30; |
上面執行的命令的解釋:
master_host=’192.168.1.100′ ## Master的IP地址
master_user=’slave’ ## 用於同步資料的使用者(在Master中授權的使用者)
master_password=’123456′ ## 同步資料使用者的密碼
master_port=3306 ## Master資料庫服務的埠
masterlogfile=’edu-mysql-bin.000001′ ##指定Slave從哪個日誌檔案開始讀複製資料(Master上執行命令的結果的File欄位)
masterlogpos=429 ## 從哪個POSITION號開始讀(Master上執行命令的結果的Position欄位)
masterconnectretry=30 ##當重新建立主從連線時,如果連線建立失敗,間隔多久後重試。單位為秒,預設設定為60秒,同步延遲調優引數。
四、檢視主從同步狀態
在Slave中執行命令
1 |
show slave status; |
可看到SlaveIOState為空, SlaveIORunning和SlaveSQLRunning是No,表明Slave還沒有開始複製過程。相反SlaveIORunning和SlaveSQLRunning是Yes表明已經開始工作了
五、開啟主從同步
在Slave中執行命令
1 |
start slave; |
查詢檢視主從同步狀態,會發現SlaveIORunning和SlaveSQLRunning是Yes了,表明開啟成功