做者簡介node
鬆信嘉範:
MySQL/Linux專家
2001年索尼公司入職
2001年開始使用oracle
2004年開始使用MySQL
2006年9月-2010年8月MySQL從事顧問
2010年-2012年 DeNA
2012年~至今 Facebookmysql
軟件簡介linux
MHA可以在較短的時間內實現自動故障檢測和故障轉移,一般在10-30秒之內;在複製框架中,MHA可以很好地解決複製過程當中的數據一致性問題,因爲不須要在現有的replication中添加額外的服務器,僅須要一個manager節點,而一個Manager能管理多套複製,因此能大大地節約服務器的數量;另外,安裝簡單,無性能損耗,以及不須要修改現有的複製部署也是它的優點之處。git
MHA還提供在線主庫切換的功能,可以安全地切換當前運行的主庫到一個新的主庫中(經過將從庫提高爲主庫),大概0.5-2秒內便可完成。github
MHA由兩部分組成:MHA Manager(管理節點)和MHA Node(數據節點)。MHA Manager能夠獨立部署在一臺獨立的機器上管理多個Master-Slave集羣,也能夠部署在一臺Slave上。當Master出現故障時,它能夠自動將最新數據的Slave提高爲新的Master,而後將全部其餘的Slave從新指向新的Master。整個故障轉移過程對應用程序是徹底透明的。sql
1)把宕機的master二進制日誌保存下來。
2)找到binlog位置點最新的slave。
3)在binlog位置點最新的slave上用relay log(差別日誌)修復其它slave。
4)將宕機的master上保存下來的二進制日誌恢復到含有最新位置點的slave上。
5)將含有最新位置點binlog所在的slave提高爲master。
6)將其它slave從新指向新提高的master,並開啓主從複製。數據庫
vim
MHA軟件由兩部分組成,Manager工具包和Node工具包,具體的說明以下:後端
Manager工具包主要包括如下幾個工具:安全
masterha_check_ssh #檢查MHA的ssh-key masterha_check_repl #檢查主從複製狀況 masterha_manger #啓動MHA masterha_check_status #檢測MHA的運行狀態 masterha_master_monitor #檢測master是否宕機 masterha_master_switch #手動故障轉移 masterha_conf_host #手動添加server信息 masterha_secondary_check #創建TCP鏈接從遠程服務器 masterha_stop #中止MHA
Node工具包主要包括如下幾個工具:
cd /root/mha4mysql-node-0.56/bin save_binary_logs #保存宕機的master的binlog apply_diff_relay_logs #識別relay log的差別 filter_mysqlbinlog #防止回滾事件 purge_relay_logs #清除中繼日誌
MHA優勢總結
1)Masterfailover and slave promotion can be done very quickly
自動故障轉移快
2)Mastercrash does not result in data inconsistency
主庫崩潰不存在數據一致性問題
3)Noneed to modify current MySQL settings (MHA works with regular MySQL)
不須要對當前mysql環境作重大修改
4)Noneed to increase lots of servers
不須要添加額外的服務器(僅一臺manager就可管理上百個replication)
5)Noperformance penalty
性能優秀,可工做在半同步複製和異步複製,當監控mysql狀態時,僅須要每隔N秒向master發送ping包(默認3秒),因此對性能無影響。你能夠理解爲MHA的性能和簡單的主從複製框架性能同樣。
ping baidu.com 10.0.0.50(icmp) sql ping select ping 檢測主庫的心跳
6)Works with any storage engine
只要replication支持的存儲引擎,MHA都支持,不會侷限於innodb
MySQL環境準備
1)環境檢查
mysql-db01
#系統版本 [root@mysql-db01 ~]# cat /etc/redhat-release CentOS release 6.7 (Final) #內核版本 [root@mysql-db01 ~]# uname -r 2.6.32-573.el6.x86_64 #IP地址 [root@mysql-db01 ~]# hostname -I 10.0.0.51
mysql-db02
#系統版本 [root@mysql-db02 ~]# cat /etc/redhat-release CentOS release 6.7 (Final) #內核版本 [root@mysql-db02 ~]# uname -r 2.6.32-573.el6.x86_64 #IP地址 [root@mysql-db02 ~]# hostname -I 10.0.0.52
mysql-db03
#系統版本 [root@mysql-db03 ~]# cat /etc/redhat-release CentOS release 6.7 (Final) #內核版本 [root@mysql-db03 ~]# uname -r 2.6.32-573.el6.x86_64 #IP地址 [root@mysql-db03 ~]# hostname -I 10.0.0.53
安裝MySQL
1)安裝包準備
#建立安裝包存放目錄 [root@mysql-db01 ~]# mkdir /home/oldboy/tools -p #進入目錄 [root@mysql-db01 ~]# cd /home/oldboy/tools/ #上傳mysql安裝包(mysql-5.6.16-linux-glibc2.5-x86_64.tar.gz) [root@mysql-db01 tools]# rz -be
2)安裝
#建立安裝目錄 [root@mysql-db01 tools]# mkdir /application #解壓mysql二進制包 [root@mysql-db01 tools]# tar xf mysql-5.6.16-linux-glibc2.5-x86_64.tar.gz #移動安裝包 [root@mysql-db01 tools]# mv mysql-5.6.16-linux-glibc2.5-x86_64 /application/mysql-5.6.16 #作軟連接 [root@mysql-db01 tools]# ln -s /application/mysql-5.6.16/ /application/mysql #建立mysql用戶 [root@mysql-db01 tools]# useradd mysql -s /sbin/nologin -M #進入mysql初始化目錄 [root@mysql-db01 tools]# cd /application/mysql/scripts/ #初始化mysql [root@mysql-db01 scripts]# ./mysql_install_db \ --user=mysql \ --datadir=/application/mysql/data/ \ --basedir=/application/mysql/ #註解 --user: 指定mysql用戶 --datadir:指定mysql數據存放目錄 --basedir:指定mysql base目錄 #拷貝mysql配置文件 [root@mysql-db01 ~]# \cp /application/mysql/support-files/my-default.cnf /etc/my.cnf #拷貝mysql啓動腳本 [root@mysql-db01 ~]# cp /application/mysql/support-files/mysql.server /etc/init.d/mysqld #修改mysql默認安裝目錄(不然沒法啓動) [root@mysql-db01 ~]# sed -i 's#/usr/local#/application#g' /etc/init.d/mysqld [root@mysql-db01 ~]# sed -i 's#/usr/local#/application#g' /application/mysql/bin/mysqld_safe #配置mysql環境變量 [root@mysql-db01 ~]# echo 'export PATH="/application/mysql/bin:$PATH"' >> /etc/profile.d/mysql.sh #刷新環境變量 [root@mysql-db01 ~]# source /etc/profile 2.2.3啓動 #加入開機自啓 [root@mysql-db01 ~]# chkconfig mysqld on #啓動mysql [root@mysql-db01 ~]# /etc/init.d/mysqld start Starting MySQL........... SUCCESS! #啓動成功 2.2.4配置密碼 #配置mysql密碼爲oldboy123 [root@mysql-db01 ~]# mysqladmin -uroot password oldboy123
GTID:全局惟一標識符,由UUID+TID,TID是事務提交編號,提交一個事務+1
342a3b8f-0d8e-11ea-8095-000c29c7dac3:1 342a3b8f-0d8e-11ea-8095-000c29c7dac3:2 342a3b8f-0d8e-11ea-8095-000c29c7dac3:23
先決條件
1)主庫和從庫都要開啓binlog
2)主庫和從庫server-id不一樣
3)要有主從複製用戶
GTID優勢:
(1).支持多線程複製:事實上是針對每一個database開啓相應的獨立線程,即每一個庫有一個單獨的(sql
thread).
(2).支持啓用GTID,在配置主從複製,傳統的方式裏,你須要找到binlog和POS點,而後change master to指向. 在
mysql5.6裏,無須再知道binlog和POS點,只須要知道master的IP/端口/帳號密碼便可,由於同步複製是自動的,MySQL通
過內部機制GTID自動找點同步.(show master status)
(3).基於Row複製只保存改變的列,大大節省Disk Space/Network resources和Memory usage.
(4).支持把Master 和Slave的相關信息記錄在Table中 原來是記錄在文件裏,記錄在表裏,加強可用性
(5).支持延遲複製
缺點:
主庫操做
修改配置文件
#編輯mysql配置文件 [root@mysql-db01 ~]# vim /etc/my.cnf #在mysqld標籤下配置 [mysqld] #主庫server-id爲1,從庫不等於1 server_id =1 #開啓binlog日誌 log_bin=mysql-bin
建立主從複製用戶
#登陸數據庫 [root@mysql-db01 ~]# mysql -uroot -poldboy123 #建立rep用戶 mysql> grant replication slave on *.* to rep@'10.0.0.%' identified by 'oldboy123';
從庫操做
修改配置文件
#修改mysql-db02配置文件 [root@mysql-db02 ~]# vim /etc/my.cnf #在mysqld標籤下配置 [mysqld] #主庫server-id爲1,從庫必須大於1 server_id =5 #開啓binlog日誌 log_bin=mysql-bin #重啓mysql [root@mysql-db02 ~]# /etc/init.d/mysqld restart #修改mysql-db03配置文件 [root@mysql-db03 ~]# vim /etc/my.cnf #在mysqld標籤下配置 [mysqld] #主庫server-id爲1,從庫必須大於1 server_id =10 #開啓binlog日誌 log_bin=mysql-bin #重啓mysql [root@mysql-db03 ~]# /etc/init.d/mysqld restart
注:在以往若是是基於binlog日誌的主從複製,則必需要記住主庫的master狀態信息。
mysql> show master status; +------------------+----------+ | File | Position | +------------------+----------+ | mysql-bin.000002 | 120 | +------------------+----------+
開啓GTID
#沒開啓以前先看一下GTID的狀態 mysql> show global variables like '%gtid%'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | enforce_gtid_consistency | OFF | | gtid_executed | | | gtid_mode | OFF | | gtid_owned | | | gtid_purged | | +--------------------------+-------+ #編輯mysql配置文件(主庫從庫都須要修改) [root@mysql-db01 ~]# vim /etc/my.cnf #在[mysqld]標籤下添加 [mysqld] gtid_mode=ON log_slave_updates #保持binlog刷新 enforce_gtid_consistency #重啓數據庫 [root@mysql-db01 ~]# /etc/init.d/mysqld restart #檢查GTID狀態 mysql> show global variables like '%gtid%'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | enforce_gtid_consistency | ON | #執行GTID一致 | gtid_executed | | | gtid_mode | ON | #開啓GTID模塊 | gtid_owned | | | gtid_purged | | +--------------------------+-------+
log-slave-updates 何時用
注:主庫從庫都須要開啓GTID不然在作主從複製的時候就會報錯:
[root@mysql-db02 ~]# mysql -uroot -poldboy123 mysql> change master to -> master_host='10.0.0.51', -> master_user='rep', -> master_password='oldboy123', -> master_auto_position=1; ERROR 1777 (HY000): CHANGE MASTER TO MASTER_AUTO_POSITION = 1 can only be executed when @@GLOBAL.GTID_MODE = ON.
配置主從複製
#登陸數據庫 [root@mysql-db02 ~]# mysql -uroot -poldboy123 #配置複製主機信息 mysql> change master to #主庫IP -> master_host='10.0.0.51', #主庫複製用戶 -> master_user='rep', #主庫複製用戶的密碼 -> master_password='oldboy123', #GTID位置點 -> master_auto_position=1; #開啓slave mysql> start slave; #查看slave狀態 mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.0.0.51 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 403 Relay_Log_File: mysql-db02-relay-bin.000002 Relay_Log_Pos: 613 Relay_Master_Log_File: mysql-bin.000003 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: 403 Relay_Log_Space: 822 Until_Condition: None
1.開啓binlog
2.開啓server_id
3.建立主從複製用戶
1.開啓binlog
2.開啓server_id:從庫與主庫之間的server_id不一樣便可, 從庫之間不能夠相同
3.change master to
4.在作主從以前,要保證數據的一致性
5.從庫也要建立主從複製用戶
#臨時關閉relay log(主庫和從庫) set global relay_log_purge = 0; # 臨時開啓 只讀(從庫) set global read_only=1; # 永久關閉自動刪除relay log(主庫和從庫) relay_log_purge = 0
1)環境準備(全部節點)
# 安裝node和manager,必需要有epel wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo # 安裝node節點(有幾臺數據庫就裝幾個node節點) [root@db01 ~]# yum localinstall -y mha4mysql-node-0.56-0.el6.noarch.rpm # 每臺數據庫上都要建立 mha 管理用戶(主庫執行從庫會複製) mysql> grant all on *.* to mha@'%' identified by 'mha';
命令軟鏈接(全部節點)
#若是不建立命令軟鏈接,檢測mha複製狀況的時候會報錯 [root@mysql-db01 ~]# ln -s /application/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog [root@mysql-db01 ~]# ln -s /application/mysql/bin/mysql /usr/bin/mysql
部署管理節點(mha-manager:mysql-db03)
#安裝manager包 [root@mysql-db03 tools]# rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm Preparing... ########################################### [100%] 1:mha4mysql-manager ########################################### [100%]
編輯配置文件
#建立配置文件目錄 [root@mysql-db03 ~]# mkdir -p /etc/mha #建立日誌目錄 [root@mysql-db03 ~]# mkdir -p /etc/mha/app1 #編輯mha配置文件 [root@mysql-db03 ~]# vim /etc/mha/app1.cnf # 修改配置文件 [server default] #MHA日誌名字 manager_log=/etc/mha/manager.log #MHA的工做目錄 manager_workdir=/etc/mha/app1 #數據庫binlog存放路徑 master_binlog_dir=/application/mysql/data #mha管理用戶的用戶名 user=mha #mha管理用戶的密碼 password=mha #監測心跳,每隔2秒監測一次(默認是3秒) ping_interval=2 #主從複製用戶的密碼 repl_password=123 #主從複製用戶 repl_user=slave #ssh遠程鏈接用戶(作完免密的) ssh_user=root [server1] hostname=10.0.0.51 port=3306 [server2] hostname=10.0.0.52 port=3306 ssh 免密認證 MHA監測啓動 [server3] hostname=10.0.0.53 port=3306 [server4] hostname=10.0.0.54 port=3306
配置文件詳解
[server default] #設置manager的工做目錄 manager_workdir=/var/log/masterha/app1 #設置manager的日誌 manager_log=/var/log/masterha/app1/manager.log #設置master 保存binlog的位置,以便MHA能夠找到master的日誌,我這裏的也就是mysql的數據目錄 master_binlog_dir=/data/mysql #設置自動failover時候的切換腳本 master_ip_failover_script= /usr/local/bin/master_ip_failover #設置手動切換時候的切換腳本 master_ip_online_change_script= /usr/local/bin/master_ip_online_change #設置mysql中root用戶的密碼,這個密碼是前文中建立監控用戶的那個密碼 password=123456 #設置監控用戶root user=root #設置監控主庫,發送ping包的時間間隔,嘗試三次沒有迴應的時候自動進行failover ping_interval=1 #設置遠端mysql在發生切換時binlog的保存位置 remote_workdir=/tmp #設置複製用戶的密碼 repl_password=123456 #設置複製環境中的複製用戶名 repl_user=rep #設置發生切換後發送的報警的腳本 report_script=/usr/local/send_report #一旦MHA到server02的監控之間出現問題,MHA Manager將會嘗試從server03登陸到server02 secondary_check_script= /usr/local/bin/masterha_secondary_check -s server03 -s server02 --user=root --master_host=server02 --master_ip=192.168.0.50 --master_port=3306 #設置故障發生後關閉故障主機腳本(該腳本的主要做用是關閉主機放在發生腦裂,這裏沒有使用) shutdown_script="" #設置ssh的登陸用戶名 ssh_user=root [server1] hostname=10.0.0.51 port=3306 [server2] hostname=10.0.0.52 port=3306 #設置爲候選master,若是設置該參數之後,發生主從切換之後將會將此從庫提高爲主庫,即便這個主庫不是集羣中事件最新的slave。 candidate_master=1 #默認狀況下若是一個slave落後master 100M的relay logs的話,MHA將不會選擇該slave做爲一個新的master,由於對於這個slave的恢復須要花費很長時間,經過設置check_repl_delay=0,MHA觸發切換在選擇一個新的master的時候將會忽略複製延時,這個參數對於設置了candidate_master=1的主機很是有用,由於這個候選主在切換的過程當中必定是新的master check_repl_delay=0
配置ssh信任(全部節點)
#建立祕鑰對 [root@mysql-db01 ~]# ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1 #發送公鑰,包括本身 [root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.51 [root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.52 [root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.53
啓動測試
#測試ssh [root@mysql-db03 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf #看到以下字樣,則測試成功 Tue Mar 7 01:03:33 2017 - [info] All SSH connection tests passed successfully. #測試複製 [root@mysql-db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf #看到以下字樣,則測試成功 MySQL Replication Health is OK.
啓動MHA
#啓動 [root@mysql-db03 ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 & #測試啓動是否成功 [root@db04 scripts]# masterha_check_status --conf=/etc/mha/app1.cnf app1 (pid:7916) is running(0:PING_OK), master:10.0.0.51
切換master測試
#登陸數據庫(db02) [root@mysql-db02 ~]# mysql -uroot -poldboy123 #檢查複製狀況 mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.0.0.51 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000006 Read_Master_Log_Pos: 191 Relay_Log_File: mysql-db02-relay-bin.000002 Relay_Log_Pos: 361 Relay_Master_Log_File: mysql-bin.000006 Slave_IO_Running: Yes Slave_SQL_Running: Yes #登陸數據庫(db03) [root@mysql-db03 ~]# mysql -uroot -poldboy123 #檢查複製狀況 mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.0.0.51 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000006 Read_Master_Log_Pos: 191 Relay_Log_File: mysql-db03-relay-bin.000002 Relay_Log_Pos: 361 Relay_Master_Log_File: mysql-bin.000006 Slave_IO_Running: Yes Slave_SQL_Running: Yes #停掉主庫 [root@mysql-db01 ~]# /etc/init.d/mysqld stop Shutting down MySQL..... SUCCESS! #登陸數據庫(db02) [root@mysql-db02 ~]# mysql -uroot -poldboy123 #查看slave狀態 mysql> show slave status\G #db02的slave已經爲空 Empty set (0.00 sec) #登陸數據庫(db03) [root@mysql-db03 ~]# mysql -uroot -poldboy123 #查看slave狀態 mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.0.0.52 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000006 Read_Master_Log_Pos: 191 Relay_Log_File: mysql-db03-relay-bin.000002 Relay_Log_Pos: 361 Relay_Master_Log_File: mysql-bin.000006 Slave_IO_Running: Yes Slave_SQL_Running: Yes
#1.恢復舊主庫 [root@db01 ~]# /etc/init.d/mysqld start Starting MySQL SUCCESS! #2.在mha日誌中找到change master to [root@db04 ~]# grep -i 'change master to' /etc/mha/manager.log Tue Nov 19 20:50:57 2019 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='slave', MASTER_PASSWORD='xxx'; Wed Nov 20 03:29:19 2019 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=120, MASTER_USER='slave', MASTER_PASSWORD='xxx'; #3.在舊主庫中執行change master語句 CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=120, MASTER_USER='slave', MASTER_PASSWORD='xxx'; #4.將mha配置文件修復 [server1] hostname=10.0.0.51 port=3306 #5.啓動mha [root@db04 ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf -- ignore_last_failover < /dev/null > /etc/mha/manager.log 2>&1 & [root@db04 ~]# masterha_check_status --conf=/etc/mha/app1.cnf #MHA啓動命令 詳解 nohup masterha_manager #配置文件路徑 --conf=/etc/mha/app1.cnf #從配置文件中移除主庫 --remove_dead_master_conf #忽略上次切換 --ignore_last_failover < /dev/null > /etc/mha/manager.log 2>&1 & #mha工做機制:在mha一次切換後,會在mha的工做目錄下生成一個lock,鎖文件
注意:從新切換後,再次啓動mha
#分別放在每一個node節點服務下 [root@db03 ~]# vim abc.sh #!/bin/bash /etc/init.d/mysqld start change=`ssh 10.0.0.54 "grep -i 'change master to' /etc/mha/manager.log"|awk -F : '{print $4}'|sed 's#xxx#123#g'` mysql -e "$change;start slave;" ssh 10.0.0.54 \cp /etc/mha/app1.cnf.ori /etc/mha/app1.cnf
若是在數據量相同的狀況下,根據server標籤,越小優先級越高
VIP漂移的兩種方式
1)經過keepalived的方式,管理虛擬IP的漂移
2)經過MHA自帶腳本方式,管理虛擬IP的漂移
MHA腳本方式
修改配置文件
#編輯配置文件 [root@mysql-db03 ~]# vim /etc/mha/app1.cnf #在[server default]標籤下添加 [server default] #使用MHA自帶腳本 master_ip_failover_script=/usr/local/bin/master_ip_failover
編輯腳本
#修改ssh端口.配置文件APP1.cnf和/etc/mha/master_ip_failover都要添加 #根據配置文件中腳本路徑編輯 [root@mysql-db03 ~]# vim /etc/mha/master_ip_failover #修改如下幾行內容 my $vip = '10.0.0.55/24'; my $key = '0'; my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip"; my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down"; #添加執行權限,不然mha沒法啓動 [root@mysql-db03 ~]# chmod +x /etc/mha/master_ip_failover #語法問題 #格式問題 yum -y install dos2unix [root@db04 mha]# dos2unix master_ip_failover dos2unix: converting file master_ip_failover to Unix format ...
手動綁定VIP
#綁定vip [root@mysql-db01 ~]# ifconfig eth0:0 10.0.0.55/24 #宕掉 ifconfig eth0:0 down #查看vip [root@mysql-db01 ~]# ip a |grep eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0 inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
測試ip漂移
#登陸db02 [root@mysql-db02 ~]# mysql -uroot -poldboy123 #查看slave信息 mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.0.0.51 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000007 Read_Master_Log_Pos: 191 Relay_Log_File: mysql-db02-relay-bin.000002 Relay_Log_Pos: 361 Relay_Master_Log_File: mysql-bin.000007 Slave_IO_Running: Yes Slave_SQL_Running: Yes #停掉主庫 [root@mysql-db01 ~]# /etc/init.d/mysqld stop Shutting down MySQL..... SUCCESS! #在db03上查看從庫slave信息 mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.0.0.52 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000006 Read_Master_Log_Pos: 191 Relay_Log_File: mysql-db03-relay-bin.000002 Relay_Log_Pos: 361 Relay_Master_Log_File: mysql-bin.000006 Slave_IO_Running: Yes Slave_SQL_Running: Yes #在db01上查看vip信息 [root@mysql-db01 ~]# ip a |grep eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0 #在db02上查看vip信息 [root@mysql-db02 ~]# ip a |grep eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 10.0.0.52/24 brd 10.0.0.255 scope global eth0 inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
1.中止vip 2.從新作從庫指向 預防: 停庫檢查mha配置文件是否補全,沒有,補全,啓動mha
1、建立建表語句 ============================================= 學生表:Student(Sno,Sname,Ssex,Sage,Sdept) ------(學號-主鍵,姓名,性別,年齡,所在系) ============================================= create table student( Sno int(10) NOT NULL COMMENT '學號', Sname varchar(16) NOT NULL COMMENT '姓名', Ssex char(2) NOT NULL COMMENT '性別', Sage tinyint(2) NOT NULL default '0' COMMENT '學生年齡', Sdept varchar(16) default NULL COMMENT '學生所在系別', PRIMARY KEY (Sno) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 2、批量插入數據腳本 #!/bin/bash MysqlLogin="mysql -uroot -p123" i=1 while true do ${MysqlLogin} -e "insert into test.student values ("$I",'zls"$i"','m','21','computer"$i"');" ((i++)) sleep 2; done
修改mha配置文件
[root@mysql-db03 ~]# vim /etc/mha/app1.cnf [binlog1] no_master=1 hostname=10.0.0.54 #主庫 master_binlog_dir=/data/mysql/binlog/
備份binlog
#建立備份binlog目錄 [root@mysql-db03 ~]# mkdir -p /data/mysql/binlog/ #進入該目錄 [root@mysql-db03 ~]# cd /data/mysql/binlog/ #備份binlog(進入創鍵目錄下) [root@mysql-db03 binlog]# mysqlbinlog -R --host=10.0.0.51 --user=mha --password=mha --raw --stop-never mysql-bin.000001 & #啓動mha [root@mysql-db03 binlog]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/mha/manager.log 2>&1 &
測試binlog備份
#查看binlog目錄中的binlog [root@mysql-db03 binlog]# ll total 44 -rw-r--r-- 1 root root 285 Mar 8 03:11 mysql-bin.000001 #登陸主庫 [root@mysql-db01 ~]# mysql -uroot -poldboy123 #刷新binlog mysql> flush logs; #再次查看binlog目錄 [root@mysql-db03 binlog]# ll total 48 -rw-r--r-- 1 root root 285 Mar 8 03:11 mysql-bin.000001 -rw-r--r-- 1 root root 143 Mar 8 04:00 mysql-bin.000002
Atlas簡介
Atlas是由 Qihoo 360公司Web平臺部基礎架構團隊開發維護的一個基於MySQL協議的數據中間層項目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基礎上,修改了大量bug,添加了不少功能特性。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基礎上,修改了大量bug,添加了不少功能特性。
Atlas主要功能
Atlas相對於官方MySQL-Proxy的優點
安裝Atlas
同窗們有福了,安裝Atlas真的是炒雞簡單,官方提供的Atlas有兩種:
1)Atlas (普通) : Atlas-2.2.1.el6.x86_64.rpm
2)Atlas (分表) : Atlas-sharding_1.0.1-el6.x86_64.rpm
這裏咱們只須要下載普通的便可。
#在主庫安裝,進入安裝包目錄 [root@mysql-db01 ~]# cd /home/oldboy/tools/ #下載Atlas [root@mysql-db01 tools]# wget httpss://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm #安裝 [root@mysql-db01 tools]# rpm -ivh Atlas-2.2.1.el6.x86_64.rpm Preparing... ########################################### [100%] 1:Atlas ########################################### [100%]
編輯配置文件
#進入Atlas工具目錄 [root@mysql-db01 ~]# cd /usr/local/mysql-proxy/bin/ #生成密碼 [root@mysql-db01 bin]# ./encrypt oldboy123 #修改Atlas配置文件 [root@mysql-db01 ~]# vim /usr/local/mysql-proxy/conf/test.cnf #(instance = test) #Atlas後端鏈接的MySQL主庫的IP和端口,可設置多項,用逗號分隔 proxy-backend-addresses = 10.0.0.51:3306 #Atlas後端鏈接的MySQL從庫的IP和端口 proxy-read-only-backend-addresses = 10.0.0.52:3306,10.0.0.53:3306 #用戶名與其對應的加密過的MySQL密碼 pwds = root:1N/CNLSgqXuTZ6zxvGQr9A== #SQL日誌的開關 sql-log = ON #Atlas監聽的工做接口IP和端口 proxy-address = 0.0.0.0:3307 #默認字符集,設置該項後客戶端再也不須要執行SET NAMES語句 charset = utf8
啓動Atlas
[root@mysql-db01 ~]# /usr/local/mysql-proxy/bin/mysql-proxyd test start OK: MySQL-Proxy of test is started
Atlas管理接口操做
#用atlas管理用戶登陸 [root@mysql-db01 ~]# mysql -uuser -ppwd -h127.0.0.1 -P2345 #查看可用命令幫助 mysql> select * from help; #查看後端代理的庫 mysql> SELECT * FROM backends; +-------------+----------------+-------+------+ | backend_ndx | address | state | type | +-------------+----------------+-------+------+ | 1 | 10.0.0.51:3307 | up | rw | | 2 | 10.0.0.53:3307 | up | ro | | 3 | 10.0.0.52:3307 | up | ro | +-------------+----------------+-------+------+ #平滑摘除mysql mysql> REMOVE BACKEND 2; Empty set (0.00 sec) #檢查是否摘除成功 mysql> SELECT * FROM backends; +-------------+----------------+-------+------+ | backend_ndx | address | state | type | +-------------+----------------+-------+------+ | 1 | 10.0.0.51:3307 | up | rw | | 2 | 10.0.0.52:3307 | up | ro | +-------------+----------------+-------+------+ #保存到配置文件中 mysql> SAVE CONFIG; Empty set (0.06 sec)
mysql> select * from help; +----------------------------+---------------------------------------------------------+ | command | description | +----------------------------+---------------------------------------------------------+ | SELECT * FROM help | shows this help | | SELECT * FROM backends | 查看後端的服務器狀態 | | SET OFFLINE $backend_id | 平滑下線 例如:set offline 2; | | SET ONLINE $backend_id | 平滑上線 例如:set online 2; | | ADD MASTER $backend | 添加後端主庫:add master 10.0.0.56:3306 | | ADD SLAVE $backend | 添加後端從庫:add slave 10.0.0.56:3306; | | REMOVE BACKEND $backend_id | 刪除後端節點: remove backend 1; | | SELECT * FROM clients | 查看容許鏈接的客戶端IP | | ADD CLIENT $client | 添加客戶端IP:add client 10.0.0.51; | | REMOVE CLIENT $client | 刪除客戶端IP:remove client 10.0.0.51 | | SELECT * FROM pwds | 查看後端數據庫的用戶和密碼 | | ADD PWD $pwd | 添加用戶,自動加密:add pwd root:123 | | ADD ENPWD $pwd | 添加用戶,須要手動加密後的密碼 | | REMOVE PWD $pwd | 刪除沒有用的用戶:remove pwd xxx; | | SAVE CONFIG | 保存到配置文件 | | SELECT VERSION | 查看版本 | +----------------------------+---------------------------------------------------------+
補充:傳統作法
主配: [root@db01 scripts]# cat /etc/my.cnf [mysqld] log-bin=mysql-bin server_id=1 #gtid_mode=on #log-slave-updates #enforce_gtid_consistency #relay_log_purge = 0 skip_name_resolve relay_log_purge = 0 從配: [root@db02 scripts]# cat /etc/my.cnf [mysqld] server_id=2 #gtid_mode=on log-bin=mysql-bin #log-slave-updates #enforce_gtid_consistency #relay_log_purge = 0 skip_name_resolve #管理節點:注意擋掉以後節點就沒了,需添加 [root@db04 scripts]# vim /etc/mha/app1.cnf [server default] manager_log=/etc/mha/manager.log manager_workdir=/etc/mha/app1 master_binlog_dir=/application/mysql/data password=mha ping_interval=2 repl_password=123 repl_user=slave ssh_user=root user=mha [server2] hostname=10.0.0.52 port=3306 [server3] hostname=10.0.0.53 port=3306 [server4] hostname=10.0.0.54 port=3306
[root@db02 ~]# cat abc.sh #!/bin/bash /etc/init.d/mysqld start change=`ssh 10.0.0.54 "grep -i 'change master to' /etc/mha/manager.log"|awk -F : '{print $4}'|sed 's#xxx#123#g'` mysql -e "$change;start slave;"
vim master_ip_failover '''' my ( $command, $ssh_user, $orig_master_host, $orig_master_ip, $orig_master_port, $new_master_host, $new_master_ip, $new_master_port ); my $vip = '10.0.0.55/24'; my $key = '0'; my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip"; my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down"; ''' sub start_vip() { `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`; `ssh $ssh_user\@$orig_master_host \" sh /root/abc.sh \"`; } sub stop_vip() { return 0 unless ($ssh_user); `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`; } '''
[root@db04 mha]# vim /root/cre.sh #!/bin/bash while true;do succ=`sed -nr 's#^Master.*ted (.*)\.$#\1#gp' /etc/mha/manager.log` if [[ $succ == 'successfully' ]];then \cp /etc/mha/app1.cnf.ori /etc/mha/app1.cnf down_master=`sed -nr 's#^Master (.*)\(.*down\!#\1#gp' /etc/mha/manager.log` new_master=`sed -rn 's#^Master .*\((.*)\) completed.*#\1#gp' /etc/mha/manager.log` new_master_num=`mysql -uuser -ppwd -h127.0.0.1 -P2345 -e 'select * from backends;'|grep '$new_master' |awk '{print $1}'` mysql -uuser -ppwd -h127.0.0.1 -P2345 -e "remove backend ${new_master_num};save config;" mysql -uuser -ppwd -h127.0.0.1 -P2345 -e "add slave ${down_master}:3306;save config;" nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/mha/manager.log 2>&1 & else echo "$(date +%F-%T) MHA沒有切換" > /etc/mha/app1.log sleep 2 fi done