MySQL 高可用MMM
阿新 • • 發佈:2017-11-13
mysql http://mysql-mmm.org
一、MMM簡介:
MMM即Multi-MasterReplication Manager for MySQL:mysql多主復制管理器,基於perl實現,關於mysql主主復制配置的監控、故障轉移和管理的一套可伸縮的腳本套件(在任何時候只有一個節點可以被寫入),MMM也能對從服務器進行讀負載均衡,所以可以用它來在一組用於復制的服務器啟動虛擬ip,除此之外,它還有實現數據備份、節點之間重新同步功能的腳本。MySQL本身沒有提供replication failover的解決方案,通過MMM方案能實現服務器的故障轉移,從而實現mysql的高可用。MMM不僅能提供浮動IP的功能,如果當前的主服務器掛掉後,會將你後端的從服務器自動轉向新的主服務器進行同步復制,不用手工更改同步配置。這個方案是目前比較成熟的解決方案。詳情請看官網:
優點:高可用性,擴展性好,出現故障自動切換,對於主主同步,在同一時間只提供一臺數據庫寫操作,保證的數據的一致性。當主服務器掛掉以後,另一個主立即接管,其他的從服務器能自動切換,不用人工幹預。 缺點:monitor節點是單點,不過這個你也可以結合keepalived或者haertbeat做成高可用;至少三個節點,對主機的數量有要求,需要實現讀寫分離,還需要在前端編寫讀寫分離程序。在讀寫非常繁忙的業務系統下表現不是很穩定,可能會出現復制延時、切換失效等問題。MMM方案並不太適應於對數據安全性要求很高,並且讀、寫繁忙的環境中。 適用場景: MMM的適用場景為數據庫訪問量大,並且能實現讀寫分離的場景。 Mmm主要功能由下面三個腳本提供: mmm_mond 負責所有的監控工作的監控守護進程,決定節點的移除(mmm_mond進程定時心跳檢測,失敗則將write ip 浮動到另外一臺master)等等 mmm_agentd 運行在mysql服務器上的代理守護進程,通過簡單遠程服務集提供給監控節點 mmm_control 通過命令行管理mmm_mond進程 在整個監管過程中,需要在mysql中添加相關授權用戶,授權的用戶包括一個mmm_monitor用戶和一個mmm_agent用戶,如果想使用mmm的備份工具則還要添加一個mmm_tools用戶。 二、部署實施 1、環境介紹 OS:centos7.2(64位) 數據庫系統:mysql5.7.13 關閉selinux 配置ntp,同步時間 角色 IP hostname Server-id Write vip Read vip Master1 192.168.31.83 master1 1 192.168.31.2 Master2(backup) 192.168.31.141 master2 2 192.168.31.3 Slave1 192.168.31.250 slave1 3 192.168.31.4 Slave2 192.168.31.225 slave2 4 192.168.31.5 monitor 192.168.31.106 monitor1 無 2、在所有主機上配置/etc/hosts文件,添加如下內容: 192.168.31.83 master1 192.168.31.141 master2 192.168.31.250 slave1 192.168.31.225 slave2 192.168.31.106 monitor1 在所有主機上安裝perl、perl-devel perl-CPANlibart_lgpl.x86_64 rrdtool.x86_64 rrdtool-perl.x86_64包 #yum -y install perl-* libart_lgpl.x86_64 rrdtool.x86_64 rrdtool-perl.x86_64 註:使用centos7在線yum源安裝 安裝perl的相關庫 #cpan -iAlgorithm::Diff Class::Singleton DBI DBD::mysql Log::Dispatch Log::Log4perlMail::Send Net::Ping Proc::Daemon Time::HiRes Params::Validate Net::ARP 3、在master1、master2、slave1、slave2主機上安裝mysql5.7和配置復制 master1和master2互為主從,slave1、slave2為master1的從 在每個mysql的配置文件/etc/my.cnf中加入以下內容, 註意server_id 不能重復。 master1主機: log-bin = mysql-bin binlog_format = mixed server-id = 1 relay-log= relay-bin relay-log-index = slave-relay-bin.index log-slave-updates = 1 auto-increment-increment = 2 auto-increment-offset = 1 master2主機: log-bin = mysql-bin binlog_format = mixed server-id = 2 relay-log= relay-bin relay-log-index = slave-relay-bin.index log-slave-updates = 1 auto-increment-increment = 2 auto-increment-offset = 2 slave1主機: server-id = 3 relay-log= relay-bin relay-log-index = slave-relay-bin.index read_only = 1 slave2主機: server-id = 4 relay-log= relay-bin relay-log-index = slave-relay-bin.index read_only = 1 在完成了對my.cnf的修改後,通過systemctl restart mysqld重新啟動mysql服務 4臺數據庫主機若要開啟防火墻,要麽關閉防火墻或者創建訪問規則: firewall-cmd --permanent--add-port=3306/tcp firewall-cmd --reload 主從配置(master1和master2配置成主主,slave1和slave2配置成master1的從): 在master1上授權: mysql> grant replication slave on *.*to rep@‘192.168.31.%‘ identified by ‘123456‘; 在master2上授權: mysql> grant replication slave on *.*to rep@‘192.168.31.%‘ identified by ‘123456‘; 把master2、slave1和slave2配置成master1的從庫: 在master1上執行show master status; 獲取binlog文件和Position點 mysql> show master status; +------------------+----------+--------------+------------------+--------------------------------------------------+ | File | Position | Binlog_Do_DB |Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+---------------------------------------------------+ | mysql-bin.000001 | 452 | | | | +------------------+----------+--------------+------------------+-----------------------------------------------------+ 在master2、slave1和slave2執行 mysql>change master tomaster_host=‘192.168.31.83‘,master_port=3306,master_user=‘rep‘,master_password=‘123456‘,master_log_file=‘mysql-bin.000001‘,master_log_pos=452; mysql>slave start; 驗證主從復制: master2主機: mysql> show slave status\G; *************************** 1. row*************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.31.83 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 452 Relay_Log_File: relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes slave1主機: mysql> showslave status\G; ***************************1. row *************************** Slave_IO_State: Waiting formaster to send event Master_Host:192.168.31.83 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 452 Relay_Log_File: relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running:Yes Slave_SQL_Running: Yes slave2主機: mysql> showslave status\G; ***************************1. row *************************** Slave_IO_State: Waiting formaster to send event Master_Host:192.168.31.83 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 452 Relay_Log_File: relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running:Yes Slave_SQL_Running: Yes 如果Slave_IO_Running和Slave_SQL_Running都為yes,那麽主從就已經配置OK了 把master1配置成master2的從庫: 在master2上執行show master status ;獲取binlog文件和Position點 mysql> show master status; +------------------+----------+--------------+------------------+--------------------------------------------------+ | File | Position | Binlog_Do_DB |Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+---------------------------------------------------+ | mysql-bin.000001 | 452 | | | | +------------------+----------+--------------+------------------+----------------------------------------------------+ 在master1上執行: mysql>change master to master_host=‘192.168.31.141‘,master_port=3306,master_user=‘rep‘,master_password=‘123456‘,master_log_file=‘mysql-bin.000001‘,master_log_pos=452; mysql> start slave; 驗證主從復制: master1主機: mysql> showslave status\G; ***************************1. row *************************** Slave_IO_State: Waiting formaster to send event Master_Host:192.168.31.141 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 452 Relay_Log_File: relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running:Yes Slave_SQL_Running: Yes 如果Slave_IO_Running和Slave_SQL_Running都為yes,那麽主從就已經配置OK了 4、mysql-mmm配置: 在4臺mysql節點上創建用戶 創建代理賬號: mysql> grant super,replicationclient,process on *.* to ‘mmm_agent‘@‘192.168.31.%‘ identified by ‘123456‘; 創建監控賬號: mysql> grant replication client on*.* to ‘mmm_monitor‘@‘192.168.31.%‘ identified by ‘123456‘; 註1:因為之前的主從復制,以及主從已經是ok的,所以我在master1服務器執行就ok了。 檢查master2和slave1、slave2三臺db上是否都存在監控和代理賬號 mysql> select user,host frommysql.user where user in (‘mmm_monitor‘,‘mmm_agent‘); +-------------+----------------------------+ | user | host | +-------------+----------------------------+ | mmm_agent | 192.168.31.% | | mmm_monitor | 192.168.31.% | +-------------+------------------------------+ 或 mysql> show grants for‘mmm_agent‘@‘192.168.31.%‘; +-----------------------------------------------------------------------------------------------------------------------------+ | Grants for [email protected].% | +-----------------------------------------------------------------------------------------------------------------------------+ | GRANT PROCESS, SUPER, REPLICATIONCLIENT ON *.* TO ‘mmm_agent‘@‘192.168.31.%‘ | +-----------------------------------------------------------------------------------------------------------------------------+ mysql> show grants for‘mmm_monitor‘@‘192.168.31.%‘; +-----------------------------------------------------------------------------------------------------------------------------+ | Grants [email protected].% | +-----------------------------------------------------------------------------------------------------------------------------+ | GRANT REPLICATION CLIENT ON *.* TO‘mmm_monitor‘@‘192.168.31.%‘ | 註2: mmm_monitor 用戶:mmm監控用於對mysql服務器進程健康檢查 mmm_agent 用戶:mmm代理用來更改只讀模式,復制的主服務器等 5、mysql-mmm安裝 在monitor主機(192.168.31.106) 上安裝監控程序 cd /tmp wgethttp://pkgs.fedoraproject.org/repo/pkgs/mysql-mmm/mysql-mmm-2.2.1.tar.gz/f5f8b48bdf89251d3183328f0249461e/mysql-mmm-2.2.1.tar.gz tar -zxf mysql-mmm-2.2.1.tar.gz cd mysql-mmm-2.2.1 make install 在數據庫服務器(master1、master2、slave1、slave2)上安裝代理 cd /tmp wgethttp://pkgs.fedoraproject.org/repo/pkgs/mysql-mmm/mysql-mmm-2.2.1.tar.gz/f5f8b48bdf89251d3183328f0249461e/mysql-mmm-2.2.1.tar.gz tar -zxf mysql-mmm-2.2.1.tar.gz cd mysql-mmm-2.2.1 make install 6、配置mmm 編寫配置文件,五臺主機必須一致: 完成安裝後,所有的配置文件都放到了/etc/mysql-mmm/下面。管理服務器和數據庫服務器上都要包含一個共同的文件mmm_common.conf,內容如下: active_master_role writer #積極的master角色的標示,所有的db服務器要開啟read_only參數,對於writer服務器監控代理會自動將read_only屬性關閉。 <host default> cluster_interface eno16777736 #群集的網絡接口 pid_path /var/run/mmm_agentd.pid #pid路徑 bin_path /usr/lib/mysql-mmm/ #可執行文件路徑 replication_user rep #復制用戶 replication_password 123456 #復制用戶密碼 agent_user mmm_agent #代理用戶 agent_password 123456 #代理用戶密碼 </host> <host master1> #master1的host名 ip 192.168.31.83 #master1的ip mode master #角色屬性,master代表是主 peer master2 #與master1對等的服務器的host名,也就是master2的服務器host名 </host> <host master2> #和master的概念一樣 ip 192.168.31.141 mode master peer master1 </host> <host slave1> #從庫的host名,如果存在多個從庫可以重復一樣的配置 ip 192.168.31.250 #從的ip mode slave #slave的角色屬性代表當前host是從 </host> <host slave2> #和slave的概念一樣 ip 192.168.31.225 mode slave </host> <role writer> #writer角色配置 hosts master1,master2 #能進行寫操作的服務器的host名,如果不想切換寫操作這裏可以只配置master,這樣也可以避免因為網絡延時而進行write的切換,但是一旦master出現故障那麽當前的MMM就沒有writer了只有對外的read操作。 ips 192.168.31.2 #對外提供的寫操作的虛擬IP mode exclusive #exclusive代表只允許存在一個主,也就是只能提供一個寫的IP </role> <role reader> #read角色配置 hosts master2,slave1,slave2 #對外提供讀操作的服務器的host名,當然這裏也可以把master加進來 ips 192.168.31.3,192.168.31.4, 192.168.31.5 #對外提供讀操作的虛擬ip,這三個ip和host不是一一對應的,並且ips也hosts的數目也可以不相同,如果這樣配置的話其中一個hosts會分配兩個ip mode balanced #balanced代表負載均衡 </role> 同時將這個文件拷貝到其它的服務器,配置不變 #for host in master1 master2 slave1slave2 ; do scp /etc/mysql-mmm/mmm_common.conf $host:/etc/mysql-mmm/ ; done 代理文件配置 編輯 4臺mysql節點機上的/etc/mysql-mmm/mmm_agent.conf 在數據庫服務器上,還有一個mmm_agent.conf需要修改,其內容是: include mmm_common.conf this master1 註意:這個配置只配置db服務器,監控服務器不需要配置,this後面的host名改成當前服務器的主機名。 啟動代理進程 在 /etc/init.d/mysql-mmm-agent的腳本文件的#!/bin/sh下面,加入如下內容 source /root/.bash_profile 添加成系統服務並設置為自啟動 #chkconfig --add mysql-mmm-agent #chkconfig mysql-mmm-agent on #/etc/init.d/mysql-mmm-agent start 註:添加source /root/.bash_profile目的是為了mysql-mmm-agent服務能啟機自啟。 自動啟動和手動啟動的唯一區別,就是激活一個console 。那麽說明在作為服務啟動的時候,可能是由於缺少環境變量 服務啟動失敗,報錯信息如下: Daemon bin: ‘/usr/sbin/mmm_agentd‘ Daemon pid: ‘/var/run/mmm_agentd.pid‘ Starting MMM Agent daemon... Can‘tlocate Proc/Daemon.pm in @INC (@INC contains: /usr/local/lib64/perl5/usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl/usr/lib64/perl5 /usr/share/perl5 .) at /usr/sbin/mmm_agentd line 7. BEGIN failed--compilation aborted at/usr/sbin/mmm_agentd line 7. failed 解決方法: # cpanProc::Daemon # cpan Log::Log4perl # /etc/init.d/mysql-mmm-agent start Daemon bin: ‘/usr/sbin/mmm_agentd‘ Daemon pid: ‘/var/run/mmm_agentd.pid‘ Starting MMM Agent daemon... Ok # netstat -antp | grep mmm_agentd tcp 0 0 192.168.31.83:9989 0.0.0.0:* LISTEN 9693/mmm_agentd 配置防火墻 firewall-cmd --permanent--add-port=9989/tcp firewall-cmd --reload 編輯 monitor主機上的/etc/mysql-mmm/mmm_mon.conf include mmm_common.conf <monitor> ip 127.0.0.1 ##為了安全性,設置只在本機監聽,mmm_mond默認監聽9988 pid_path /var/run/mmm_mond.pid bin_path /usr/lib/mysql-mmm/ status_path /var/lib/misc/mmm_mond.status ping_ips 192.168.31.83,192.168.31.141,192.168.31.250,192.168.31.225 #用於測試網絡可用性 IP 地址列表,只要其中有一個地址 ping 通,就代表網絡正常,這裏不要寫入本機地址 auto_set_online 0 #設置自動online的時間,默認是超過60s就將它設置為online,默認是60s,這裏將其設為0就是立即online </monitor> <check default> check_period 5 trap_period 10 timeout 2 #restart_after 10000 max_backlog 86400 </check> check_period 描述:檢查周期默認為5s 默認值:5s trap_period 描述:一個節點被檢測不成功的時間持續trap_period秒,就慎重的認為這個節點失敗了。 默認值:10s timeout 描述:檢查超時的時間 默認值:2s restart_after 描述:在完成restart_after次檢查後,重啟checker進程 默認值:10000 max_backlog 描述:記錄檢查rep_backlog日誌的最大次數 默認值:60 <host default> monitor_user mmm_monitor #監控db服務器的用戶 monitor_password 123456 #監控db服務器的密碼 </host> debug 0 #debug 0正常模式,1為debug模式 啟動監控進程: 在 /etc/init.d/mysql-mmm-monitor的腳本文件的#!/bin/sh下面,加入如下內容 source /root/.bash_profile 添加成系統服務並設置為自啟動 #chkconfig --add mysql-mmm-monitor #chkconfig mysql-mmm-monitor on #/etc/init.d/mysql-mmm-monitor start 啟動報錯: Starting MMM Monitor daemon: Can notlocate Proc/Daemon.pm in @INC (@INC contains: /usr/local/lib64/perl5/usr/local/share/perl5 /usr/lib64/perl5/vendor_perl/usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/sbin/mmm_mondline 11. BEGIN failed--compilation aborted at /usr/sbin/mmm_mond line 11. failed 解決方法:安裝下列perl的庫 #cpan Proc::Daemon #cpan Log::Log4perl [root@monitor1 ~]#/etc/init.d/mysql-mmm-monitor start Daemon bin: ‘/usr/sbin/mmm_mond‘ Daemon pid: ‘/var/run/mmm_mond.pid‘ Starting MMM Monitor daemon: Ok [root@monitor1 ~]# netstat -anpt | grep9988 tcp 0 0 127.0.0.1:9988 0.0.0.0:* LISTEN 8546/mmm_mond 註1:無論是在db端還是在監控端如果有對配置文件進行修改操作都需要重啟代理進程和監控進程。 註2:MMM啟動順序:先啟動monitor,再啟動 agent 檢查集群狀態: [root@monitor1 ~]# mmm_control show master1(192.168.31.83) master/ONLINE. Roles: writer(192.168.31.2) master2(192.168.31.141) master/ONLINE. Roles: reader(192.168.31.5) slave1(192.168.31.250) slave/ONLINE. Roles: reader(192.168.31.4) slave2(192.168.31.225) slave/ONLINE. Roles: reader(192.168.31.3) 如果服務器狀態不是ONLINE,可以用如下命令將服務器上線,例如: #mmm_control set_online 主機名 例如:[root@monitor1 ~]#mmm_control set_online master1 從上面的顯示可以看到,寫請求的VIP在master1上,所有從節點也都把master1當做主節點。 查看是否啟用vip [root@master1 ~]# ip addr show deveno16777736 eno16777736:<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen1000 link/ether 00:0c:29:6d:2f:82 brd ff:ff:ff:ff:ff:ff inet 192.168.31.83/24 brd 192.168.31.255 scope global eno16777736 valid_lft forever preferred_lft forever inet192.168.31.2/32 scope global eno16777736 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe6d:2f82/64 scope link valid_lft forever preferred_lft forever [root@master2 ~]# ip addr show dev eno16777736 eno16777736:<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen1000 link/ether 00:0c:29:75:1a:9c brd ff:ff:ff:ff:ff:ff inet 192.168.31.141/24 brd 192.168.31.255 scope global dynamiceno16777736 valid_lft 35850sec preferred_lft 35850sec inet 192.168.31.5/32 scope globaleno16777736 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe75:1a9c/64 scope link valid_lft forever preferred_lft forever [root@slave1 ~]# ip addr show dev eno16777736 eno16777736:<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen1000 link/ether 00:0c:29:02:21:19 brd ff:ff:ff:ff:ff:ff inet 192.168.31.250/24 brd 192.168.31.255 scope global dynamiceno16777736 valid_lft 35719sec preferred_lft 35719sec inet 192.168.31.4/32 scope globaleno16777736 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe02:2119/64 scope link valid_lft forever preferred_lft forever [root@slave2 ~]# ip addr show deveno16777736 eno16777736:<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen1000 link/ether 00:0c:29:e2:c7:fa brd ff:ff:ff:ff:ff:ff inet 192.168.31.225/24 brd 192.168.31.255 scope global dynamiceno16777736 valid_lft 35930sec preferred_lft 35930sec inet 192.168.31.3/32 scope globaleno16777736 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fee2:c7fa/64 scope link valid_lft forever preferred_lft forever 在master2,slave1,slave2主機上查看主mysql的指向 mysql> show slave status\G; *************************** 1. row*************************** Slave_IO_State: Waiting formaster to send event Master_Host: 192.168.31.83 Master_User: rep Master_Port: 3306 Connect_Retry: 60 MMM高可用性測試: 服務器讀寫采有VIP地址進行讀寫,出現故障時VIP會漂移到其它節點,由其它節點提供服務。 首先查看整個集群的狀態,可以看到整個集群狀態正常 [root@monitor1 ~]# mmm_control show master1(192.168.31.83) master/ONLINE. Roles: writer(192.168.31.2) master2(192.168.31.141) master/ONLINE. Roles: reader(192.168.31.5) slave1(192.168.31.250) slave/ONLINE. Roles: reader(192.168.31.4) slave2(192.168.31.225) slave/ONLINE. Roles: reader(192.168.31.3) 模擬master1宕機,手動停止mysql服務,觀察monitor日誌,master1的日誌如下: [root@monitor1 ~]# tail -f/var/log/mysql-mmm/mmm_mond.log 2017/01/09 22:02:55 WARN Check ‘rep_threads‘ on ‘master1‘ is inunknown state! Message: UNKNOWN: Connect error (host = 192.168.31.83:3306, user= mmm_monitor)! Can‘t connect to MySQL server on ‘192.168.31.83‘ (111) 2017/01/09 22:02:55 WARN Check ‘rep_backlog‘ on ‘master1‘ is inunknown state! Message: UNKNOWN: Connect error (host = 192.168.31.83:3306, user= mmm_monitor)! Can‘t connect to MySQL server on ‘192.168.31.83‘ (111) 2017/01/09 22:03:05 ERROR Check ‘mysql‘on ‘master1‘ has failed for 10 seconds! Message: ERROR: Connect error (host =192.168.31.83:3306, user = mmm_monitor)! Can‘t connect to MySQL server on‘192.168.31.83‘ (111) 2017/01/09 22:03:07 FATAL State of host‘master1‘ changed from ONLINE to HARD_OFFLINE (ping: OK, mysql: not OK) 2017/01/09 22:03:07 INFO Removing all roles from host ‘master1‘: 2017/01/09 22:03:07 INFO Removed role ‘writer(192.168.31.2)‘ from host ‘master1‘ 2017/01/09 22:03:07 INFO Orphaned role ‘writer(192.168.31.2)‘ hasbeen assigned to ‘master2‘ 查看群集的最新狀態 [root@monitor1 ~]# mmm_control show master1(192.168.31.83) master/HARD_OFFLINE.Roles: master2(192.168.31.141) master/ONLINE. Roles: reader(192.168.31.5),writer(192.168.31.2) slave1(192.168.31.250) slave/ONLINE. Roles: reader(192.168.31.4) slave2(192.168.31.225) slave/ONLINE. Roles: reader(192.168.31.3) 從顯示結果可以看出master1的狀態有ONLINE轉換為HARD_OFFLINE,寫VIP轉移到了master2主機上。 檢查所有的db服務器群集狀態 [root@monitor1 ~]# mmm_control checksall master1 ping [last change: 2017/01/09 21:31:47] OK master1 mysql [last change: 2017/01/09 22:03:07] ERROR: Connect error (host = 192.168.31.83:3306, user = mmm_monitor)!Can‘t connect to MySQL server on ‘192.168.31.83‘ (111) master1 rep_threads [last change: 2017/01/0921:31:47] OK master1 rep_backlog [last change:2017/01/09 21:31:47] OK: Backlog is null slave1 ping [last change:2017/01/09 21:31:47] OK slave1 mysql [last change:2017/01/09 21:31:47] OK slave1 rep_threads [last change: 2017/01/0921:31:47] OK slave1 rep_backlog [last change:2017/01/09 21:31:47] OK: Backlog is null master2 ping [last change:2017/01/09 21:31:47] OK master2 mysql [last change:2017/01/09 21:57:32] OK master2 rep_threads [last change:2017/01/09 21:31:47] OK master2 rep_backlog [last change:2017/01/09 21:31:47] OK: Backlog is null slave2 ping [last change:2017/01/09 21:31:47] OK slave2 mysql [last change:2017/01/09 21:31:47] OK slave2 rep_threads [last change:2017/01/09 21:31:47] OK slave2 rep_backlog [last change:2017/01/09 21:31:47] OK: Backlog is null 從上面可以看到master1能ping通,說明只是服務死掉了。 查看master2主機的ip地址: [root@master2 ~]# ip addr show deveno16777736 eno16777736:<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen1000 link/ether 00:0c:29:75:1a:9c brd ff:ff:ff:ff:ff:ff inet 192.168.31.141/24 brd 192.168.31.255 scope global dynamiceno16777736 valid_lft 35519sec preferred_lft 35519sec inet 192.168.31.5/32 scope global eno16777736 valid_lft forever preferred_lft forever inet 192.168.31.2/32 scope globaleno16777736 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe75:1a9c/64 scope link valid_lft forever preferred_lft forever slave1主機: mysql> show slave status\G; *************************** 1. row*************************** Slave_IO_State: Waiting formaster to send event Master_Host: 192.168.31.141 Master_User: rep Master_Port: 3306 slave2主機: mysql> show slave status\G; *************************** 1. row*************************** Slave_IO_State: Waiting formaster to send event Master_Host: 192.168.31.141 Master_User: rep Master_Port: 3306 啟動master1主機的mysql服務,觀察monitor日誌,master1的日誌如下: [root@monitor1 ~]# tail -f/var/log/mysql-mmm/mmm_mond.log 2017/01/09 22:16:56 INFO Check ‘mysql‘ on ‘master1‘ is ok! 2017/01/09 22:16:56 INFO Check ‘rep_backlog‘ on ‘master1‘ is ok! 2017/01/09 22:16:56 INFO Check ‘rep_threads‘ on ‘master1‘ is ok! 2017/01/09 22:16:59 FATAL State of host‘master1‘ changed from HARD_OFFLINE to AWAITING_RECOVERY 從上面可以看到master1的狀態由hard_offline改變為awaiting_recovery狀態 用如下命令將服務器上線: [root@monitor1 ~]#mmm_control set_onlinemaster1 查看群集最新狀態 [root@monitor1 ~]# mmm_control show master1(192.168.31.83) master/ONLINE. Roles: master2(192.168.31.141) master/ONLINE. Roles: reader(192.168.31.5),writer(192.168.31.2) slave1(192.168.31.250) slave/ONLINE. Roles: reader(192.168.31.4) slave2(192.168.31.225) slave/ONLINE. Roles: reader(192.168.31.3) 可以看到主庫啟動不會接管主,只到現有的主再次宕機。 總結 (1)master2備選主節點宕機不影響集群的狀態,就是移除了master2備選節點的讀狀態。 (2)master1主節點宕機,由master2備選主節點接管寫角色,slave1,slave2指向新master2主庫進行復制,slave1,slave2會自動change master到master2. (3)如果master1主庫宕機,master2復制應用又落後於master1時就變成了主可寫狀態,這時的數據主無法保證一致性。 如果master2, slave1,slave2延遲於master1主,這個時master1宕機,slave1,slave2將會等待數據追上db1後,再重新指向新的主node2進行復制操作,這時的數據也無法保證同步的一致性。 (4)如果采用MMM高可用架構,主,主備選節點機器配置一樣,而且開啟半同步進一步提高安全性或采用MariaDB/mysql5.7進行多線程從復制,提高復制的性能。 附: 1、日誌文件: 日誌文件往往是分析錯誤的關鍵,所以要善於利用日誌文件進行問題分析。 db端:/var/log/mysql-mmm/mmm_agentd.log 監控端:/var/log/mysql-mmm/mmm_mond.log 2、命令文件: mmm_agentd :db代理進程的啟動文件 mmm_mond :監控進程的啟動文件 mmm_backup :備份文件 mmm_restore :還原文件 mmm_control:監控操作命令文件 db服務器端只有mmm_agentd程序,其它的都是在monitor服務器端。 3、mmm_control用法 mmm_control程序可以用於監控群集狀態、切換writer、設置online\offline操作等。 Valid commands are: help - show this message #幫助信息 ping - ping monitor #ping當前的群集是否正常 show - show status #群集在線狀態檢查 checks [<host>|all [<check>|all]]- show checks status #執行監控檢查操作 set_online <host> - set host <host> online #將host設置為online set_offline <host> - set host <host> offline #將host設置為offline mode - print current mode. #打印輸出當前的mode set_active - switch into active mode. set_manual - switch into manual mode. set_passive - switch into passive mode. move_role [--force] <role> <host>- move exclusive role <role> to host <host> #移除writer服務器為指定的host服務器(Only use--force if you know what you are doing!) set_ip <ip> <host> - set role with ip <ip> to host<host> 檢查所有的db服務器群集狀態: [root@monitor1 ~]# mmm_control checksall 檢查項包括:ping、mysql是否正常運行、復制線程是否正常等 檢查群集環境在線狀況: [root@monitor1 ~]# mmm_control show 對指定的host執行offline操作: [root@monitor1 ~]# mmm_controlset_offline slave2 對指定的host執行onine操作: [root@monitor1 ~]# mmm_control set_onlineslave2 執行write切換(手動切換): 查看當前的slave對應的master [root@slave2 ~]# mysql -uroot -p123456-e ‘show slave status\G;‘ mysql: [Warning] Using a password on thecommand line interface can be insecure. *************************** 1. row*************************** Slave_IO_State: Waiting formaster to send event Master_Host: 192.168.31.141 writer切換,要確保mmm_common.conf文件中的writer屬性有配置對應的host,否則無法切換 [root@monitor1 ~]# mmm_control move_rolewriter master1 OK: Role ‘writer‘ has been moved from‘master2‘ to ‘master1‘. Now you can wait some time and check new roles info! [root@monitor1 ~]# mmm_control show master1(192.168.31.83) master/ONLINE. Roles: writer(192.168.31.2) master2(192.168.31.141) master/ONLINE. Roles: reader(192.168.31.5) slave1(192.168.31.250) slave/ONLINE. Roles: reader(192.168.31.4) slave2(192.168.31.225) slave/ONLINE. Roles: reader(192.168.31.3) save從庫自動切換到了新的master [root@slave2 ~]# mysql -uroot -p123456-e ‘show slave status\G;‘ mysql: [Warning] Using a password on thecommand line interface can be insecure. *************************** 1. row *************************** Slave_IO_State: Waiting formaster to send event Master_Host: 192.168.31.83 4、其它處理問題 如果不想讓writer從master切換到backup(包括主從的延時也會導致寫VIP的切換),那麽可以在配置/etc/mysql-mmm/mmm_common.conf時,去掉<role write>中的backup <role writer> #writer角色配置 hosts master1 #這裏只配置一個Hosts ips 192.168.31.2 #對外提供的寫操作的虛擬IP mode exclusive #exclusive代表只允許存在一個主,也就是只能提供一個寫的IP </role> 這樣的話當master1出現故障了writer寫操作不會切換到master2服務器,並且slave也不會指向新的master,此時當前的MMM之前對外提供寫服務。 5、總結 1.對外提供讀寫的虛擬IP是由monitor程序控制。如果monitor沒有啟動那麽db服務器不會被分配虛擬ip,但是如果已經分配好了虛擬ip,當monitor程序關閉了原先分配的虛擬ip不會立即關閉外部程序還可以連接訪問(只要不重啟網絡),這樣的好處就是對於monitor的可靠性要求就會低一些,但是如果這個時候其中的某一個db服務器故障了就無法處理切換,也就是原先的虛擬ip還是維持不變,掛掉的那臺DB的虛擬ip會變的不可訪問。 2.agent程序受monitor程序的控制處理write切換,從庫切換等操作。如果monitor進程關閉了那麽agent進程就起不到什麽作用,它本身不能處理故障。 3.monitor程序負責監控db服務器的狀態,包括Mysql數據庫、服務器是否運行、復制線程是否正常、主從延時等;它還用於控制agent程序處理故障。 4.monitor會每隔幾秒鐘監控db服務器的狀態,如果db服務器已經從故障變成了正常,那麽monitor會自動在60s之後將其設置為online狀態(默認是60s可以設為其它的值),有監控端的配置文件參數“auto_set_online”決定,群集服務器的狀態有三種分別是:HARD_OFFLINE→AWAITING_RECOVERY→online 5.默認monitor會控制mmm_agent會將writer db服務器read_only修改為OFF,其它的db服務器read_only修改為ON,所以為了嚴謹可以在所有的服務器的my.cnf文件中加入read_only=1由monitor控制來控制writer和read,root用戶和復制用戶不受read_only參數的影響。
本文出自 “SaltStack” 博客,請務必保留此出處http://wuhui1994.blog.51cto.com/12899232/1981129
MySQL 高可用MMM