Master Master 基本上就是兩台 node 各互為 master 與 slaver 的狀態,node1 會同步資料給 node2,nod2 也會把資料同步給 node1,再來就讓 mysql-mmm (perl 寫的) 工具達到自動切換備援功能 (使用 VIP),當 node1 掛了時,自動讓 node2 當主要的。假如多新增一台 slaver 備援時,這台 slaver 所同步的來源,也會自動在 node1 與 node2 之間自行切換同步 (slaver 本來是同步 node1,當 node1 掛了,可以自動讓 slaver 去抓 node2 )。
環境
node1 : 192.168.10.180
node2 : 192.168.10.134
web : 192.168.10.137
monitor: 192.168.10.171
假設兩個 node 的 mysql 都已安裝並 start 了
這邊我是拿 wordpress 來作測試,所以已事先安裝過了,所以目前有的資料為 web data,與 sql dump 檔 (wow.sql),在 node1 與 node2 建立資料庫(讓web可連線)、使用者,及匯入資料庫
mysql> create database wow; mysql> grant all on wow.* to [email protected] identified by '123456'; mysql -u root -p123456 wow < wow.sql
再來在 node1 設定 my.cnf,同步的設定,我也只同步 wow 資料庫
server-id=1 # avoid auto incremented primary keys from clashing across servers # 讓 node1 的 auto_increment id 以 1 3 5 7 下去,而 node2 為 2 4 6 8 .... auto_increment_increment=2 auto_increment_offset=1 log-bin=mysqld-bin binlog-do-db=wow # to ensure that changes that happened on the other master are also reflected in this machine's binary log log_slave_updates=1 relay-log = relay-bin relay-log-index = relay-bin.index relay-log-info-file = relay-bin.info read-only=1 # 每台 node 都要設定,才能讓 mysql-mmm 根據 roles 判定真的讀可讀,寫可寫
service mysqld restart
node1 上,再建立 replication 使用者,是同步用的權限
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%' IDENTIFIED BY 'replpass';
從 node1 查看要給 node2 的 File 與 POS 編號,這是要讓 node2 可以知道從那裡開始同步 (MASTER_LOG_FILE 與 MASTER_LOG_POS)
mysql> show master status;
設定 node2 的 my.cnf
server-id=2 # avoid auto incremented primary keys from clashing across servers auto_increment_increment=2 auto_increment_offset=2 log-bin=mysqld-bin binlog-do-db=wow log_slave_updates=1 relay-log = relay-bin relay-log-index = relay-bin.index relay-log-info-file = relay-bin.info read-only=1 # 每台 node 都要設定,才能讓 mysql-mmm 根據 roles 判定真的讀可讀,寫可寫
service mysqld restart
node2,開始設定同步動作
# 先讓 slave 停止 mysql> slave stop; # 指派 node2 是要去同步 node1 裡的資料 mysql> CHANGE MASTER TO MASTER_HOST='192.168.10.180', MASTER_USER='replica', MASTER_PASSWORD='replpass', MASTER_LOG_FILE='mysqld-bin.000004', MASTER_LOG_POS=32844; # 啟用 slave mysql> slave start; # Slave_IO_Running 與 slave_SQL_Running 同為 Yes 就是成功的 mysql> show slave status\G;
再來就是相反過來讓 node1 可以同步 node2 的資料
所以在 node2 上建立 replication 使用者
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%' IDENTIFIED BY 'replpass';
並查看要給 node1 的 File 與 POS 編號
mysql> show master status;
再到 node1
mysql> slave stop; mysql> CHANGE MASTER TO MASTER_HOST='192.168.10.134', MASTER_USER='replica', MASTER_PASSWORD='replpass', MASTER_LOG_FILE='mysqld-bin.000004', MASTER_LOG_POS=259; mysql> slave start; # Slave_IO_Running 與 slave_SQL_Running 同為 Yes 就是成功的 mysql> show slave status\G;
以上就完成 master vs master 的環境了
再來就使用 mysql-mmm 工具作監控、自動切換的動作,比如說 node1 掛了,就讓 node2 接手 當 主力 master
安裝 mysql-mmm
monitor 安裝 monitor
rpm -ivh http://mirror01.idc.hinet.net/EPEL/6/i386/epel-release-6-8.noarch.rpm yum install mysql-mmm-monitor -y
node1 與 node2 安裝 agent
rpm -ivh http://mirror01.idc.hinet.net/EPEL/6/i386/epel-release-6-8.noarch.rpm yum install mysql-mmm-agent -y
node1 與 node2 建立監控的 mysql 使用者
GRANT REPLICATION CLIENT ON *.* TO 'mmm_monitor'@'%' IDENTIFIED BY 'monitor'; GRANT SUPER, REPLICATION CLIENT, PROCESS ON *.* TO 'mmm_agent'@'%' IDENTIFIED BY 'agent';
node1 與 node2 有相同的 mmm_common.conf 設定
vi /etc/mysql-mmm/mmm_common.conf active_master_role writer <host default> cluster_interface eth0 pid_path /var/run/mysql-mmm/mmm_agentd.pid bin_path /usr/libexec/mysql-mmm/ replication_user replica replication_password replpass agent_user mmm_agent agent_password agent </host> <host node1> ip 192.168.10.180 mode master peer node2 </host> <host node2> ip 192.168.10.134 mode master peer node1 </host> <role writer> hosts node1, node2 ips 192.168.10.1 mode exclusive </role> <role reader> hosts node1, node2 ips 192.168.10.2, 192.168.10.3 mode balanced </role>
192.168.1 與 2 跟 3 都是 VIP,1 是用來作寫的溝通,2 跟 3 是讀
不用真的在 ifcfg-ethX 裡作設定,mysql-mmm 工具會搞定
node1 與 node2 主機,編輯 /etc/mysql-mmm/mmm_agent.conf
在 192.168.10.180 就是 this node1,而 192.168.10.134 就是 this node2,這名稱是跟著 mmm_common.conf 裡的 <host XXX> 走的
include mmm_common.conf this node1
monitor 還要編輯 /etc/mysql-mmm/mmm_mon.conf,修改 ping_ips、monitor_user、monitor_password
include mmm_common.conf <monitor> ip 127.0.0.1 pid_path /var/run/mysql-mmm/mmm_mond.pid bin_path /usr/libexec/mysql-mmm status_path /var/lib/mysql-mmm/mmm_mond.status ping_ips 192.168.10.180, 192.168.10.134 auto_set_online 60 # The kill_host_bin does not exist by default, though the monitor will # throw a warning about it missing. See the section 5.10 "Kill Host # Functionality" in the PDF documentation. # # kill_host_bin /usr/libexec/mysql-mmm/monitor/kill_host # </monitor> <host default> monitor_user mmm_monitor monitor_password monitor </host> debug 0
monitor 啟動
/etc/init.d/mysql-mmm-monitor start
node1 與 node2 啟動
/etc/init.d/mysql-mmm-agent start
成功的話就可以在 monitor 上看到
[root@monitor mysql-mmm]# mmm_control show node1(192.168.10.180) master/ONLINE. Roles: reader(192.168.10.3), writer(192.168.10.1) node2(192.168.10.134) master/ONLINE. Roles: reader(192.168.10.2)
這時後 web 上的 wordpress 就可以連 192.168.10.1 這 IP 存取資料庫,也就是 node1
在 node1 與 node2 分別用 ip a 看到如下,這就是為何可以用 VIP 來作連線的 IP,讓 mysql-mmm 自動作切換就不用再改程式了
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:c6:af:6b brd ff:ff:ff:ff:ff:ff inet 192.168.10.180/24 brd 192.168.10.255 scope global eth0:192 inet 192.168.10.3/32 scope global eth0 inet 192.168.10.1/32 scope global eth0 inet6 fe80::a00:27ff:fec6:af6b/64 scope link tentative dadfailed valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:c6:af:6b brd ff:ff:ff:ff:ff:ff inet 192.168.10.134/24 brd 192.168.10.255 scope global eth0:192 inet 192.168.10.2/32 scope global eth0 inet6 fe80::a00:27ff:fec6:af6b/64 scope link tentative dadfailed valid_lft forever preferred_lft forever
根據 mmm_control show 的狀態,現在是 node1 為主要的寫入主機
如果 node1 的 mysql 掛了,狀態就會變這樣子
node1(192.168.10.180) master/HARD_OFFLINE. Roles: node2(192.168.10.134) master/ONLINE. Roles: reader(192.168.10.2), reader(192.168.10.3), writer(192.168.10.1)
如果 node1 這時起來了,寫還是會在 node2
node1(192.168.10.180) master/ONLINE. Roles: reader(192.168.10.2) node2(192.168.10.134) master/ONLINE. Roles: reader(192.168.10.3), writer(192.168.10.1)
那如果這時 restart monitor 的 mysql-mmm-monitor 呢,狀態還是同上
另外我根據 roles 去測試讀寫, 192.168.10.1 確實可寫,192.168.10.2 確實只可讀,但 192.168.10.3 卻仍可寫
假如我這時後想再新增一台 slaver 作備援用呢
slaver: 192.168.10.171
一樣找主要的 master 的 file 與 pos 編號,然後指定 change master
一樣要新增 mmm_monitor 與 mmm_agent 使用者
編輯 slaver 的 /etc/mysql-mmm/mmm_agent.conf
this node3
還要編輯 /etc/mysql-mmm/mmm_common.conf 新增,記得 monitor、 node1、node2 及新增的 slaver 都要同內容
... <host node3> ip 192.168.10.171 mode slave </host> ... <role reader> hosts node1, node2, node3 ips 192.168.10.2, 192.168.10.3, 192.168.10.4 mode balanced </role>
monitor 要再修改 /etc/mysql-mmm/mmm_mon.conf
ping_ips 192.168.10.180, 192.168.10.134, 192.168.10.171
然後各自 restart agent 與 monitor
狀態就會變成
node1(192.168.10.180) master/ONLINE. Roles: reader(192.168.10.3), writer(192.168.10.1) node2(192.168.10.134) master/ONLINE. Roles: reader(192.168.10.4) node3(192.168.10.171) slave/ONLINE. Roles: reader(192.168.10.2)
在這 master1、master2、slaver 環境下,原本 slaver1 是指向 master1 同步,如果 master1 掛了,slaver 怎麼同步 master2 ?
放心,mysql-mmm 會自動切換到 master2 ,連同 file 及 pos 編號都搞定了
同樣的當 master1 回復了, slaver 的指向仍在 master2 身上
有人有遇到 ARP 問題 (我尚未遇過),可以參考 http://sofar.blog.51cto.com/353572/1404039
留言
Nice