mysql主主複製

說到主主複製我們必須首選對主從複製原理有極深的瞭解,否則主主複製很難掌握其內在原理

主從複製原理:mysql主從複製中其實就一個主在工作,而從主機就相當於一個備份機器,從主機通過日誌監測的方式來備份主上數據庫的數據而保證主庫的數據安全。在這種架構中如果從主機上的數據做了改變,主數據是不會用任何變化的。因爲mysql主從架構主要是mysql從主機監控mysql主的日誌變化來實現同步,相反的在這個架構中主並沒有監控從的日誌變化。所以,mysql從數據反生變化,主mysql數據沒有發生任變化。

通過上述描述,可以看到如果想實現主主複製,無非就是在mysql主從架構上讓mysql主實現監測從的日誌變化,從而實現兩臺機器相互同步。

主主複製概念
所謂雙主備份,其實也就是互做主從複製,每臺master既是master,又是另一臺服務器的slave。這樣,任何一方所做的變更,都會通過複製應用到另外一方的數據庫中。。

使用場景/解決問題
可以做災備,其中一個壞了可以通過keepalived輔助軟件自動切換到另外一臺服務器。
可以做負載均衡,可以將請求分攤到其中任何一臺上,提高網站吞吐量。

msyql主主複製工作原理圖

配置要求:
1.需要服務器兩臺A,B
2.服務器上安裝最好是相同版本的mysql數據庫(建議)
3.必須保證數據庫的結構和數據是完全一致,server-id 是不相同

安裝步驟
[假定A服務器的ip爲10.1.1.7] A作爲主(master)
[假定B服務器的ip爲10.1.1.8] B作爲主(master)
注意事項

在做主主同步之前必須保證兩臺服務器上的數據是完全相同的

【開始部署】

  1. 同步數據:以A庫的數據爲準,同步A B數據,使AB數據保持一致。

一,手動備份數據庫保證二者數據庫是一致的

1.登陸A服務器數據庫->選定數據庫->鎖定數據庫->導出數據庫

以下操作的目的:
對A庫加鎖:
避免同步時數據發生改變, 關閉所有打開的表,同時對於所有數據庫中的表都加一個讀鎖,直到顯示地執行unlock tables,該操作常常用於數據備份的時候。也就是將所有的髒頁都要刷新到磁盤,然後對所有的表加上了讀鎖,於是這時候直接拷貝數據文件也就是安全的。爲此庫下的所有表施加讀鎖,退出會話後失效,所謂讀鎖,也就是隻能讀,不能寫。

2.登陸B服務器數據庫->創建數據庫->導入數據庫文件

[root@10-1-1-8 ~]# mysql -uroot -p10isp.com #登陸數據庫
mysql> create database demo; #創建數據庫demo
mysql> exit;
在shell中通過mysql命令導入數據庫文件
[root@10-1-1-8 ~]# mysql -u root-p demo<demo.sql ; #導入數據庫demo

二,以A爲主,B爲從
A)
1.開啓二進制文件 vim /etc/my.cnf 或者 vim /usr/my.cnf (在[mysqld]下添加:)

server-id=1 #指定master主機的id,不可爲0,否則拒絕所有slave連接。
log-bin=mysql_bin #指定bin-log文件前綴名稱,開啓binlog日誌
binlog_do_db=database_name #指定binlog日誌是記錄的是哪個庫
replicate-do-db=database_name #指定複製哪一個庫
auto-increment-increment = 2 #每次增長2
auto-increment-offset = 1 #設置自動增長的字段的偏移量,即初始值爲1
log_bin_trust_function_creators=1 #詳解如下方
expire_logs_days = 10 #保留10天的bin_log日誌,防止日誌太多佔用磁盤空間
max_binlog_size = 100M #限制每個bin_log日誌大小最大爲100M。
log-slave-updates=1 #slave執行master的sql後,將sql記錄在binlog日誌中(默認是不記錄的)——實際生產我沒開啓這條
max_connections=600 #指定最大連接數
wait_timeout=5 #等待超時

2.master中創建一個僅用於主從複製的賬號,給與REPLICATION SLAVE權限。此權限僅允許slave訪問Master的bin-log日誌。

mysql>grant replication slave on *.* to 'user_a'@'10.1.1.8' identified by 'wanjianning' with grant option;

3.重啓服務器

[root@10-1-1-7 ~]# service mysqld restart;

4.查詢Amaster服務狀態

mysql> show master status\G;

查詢結果如下:

*************************** 1. row ***************************
File: mysql-bin.000004
Position: 438
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)

ERROR:
No query specified

5.解鎖

mysql>unlock tables;

B)
1.修改B從的的配置文件 vim my.cnf

[mysqld]
server-id=2
auto-increment-increment = 2 //每次增長2
auto-increment-offset = 2 //設置自動增長的字段的偏移量,即初始值爲2
注:二都只有server_id不同和 auto-increment- offset不同
auto-increment-increment的值應設爲整個結構中服務器的總數,本案例用到兩臺服務器,所以值設2。

2.重啓數據庫服務器

[root@10-1-1-8 ~]# service mysqld restart;

3.配置連接master的相關信息配置。在slave中指定master相關參數。

mysql>change master to master_host='10.1.1.7',master_user='user_a',master_port=3306,master_password='wanjianning',master_log_file='mysql-bin.000004', master_log_pos=438;

解釋:
連接master的配置信息在命令行中配置好後,默認存在/var/lib/mysql/master.info文件,可以使用show master status\G;命令查看,所有就算重啓也不用擔心連接master的配置丟失。

4.開啓slave

mysql>start slave

5.查詢slave 狀態

mysql>show slave status\G;

查詢結果如下:

mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.1.1.7
Master_User: user_a
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 438
Relay_Log_File: localhost-relay-bin.000003
Relay_Log_Pos: 604
Relay_Master_Log_File: mysql-bin.000004
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: 438
Relay_Log_Space: 815
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: 1
Master_UUID: 23428086-a1f6-11e8-91ff-000c29267d00
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
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
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.03 sec)

ERROR:
No query specified

Slave_IO_Running和Slave_SQL_Running的狀態都是YES,說明同步開啓成功。

到這個位置,基本是以A爲主,B爲從的複製已經完成了,接下來就是B爲主,A爲從的複製

三,以B爲主,A爲從

master(B庫) —-> slave(A庫)

B)
1.master中創建一個僅用於主從複製的賬號

mysql> grant REPLICATION SLAVE on *.* to 'user_b'@'10.1.1.7' identified by 'wanjianning';

2.查看B庫中binlog日誌的位置

mysql> show master status\G;
查詢結果如下:
*************************** 1. row ***************************
File: mysql-bin.000006
Position: 1039
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)

ERROR:
No query specified

A)
1.同步數據

mysql>change master to master_host='10.1.1.8',master_user='user_b',master_port=3306,master_password='wanjianning',master_log_file='mysql-bin.000003', master_log_pos=154;

2.開啓slave A(slave)庫中:start slave;

mysql>start slave;

3.查詢A從的狀態

mysql >show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.1.1.8
Master_User: user_b
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000006
Read_Master_Log_Pos: 1039
Relay_Log_File: localhost-relay-bin.000002
Relay_Log_Pos: 891
Relay_Master_Log_File: mysql-bin.000006
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: 1039
Relay_Log_Space: 1102
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: 2
Master_UUID: 5c9f7fba-a442-11e8-b7ce-000c2968df9a
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
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
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)

ERROR:
No query specified

當兩個yes 說明主主已經成功了
解釋:
log_bin_trust_function_creators=1
當二進制日誌啓用後,這個變量就會啓用。它控制是否可以信任存儲函數創建者,不會創建寫入二進制日誌引起不安全事件的存儲函數。如果設置爲0(默認值),用戶不得創建或修改存儲函數,除非它們具有除CREATE ROUTINE或ALTER ROUTINE特權之外的SUPER權限。如果變量設置爲1,MySQL不會對創建存儲函數實施這些限制。 此變量也適用於觸發器的創建。

server-id=1
原理:在master中,您必須配置一個獨特的服務器ID(可能需要重新啓動服務器)和啓用二進制日誌,slave的複製基於master的二進制日誌。如果沒有使用log-bin選項啓用二進制日誌,複製是不可能的。每個slave與master必須配置一個獨特的ID。這個ID用於識別主從服務器,而且必須是一個正整數1和(232)−1之間。

驗證:
1. ls /var/lib/mysql/ 會發現有mysql-bin.000001mysql、mysql-bin.index ,表示啓用二進制日誌成功。

mysql_bin.000001: Master記錄操作的二進制日誌文件。
mysql_bin.index: 二進制文件的索引文件,存放二進制日誌文件的名字和路徑。
2. 命令查看
#查看否開啓了bin-log mysql> show variables like '%log_bin%';
#查看bin-log相關參數 mysql> show variables like '%binlog%';
#當前mysql二進制日誌文件的默認位置 mysql> show variables like '%datadir%';
#查看mysql二進制文件名稱及大小 mysql> show binary logs;


3. Master常用命令
#查看Master複製狀態 mysql> show master status;
#查看二進制日誌文件事件內容 mysqlbinlog mysql-bin.xxx ---可讀性差
#查看二進制日誌文件事件內容 mysql> show binlog events in 'mysql-bin.000003';

4. 管理二進制日誌文件

#刪除二進制日誌文件
手動刪除:
語法: > PURGE {MASTER | BINARY} LOGS TO 'log_name'
> PURGE {MASTER | BINARY} LOGS BEFORE 'date'
#我使用時沒發現MASTER 和BINARY的區別,都一樣用,都可以。
mysql> purge binary logs to 'mysql_bin.000002';
//刪除mysql_bin.000002之前的二進制日誌文件,並同步刪除日誌索引文件mysql_bin.index中mysql_bin.000002之前的索引信息。注意不包含mysql_bin.000002

mysql> purge master logs before '2017-07-20 21:58:00'; //清除2017-07-20 21:58:00 之前的二進制日誌,並同步清楚日誌索引文件的信息。


自動刪除:
my.cnf中加入以下,然後重啓:
SET GLOBAL expire_logs_days = 7 \\設置二進制日誌只保留7天的
--如果不想重啓直接mysql> SET GLOBAL expire_logs_days = 7

#重置master二進制日誌文件及內容
mysql> reset master;
或者是
mysql>flush logs;

 

 

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