上一篇文章講了Master-Slave的主備設計及配置方案的例子,這篇就是講master-master雙主的思路以及方案。
首先原理其實很簡單,就是mysql的主主策略嘛,話不多說直接上圖:
雙主模式在中小型公司的設計方案中基本不會用到,畢竟很消耗資源並且成本也不低。
Start:
1.a will be the master and a slave to the new server, so this config is a hybrid of the two configurations used to Establish Replication.
In order to be a replication master, it needs log_bin
enabled,
and a server_id
that
is not the default (0).
In order to be a replication slave, it also needs the relay_log
file
name to not depend on its host name.
And to prepare this server to be a master of more slaves, we'll enable log_slave_updates
.
This ensures changes from b will be propagated out to a's slaves.
在這裏我們在機器a上搭建另一個Master mysql數據庫,第一步依然是打開相應的配置項,最重要的肯定是Log_bin,因爲master之間也是通過log file進行數據同步的。
a ~ $ sudoedit /etc/my.cnf
[mysqld]
log_bin = mysql-bin
server_id = 10
log_slave_updates = 1
relay_log = mysql-relay-bin
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
再重啓下數據庫使其生效
a ~ $ sudo service mysqld restart
Stopping mysqld: [ OK ]
Starting mysqld: [ OK ]
再進入數據庫查看剛纔的配置是否已經成功生效:
a ~ $ mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.29-log MySQL Community Server (GPL)
Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show variables where Variable_Name IN ("server_id", "log_bin", "relay_log", "log_slave_updates");
+-------------------+-----------------+
| Variable_name | Value |
+-------------------+-----------------+
| log_bin | ON |
| log_slave_updates | ON |
| relay_log | mysql-relay-bin |
| server_id | 10 |
+-------------------+-----------------+
5 rows in set (0.00 sec)
mysql>
2.Add a service account with replication privileges.
Each server will use this account to authenticate to the other.
The account itself will be copied to the new server in the backup.
第二步就是創建一個有備份權限的用戶,用以接下去進行remote登錄。
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replicator'@'%' IDENTIFIED BY 'NoseTinSuchEdge';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql>
3.備份a中數據庫原來的數據:
mysql> exit
a ~ $ mysqldump -u root --single-transaction --all-databases --master-data=1 > /tmp/master_backup.sql
-- Warning: Skipping the data of table mysql.event. Specify the --events option explicitly.
backup的文件在/tmp/master_backup.sql
4.將backup的文件scp到另一個名字叫b的master上:
<span style="font-size:14px;">a ~ $ scp /tmp/master_backup.sql b.example.com:/tmp/
The authenticity of host 'b.example.com (10.242.58.189)' can't be established.
RSA key fingerprint is 0f:47:42:f4:71:51:4c:a3:70:94:db:83:03:4c:d2:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'b.example.com,10.242.58.189' (RSA) to the list of known hosts.
[email protected]'s password: (input your password)
master_backup.sql 100% 501KB 501.3KB/s 00:00
a ~ $ </span>
b ~ $ sudoedit /etc/my.cnf
[mysqld]
log_bin = mysql-bin
server_id = 20
log_slave_updates = 1
relay_log = mysql-relay-bin
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
b ~ $ sudo service mysqld restart
Stopping mysqld: [ OK ]
Starting mysqld: [ OK ]
6.在b的數據庫中導入a的數據:
b ~ $ mysql -u root
mysql> source /tmp/master_backup.sql
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 508 rows affected (0.02 sec)
Records: 508 Duplicates: 0 Warnings: 0
b picked up a's binary log information from the backup file. Now we need to write down the binary log information from b to provide to a.
查看二進制文件Log file
<span style="color:#333333;">mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | </span><span style="color:#ff0000;"> 511309 </span><span style="color:#333333;">| | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
mysql></span>
mysql> CHANGE MASTER TO MASTER_HOST='a.example.com',
MASTER_USER='replicator',
MASTER_PASSWORD='NoseTinSuchEdge';
- On b, MySQL shows the replication setting
MASTER_HOST
has valuea.example.com
- On b, MySQL shows the replication setting
MASTER_USER
has valuereplicator
mysql> SLAVE START;
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: a.example.com
Master_User: replicator
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 960
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 1106
Relay_Master_Log_File: mysql-bin.000001
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: 960
Relay_Log_Space: 1262
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: 10
1 row in set (0.00 sec)
mysql>
9.配置a從b進行數據同步
<span style="color:#333333;">a ~ $ mysql -u root
mysql> CHANGE MASTER TO MASTER_HOST='b.example.com',
MASTER_USER='replicator',
MASTER_PASSWORD='NoseTinSuchEdge',
MASTER_LOG_FILE='mysql-bin.000001',
</span><span style="color:#ff0000;">MASTER_LOG_POS=511309;</span><span style="color:#333333;">
Query OK, 0 rows affected (0.09 sec)
mysql> </span>
這裏的關鍵點就是log file的postion,a到b的數據同步需要知道b的log file的postion,之前上面紅色已標出。
10.開啓b到a的repalication:
mysql> slave start;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: b.example.com
Master_User: replicator
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 511561
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000001
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: 511561
Relay_Log_Space: 409
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: 20
1 row in set (0.00 sec)
mysql>
配置到這裏就全部完成了,接下去測試下:
在a上insert數據:
mysql> INSERT INTO important.stuff SET details='Gift from A to B';
Query OK, 1 row affected (0.03 sec)
在b上同樣的表insert一條不同的數據:
mysql> INSERT INTO important.stuff SET details='Gift from B to A';
Query OK, 1 row affected (0.03 sec)
mysql>
檢查a剛剛的表:
mysql> select * from important.stuff\G
*************************** 1. row ***************************
id: 1
details: Gift from A to B
happened: 2013-03-27 04:06:02
*************************** 2. row ***************************
id: 2
details: inserted by grading server
happened: 2013-03-27 04:09:26
*************************** 3. row ***************************
id: 3
details: Gift from B to A
happened: 2013-03-27 04:09:40
3 rows in set (0.00 sec)
會發現b insert的數據也在。
其實總結一下,前面a,b的配置和master-slave的配置一樣,就是在之後在a上也配置了一個slave,即對b的數據也進行同步,這樣不管是往a還是b裏插數據都是可以互相進行同步的,而master-slave模式中,往slave裏插數據(只有root用戶登進去才行)master是不會去同步的。所以呢,雙主和主備在配置上的區別其實很簡單,原理上理解起來也不難,有興趣的博友可以自己裝mysql玩一玩就很快可以理解了,希望本文對大家有所幫助。