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 wow@192.168.10.137 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

最後修改日期: 2015 年 06 月 04 日

作者

留言

Nice

[Reply]

撰寫回覆或留言

發佈留言必須填寫的電子郵件地址不會公開。