亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

什么是雙主復制

在傳統的主從復制架構中,從庫僅僅是作為主庫數據的備份,當主庫發生故障時,數據庫將停止對外提供服務,并且主庫故障后手動進行主從切換的過程也較為繁瑣。為了解決這個問題,可以采用 MySQL 雙主模式,其中一臺主庫提供服務,另一臺作為熱備。結合 keepalived 使用虛擬 IP 對外提供服務,一旦主庫發生故障,備庫可以在很短的時間內接管服務。

 

機器規劃

搭建 MySQL 雙主同步

準備工作

創建相關目錄

#創建用戶userdel -r mysqlgroupadd mysql useradd -r -g mysql -s /bin/false mysql 

#創建目錄# /mysql/App/                                   MySQL 數據庫軟件根目錄# /mysql/data/3306/data/                        MySQL 數據文件目錄# /mysql/log/3306/binlog                        MySQL 二進制日志目錄# /mysql/log/3306/relaylog                      MySQL 中繼日志目錄# /mysql/backup/3306/xtrabackup/target_dir      MySQL xtrabackup 物理備份目錄# /mysql/backup/3306/mysqldump                  MySQL mysqldump 邏輯備份目錄# /mysql/script                                 MySQL 常用腳本存放目錄
mkdir -p /mysql/app/            mkdir -p /mysql/data/3308/data/                                 mkdir -p /mysql/log/3308/binlog                                 mkdir -p /mysql/log/3308/relaylog                               mkdir -p /mysql/backup/3308/xtrabackup/target_dir               mkdir -p /mysql/backup/3308/mysqldump    mkdir -p /mysql/script                                                                      
#給目錄授權chown -R mysql:mysql /mysql

復制代碼

下載并解壓 MySQL 安裝包

MySQL 壓縮包下載地址:https://dev.mysql.com/downloads/mysql/5.7.html

 

#解壓壓縮包tar zxvf mysql-5.7.29-linux-glibc2.12-x86_64.tar.gz -C /mysql/appmv /mysql/app/mysql-5.7.29-linux-glibc2.12-x86_64 /mysql/app/mysqlchown -R mysql:mysql /mysql  

復制代碼

配置環境變量

##將MySQL目錄添加環境變量##cat >> ~/.bash_profile <<-EOFexport PATH=$PATH:/mysql/app/mysql/binEOF
source ~/.bash_profile

復制代碼

初始化主庫 A

主庫 A 重要配置如下:

 

  • 開啟 binlog:log_bin=binlog 目錄

  • 設置 server_id:server_id = 1,主庫 A 的 server_id 和主庫 B 要不一樣。

  • 針對 GTIP 的方式同步有兩個參數必須設置:

  • gtid_mode=on

  • enforce_gtid_consistency=on

  • 防止主鍵沖突:

  • 設置自增主鍵步長,通常有幾個主庫 就寫幾,避免主鍵沖突:auto_increment_increment=2

  • 設置自增主鍵起始值,第一個主庫為 1,第二個主庫為 2,以此類推:auto_increment_offset=1

 

關于防止主鍵沖突的兩個參數的詳解可以查看 這篇博客。

 

#主機名和端口號作為目錄名的一部分HostName=`hostname`MySql_Port=3308#IP地址Ip=192.168.1.36#master server_id 要和 slave 不一樣Server_Id=1
cat > /mysql/data/$MySql_Port/my.cnf <<-EOF#------------------------------------ #客戶端設置#------------------------------------[client]port=$MySql_Portsocket =/mysql/data/$MySql_Port/mysql.sockdefault-character-set=utf8 

#------------------------------------ #mysql連接工具設置#------------------------------------[mysql]prompt="\u@\h \d \r:\m:\s>" #登錄時顯示登錄的用戶名、服務器地址、默認數據庫名、當前時間auto-rehash #讀取表信息和列信息,可以在連上終端后開啟tab補齊功能。default-character-set=utf8 #默認字符集
#------------------------------------ #基本設置#------------------------------------[mysqld]bind_address=0.0.0.0  #監聽本地所有地址port=$MySql_Port  #端口號user=mysql  #用戶basedir=/mysql/app/mysql  #安裝路徑datadir=/mysql/data/$MySql_Port/data  #MySQL數據目錄socket=/mysql/data/$MySql_Port/mysql.sock #用于本地連接的socket文件目錄pid-file=/mysql/data/$MySql_Port/mysql.pid #進程ID文件的目錄。character-set-server=utf8 #默認字符集
#------------------------------------ #log setting 日志設置#------------------------------------long_query_time=10 #慢查詢時間,超過 10 秒則認為是慢查詢slow_query_log=ON #啟用慢查詢日志slow_query_log_file=/mysql/log/$MySql_Port/${HostName}-query.log #慢查詢日志目錄log_queries_not_using_indexes=1 #記錄未使用索引的語句log_slow_admin_statements=1 #慢查詢也記錄那些慢的optimize table,analyze table和alter table語句log-error=/mysql/log/$MySql_Port/${HostName}-error.log #錯誤日志目錄

#------------------------------------ #master modify parameter 主庫A復制更改參數#------------------------------------server_id=$Server_Id #master和slave server_id 需要不同
#------------------------------------ #slave parameter  主庫B參數#------------------------------------relay_log=/mysql/log/$MySql_Port/relaylog/${HostName}-relaylog #中繼日志目錄relay-log-index=/mysql/log/$MySql_Port/relaylog/${HostName}-relay.index  #中繼日志索引目錄log_slave_updates=1 #主庫B從主庫A復制的數據會寫入主庫B binlog 日志文件里,默認是不寫入read_only=0  #主庫B讀寫權限relay_log_purge=1 #自動清空不再需要中繼日志

#二進制日志參數配置log_bin=/mysql/log/$MySql_Port/binlog/${HostName}-binlog  #binlog目錄log_bin_index=/mysql/log/$MySql_Port/binlog/${HostName}-binlog.index  #指定索引文件的位置binlog_format=row #行模式復制,默認是 rowbinlog_rows_query_log_events=on #在 row 模式下,開啟該參數,可以將把 sql 語句打印到 binlog 日志里面,方便查看binlog_cache_size=1M #事務能夠使用的最大 binlog 緩存空間。max_binlog_size=2048M #binlog 文件最大空間,達到該大小時切分文件expire_logs_days=7 #設置自動刪除 binlog 文件的天數。sync_binlog=1 #表示每次事務的 binlog 都會fsync持久化到磁盤,MySQL 5.7.7 之后默認為1,之前的版本默認為0innodb_flush_log_at_trx_commit=1 #表示每次事務的 redo log 都直接持久化到磁盤,默認值為1
#------------------------------------ #GTID Settings GTID 同步復制設置#------------------------------------gtid_mode=on  #開啟GTID同步enforce_gtid_consistency=on #強制事務一致,確保 GTID 的安全,在事務中就不能創建和刪除臨時表binlog_gtid_simple_recovery=1 #這個變量用于在 MySQL 重啟或啟動的時候尋找 GTIDs 過程中,控制 binlog 如何遍歷的算法

#------------------------------------ #避免主鍵沖突設置#------------------------------------auto_increment_increment=2  #自增主鍵步長,通常有幾個主庫A就寫幾,避免主鍵沖突auto_increment_offset=1  #設置自增主鍵起始值,第一個主庫A為1,第二個主庫A為2,以此類推EOF

復制代碼

 

初始化主庫 A:

 

mysqld --defaults-file=/mysql/data/3308/my.cnf --initialize --user=mysql --basedir=/mysql/app/mysql --datadir=/mysql/data/3308/data

復制代碼

 

配置 MySQL 啟動腳本:

 

cp /mysql/app/mysql/support-files/mysql.server /etc/init.d/mysql_3308ln -sf /etc/init.d/mysql_3308 /usr/lib/systemd/system/mysql_3308
#修改啟動腳本##vim /etc/init.d/mysql_3308
basedir=/mysql/app/mysqldatadir=/mysql/data/3308/datamysqld_pid_file_path=/mysql/data/3308/mysql.pid
#在$bindir/mysqld_safe 后面添加,注意 --defaults-file 要放在第一個--defaults-file="/mysql/data/3308/my.cnf" 
systemctl daemon-reload

復制代碼

 

 

啟動 MySQL,修改密碼,運行遠程登錄:

 

#啟動、MySQL服務systemctl start mysql_3308
#獲取MySQL臨時密碼Passwd=`cat /mysql/log/3308/*-error.log |grep "root@localhost:"|awk -F ' ' '{print $11}'`echo $Passwd
#通過本地 socket 登錄、修改密碼mysql -uroot -p$Passwd -S /mysql/data/3308/mysql.sockalter user 'root'@'localhost' identified by  "123456";
#允許遠程登錄grant all privileges on *.* to root@'%' identified by '123456';
#刷新權限flush privileges;

復制代碼

初始化主庫 B

主庫 B 配置文件,主要是 ip 地址,server_id 以及 auto_increment_offset 的配置和主庫 A 不一樣,其余配置和主庫 A 一樣。

 

#主機名和端口號作為目錄名的一部分HostName=`hostname`MySql_Port=3308#IP地址Ip=192.168.1.37#master server_id 要和 slave 不一樣Server_Id=2
cat > /mysql/data/$MySql_Port/my.cnf <<-EOF#------------------------------------ #客戶端設置#------------------------------------[client]port=$MySql_Portsocket =/mysql/data/$MySql_Port/mysql.sockdefault-character-set=utf8 

#------------------------------------ #mysql連接工具設置#------------------------------------[mysql]prompt="\u@\h : \d\r:\m:\s>" #登錄時顯示登錄的用戶名、服務器地址、默認數據庫名、當前時間auto-rehash #讀取表信息和列信息,可以在連上終端后開啟tab補齊功能。default-character-set=utf8 #默認字符集
#------------------------------------ #基本設置#------------------------------------[mysqld]bind_address=0.0.0.0  #監聽本地所有地址port=$MySql_Port  #端口號user=mysql  #用戶basedir=/mysql/app/mysql  #安裝路徑datadir=/mysql/data/$MySql_Port/data  #MySQL數據目錄socket=/mysql/data/$MySql_Port/mysql.sock #用于本地連接的socket文件目錄pid-file=/mysql/data/$MySql_Port/mysql.pid #進程ID文件的目錄。character-set-server=utf8 #默認字符集
#------------------------------------ #log setting 日志設置#------------------------------------long_query_time=10 #慢查詢時間,超過 10 秒則認為是慢查詢slow_query_log=ON #啟用慢查詢日志slow_query_log_file=/mysql/log/$MySql_Port/${HostName}-query.log #慢查詢日志目錄log_queries_not_using_indexes=1 #記錄未使用索引的語句log_slow_admin_statements=1 #慢查詢也記錄那些慢的optimize table,analyze table和alter table語句log-error=/mysql/log/$MySql_Port/${HostName}-error.log #錯誤日志目錄

#------------------------------------ #master modify parameter 主庫A復制更改參數#------------------------------------server_id=$Server_Id #master和slave server_id 需要不同

#二進制日志參數配置log_bin=/mysql/log/$MySql_Port/binlog/${HostName}-binlog  #binlog目錄log_bin_index=/mysql/log/$MySql_Port/binlog/${HostName}-binlog.index  #指定索引文件的位置binlog_format=row #行模式復制,默認是 rowbinlog_rows_query_log_events=on #在 row 模式下,開啟該參數,可以將把 sql 語句打印到 binlog 日志里面,方便查看binlog_cache_size=1M #事務能夠使用的最大 binlog 緩存空間。max_binlog_size=2048M #binlog 文件最大空間,達到該大小時切分文件expire_logs_days=7 #設置自動刪除 binlog 文件的天數。sync_binlog=1 #表示每次事務的 binlog 都會fsync持久化到磁盤,MySQL 5.7.7 之后默認為1,之前的版本默認為0innodb_flush_log_at_trx_commit=1 #表示每次事務的 redo log 都直接持久化到磁盤,默認值為1
#------------------------------------ #slave parameter  主庫B參數#------------------------------------relay_log=/mysql/log/$MySql_Port/relaylog/${HostName}-relaylog #中繼日志目錄relay-log-index=/mysql/log/$MySql_Port/relaylog/${HostName}-relay.index  #中繼日志索引目錄log_slave_updates=1 #主庫B從主庫A復制的數據會寫入主庫B binlog 日志文件里,默認是不寫入read_only=0  #主庫B讀寫權限relay_log_purge=1 #自動清空不再需要中繼日志
# 并行復制參數#主庫A上面怎么并行,主庫B上面就怎么回放,基于邏輯時鐘的概念#binlog 會記錄組提交的信息,從回放的時候就可以知道哪些事務是一組里面的,#一組里面的就丟到不同線程去回放,不是一組里的就等待,以此來提升并行度slave-parallel-type=LOGICAL_CLOCK#多線程復制slave-parallel-workers=4#slave 上commit 的順序保持一致,否則可能會有間隙鎖產生slave-preserve-commit_order=1
master_info_repository=TABLE #默認每接收到10000個事件,寫一次master-info,默認是寫在文件中的#修改 relay_log_info_repository 的好處#1.relay.info 明文存儲不安全,把 relay.info 中的信息記錄在 table 中相對安全。#2.可以避免 relay.info 更新不及時,slave 重啟后導致的主從復制出錯。relay_log_info_repository=TABLE #將回放信息記錄在 slave_relay_log_info 表中,默認是記錄在 relay-info.log 文件中relay_log_recovery=1  #當slave重啟時,將所有 relay log 刪除,通過 sql 線程重放的位置點去重新拉日志

#------------------------------------ #Replication Filter 主庫B復制過濾參數#------------------------------------#(過濾某個數據庫、數據庫.表)#replicate_do_db=yzjtestdb#replicate_wild_do_table=yzjtestdb.%
#replicate_do_table=yzjtestdb.yzjtest_yg#replicate_wild_do_table=yzjtestdb.yzjtest_yg
#------------------------------------ #GTID Settings GTID 同步復制設置#------------------------------------gtid_mode=on  #開啟GTID同步enforce_gtid_consistency=on #強制事務一致,確保 GTID 的安全,在事務中就不能創建和刪除臨時表binlog_gtid_simple_recovery=1 #這個變量用于在 MySQL 重啟或啟動的時候尋找 GTIDs 過程中,控制 binlog 如何遍歷的算法
#------------------------------------ #避免主鍵沖突設置#------------------------------------auto_increment_increment=2  #自增主鍵步長,通常有幾個主庫A就寫幾,避免主鍵沖突auto_increment_offset=2  #設置自增主鍵起始值,第一個主庫A為1,第二個主庫A為2,以此類推EOF

復制代碼

 

初始化主庫 B:

 

mysqld --defaults-file=/mysql/data/3308/my.cnf --initialize --user=mysql --basedir=/mysql/app/mysql --datadir=/mysql/data/3308/data

復制代碼

 

配置 MySQL 啟動腳本:

 

cp /mysql/app/mysql/support-files/mysql.server /etc/init.d/mysql_3308ln -sf /etc/init.d/mysql_3308 /usr/lib/systemd/system/mysql_3308
#修改啟動腳本##vi /etc/init.d/mysql_3308
basedir=/mysql/app/mysqldatadir=/mysql/data/3308/datamysqld_pid_file_path=/mysql/data/3308/mysql.pid
#在$bindir/mysqld_safe 后面添加,注意 --defaults-file 要放在第一個--defaults-file="/mysql/data/3308/my.cnf" 
systemctl daemon-reload

復制代碼

 

啟動 MySQL,修改密碼,運行遠程登錄:

 

#啟動、MySQL服務systemctl start mysql_3308
#獲取MySQL臨時密碼Passwd=`cat /mysql/log/3308/*-error.log |grep "root@localhost:"|awk -F ' ' '{print $11}'`echo $Passwd
#通過本地 socket 登錄、修改密碼mysql -uroot -p$Passwd -S /mysql/data/3308/mysql.sockalter user 'root'@'localhost' identified by  "123456";
#允許遠程登錄grant all privileges on *.* to root@'%' identified by '123456';
#刷新權限flush privileges;

復制代碼

創建復制用戶

分別在主庫 A 和主庫 B 上創建一個用于數據復制的用戶。

 

grant replication slave on *.* to 'repuser'@'%' identified by 'repuser123';

復制代碼

建立主從關系

主庫 A 和主庫 B 都先清除下 binlog。

 

reset master;

復制代碼

 

主庫 A 配置主從,指向主庫 B。

 

stop slave;change master to    master_host='192.168.1.36',    master_port=3308,    master_user='repuser',    master_password='repuser123',    master_auto_position=1;start slave;

復制代碼

 

主庫 B 配置主從,指向主庫 A。

 

stop slave;change master to    master_host='192.168.1.37',    master_port=3308,    master_user='repuser',    master_password='repuser123',    master_auto_position=1;start slave;

復制代碼

 

使用 show slave statusG 命令查看主從同步狀態,IO 線程和 SQL 線程都為 YES 表示同步正常,主庫 A 和主庫 B 互為主從。

 

部署 Keepalived

下載并解壓安裝包

wget https://www.keepalived.org/software/keepalived-2.2.4.tar.gztar -xzvf keepalived-2.2.4.tar.gz

復制代碼

安裝相關依賴

yum install kernel-devel openssl-devel popt-devel -y

復制代碼

安裝 keepalived,設置開機自動啟動

mkdir /software/keepalivedcd keepalived-2.2.4./configure --prefix=/software/keepalivedmake && make installsystemctl enable keepalivedmkdir /etc/keepalived

復制代碼

配置 Keepalived

主庫 A 配置 Keepalived

主庫 A keepalived 配置文件,編輯 /etc/keepalived/keepalived.conf 文件:

 

global_defs {   router_id keep_mysql_repl_g1          # 負載均衡標識,在局域網內應該是唯一的 }
# vrrp_script 級別和 vrrp_instance 一樣vrrp_script chk_mysql {               # 配置虛擬腳本 chk_mysql  script "/etc/keepalived/check_mysql.sh"     # 執行腳本,檢查 mysql 服務是否存活  interval 3                    # 腳本執行間隔:秒}
# vrrp_instance  vrrp_instance v_mysql_1 {   state BACKUP                   # 指定該 keepalived 節點的初始狀態(MASTER|BACKUP)  interface ens192                 # VRRP 實例綁定的網口,用于發送 VRRP 包  virtual_router_id 200               # 路由 ID,范圍是 0-255,主備都一樣  priority 100                   # 指定優先級,優先級高的將成為 MASTER  advert_int 1                   # 指定發送 VRRP 廣播的間隔。單位是秒  nopreempt                     # 設置為不搶占。默認是搶占的                  authentication {                   # 身份驗證  auth_type PASS                                  # 指定認證方式  auth_pass mysql                                 # 指定認證所使用的密碼 mysql ,主備都一樣}
track_script {                     # 調用"vrrp_script"的腳本  chk_mysql                     # 增加一個跟蹤腳本到網口上}
virtual_ipaddress {                 # 虛擬 IP  192.168.1.38/24   } }

復制代碼

 

主庫 A 檢查腳本,編輯 /etc/keepalived/check_mysql.sh 文件:

 

#!/bin/bash#/etc/keepalived/check_mysql.sh#chmod u+x /etc/keepalived/check_mysql.sh#Linux 7 使用,如果是配置Linux 6 需要修改腳本


# MySQL賬號密碼mysql_user="root"mysql_pass="123456"
# MySQL錯誤日志輸出mysql_err="/mysql/log/3308/check_mysql_err.log"
# MySQL殺進程腳本mysql_kill_session="/tmp/kill.sql"
# MySQL連接字符串mysql_con="mysql -u${mysql_user} -p${mysql_pass} -S /mysql/data/3308/mysql.sock"



source ~/.bash_profileif [ `ps -ef|grep -w "$0"|grep "/bin/sh*"|grep "?"|grep "?"|grep -v "grep"|wc -l` -gt 2 ];then  #    exit 0fi

function excute_query {    $mysql_con -e "select 1 from dual;" 2>> $mysql_err}
function service_error {    echo -e "`date "+%F  %H:%M:%S"`    -----mysql service error,now stop keepalived-----" >> $mysql_err    echo -e "n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@n" >> $mysql_err}
function query_error {    echo -e "`date "+%F  %H:%M:%S"`    -----query error, but mysql service ok, retry after 30s-----" >> $mysql_err    sleep 30    excute_query    if [ $? -ne 0 ];then        echo -e "`date "+%F  %H:%M:%S"`    -----still can't execute query-----" >> $mysql_err
        echo -e "`date "+%F  %H:%M:%S"`    -----set read_only = 1 on DB1-----" >> $mysql_err        $mysql_con -e "set global read_only = 1;" 2>> $mysql_err
        echo -e "`date "+%F  %H:%M:%S"`    -----kill current client thread-----" >> $mysql_err        rm -f $mysql_kill_session &>/dev/null
        $mysql_con -NB -e 'select concat("kill ",id,";") from  information_schema.PROCESSLIST where command="Query" or command="Execute"' > $mysql_kill_session        $mysql_con -e "source $mysql_kill_session"        sleep 2 
        echo -e "`date "+%F  %H:%M:%S"`    -----stop keepalived-----" >> $mysql_err        systemctl stop keepalived &>> $mysql_err        echo -e "n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@n" >> $mysql_err    else        echo -e "`date "+%F  %H:%M:%S"`    -----query ok after 30s-----" >> $mysql_err        echo -e "n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@n" >> $mysql_err    fi}
excute_queryif [ $? -ne 0 ];then    systemctl status mysql &>/dev/null    if [ $? -ne 0 ];then        service_error    else        query_error    fifi

復制代碼

 

給檢查腳本賦與執行權限:

 

chmod u+x /etc/keepalived/check_mysql.sh

復制代碼

主庫 B 配置 Keepalived

主庫 B keepalived 配置文件,編輯 /etc/keepalived/keepalived.conf 文件:

 

global_defs {   router_id keep_mysql_repl_g1               # 負載均衡標識,在局域網內應該是唯一的 }
# vrrp_instance  vrrp_instance v_mysql_1 {                     state BACKUP                       # 指定該 keepalived 節點的初始狀態(MASTER|BACKUP)        interface ens192                                         # VRRP 實例綁定的網口,用于發送 VRRP 包  virtual_router_id 200                                   # 路由ID,范圍是0-255,主備都一樣  priority 90                                             # 指定優先級,優先級高的將成為 MASTER  advert_int 1                                            # 指定發送VRRP廣播的間隔。單位是秒  nopreempt                                               # 設置為不搶占。默認是搶占的  authentication {                       # 身份驗證  auth_type PASS                                          # 指定認證方式  auth_pass mysql                                         # 指定認證所使用的密碼 mysql ,主備都一樣}
notify_master /etc/keepalived/notify_master_mysql.sh    # 轉換成 master 時,執行的腳本virtual_ipaddress {   192.168.1.38/24   } }

復制代碼

 

主庫 B 腳本,當發生主從切換時,會執行該腳本。編輯 /etc/keepalived/notify_master_mysql.sh 文件:

 

#!/bin/bash#/etc/keepalived/notify_master_mysql.sh#chmod u+x /etc/keepalived/notify_master_mysql.sh
# MySQL賬號密碼mysql_user="root"mysql_pass="123456"
# 配置更變日志change_log="/mysql/log/3308/state_change.log"
# 主庫B狀態日志slave_status_log="/mysql/log/3308/slave_status_log.log"
# MySQL連接字符串mysql_conn="mysql -u${mysql_user} -p${mysql_pass} -S /mysql/data/3308/mysql.sock"

source ~/.bash_profileecho -e "`date "+%F  %H:%M:%S"`   -----keepalived change to MASTER-----" >> $change_logecho -e "`date "+%F  %H:%M:%S"`   ----------" >> $slave_status_log$mysql_conn -e "show slave statusG;" >> $slave_status_log
Slave_IO_Running=`$mysql_conn -e "show slave statusG;"|egrep -w "Slave_IO_Running|Slave_SQL_Running"|awk 'NR==1{print}' | awk '{print $2}'`Slave_SQL_Running=`$mysql_conn -e "show slave statusG;"|egrep -w "Slave_IO_Running|Slave_SQL_Running"|awk 'NR==2{print}' | awk '{print $2}'`Master_Log_File=`$mysql_conn -e "show slave statusG;" |egrep -w "Master_Log_File|Read_Master_Log_Pos|Exec_Master_Log_Pos"|awk 'NR==1{print}' | awk '{print $2}'`Read_Master_Log_Pos=`$mysql_conn -e "show slave statusG;" |egrep -w "Master_Log_File|Read_Master_Log_Pos|Exec_Master_Log_Pos"|awk 'NR==2{print}' | awk '{print $2}'`Exec_Master_Log_Pos=`$mysql_conn -e "show slave statusG;" |egrep -w "Master_Log_File|Read_Master_Log_Pos|Exec_Master_Log_Pos"|awk 'NR==3{print}' | awk '{print $2}'`

action() {    echo -e "`date "+%F  %H:%M:%S"`    -----set read_only = 0 on `hostname`-slave-----" >> $change_log
    $mysql_conn -e "set global read_only = 0;" 2>> $change_log        $mysql_conn -e "stop slave;" 2>> $change_log    echo "`hostname`-slave keepalived 轉為 MASTER 狀態,線上數據庫切換至`hostname`-slave" >> $change_log
    echo -e "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@n" >> $change_log}
if [ "$Slave_IO_Running" = "Yes" -a "$Slave_SQL_Running" = "Yes" ];then        if [ $Read_Master_Log_Pos = $Exec_Master_Log_Pos ];then            echo -e "`date "+%F  %H:%M:%S"`    -----Master_Log_File=$Master_Log_File . Exec_Master_Log_Pos($Exec_Master_Log_Pos) is equal Read_Master_Log_Pos($Read_Master_Log_Pos)" >> $change_log                        action                        $mysql_conn -e "reset slave all;" 2>> $change_log                        else                    echo -e "`date "+%F  %H:%M:%S"`    -----Master_Log_File=$Master_Log_File . Exec_Master_Log_Pos($Exec_Master_Log_Pos) is behind Read_Master_Log_Pos($Read_Master_Log_Pos), The wAIts time is more than 10s,now force change." >> $change_log                    sleep 10                        action                        $mysql_conn -e "reset slave all;" 2>> $change_log            exit 0        fiaction 
else    echo -e "`hostname`-slave's slave status is wrong,now force change. Master_Log_File=$Master_Log_File Read_Master_Log_Pos=$Read_Master_Log_Pos  Exec_Master_Log_Pos=$Exec_Master_Log_Pos" >> $change_log  actionfi

復制代碼

 

給腳本賦與執行權限:

 

chmod u+x /etc/keepalived/notify_master_mysql.sh 

復制代碼

啟動 Keepalived

在主庫 A 和主庫 B 上分別啟動 keepalived。

 

systemctl start keepalived

復制代碼

 

查看 keepalived 狀態。

 

[root@mysql-master keepalived-2.2.4]# systemctl status keepalived.service ● keepalived.service - LVS and VRRP High Availability Monitor   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; enabled; vendor preset: disabled)   Active: active (running) since 五 2021-09-10 21:13:37 CST; 18s ago     Docs: man:keepalived(8)           man:keepalived.conf(5)           man:genhash(1)           https://keepalived.org  Process: 8184 ExecStart=/software/keepalived/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS) Main PID: 8186 (keepalived)   Memory: 680.0K   CGroup: /system.slice/keepalived.service           ├─8186 /software/keepalived/sbin/keepalived -D           └─8187 /software/keepalived/sbin/keepalived -D
9月 10 21:13:41 mysql-master Keepalived_vrrp[8187]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:13:41 mysql-master Keepalived_vrrp[8187]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:13:41 mysql-master Keepalived_vrrp[8187]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:13:41 mysql-master Keepalived_vrrp[8187]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:13:46 mysql-master Keepalived_vrrp[8187]: (v_mysql_1) Sending/queueing gratuitous ARPs on ens192 for 192.168.1.389月 10 21:13:46 mysql-master Keepalived_vrrp[8187]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:13:46 mysql-master Keepalived_vrrp[8187]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:13:46 mysql-master Keepalived_vrrp[8187]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:13:46 mysql-master Keepalived_vrrp[8187]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:13:46 mysql-master Keepalived_vrrp[8187]: Sending gratuitous ARP on ens192 for 192.168.1.38

復制代碼

 

查看網卡地址,此時虛擬 IP 在主庫 A 上。

 

[root@mysql-master keepalived-2.2.4]# ip addr1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00    .NET 127.0.0.1/8 scope host lo       valid_lft forever preferred_lft forever    inet6 ::1/128 scope host        valid_lft forever preferred_lft forever2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000    link/ether 00:50:56:8b:1b:ca brd ff:ff:ff:ff:ff:ff    inet 192.168.1.36/24 brd 192.168.1.255 scope global ens192       valid_lft forever preferred_lft forever    #虛擬 IP    inet 192.168.1.38/24 scope global secondary ens192       valid_lft forever preferred_lft forever    inet6 fe80::2556:f369:b4e7:fb64/64 scope link tentative dadfailed        valid_lft forever preferred_lft forever    inet6 fe80::6b8d:29f7:a5fe:dbee/64 scope link tentative dadfailed        valid_lft forever preferred_lft forever    inet6 fe80::f387:57a3:4975:d8f2/64 scope link tentative dadfailed        valid_lft forever preferred_lft forever

復制代碼

驗證高可用

客戶端通過虛擬 IP 192.168.1.38 連接數據庫,通過 select @@hostname 命令可以看到當前連接的為主庫 A。

 

? mysql -uroot -h 192.168.1.38 -P 3308  -p123456;mysql: [Warning] Using a password on the command line interface can be insecure.Welcome to the MySQL monitor.  Commands end with ; or g.Your MySQL connection id is 268Server version: 5.7.29-log MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
[email protected] (none) 09:11:13>select @@hostname;+--------------+| @@hostname   |+--------------+| mysql-master |+--------------+1 row in set (0.01 sec)
[email protected] (none) 09:11:26>

復制代碼

 

客戶端創建表并插入數據。

 

create database testdb;create table testdb.data01( id int not null primary key auto_increment, name varchar(60), age int); 
insert into testdb.data01 (name,age) values('tom',18),('jack',17),('rock',16),('james',15),('cris',20);

復制代碼

 

此時分別登錄主庫 A 和主庫 B 查看 testdb.data01 表中的數據,可以確定主庫 A 和主庫 B 目前數據是同步的。并且查看表中的內容可以發現主鍵是以 2 為間隔遞增的,這是為了防止主從切換時插入數據產生主鍵沖突。主庫 A 的主鍵會以 1,3,5,7,9 的序號遞增。假如在序號為 9 時發生主從切換,新的主庫(主庫 A)的主鍵會以 10,12,14,16,18 的序號遞增。

 

停止主庫 A,模擬故障切換

[root@mysql-master ~]# systemctl stop mysql_3308.service 

復制代碼

 

在主庫 A 的機器上查看 keepalived 狀態,可以看到 keepalived 的優先級被設置為 0,此時虛擬 IP 將會飄到主庫 B 的機器上。

 

[root@mysql-master tmp]# systemctl status keepalived.service ● keepalived.service - LVS and VRRP High Availability Monitor   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; enabled; vendor preset: disabled)   Active: active (running) since 五 2021-09-10 21:42:11 CST; 3min 59s ago     Docs: man:keepalived(8)           man:keepalived.conf(5)           man:genhash(1)           https://keepalived.org  Process: 13365 ExecStart=/software/keepalived/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS) Main PID: 13367 (keepalived)   Memory: 1.0M   CGroup: /system.slice/keepalived.service           ├─13367 /software/keepalived/sbin/keepalived -D           ├─13368 /software/keepalived/sbin/keepalived -D           ├─14761 /bin/bash /etc/keepalived/check_mysql.sh           └─14778 sleep 30
9月 10 21:42:20 mysql-master Keepalived_vrrp[13368]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:42:20 mysql-master Keepalived_vrrp[13368]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:42:20 mysql-master Keepalived_vrrp[13368]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:42:20 mysql-master Keepalived_vrrp[13368]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:42:20 mysql-master Keepalived_vrrp[13368]: Sending gratuitous ARP on ens192 for 192.168.1.389月 10 21:45:47 mysql-master Keepalived_vrrp[13368]: Track script chk_mysql is already running, expect idle - skipping run9月 10 21:45:47 mysql-master Keepalived_vrrp[13368]: VRRP_Script(chk_mysql) timed_out9月 10 21:45:47 mysql-master Keepalived_vrrp[13368]: (v_mysql_1) Entering FAULT STATE9月 10 21:45:47 mysql-master Keepalived_vrrp[13368]: (v_mysql_1) sent 0 priority9月 10 21:45:47 mysql-master Keepalived_vrrp[13368]: (v_mysql_1) removing VIPs.

復制代碼

 

查看主庫 B 機器網卡的地址,發現虛擬 IP 已經切換到主庫 B 上了。當發生主從切換時,主庫 B 的腳本會執行 reset slave all,停止向主庫 A 的同步,防止原主庫 A 恢復后數據意外同步。

 

[root@mysql-slave keepalived]# ip addr1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00    inet 127.0.0.1/8 scope host lo       valid_lft forever preferred_lft forever    inet6 ::1/128 scope host        valid_lft forever preferred_lft forever2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000    link/ether 00:50:56:8b:71:df brd ff:ff:ff:ff:ff:ff    inet 192.168.1.37/24 brd 192.168.1.255 scope global ens192    #虛擬 IP       valid_lft forever preferred_lft forever    inet 192.168.1.38/24 scope global secondary ens192       valid_lft forever preferred_lft forever    inet6 fe80::2556:f369:b4e7:fb64/64 scope link tentative dadfailed        valid_lft forever preferred_lft forever    inet6 fe80::6b8d:29f7:a5fe:dbee/64 scope link tentative dadfailed        valid_lft forever preferred_lft forever    inet6 fe80::f387:57a3:4975:d8f2/64 scope link tentative dadfailed        valid_lft forever preferred_lft forever

復制代碼

 

客戶端發生了重連,通過 select @@hostname 查看可以看到此時連接的是主庫 B。

 

[email protected] (none) 09:42:14>select @@hostname;#重連ERROR 2006 (HY000): MySQL server has gone awayNo connection. Trying to reconnect...Connection id:    19Current database: *** NONE ***
+-------------+| @@hostname  |+-------------+| mysql-slave |+-------------+1 row in set (0.04 sec)

復制代碼

 

客戶端插入幾條數據:

 

insert into testdb.data01 (name,age) values('peter',28),('mark',27),('marry',26),('hule',25),('handson',20);

復制代碼

 

查詢數據,可以看到在原主庫 B 上插入的數據主鍵會以 10,12,14,16,18 的序號遞增。

 

[email protected] (none) 09:44:19>select * from testdb.data01;+----+---------+------+| id | name    | age  |+----+---------+------+|  1 | tom     |   18 ||  3 | jack    |   17 ||  5 | rock    |   16 ||  7 | james   |   15 ||  9 | cris    |   20 || 10 | peter   |   28 || 12 | mark    |   27 || 14 | marry   |   26 || 16 | hule    |   25 || 18 | handson |   20 |+----+---------+------+10 rows in set (0.01 sec)

復制代碼

重新啟動主庫 A,觀察數據同步

由于我們關閉了搶占模式,當主庫 A 重新啟動時,主從不會發送切換。

 

[root@mysql-master]# systemctl start mysql_3308.service

復制代碼

 

主庫 A 的數據可以和主庫 B 同步。

 

參考資料

  • https://www.cnblogs.com/kerrycode/p/11150782.html

  • http://www.linuxe.cn/post-492.html

  • https://blog.csdn.net/JesseYoung/article/details/41942809

分享到:
標簽:MySQL
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定