思維導圖
主從複製
基本介紹
主從複製搭建:
1、兩臺+ 同版本的mysql實例;server_id 各不相同
2、主庫方面:二進制日誌;複製用戶
3、從庫方面:通過備份恢復初始化數據(將主庫之前的數據拿到從庫中:採用最近的一次全備)
1、你怎麼監控複製延時:
1、second behind master 只能查看出秒數
2、查看日誌量 (也可以利用pt-heartbeat工具)
2、主從延時的原因有哪些
主庫方面
(binlog是否實時寫入 sync_binlog=1)(5.6版本以前dump線程串行工作;5.7開啓dump gtid 並行工作 根據gtid寫入binlog的落盤順序) (減少大事務 和線上做DDL導致全局鎖)
從庫方面
(SQL線程 5.6 默認是串行的;5.7 基於邏輯時鐘進行併發回放) (大量DDL 導致鎖的爭用問題)
特殊從庫
延時從庫:異步同步到從庫中
過濾複製:白名單、黑名單 兩者只選其一
gtid
半同步:mysql版本過渡的產物(dump 通過tcp ip方式發送給IO線程後就不管了(有ack的確認 但是隻是放在IO的緩存中了 沒有落地到relaylog 中,所以不能保證從庫的數據一定會落盤),不管IO線程是否接受到了)
半同步作用於IO線程處,在主從雙節點上安裝插件 semi-sync 作用:只有當日志信息從IO緩存中落地到relaylog中才會給主庫反饋一個確認的信息
GTID複製:
只要主庫生成的gtid號碼 會在傳輸到從庫時,一同傳輸過去,可以根據gtid號碼進行確認是否
gtid和傳統主從複製的差異
不同點:
1、搭建時的命令:
master_auto_position=1 自動尋找複製起點
分爲兩種情況:
沒有備份: 自動從主庫的第一個gtid對應的position號碼開始複製
有備份:
mysqldump -A --master-date=2 /tmp/full.sql
SET @GLOBAL.GTID purged=’ :1-10’;
從庫會自動從第11個gtid開始複製
enforce-gtid-consistency=true 強制gtid一致性
log_bin=/data/binlog/mysql-bin 開啓binlog日誌
log-slave-updates=1 從庫強制更新binlog日誌
gtid-mode =on 開啓gtid
功能:主從之間 自動校驗gtid一致性:主庫binlog 檢驗於 從庫relaylog 和 binlog
MHA的高可用
1、數據損壞的類型
物理損壞:磁盤、主機、程序、實例、數據文件
邏輯損壞:drop 等
高可用是架構在主從之上的。一主兩從
高可用技術解決物理損壞
高可用解決方案選型依據
高可用解決方案選型依據全年無故障率
無故障時間 故障時間 解決方案
99.9% 0.1% = 525.6 min KA+雙主 :人爲干預
99.99% 0.01% = 52.56 min MHA :半自動化
應用場景:比較適合非金融類互聯網公司。 facebook MHA ,淘寶 TMHA --》polardb。 替代產品: ORCH go語言。
99.999% 0.001% = 5.256 min PXC 、 MGR 、MGC
應用場景: 金融類業務。
99.9999% 0.0001% = 0.5256 min 自動化、雲化、平臺化
MHA基礎環境實施
準備3節點MySQL GTID 複製。
略。
MHA 軟件結構
manager 組件
masterha_manger 啓動MHA
masterha_check_ssh 檢查MHA的SSH配置狀況
masterha_check_repl 檢查MySQL複製狀況,配置信息
masterha_master_monitor 檢測master是否宕機
masterha_check_status 檢測當前MHA運行狀態
masterha_master_switch 控制故障轉移(自動或者手動)
masterha_conf_host 添加或刪除配置的server信息
node 組件
save_binary_logs 保存和複製master的二進制日誌
apply_diff_relay_logs 識別差異的中繼日誌事件並將其差異的事件應用於其他的
purge_relay_logs 清除中繼日誌(不會阻塞SQL線程)
MHA軟件安裝及配置
程序軟連接
ln -s /data/app/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /data/app/mysql/bin/mysql /usr/bin/mysql
各節點進行互信
db01:
rm -rf /root/.ssh
ssh-keygen
cd /root/.ssh
mv id_rsa.pub authorized_keys
scp -r /root/.ssh 10.0.0.52:/root
scp -r /root/.ssh 10.0.0.53:/root
各節點驗證
db01:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date
db02:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date
db03:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date
安裝軟件
#所有節點安裝Node軟件依賴包
yum install perl-DBD-MySQL -y
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
#Manager軟件安裝(db03)
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
yum install -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
在db01主庫中創建mha需要的用戶
grant all privileges on *.* to mha@'10.0.0.%' identified by 'mha';
Manager配置文件準備(db03)
#創建配置文件目錄
mkdir -p /etc/mha
#創建日誌目錄
mkdir -p /var/log/mha/app1
#編輯mha配置文件
cat > /etc/mha/app1.cnf <<EOF
[server default]
manager_log=/var/log/mha/app1/manager # MHA的工作日誌設置
manager_workdir=/var/log/mha/app1 # MHA工作目錄
master_binlog_dir=/data/binlog # 主庫的binlog目錄
user=mha # 監控用戶
password=mha # 監控密碼
ping_interval=2 # 心跳檢測的間隔時間
repl_password=123 # 複製用戶
repl_user=repl # 複製密碼
ssh_user=root # ssh互信的用戶
[server1] # 節點信息....
hostname=10.0.0.51
port=3306
[server2]
hostname=10.0.0.52
port=3306
candidate_master=1
[server3]
no_master=1
hostname=10.0.0.53
port=3306
EOF
狀態檢查(db03)
masterha_check_ssh --conf=/etc/mha/app1.cnf
masterha_check_repl --conf=/etc/mha/app1.cnf
開啓MHA-manager
開啓MHA(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 &
查看MHA狀態
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:4719) is running(0:PING_OK), master:10.0.0.51
MHA工作原理
站在產品經理的角度看高可用應該如何設計?
1、啓動MHA 軟件
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 &
同一個軟件通過不同的配置文件來啓動不同的集羣
2、 監控
自動調用腳本 masterha_check_ssh 每隔ping_interval(2)秒 去執行一次這個腳本,如果連續四次還是沒有 說明主庫宕機
/usr/bin/masterha_master_monitor
,每隔ping_interval秒探測1次,連續4次還沒有,說明主庫宕機。
[root@slave2 bin]# mysql -umha -pmha -h 10.0.0.51 -e "select user();"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+
| user() |
+---------------+
| [email protected] |
+---------------+
[root@slave2 bin]#
3、監控到之後 再選擇一個主庫
日誌量 latest
備選主 pref
哪些不被選主 bad
no_master=1
log_bin 二進制日誌沒開
check_slave_delay,如果從庫落後主庫100M的日誌量(可以關閉)
alive 存活節點數組 52 53
lastest 最接近主庫的從庫 ****第二優先級
pref candidate_master=1 備選主 *****優先級最高
bad 設定no_master =1 則不參與選主 ***第三優先級
log_bin 日誌沒有開啓 不參與選主
check_slave_delay 如果從庫落後主庫100M的日誌量 則不會參與選主
選主條件:
①latest 日誌量
②備選主 pref candidate_master=1
如果多個從庫從這 兩個選主條件都滿足 那麼就會按照配置文件的順序
選主原理:首先他在alived中查找主機清單,然後排除bad,最後根據pref和latest的優先級選主
如果設置了no_master =1 即使已經沒有可以切換的從庫了 只剩了配置no_master =1 那麼也不會切換給這個配置的從庫
=============
數組:
alive : 存活
latest :最新
pref :備選
bad :不選
選主判斷:
僞代碼:
if 情況
=1. 如果pref和bad數組當中slave的個數爲0,則選擇latest數組當中的第一個slave爲master。
db02沒有candidate_master,又沒有以下bad三種情況,db02恰好是latest。
=2. 循環對比latest數組和perf數組的slave,如果存在相同的slave,並且這個slave不在bad數組當中,該slave會被推選爲新的master。
db02 pref , latest ,又不是bad,會被選主。
=3. 循環對比slaves數組pref數組當中的slave,如果有一個slave相同並且不在bad數組當中,該就會成爲新的master。
db02 ,不是latest,不是bad,是pref。會被選擇。
=4. 循環latest數組,如果又循環到的slave不在bad數組當中,這個slave就會成爲master。
也就是說就算添加了candidate_master=1,該slave也不一定會成爲主庫。
db02 , latest ,不是bad
db03 , pref,不是latest ,不是bad
=5. 從活着的slave當中進行循環,如果循環到的slave不在bad數組當中,那麼這個slave就會成爲主庫。
db02 ,slaves ,不是bad 。
else 如果進行了多次選擇都找不到主庫,那麼主庫選擇失敗,failover失敗。
==============
4、數據補償
情景1:原來的主庫 ssh能連接
各個從節點調用save_binary_logs腳本 立即保存缺失部分的binary 到各自節點/var/tmp目錄中
情景2:原主庫ssh不能連接
從從1調用apply_diff_relay_logs 進行relay-log日誌差異補償給從2 但是如果原主 10 從1 8 從2 6
原主庫 10的數據以及不能ssh登錄 那麼只能將從1的 8 中的 6 7 補償給 從2 與原來的數據相比 仍然缺少 9 10 兩個日誌
額外數據補償
binlog_server
主庫日誌的冗餘機制
原主庫ssh能連接
各個從節點調用: save_binary_logs 腳本,立即保存缺失部分的binlog到各自節點/var/tmp目錄。
原主庫ssh不能連接
從節點調用apply_diff_relay_logs ,進行relay-log日誌差異補償。
額外數據補償(主庫日誌冗餘機制)
binlog_server.
5、切換主從關係
解除所有從庫主從身份。stop slave ; restart slalve
重構新的主從關係 change master to
6、vip應用透明
7、故障提醒
8、額外數據補償
9、剔除故障節點
10、manager 程序自殺
dos2unix /usr/local/bin/* 利用命令將腳本中的一些中文字符識別出來
應用透明(VIP)
vip 介紹
#作用網卡:
eth0:1
ens33:1
#IP
vip : 10.0.0.55/24
一定是一個空閒地址。
一定要和對外提供服務的地址同一網段。
不能跨網段。
vip 故障轉移腳本
上傳腳本文件到/usr/local/bin
[root@db03 mha_script]# \cp -a * /usr/local/bin
修改權限
[root@db03 bin]# chmod +x /usr/local/bin/*
修改內容
[root@db03 bin]#vim /usr/local/bin/master_ip_failover
my $vip = '10.0.0.55/24';
my $key = '1';
my $if = 'ens33';
my $ssh_start_vip = "/sbin/ifconfig $if:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig $if:$key down";
my $ssh_Bcast_arp= "/sbin/arping -I $if -c 3 -A 10.0.0.55";
解釋
my $vip = '10.0.0.55/24'; vip地址
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip"; 修改網卡名字
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
my $ssh_Bcast_arp= "/sbin/arping -I eth0 -c 3 -A 10.0.0.55";vip地址
修改Manager 配置文件
vim /etc/mha/app1.cnf
master_ip_failover_script=/usr/local/bin/master_ip_failover
重啓MHA
[root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf
[root@db03 bin]# 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 &
手工在主庫添加VIP
[root@db02 ~]# ifconfig ens33:1 10.0.0.55/24
故障提醒功能
準備腳本
[root@db03 bin]# vim send_report
my $smtp='smtp.qq.com'; # smtp服務器
my $mail_from='[email protected]'; # 發件箱
my $mail_user='22654481'; # 用戶名 QQ號
my $mail_pass='gemghsvgkeyzcagh'; # 授權碼
my $mail_to=['[email protected]']; # 收件箱
#my $mail_to=['[email protected]','[email protected]'];
我的配置文件
my $smtp='smtp.163.com';
my $mail_from='[email protected]';
my $mail_user='[email protected]';
my $mail_pass='liushiya111';
#my $mail_to=['[email protected]','[email protected]'];
my $mail_to='[email protected]';
修改配置文件
vim /etc/mha/app1.cnf
#添加一行:
report_script=/usr/local/bin/send_report
重啓MHA
[root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf
[root@db03 bin]# 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 &
日誌補償的冗餘方案–binlog_server
創建必要目錄(db03)
mkdir -p /data/binlog_server/
chown -R mysql.mysql /data/*
cd /data/binlog_server/
[root@db03 ~]# mysql -e "show slave status \G"|grep "Master_Log"
mysqlbinlog -R --host=10.0.0.51 --user=mha --password=mha --raw --stop-never mysql-bin.000002 &
注意:
拉取日誌的起點,需要按照目前從庫的已經獲取到的二進制日誌點爲起點
配置文件設置
vim /etc/mha/app1.cnf
[binlog1]
no_master=1
hostname=10.0.0.53
master_binlog_dir=/data/binlog_server/
重啓MHA
[root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf
[root@db03 bin]# 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 &
MHA高可用,故障模擬及恢復演練
模擬故障
db01:
/etc/init.d/mysqld stop
db03: 看日誌
[root@db03 binlog_server]# tail -f /var/log/mha/app1/manager
MHA的維護操作 - 在線切換功能
只切換角色
masterha_master_switch --conf=/etc/mha/app1.cnf --master_state=alive --new_master_host=10.0.0.52 --orig_master_is_new_slave --running_updates_limit=10000
注意:
master_ip_online_change_script is not defined. If you do not disable writes on the current master manually, applications keep writing on the current master. Is it ok to proceed? (yes/NO): yes
- 此種方法切換,要注意將原主庫,FTWRL(Flush table with read lock),否則會造成主從不一致。
- 手工切換vip
- 重新拉去新主庫的binlog
master_ip_online_change_script功能實現
功能: 在線切換時,自動鎖原主庫,VIP自動切換
準備切換腳本
vim /usr/local/bin/master_ip_online_change
my $vip = "10.0.0.55/24";
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key $vip down";
my $ssh_Bcast_arp= "/sbin/arping -I ens33 -c 3 -A 10.0.0.55";
修改MHA配置文件
vim /etc/mha/app1.cnf
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
停 MHA
[root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf
檢查repl
[root@db03 bin]# masterha_check_repl --conf=/etc/mha/app1.cnf
在線切換
masterha_master_switch --conf=/etc/mha/app1.cnf --master_state=alive --new_master_host=10.0.0.51 --orig_master_is_new_slave --running_updates_limit=10000
重構binlogserver
[root@db03 bin]# ps -ef |grep mysqlbinlog
root 28144 16272 0 17:50 pts/1 00:00:00 mysqlbinlog -R --host=10.0.0.52 --user=mha --password=x x --raw --stop-never mysql-bin.000005
root 28529 16272 0 18:03 pts/1 00:00:00 grep --color=auto mysqlbinlog
[root@db03 bin]# kill -9 28144
[root@db03 bin]# cd /data/binlog_server/
[root@db03 binlog_server]# ll
total 4
-rw-r----- 1 root root 194 Apr 1 17:50 mysql-bin.000005
[root@db03 binlog_server]# rm -rf *
[root@db03 binlog_server]# mysqlbinlog -R --host=10.0.0.51 --user=mha --password=mha --raw --stop-never mysql-bin.000009 &
[1] 28534
啓動MHA
[root@db03 bin]# 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@db03 binlog_server]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:28535) is running(0:PING_OK), master:10.0.0.51
- MHA故障通用修復方法
9.0 檢查三節點是否啓動
9.1 檢查主從關係
1主2從:
[root@db03 binlog_server]# mysql -e "show slave status\G" |grep "Master_Host"
Master_Host: 10.0.0.52
[root@db01 data]# mysql -e "show slave status\G" |grep "Master_Host"
修復1主從:
db01:
change master to
master_host='10.0.0.52',
master_user='repl',
master_password='123' ,
MASTER_AUTO_POSITION=1;
start slave;
[root@db01 data]# mysql -e "show slave status\G" |grep "Master_Host"
Master_Host: 10.0.0.52
檢查vip是否在主庫
[root@db02 data]# ip a
檢查binlog_server狀態
[root@db03 binlog_server]# ps -ef |grep mysqlbinlog
root 77828 39593 0 17:53 pts/2 00:00:00 grep --color=auto mysqlbinlog
[root@db03 binlog_server]#
修復binlog_server:
[root@db03 binlog_server]# rm -rf /data/binlog_server/*
[root@db03 binlog_server]# cd /data/binlog_server/
[root@db03 ~]# mysql -e "show slave status \G"|grep "Master_Log"
[root@db03 ~]# mysqlbinlog -R --host=10.0.0.52 --user=mha --password=mha --raw --stop-never mysql-bin.000002 &
檢查配置文件
三個節點是否存在:
[root@db03 binlog_server]# cat /etc/mha/app1.cnf
添加新節點到配置文件:
masterha_conf_host --command=add --conf=/etc/mha/app1.cnf --hostname=10.0.0.51 --block=server1 --params="port=3306"
++++++++
masterha_conf_host --command=delete --conf=/etc/mha/app1.cnf --block=server1
++++++++
檢查ssh互信和repl
[root@db03 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
啓動MHA
[root@db03 bin]# 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@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:78201) is running(0:PING_OK), master:10.0.0.52
[root@db03 ~]#