mysql的MHA高可用

来源:https://www.cnblogs.com/1naonao/archive/2019/11/25/11929771.html
-Advertisement-
Play Games

一.MHA簡介 作者簡介 松信嘉範: MySQL/Linux專家 2001年索尼公司入職 2001年開始使用oracle 2004年開始使用MySQL 2006年9月 2010年8月MySQL從事顧問 2010年 2012年 DeNA 2012年~至今 Facebook 軟體簡介 MHA能夠在較短的 ...


一.MHA簡介

作者簡介


松信嘉範:
MySQL/Linux專家
2001年索尼公司入職
2001年開始使用oracle
2004年開始使用MySQL
2006年9月-2010年8月MySQL從事顧問
2010年-2012年 DeNA
2012年~至今 Facebook


軟體簡介

MHA能夠在較短的時間內實現自動故障檢測和故障轉移,通常在10-30秒以內;在複製框架中,MHA能夠很好地解決複製過程中的數據一致性問題,由於不需要在現有的replication中添加額外的伺服器,僅需要一個manager節點,而一個Manager能管理多套複製,所以能大大地節約伺服器的數量;另外,安裝簡單,無性能損耗,以及不需要修改現有的複製部署也是它的優勢之處。

MHA還提供線上主庫切換的功能,能夠安全地切換當前運行的主庫到一個新的主庫中(通過將從庫提升為主庫),大概0.5-2秒內即可完成。

MHA由兩部分組成:MHA Manager(管理節點)和MHA Node(數據節點)。MHA Manager可以獨立部署在一臺獨立的機器上管理多個Master-Slave集群,也可以部署在一臺Slave上。當Master出現故障時,它可以自動將最新數據的Slave提升為新的Master,然後將所有其他的Slave重新指向新的Master。整個故障轉移過程對應用程式是完全透明的。

二.工作流程

1)把宕機的master二進位日誌保存下來。
2)找到binlog位置點最新的slave。
3)在binlog位置點最新的slave上用relay log(差異日誌)修複其它slave。
4)將宕機的master上保存下來的二進位日誌恢復到含有最新位置點的slave上。
5)將含有最新位置點binlog所在的slave提升為master。
6)將其它slave重新指向新提升的master,並開啟主從複製。

三.MHA架構圖

img

  • MHA manager 可以安裝在任意一臺伺服器上
  • 一個MHA manager可以管理多套mysql集群(上百套)
  • 儘量避免安裝在主庫上(防止主庫斷點,斷網)
  • c\s結構的服務

四.MHA工具介紹

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的主從複製

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).支持延遲複製

缺點:

  • mysqldump備份起來很麻煩,需要額外加參數,--set-gtid=on
  • 如果只從複製遇到了錯誤,s起來停了.跳過錯誤,gtid無法跳過錯誤

主庫操作

修改配置文件

#編輯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

註:主庫從庫都需要開啟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

六.部署MHA(前提已經做好主從,儘量不在主庫上安裝管理節點)

主庫

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 [email protected]
[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]
[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]

啟動測試

#測試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

mha恢復(傳統的)

#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

MHA切換

如果在數據量相同的情況下,根據server標簽,越小優先順序越高

七.配置VIP漂移

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

測試動點vip漂移

一、創建建表語句
=============================================
學生表: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;

二、批量插入數據腳本
#!/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

八.配置binlog-server

修改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

九.MySQL中間件Atlas

Atlas簡介

Atlas是由 Qihoo 360公司Web平臺部基礎架構團隊開發維護的一個基於MySQL協議的數據中間層項目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基礎上,修改了大量bug,添加了很多功能特性。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基礎上,修改了大量bug,添加了很多功能特性。

Atlas主要功能


  • 1.讀寫分離
  • 2.從庫負載均衡
  • 3.IP過濾
  • 4.自動分表
  • 5.DBA可平滑上下線DB
  • 6.自動摘除宕機的DB

Atlas相對於官方MySQL-Proxy的優勢


  • 1.將主流程中所有Lua代碼用C重寫,Lua僅用於管理介面
  • 2.重寫網路模型、線程模型
  • 3.實現了真正意義上的連接池
  • 4.優化了鎖機制,性能提高數十倍

安裝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

vip漂移,atlas

node節點自動恢復從庫腳本

[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;"

管理節點調用腳本實現非交互,實現VIP漂移

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 \"`;
}
'''

實現atlas管理資料庫腳本

[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

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • watch 能間歇地執行程式,並將輸出結果以全屏的方式顯示,預設時2s執行一次; watch -n 5 ping -c 1 www.baidu.com # 進行迴圈5秒鐘,發送一次ping包; 使用範例: To watch for mail, you might do watch -n 60 fro ...
  • 一 前期準備 1.1 前置條件 集群部署:Kubernetes集群部署參考003——019。 glusterfs-Kubernetes部署:參考《附010.Kubernetes永久存儲之GlusterFS超融合部署》。 1.2 部署規劃 本實驗使用StatefulSet部署MongoDB集群,同時每 ...
  • 問題現象: 表示連接管道已經斷開 解決方法: 方法一:客戶端配置 在客戶端的 ~/.ssh/ config文件(如不存在請自行創建)中添加下麵內容: ServerAliveInterval 60 方法二:伺服器端配置 在伺服器的 /etc/ssh/sshd_config 中添加如下的配置: Clie ...
  • 修改nginx的配置文件,添加client_max_body_size 欄位 註:client_max_body_size 必須要放在server下的server_name下,而不是放在location欄位下麵 ...
  • https://sqlserver.code.blog/2019/11/25/you-may-fail-to-backup-log-or-restore-log-after-tde-certification-key-rotation/ ...
  • https://sqlserver.code.blog/2019/11/25/password-required-when-you-trying-to-add-a-database-having-a-master-key-to-ag-group/ ...
  • 上一篇說到,在Spark 2.x當中,實際上SQLContext和HiveContext是過時的,相反是採用SparkSession對象的sql函數來操作SQL語句的。使用這個函數執行SQL語句前需要先調用DataFrame的createOrReplaceTempView註冊一個臨時表,所以關鍵是先 ...
  • MongoDB簡介 基於分散式文件存儲的開源資料庫系統 將數據存儲為一個文檔,文檔類似於Json格式 MongoDB進入與退出 進入:mongo 退出:exit 庫級操作 顯示所有庫: show dbs 切換/創建資料庫: use 資料庫名稱 查看所在庫: db 刪除庫:db.dropDatabas ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...