在大部分場景中我們都是用MySQL主從復制來實現數據庫的冗余,這裡是用多級復制來處理,多級復制可以快速簡單的處理數據庫的故障,數據庫有A、B、C服務器,正常情況下A為主、B為A的從、C為B的從。
A-->B-->C
當A出現問題時,將B設為主,C為B的從,A正常後就為C的從
B-->C-->A
當B出問題後,C為主,A為C的從,B為A的從,如此反復可以快速解決問題
角色 IP 主機名 數據庫版本 主 192.168.2.241 db1 5.6.29 備 192.168.2.242 db2 5.6.29 備 192.168.2.243 db3 5.6.29注意在這樣的場景下數據庫的版本必須為一致,否則會因為版本之間不兼容導致出現問題
創建復制賬戶
配置數據庫配置
備份主庫,然後導入到備庫
配置主從
1.創建復制賬戶
mysql>grantrepicationslaveon*.*to'repl'@'192.168.2.%'identifiedby'repl'; mysql>flushprivileges;
2.開啟數據庫binlog,設置server-id和啟用log_slave_updates
說明:log_slave_updates是將從服務器從主服務器收到的更新記入到從服務器自己的二進制日志文件中
如果沒有開啟log_slave_updates則在A-->B-->C場景中,C將無法從B中獲取到數據
在MySQL配置文件/etc/my.cnf中的[mysqld]下添加如下語句
log-bin=mysqlbin server-id=241#這裡每台服務器都必須不一致,最好是IP的末段 log_slave_updates=1 expire_logs_days=7
記得重啟下數據庫
3.備份主庫,然後導入到備庫中
鎖表
mysql>flushtableswithreadlock; mysql>showmasterstatus; +---------------+----------+--------------+------------------+-------------------+ |File|Position|Binlog_Do_DB|Binlog_Ignore_DB|Executed_Gtid_Set| +---------------+----------+--------------+------------------+-------------------+ |binlog.000002|409|||| +---------------+----------+--------------+------------------+-------------------+ 1rowinset(0.00sec)
注意:這裡不能退出mysql命令行會話,另外再開一個窗口將數據庫導出,因為鎖表的時候,只要退出會話鎖表自動解除
[[email protected]~]#mysqldump-uroot-p--all-database--add-drop-table>all_database.sql
將上面導出的all_database.sql導入到其他的db2、db3中
[[email protected]~]#mysql-uroot-p[[email protected]~]#mysql-uroot-p<all_database.sql< pre=""><p>4.開啟主從復制</p><p>在db2上:</p><pre class="brush:sql;toolbar:false">mysql>changemastertomaster_host='192.168.2.241',master_user='repl',master_password='repl',master_log_file='binlog.000002',master_log_pos=409; mysql>startslave; mysql>showmasterstatus; +---------------+----------+--------------+------------------+-------------------+ |File|Position|Binlog_Do_DB|Binlog_Ignore_DB|Executed_Gtid_Set| +---------------+----------+--------------+------------------+-------------------+ |binlog.000002|647569|||| +---------------+----------+--------------+------------------+-------------------+</pre><p>在db3上:</p><pre class="brush:sql;toolbar:false">mysql>changemastertomaster_host='192.168.2.242',master_user='repl',master_password='repl',master_log_file='binlog.000002',master_log_pos=647569; mysql>startslave;</pre><p>然後分別在db2和db3上執行show slave status\G;查看是否有錯</p><pre class="brush:sql;toolbar:false">mysql>showslavestatus\G; ***************************1.row*************************** Slave_IO_State:Waitingformastertosendevent Master_Host:192.168.2.242 Master_User:repl Master_Port:3306 Connect_Retry:60 Master_Log_File:binlog.000002 Read_Master_Log_Pos:647569 Relay_Log_File:db3-relay-bin.000002 Relay_Log_Pos:280 Relay_Master_Log_File:binlog.000002 Slave_IO_Running:Yes Slave_SQL_Running:Yes Replicate_Do_DB: 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:647569 Relay_Log_Space:451 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:242 Master_UUID:25a2315a-d9f0-11e5-9aa9-000c296e3855 Master_Info_File:/var/lib/mysql/master.info SQL_Delay:0 SQL_Remaining_Delay:NULL Slave_SQL_Running_State:Slavehasreadallrelaylog;waitingfortheslaveI/Othreadtoupdateit 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 1rowinset(0.00sec)</pre><p>可以看到</p><p>Slave_IO_Running: Yes</p><p>Slave_SQL_Running: Yes</p><p>為yes,說明復制正常</p><p> </p><p>接著測試一下:</p><p>在數據庫中插入數據,然後在db1、db2、db3上查詢即可</p><p> </p><p>如有問題可以show slave status\G;查看是否有錯誤</p><p>如果遇到類似1062的錯誤的話可以忽略,則可以直接</p><pre class="brush:sql;toolbar:false">mysql>stopslave; mysql>SETGLOBALSQL_SLAVE_SKIP_COUNTER=1; mysql>startslave;</pre><p>在運行一段時間後,db1出現問題,導致無法恢復的故障,則只需要在db2上執行stop slave;</p><p>然後db1恢復後,從db3導出數據並記錄點,然後change master到db3上</p><p>如果為了防止在從庫意外寫入,也可以在從數據庫的配置文件中加入read_only = 1</p><p> </p><p> </p><p> </p><p> </p></all_database.sql<>