> MySQL安裝和復制請查看7.1/7.2相關章節
> MHA要求MySQL所有節點創建復制賬戶
> LVS負責讀操作的負載均衡
#### 基礎環境
操作系統:Centos 7.3 64位;
```shell
數據庫寫VIP:192.168.0.20
數據庫讀VIP(LVS):192.168.0.21
```
服務器角色和配置信息
|角色|IP地址|主機名|Server-ID|功能類型|
| :------------: | :------------: | :------------: | :------------: | :------------: |
|Master|192.168.0.230|mdb01.prod.ding|168001200|寫|
|Candicate Master|192.168.0.236|mdb01-s1.prod.ding|168001201|讀|
|Slave|192.168.0.235|mdb01-s2.prod.ding|168001202|讀|
|Monitor host|192.168.0.237|mha.prod.ding||MySQL主庫的故障轉移|
|LVS+Keepalived-A|192.168.0.90|mdb-lvs01.prod.ding||讀操作的負載均衡|
|LVS+Keepalived-B|192.168.0.91|mdb-lvs02.prod.ding||LVS高可用備機|
各服務器軟件部署情況
|角色|Manager|Node|Keepalived|LVS|
| :------------: | :------------: | :------------: | :------------: | :------------: |
|Master|-|部署|-|-|
|Candicate Master|-|部署|-|-|
|Slave|-|部署|-|-|
|MHA host|部署|部署|-|-|
|LVS+Keepalived-A|-|-|部署|部署|
|LVS+Keepalived-B|||部署|部署|
#### 拓撲圖及實現原理

##### 業務流程
**讀操作**
1. LVS實現讀操作的負載均衡;
2. Keepalived在上層管理LVS,并對兩臺從庫進行健康檢測(通過定義Check腳本);
3. 一臺從庫出現故障后,Keepalived將其剔除出負載均衡集群;
**寫操作**
1. 在Master上綁定寫VIP(MHA啟動后會通過腳本進行操作);
2. MHA監控Master狀態,當Master出現故障后(宕機、復制暫停)時;
3. 通過Failover腳本,卸載Master上的WVIP;
4. 通過Failover在CMaster上綁定WVIP,提升其為主庫;
5. 同步并應用差異日志,并將從庫指向新主庫;
問題:當MHA把Master切換到了CMaster上后,LVS如何處理分發在CMaster上的讀操作?
解釋:由于Keepalived會通過腳本定期監控CMaster的狀態,包括同步、SQL線程、I/O線程,所以當CMaster升級為主庫后,這些狀態都將消失,Keepalived將自動將CMaster剔除出負載均衡集群。
#### 部署MHA
MHA使用Perl編寫,需要安裝Perl依賴,建議使用阿里云的YUM源,YUM安裝
Node節點需要perl-DBD-MySQL perl-DBI
Manger需要perl-Config-Tiny.noarch perl-Log-Dispatch.noarch perl-Parallel-ForkManager.noarch perl-DBD-MySQL perl-DBI
##### 部署約定
|序號|目錄名稱|目錄位置|
| :------------: | :------------: | :------------: |
|1|上傳文件目錄|/tmp/|
|2|MHA配置文件目錄|/app/mha|
|3|MHA日志文件目錄|/app/mha/log|
|4|MHA管理目錄|/app/mha/app1|
|5|MHA處理數據目錄|/tmp|
|6|relay_log_purge腳本目錄|/app/scripts|
|7|master_ip_failover腳本目錄|/app/scripts|
##### 配置阿里云的YUM源
```shell
#clean OS default repo
mkdir /etc/yum.repos.d/old && mv /etc/yum.repos.d/C* /etc/yum.repos.d/old/
#add local repo
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
```
##### 安裝Perl依賴
方法一 使用YUM 安裝(推薦)
```shell
yum install -y perl-Config-Tiny.noarch perl-Log-Dispatch.noarch perl-Parallel-ForkManager.noarch perl-DBD-MySQL perl-DBI
```
方法二 使用cpanm安裝。注意:時間必須整正確
編寫腳本DBD_install.sh
```shell
#!/bin/bash
wget http://xrl.us/cpanm --no-check-certificate
mv cpanm /usr/bin/
chmod 755 /usr/bin/cpanm
cat >/root/list<<EOF
install DBD::mysql
install Config::Tiny
install Log::Dispatch
install Parallel::ForkManager
install Time::HiRes
EOF
for package in `cat /root/list`
do
cpanm $package
done
```
##### 在所有節點上安裝MHA Node:
rpm包安裝
```shell
cd /opt/
rpm -ivh mha4mysql-node-0.57-0.el7.noarch.rpm
```
編譯安裝
```shell
tar xf mha4mysql-node-0.53.tar.gz
cd mha4mysql-node
perl Makefile.PL
make && make install
```
##### 安裝MHA Manager
rpm包安裝
```shell
cd /opt/
rpm -ivh mha4mysql-manager-0.57-0.el7.noarch.rpm
rpm -ivh mha4mysql-node-0.57-0.el7.noarch.rpm
```
編譯安裝
```shell
tar zxf mha4mysql-manager-0.53.tar.gz
cd mha4mysql-manager-0.53
perl Makefile.PL
make
make install
```
#### 配置MHA manger
創建基礎目錄
```shell
mkdir -p /etc/mha
mkdir -p /etc/mha/log
mkdir -p /etc/mha/app1
mkdir -p /etc/mha/scripts
mkdir -p /tmp/
```
##### 配置MHA對MySQL監控和binlog控制
>這個賬戶和復制賬戶沒有關系
```shell
grant all on *.* to 'mha'@'192.168.0.%' identified by 'mha'; flush privileges;
```
##### 在(MHA/M/S1/S2)服務器上配置主機名(MHA管理腳本通過主機名調用)
```shell
cat >>/etc/hosts<< EOF
192.168.0.230 ip230
192.168.0.235 ip235
192.168.0.236 ip236
192.168.0.237 ip237
EOF
```
##### 所有MySQL節點增加mysqlbinlog環境變量(解析binlog用)
```shell
echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/bashrc ;source /etc/bashrc
```
> bashrc是每次執行bash腳本時加載的變量
##### 配置MHA和MySQL主從之間的主機免密鑰登錄
所有節點執行以下操作
- 部署SSH免密鑰登錄
- 所有節點可以SSH訪問MHA和其他MySQL節點
- 所有節點可以SSH訪問自己
```shell
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub "root@192.168.0.230"
ssh-copy-id -i ~/.ssh/id_rsa.pub "root@192.168.0.235"
ssh-copy-id -i ~/.ssh/id_rsa.pub "root@192.168.0.236"
ssh-copy-id -i ~/.ssh/id_rsa.pub "root@192.168.0.237"
```
##### 在/app/mha下創建app1.cnf
>注意修改相關配置文件master_binlog_dir為MySQl的數據目錄
```shell
[server default]
manager_log=/etc/mha/log/app1.log
manager_workdir=/etc/mha/app1/
master_binlog_dir=/data/mysql3306
master_ip_failover_script=/etc/mha/master_ip_failover
ping_interval=1
remote_workdir=/tmp
secondary_check_script=/bin/masterha_secondary_check -s ip235 -s ip236 --user=root --master_host=ip230 --master_ip=192.168.0.230 --master_port=3306
ssh_user=root
user=mha
password=mha
repl_password=repl
repl_user=repl
[server1]
hostname=192.168.0.230
port=3306
[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.0.235
port=3306
[server3]
hostname=192.168.0.236
port=3306
```
> 根據實際情況修改masterha_secondary_check位置,rpm安裝在bin目錄下
#### 上傳并修改/etc/mha/master_ip_failover腳本
```shell
chmod 600 master_ip_failover
```
內容詳見結尾附件
##### 調整參數(網卡名稱和IP)
```shell
my $vip = '192.168.0.20/24'; # Virtual IP
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
```
#### 部署從庫(S1/S2)的手動回收中繼日志腳本
上傳relay_purge.sh到/app/scripts下并增加執行權限
```shell
#!/bin/bash
/usr/bin/purge_relay_logs --user=root --password=123.com --socket=/tmp/mysql3306.sock --host=localhost -disable_relay_log_purge --port=3306 --workdir=/tmp >> /app/scripts/purge_relay_logs.log 2>&1
```
增加執行權限
```shell
chmod 600 /app/scripts/relay_purge.sh
```
部署定時任務
```shell
echo '0 4 * * * /bin/sh /app/scripts/relay_purge.sh' >/var/spool/cron/root
```
#### 切換測試
##### 驗證SSH配置
```shell
masterha_check_ssh --conf=/etc/mha/app1.cnf
```
##### 測試復制、應用差異日志、故障轉移腳本
```shell
masterha_check_repl --conf=/etc/mha/app1.cnf
```
##### 啟動MHA
```shell
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover< /dev/null >/etc/mha/app1/manager.log 2>&1 &
#狀態檢查
sterha_check_status --conf=/etc/mha/app1.cnf
```
##### 關閉MHA
正常關閉
```shell
masterha_stop --conf=/etc/mha/app1.cnf
```
##### 關閉主庫,并監控MHA日志
具體日志請查看MHA日志部分
這時,230(down) 235提升為主庫,236指向了235
#### 恢復原有環境
1.啟動230數據庫,并查看position情況
```shell
show master status\G
```
2.將236重新指向230
```shell
stop slave;
change master to master_host='192.168.0.230',master_user='repl',master_password='repl',master_log_file='mysql-bin.000003',master_log_pos=154;
start slave;
```
3.將235重新指向230
```shell
change master to master_host='192.168.0.230',master_user='repl',master_password='repl',master_log_file='mysql-bin.000003',master_log_pos=154;
start slave;
```
4.恢復MHA配置文件,并刪除鎖文件
```shell
rm -f /etc/mha/app1/app1.failover.complete
```
> 不刪除,不會切換,防止反復切換
5.卸載235上的寫VIP
```shell
/sbin/ifconfig eth0:1 down
```
#### 附件
/etc/mha/master_ip_failover
```shell
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port,
);
my $vip = '192.168.0.20/24'; # Virtual IP
my $key = "0";
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
$ssh_user = "root";
GetOptions(
'command=s' => \$command,
'ssh_user=s' => \$ssh_user,
'orig_master_host=s' => \$orig_master_host,
'orig_master_ip=s' => \$orig_master_ip,
'orig_master_port=i' => \$orig_master_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
);
exit &main();
sub main {
print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
if ( $command eq "stop" || $command eq "stopssh" ) {
# $orig_master_host, $orig_master_ip, $orig_master_port are passed.
# If you manage master ip address at global catalog database,
# invalidate orig_master_ip here.
my $exit_code = 1;
#eval {
# print "Disabling the VIP on old master: $orig_master_host \n";
# &stop_vip();
# $exit_code = 0;
#};
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
#my $ping=`ping -c 1 10.0.0.13 | grep "packet loss" | awk -F',' '{print $3}' | awk '{print $1}'`;
#if ( $ping le "90.0%" && $ping gt "0.0%" ){
#$exit_code = 0;
#}
#else {
&stop_vip();
# updating global catalog, etc
$exit_code = 0;
#}
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {
# all arguments are passed.
# If you manage master ip address at global catalog database,
# activate new_master_ip here.
# You can also grant write access (create user, set read_only=0, etc) here.
my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
`ssh $ssh_user\@$orig_master_ip \" $ssh_start_vip \"`;
exit 0;
}
else {
&usage();
exit 1;
}
}
# A simple system call that enable the VIP on the new master
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}
# the end.
```
- 獻給樂于奉獻的你
- 一、工作感悟
- 1.1 工作感悟
- 1.2 數據庫工作總結
- 二、運維專題(非技術)
- 2.1 公有云運維
- 2.1.1 阿里云采坑記.md
- 三、運維專題(技術類)
- 3.1 Linux(操作系統)
- 3.1.1 常見工作總結
- 3.1.2 常見服務使用和部署
- 3.1.3 操作系統優化
- 3.1.4 常用命令(Centos8)
- 3.2 Docker & K8s(容器技術)
- 3.2.1 Docker
- 1. Docker
- 1-1 容器基礎
- 1-2 部署和加速
- 1-3 常用命令
- 1-4 Dockerfile編寫
- 1-5 容器網絡
- 1-6 數據持久化
- 2. docker-compose
- 2-1 基礎
- 3.2.2 kubernetes
- 1. 導讀-請先看我
- 2. kubeadm部署集群
- 1-1 k8s-1.14-基于calico
- 1-2 k8s-1.17-基于flanne
- 3. 二進制部署集群
- 4. 日常工作及故障處理
- 4-1 常用命令
- 4-2 故障處理
- 3.2.3 依賴服務部署
- 1. Harbor(鏡像倉庫)
- 1-1 harbor-2.1.0(單節點)
- 3.3 CICD(持續集成/部署)
- 3.3.1 GitLab
- 1. 服務部署
- 1-1 Gitlab-CE-13.3.4(單節點)
- 2. Git基礎
- 3.3.2 Ansible
- 1. 服務部署
- 1-2 ansible-2.5(pip部署)
- 3. ansible-playbook
- 3-1 基于Roles的Playbook
- 3-3 循環語法
- 3.3.3 Jnekins
- 1. Jenkins部署
- 1-1 Jenkins-2.65部署
- 1-2 Jenkins-2.249部署
- 2. Jenkins項目初始化
- 3. Jenkins集成
- 3-1 Jenkins-2.65集成Sonar
- 3.4 LB/HA(負載均衡,反向代理)
- 3.4.1 LVS+Keepalive
- 1. LVS為MySQL讀提供負載均衡
- 3.4.2 Pacemaker(HA)
- 1. 常用命令(轉)
- 3.5 Runtime(代碼運行環境)
- 3.5.1 Tomcat(Web中間件)
- 1. Tomcat部署手冊
- 1-1 Tomcat-7.0.76部署
- 2. Tomcat常用腳本
- 3.6 NoSQL(非關系型數據庫)
- 3.6.1 redis(非關系數據庫)
- 1. Redis 基礎
- 2. Redis 4.0變化
- 3. Codis實現Redis的集群
- 4. Redis故障處理
- 5. redis安全第一步
- 6. Redis集群搭建
- 7. CacheCloud部署
- 3.6.1 Redis挑戰
- 3.6.2 MongoDB(文檔數據庫)
- 1. Mongodb基礎
- 1-1 Mongodb4.0新特性
- 1-2 支持多大數據量
- 2. Mongodb安裝
- 2-1 Mac OS安裝Mongodb
- 2-2 Yum安裝Mongodb
- 2-3 二進制安裝Mongodb
- 2-4 docker容器安裝Mongodb
- 2-5 Mongodb 配置文件詳解
- 2-6 Mongodb 生產安全清單
- 2-7 用戶身份認證和授權
- 3. Mongodb副本集
- 3-1 副本集搭建
- 3-2 用戶身份認證與授權
- 4. 日常維護工作
- 4-1 Mongodb磁盤回收
- 4-2 Mongodb備份恢復到任意時間點
- 4-3 Mongodb慢查詢分析
- 4-4 Mongodb版本升級
- 4-5 Mongodb副本集成員狀態
- 4-6 Mongodb備份恢復工具使用
- 4-7 Mongodb服務啟動和停止
- 4-8 修改副本集成員oplog大小
- 4-9 Mongodb 副本集Oplog
- 3.7 MQ(消息隊列)
- 3.7.1 Zookeeper(分布式協調系統)
- 1. ZooKeeper基礎
- 2. ZooKeeper集群搭建
- 2-1 ZK-3.4.10部署
- 3.2 RabbitMQ(消息隊列)
- 1. 服務部署
- 1-1 RabbitMQ-3.8部署
- 2. 常用命令
- 3.8 Monitor(數據收集,監控)
- 3.8.1 Zabbix(運維監控)
- 1. 服務部署
- 1-1 服務端部署
- 1-2 客戶端部署
- 2. 監控服務
- 2-1 監控Apache
- 2-2 監控IIS
- 2-3 監控Ningx
- 2-4 監控Tomcat(6/7/8)
- 2-5 監控WebSphere 7
- 2-6 監控MySQL
- 2-7 監控Oracle
- 2-8 監控SQL Servre
- 2-9 監控Weblogic
- 2-10 監控Windows
- 2-11 自定義監控項
- 3. 告警推送
- 3-1 郵件告警
- 3-2 短信告警
- 3-3 告警推到Syslog
- 4. 日常工作
- 4-1 數據庫優化(TokuDB)
- 4-2 數據庫優化(分區表)
- 4-3 前端定制(Grafana)
- 5. 與Grafana結合
- 3.8.2 ELKBstack(日志收集展示)
- 1. 服務部署
- 1-1 ELK 5.5部署及配置
- 1-1-1 ELKBstack介紹
- 1-1-2 Elasticsearch部署
- 1-1-3 Logstash部署
- 1-1-4 Kibana部署
- 1-1-5 X-pack部署
- 1-1-6 Filebeat部署
- 2. ELK高級配置
- 1. Elasticsearch實戰
- 2. Logstash實戰
- 3. Filebeat實戰
- 5. 引入隊列
- 3.9 Virtualization(虛擬化)
- 3.10 Basic(基礎服務)
- 3.10.1 Piwik-Matomo(用戶行為分析)
- 1. Piwik前期分析
- 2. Piwik介紹和部署
- 2-1 Piwik-3.x版本(早期)
- 3. Piwik 功能配置
- 4. Piwik 模擬數據和壓測
- 5. Piwik運轉原理
- 6. Piwik數據庫模式(一)
- 6-1 第一部分
- 6-2 第二部分
- 3.10.2 Cobbler(系統自動部署)
- 1. Cobbler 可以干什么?
- 2. Cobbler 基礎原理
- 3. Cobbler 安裝
- 3-1 Cobbler-2.8部署
- 4. Cobbler 基礎配置
- 5. Cobbler 配置文件
- 6. 一鍵優化腳本
- 3.10.3 Rsync(數據同步服務)
- 1. Rsync基礎
- 2. 案例:頁面部署(服務端拉取)
- 3.10.4 NFS(共享存儲)
- 1. NFS部署手冊
- 2. 客戶端NFS備份腳本
- 3.10.5 Grafana(可視化)
- 1. 安裝(8.2.x)
- 3.11 Tools(軟件工具)
- 3.11.1 基準測試
- 1. 基準測試方法論
- 2. 壓測工具 - Siege
- 3. 壓測工具 - http_load
- 3.12 DB(關系型數據庫)
- 3.12.1 MySQL(關系數據庫)
- 1. MySQL部署
- 1-1 MySQL-5.7部署
- 1-2 Percona-5.7 + TokuDB 部署
- 2. MySQL復制
- 2-1 MySQL異步復制
- 3. MySQL備份恢復
- 3-1 xtrabackup 備份恢復
- 4. MySQL 高可用
- 4-1 MHA(HA)
- 4-1-1 MHA 架構介紹和原理
- 4-1-2 MHA日常管理
- 4-1-3 MHA 自動Failover
- 4-1-4 MHA常用參數
- 4-1-5 MHA 報錯
- 4-1-6 MHA相關配置文件和腳本
- 4-2 MyCAT
- 4-2-1 MyCAT 介紹和部署
- 4-1-3 MyCAT讀寫分離案例解析
- 5. MySQL 常用腳本
- 5-1 MySQL常用統計語句
- 5-2 MySQL性能分析腳本
- 6. MySQL 日常及故障處理
- 6-1 MySQL死鎖排查
- 6-2 復制故障
- 6-3 MySQL 升級注意事項
- 6-3 MySQL授權
- 3.12.2 Oracle(關系數據庫)
- 1. Oracle部署
- 1-1 Oracle11g單實例部署
- 1-2 Oracle12c單實例部署
- 2. Oracle常用腳本
- 3. Oracle 知識點
- 六、Ansible開源項目
- 6.1 項目初始化手冊
- 6.1.1 Ansible錯誤處理
- 6.1.2 一種預先判斷是否操作的方法
- 6.2 System初始化
- 6.3 Nginx/Tnginx部署
- 6.4 Python部署
- 6.5 PHP部署
- 6.6 MySQL部署
- 6.7 Docker部署
- 6.8 Haproxy部署
- 6.9 Redis部署
- 1. 變量和tags信息
- 3. Redis主從部署
- 4. Redis集群部署
- 5. 清理數據
- 6.10 Software軟件部署
- 6.11 Zabbix部署
- 6.12 Elastic部署
- 6.13 Tomcat
- 6.14 Kafka部署
- 6.15 Zookeeper部署
- 6.16 Etcd集群部署
- 6.17 M3DB部署
- 6.18 Pormetheus部署
- 七、學習資源推薦
- 八、從瞎搞到放棄
- 8.1 CodeQL(語義代碼分析引擎)
- 8.1.1 背景及計劃
- 8.1.2 CodeQL概述
- 8.1.3 簡單部署和使用
- 8.1.4 后續
- 8.2 dbdeployer(輕松部署MySQL)
- 歸檔筆記
- 三、常用服務部署(遷移中)
- 3.4 Nginx & PHP(Web服務)
- 3.4.1 Nginx(Web)
- 1. Nginx基礎和部署
- 2. Nginx 我的一些思考
- 3. Nginx(Web)配置
- 4. Nginx(Proxy)配置
- 5. Nginx日常管理
- 3.4.3 PHP
- 1. PHP 7.1 部署
- 2. PHP5.6 部署
- 4. PHP原理
- 5. PHP 常用模塊
- 二、運維項目實戰(遷移中)
- 2.1 標準化 & 工具化項目
- 2.1.1 系統部署和優化
- 2.1.5 全網日志收集展示平臺項目
- 1. 項目需求
- 2. 整體方案規劃
- 3. 日志收集配置
- 4. 消息緩沖隊列
- 5. 日志處理轉發
- 6. 日志數據展示(待補充)
- 7. ELK安全配置(上)
- 8. ELK安全配置(下)
- 9. 項目總結
- 2.2 高性能Web項目
- 2.2.1 網站需求(完善中)