MySQL高可用及读写分离
- 为什么要使用高可用 ?
- 什么是高可用?
企业高可用标准:全年无故障时间
无故障时间 故障时间
99.9% 0.1% = 525.6 min KA+双主 :人为干预
99.99% 0.01% = 52.56 min MHA ORCH TMHA :半自动化
99.999% 0.001% = 5.256 min PXC 、 MGR 、MGC
99.9999% 0.0001% = 0.5256 min 自动化、云化、平台化
- MHA的软件结构介绍及搭建过程
一堆perl写的脚本。
2.1 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信息
2.2 node 组件
save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的
purge_relay_logs 清除中继日志(不会阻塞SQL线程)
2.3 MHA部署
2.3.1 GTID 复制环境准备
清理环境
pkill mysqld
rm -rf /data/3306/*
mv /etc/my.cnf /tmp
创建相关目录
mkdir -p /data/3306/data /data/3306/binlog
chown -R mysql.mysql /data
创建配置文件
db01
cat > /etc/my.cnf <
user=mysql
basedir=/data/app/mysql
datadir=/data/3306/data
server_id=6
socket=/tmp/mysql.sock
log_bin=/data/3306/binlog/mysql-bin
gtid_mode=ON
enforce_gtid_consistency
log-slave-updates=1
secure-file-priv=/tmp
innodb_data_file_path=ibdata1:128M;ibdata2:128M:autoextend
innodb_temp_data_file_path=ibtmp1:128M;ibtmp2:128M:autoextend:max:500M
innodb_undo_tablespaces=3
innodb_max_undo_log_size=128M
innodb_undo_log_truncate=ON
innodb_purge_rseg_truncate_frequency=32
autocommit=0
innodb_flush_method=O_DIRECT
slow_query_log=ON
slow_query_log_file=/data/3306/data/db01-slow.log
long_query_time=0.1
log_queries_not_using_indexes
[client]
socket=/tmp/mysql.sock
[mysql]
prompt=db01 [\d]>
socket=/tmp/mysql.sock
EOF
db02
cat > /etc/my.cnf <
user=mysql
basedir=/data/app/mysql
datadir=/data/3306/data
server_id=7
socket=/tmp/mysql.sock
log_bin=/data/3306/binlog/mysql-bin
gtid_mode=ON
enforce_gtid_consistency
log-slave-updates=1
secure-file-priv=/tmp
innodb_data_file_path=ibdata1:128M;ibdata2:128M:autoextend
innodb_temp_data_file_path=ibtmp1:128M;ibtmp2:128M:autoextend:max:500M
innodb_undo_tablespaces=3
innodb_max_undo_log_size=128M
innodb_undo_log_truncate=ON
innodb_purge_rseg_truncate_frequency=32
autocommit=0
innodb_flush_method=O_DIRECT
slow_query_log=ON
slow_query_log_file=/data/3306/data/db01-slow.log
long_query_time=0.1
log_queries_not_using_indexes
[client]
socket=/tmp/mysql.sock
[mysql]
prompt=db02 [\d]>
socket=/tmp/mysql.sock
EOF
db03
cat > /etc/my.cnf <
user=mysql
basedir=/data/app/mysql
datadir=/data/3306/data
server_id=8
socket=/tmp/mysql.sock
log_bin=/data/3306/binlog/mysql-bin
gtid_mode=ON
enforce_gtid_consistency
log-slave-updates=1
secure-file-priv=/tmp
innodb_data_file_path=ibdata1:128M;ibdata2:128M:autoextend
innodb_temp_data_file_path=ibtmp1:128M;ibtmp2:128M:autoextend:max:500M
innodb_undo_tablespaces=3
innodb_max_undo_log_size=128M
innodb_undo_log_truncate=ON
innodb_purge_rseg_truncate_frequency=32
autocommit=0
innodb_flush_method=O_DIRECT
slow_query_log=ON
slow_query_log_file=/data/3306/data/db01-slow.log
long_query_time=0.1
log_queries_not_using_indexes
[client]
socket=/tmp/mysql.sock
[mysql]
prompt=db03 [\d]>
socket=/tmp/mysql.sock
EOF
初始化数据
mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql --datadir=/data/3306/data
启动数据库
/etc/init.d/mysqld start
构建主从
db01 创建复制用户
db01 [(none)]>grant replication slave on . to repl@'10.0.0.%' identified by '123';
db02、db03 构建主从
change master to
master_host='10.0.0.51',
master_user='repl',
master_password='123' ,
MASTER_AUTO_POSITION=1;
start slave;
2.3.2 MHA软件安装配置
2.1 规划:
主库:
51 node
从库:
52 node
53 node manager
2.2 准备环境(略。1主2从GTID)
2.3 配置关键程序软连接(所有节点)
ln -s /data/app/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /data/app/mysql/bin/mysql /usr/bin/mysql
2.4 配置各节点互信(密钥对)
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
2.5 安装软件
下载mha软件
mha官网:https://code.google.com/archive/p/mysql-master-ha/
github下载地址:https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads
说明:
8.0 的版本:
- 密码加密模式 sha2 ---> native
- 使用0.58 版本MHA软件
所有节点安装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';
2.6 Manager配置文件准备(db03)
创建配置文件目录
mkdir -p /etc/mha
创建日志目录
mkdir -p /var/log/mha/app1
编辑mha配置文件
cat > /etc/mha/app1.cnf <
manager_log=/var/log/mha/app1/manager
manager_workdir=/var/log/mha/app1
master_binlog_dir=/data/binlog
user=mha
password=mha
ping_interval=2
repl_password=123
repl_user=repl
ssh_user=root
[server1]
hostname=10.0.0.51
port=3306
[server2]
hostname=10.0.0.52
port=3306
[server3]
hostname=10.0.0.53
port=3306
EOF
2.7 状态检查(db03)
masterha_check_ssh --conf=/etc/mha/app1.cnf
masterha_check_repl --conf=/etc/mha/app1.cnf
2.8 开启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 &
2.9 查看MHA状态
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:4719) is running(0:PING_OK), master:10.0.0.51
- 站在产品经理角度,评估高可用软件设计
3.1 监控
3.2 选主
3.3 数据补偿
3.4 故障转移
3.5 应用透明
3.6 自动提醒
3.7 自愈
- MHA FailOver 原理
4.1 监控 :
通过 masterha_master_monitor ,每隔ping_interval秒特测一此Master 心跳。
监测不到心跳,一共给4次机会。
4.2 选主
4.2.1 备选主
candidate_master=1 强制某个节点为备选主。如果日志量超过100M差异,放弃掉他。
check_repl_delay=0 不检查日志量的差异。
4.2.2 日志量
各个从库回放到的日志量。
无GTID:
[root@db02 ~]# mysql -e "show slave status\G" |grep "Master_Log"
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 194
Relay_Master_Log_File: mysql-bin.000003
Exec_Master_Log_Pos: 194
有GTID:
[root@db02 ~]# mysql -e "show slave status\G" |grep "Executed_Gtid_Set"
Executed_Gtid_Set: 1c35b73a-7321-11ea-8974-000c29248f69:1-6
[root@db02 ~]#
4.2.3 如果没有权重,从库日志量一样
根据配置文件的先后顺序选择新主。
4.3 日志补偿
4.3.1 if 主库ssh 能连接
各个从节点,通过save_binary_logs 立即保存缺失部分的binlog到/var/tmp/xxxxx
怎么判断缺失日志?
有GTID?
[root@db01 ~]# mysql -e "show master status;"
[root@db02 ~]# mysql -e "show slave status\G" |grep "Retrieved_Gtid_Set"
4.3.2 eles 主库 ssh 不能连接
从节点调用apply_diff_relay_logs,计算两个从节点的relay-log日志差异。
4.4 故障转移
- 取消所有节点的从库状态
- 构建新的主从关系
4.5 自动将故障节点,从配置文件剔除
--remove_dead_master_conf
4.6 自杀
manager自动退出。
4.7 应用透明: vip
4.8 数据补偿补充方案:binlog_server
4.9 切换提醒:send_report
- 模拟故障并恢复
5.0 工作状态查看
[root@db03 app1]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:17501) is running(0:PING_OK), master:10.0.0.51
5.1 宕主库测试
[root@db01 ~]# /etc/init.d/mysqld stop
Shutting down MySQL............ SUCCESS!
[root@db01 ~]#
5.2 看日志
[root@db03 app1]# vim /var/log/mha/app1/manager
5.3 恢复
5.3.1 修复故障节点
[root@db01 ~]# /etc/init.d/mysqld start
Starting MySQL.. SUCCESS!
如果生产怎么办?
按实际情况。
5.3.2 恢复主从
change master to
master_host='10.0.0.52',
master_user='repl',
master_password='123' ,
MASTER_AUTO_POSITION=1;
start slave;
5.3.3 修复配置文件
方法一:
vim /etc/mha/app1.cnf
[server1]
hostname=10.0.0.51
port=3306
方法二:
[root@db03 ~]# masterha_conf_host --command=add --conf=/etc/mha/app1.cnf --hostname=10.0.0.51 --block=server10 --params="port=3306"
masterha_conf_host --command=delete --conf=/etc/mha/app1.cnf --block=server1
5.3.4 预检测脚本
[root@db03 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
5.3.5 启动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 &
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:24316) is running(0:PING_OK), master:10.0.0.52
[root@db03 ~]#
- 应用透明---VIP
vip : 10.0.0.55/24
6.1 vip 故障转移脚本
上传mha_script.tar文件到/usr/local/bin 解压
6.2 修改权限
[root@db03 bin]# chmod +x /usr/local/bin/*
6.3 修改内容
[root@db03 bin]# cp master_ip_failover master_ip_failover.bak
my key = '1';
my ssh_start_vip = "/sbin/ifconfig key ssh_stop_vip = "/sbin/ifconfig key down";
my if -c 3 -A 10.0.0.55";
6.4 修改Manager 配置文件
vim /etc/mha/app1.cnf
master_ip_failover_script=/usr/local/bin/master_ip_failover
6.5 重启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 &
6.6 手工在主库添加VIP
[root@db02 ~]# ifconfig ens33:1 10.0.0.55/24
- 故障提醒功能
7.1 准备脚本
[root@db03 bin]# cp send_report send_report.bak1
my mail_from='[email protected]'; # 发件箱
my mail_pass='gemghsvgkeyzcagh'; # 授权码
my $mail_to=['[email protected]']; # 收件箱
my $mail_to=['[email protected]','[email protected]'];
7.2 修改配置文件
vim /etc/mha/app1.cnf
添加一行:
report_script=/usr/local/bin/send_report
7.3 重启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 &
7.4 模拟主库宕机
7.4.1 确认主库
[root@db03 bin]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:27096) is running(0:PING_OK), master:10.0.0.52
7.4.2 宕主库
[root@db02 ~]# /etc/init.d/mysqld stop
Shutting down MySQL............ SUCCESS!
7.4.3 观察 vip 漂移
7.4.4 观察 邮件
7.5 修复MHA 架构1主2从
略
- 日志补偿的冗余方案--binlog_server
8.1 创建必要目录(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"
Master_Log_File: mysql-bin.000008
Read_Master_Log_Pos: 194
Relay_Master_Log_File: mysql-bin.000008
Exec_Master_Log_Pos: 194
[root@db03 ~]#
mysqlbinlog -R --host=10.0.0.52 --user=mha --password=mha --raw --stop-never mysql-bin.000003 &
注意:
拉取日志的起点,需要按照目前从库的已经获取到的二进制日志点为起点
8.2 配置文件设置
vim /etc/mha/app1.cnf
[binlog1]
no_master=1
hostname=10.0.0.53
master_binlog_dir=/data/binlog_server/
8.3 重启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的维护操作 - 在线切换功能
9.1 只切换角色
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
9.2 master_ip_online_change_script功能实现
功能: 在线切换时,自动锁原主库,VIP自动切换
9.2.1 准备切换脚本
vim /usr/local/bin/master_ip_online_change
my key = "1";
my key ssh_stop_vip = "/sbin/ifconfig ens33:vip down";
my $ssh_Bcast_arp= "/sbin/arping -I ens33 -c 3 -A 10.0.0.55";
9.2.2 修改MHA配置文件
vim /etc/mha/app1.cnf
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
9.2.3 停 MHA
[root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf
9.2.4 检查repl
[root@db03 bin]# masterha_check_repl --conf=/etc/mha/app1.cnf
9.2.4 在线切换
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
9.2.5 重构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
9.2.6 启动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
===================
Altas 读写分离
- 介绍
Atlas是由 Qihoo 360, Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。
它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。
360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。
下载地址
https://github.com/Qihoo360/Atlas/releases
注意:
1、Atlas只能安装运行在64位的系统上
2、Centos 5.X安装 Atlas-XX.el5.x86_64.rpm,Centos 6.X安装Atlas-XX.el6.x86_64.rpm。
3、后端mysql版本应大于5.1,建议使用Mysql 5.6以上
2.安装配置
yum install -y Atlas*
cd /usr/local/mysql-proxy/conf
mv test.cnf test.cnf.bak
vi test.cnf
[mysql-proxy]
admin-username = user
admin-password = pwd
proxy-backend-addresses = 10.0.0.55:3306
proxy-read-only-backend-addresses = 10.0.0.51:3306,10.0.0.53:3306
pwds = repl:3yb5jEku5h4=,mha:O2jBXONX098=
daemon = true
keepalive = true
event-threads = 8
log-level = message
log-path = /usr/local/mysql-proxy/log
sql-log=ON
proxy-address = 0.0.0.0:33060
admin-address = 0.0.0.0:2345
charset=utf8
启动atlas
/usr/local/mysql-proxy/bin/mysql-proxyd test start
ps -ef |grep proxy
- Atlas功能测试
测试读操作:
mysql -umha -pmha -h 10.0.0.53 -P 33060
db03 [(none)]>select @@server_id;
测试写操作:
mysql> begin;select @@server_id;commit;
注意:
DDL建议不要再Atlas触发,最好是到主库触发(Online DDL或者PT-OSC)。
DML建议begin; DML; commit;
- Atlas 的管理操作
[root@db03 conf]# mysql -uuser -ppwd -h 10.0.0.53 -P2345
db03 [(none)]>select * from help;
4.1 查看所有节点
db03 [(none)]>SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address | state | type |
+-------------+----------------+-------+------+
| 1 | 10.0.0.55:3306 | up | rw |
| 2 | 10.0.0.52:3306 | up | ro |
| 3 | 10.0.0.53:3306 | up | ro |
+-------------+----------------+-------+------+
3 rows in set (0.00 sec)
4.2 节点的上线和下线
db03 [(none)]>SET OFFLINE 1;
+-------------+----------------+---------+------+
| backend_ndx | address | state | type |
+-------------+----------------+---------+------+
| 1 | 10.0.0.55:3306 | offline | rw |
+-------------+----------------+---------+------+
1 row in set (0.01 sec)
db03 [(none)]>SELECT * FROM backends;
+-------------+----------------+---------+------+
| backend_ndx | address | state | type |
+-------------+----------------+---------+------+
| 1 | 10.0.0.55:3306 | offline | rw |
| 2 | 10.0.0.52:3306 | up | ro |
| 3 | 10.0.0.53:3306 | up | ro |
+-------------+----------------+---------+------+
db03 [(none)]>SET ONLINE 1;
+-------------+----------------+---------+------+
| backend_ndx | address | state | type |
+-------------+----------------+---------+------+
| 1 | 10.0.0.55:3306 | unknown | rw |
+-------------+----------------+---------+------+
4.3 删除和添加节点
db03 [(none)]>REMOVE BACKEND 3;
db03 [(none)]>ADD SLAVE 10.0.0.53:3306;
4.4 用户管理
db01 [(none)]>grant all on . to oldguo@'10.0.0.%' identified by '123';
db03 [(none)]>SELECT * FROM pwds;
db03 [(none)]>add pwd oldguo:123;
4.5 持久化配置文件
db03 [(none)]>save config;
==================================================
- MySQL PT(percona-toolkit)工具使用
[root@db01 ~]# yum install -y percona-toolkit-3.1.0-2.el7.x86_64.rpm
5.1. 系统配置总览
pt-summary
作用: 系统状态总览。
应用场景: 系统巡检工作。
- 表归档:pt-archiver
重要参数
--limit 100 每次取100行数据用pt-archive处理
--txn-size 100 设置100行为一个事务提交一次
--where 'id<3000' 设置操作条件
--progress 5000 每处理5000行输出一次处理信息
--statistics 输出执行过程及最后的操作统计。
--charset=UTF8 指定字符集为UTF8—这个最后加上不然可能出现乱码。
--bulk-delete 批量删除source上的旧数据(例如每次1000行的批量删除操作)
--for-update: 在每个select语句后面加入for update
经典需求:
- 一张表有 10亿+ ,现在要求按照条件1000w数据
- 归档数据到别的节点。
使用案例:
归档到数据库(本地)
pt-archiver --source h=10.0.0.51,D=world,t=city,u=root,p=123 --dest h=10.0.0.51,D=world,t=city2,u=root,p=123 --where 'id<1000' --no-check-charset --no-delete --limit=100 --commit-each --progress 200 --statistics
归档到数据库(异地)
pt-archiver --source h=10.0.0.51,D=world,t=city,u=root,p=123 --dest h=10.0.0.52,D=world,t=city2,u=root,P=3307,p=123 --where 'id<1000' --no-check-charset --no-delete --limit=100 --commit-each --progress 200 --statistics
只清理数据
pt-archiver --source h=10.0.0.51,D=world,t=city,u=root,p=123 --where 'id<1000' --purge --limit=1 --no-check-charset
只把数据导出到外部文件,但是不删除源表里的数据
pt-archiver --source h=10.0.0.51,D=world,t=city,u=root,p=123 --where 'id>900' --no-check-charset --no-delete --file="/tmp/archiver.dat"
- pt-osc Online DDL
原理:
1、检查更改表是否有主键或唯一索引,是否有触发器
2、检查修改表的表结构,创建一个临时表,在新表上执行ALTER TABLE语句
3、在源表上创建三个触发器分别对于INSERT UPDATE DELETE操作
4、从源表拷贝数据到临时表,在拷贝过程中,对源表的更新操作会写入到新建表中
5、将临时表和源表rename(需要元数据修改锁,需要短时间锁表)
6、删除源表和触发器,完成表结构的修改。
=====================================================##
pt-osc工具限制
1、源表必须有主键或唯一索引,如果没有工具将停止工作
2、如果线上的复制环境过滤器操作过于复杂,工具将无法工作
3、如果开启复制延迟检查,但主从延迟时,工具将暂停数据拷贝工作
4、如果开启主服务器负载检查,但主服务器负载较高时,工具将暂停操作
5、当表使用外键时,如果未使用--alter-foreign-keys-method参数,工具将无法执行
6、只支持Innodb存储引擎表,且要求服务器上有该表1倍以上的空闲空间。
pt-osc之alter语句限制
1、不需要包含alter table关键字,可以包含多个修改操作,使用逗号分开,如"drop clolumn c1, add column c2 int"
2、不支持rename语句来对表进行重命名操作
3、不支持对索引进行重命名操作
4、如果删除外键,需要对外键名加下划线,如删除外键fk_uid, 修改语句为"DROP FOREIGN KEY _fk_uid"
pt-osc之命令模板
--execute表示执行
--dry-run表示只进行模拟测试
表名只能使用参数t来设置,没有长参数
pt-online-schema-change
--host="127.0.0.1"
--port=3358
--user="root"
--password="root@root"
--charset="utf8"
--max-lag=10
--check-salve-lag='xxx.xxx.xxx.xxx'
--recursion-method="hosts"
--check-interval=2
--database="testdb1"
t="tb001"
--alter="add column c4 int"
--execute
例子:
pt-online-schema-change --user=root --password=123 --host=10.0.0.52 --alter "add column age int default 0" D=world,t=city --print --execute
- 主从一致性校验
(1) 创建数据库
Create database pt CHARACTER SET utf8;
创建用户checksum并授权
GRANT ALL ON . TO 'checksum'@'10.0.0.%' IDENTIFIED BY 'checksum';
flush privileges;
--[no]check-replication-filters:是否检查复制的过滤器,默认是yes,建议启用不检查模式。
--databases | -d:指定需要被检查的数据库,多个库之间可以用逗号分隔。
--[no]check-binlog-format:是否检查binlog文件的格式,默认值yes。建议开启不检查。因为在默认的row格式下会出错。
--replicate:把checksum的信息写入到指定表中。
--replicate-check-only:只显示不同步信息
小坑
所有库:
autocommit=1
从库 :
report_host=10.0.0.xx
report_port=3306
应用:
针对表校验:
pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=pt.checksums --create-replicate-table --databases=world --tables=city h=10.0.0.52,u=checksum,p=checksum,P=3306
针对库校验:
pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=pt.checksums --create-replicate-table --databases=test h=10.0.0.51,u=checksum,p=checksum,P=3306
脚本模板:
!/bin/bash
date >> /root/db/checksum.log
pt-table-checksum --nocheck-binlog-format --nocheck-plan
--nocheck-replication-filters --replicate=pt.checksums --set-vars
innodb_lock_wait_timeout=120 --databases test -u'checksum' -p'checksum'
-h'10.0.0.11' >> /root/db/checksum.log
date >> /root/db/checksum.log
pt-table-sync
主要参数介绍
--replicate :指定通过pt-table-checksum得到的表.
--databases : 指定执行同步的数据库。
--tables :指定执行同步的表,多个用逗号隔开。
--sync-to-master :指定一个DSN,即从的IP,他会通过show processlist或show slave status 去自动的找主。
h= :服务器地址,命令里有2个ip,第一次出现的是Master的地址,第2次是Slave的地址。
u= :帐号。
p= :密码。
--print :打印,但不执行命令。
--execute :执行命令。
pt-table-sync --replicate=pt.checksums h=10.0.0.52,u=root,p=123,P=3306 --print
pt-table-sync --replicate=pt.checksums h=10.0.0.52,u=root,p=123,P=3306 --execute
- 显示主从结构:pt-slave-find
[root@db01 tmp]# pt-slave-find -h10.0.0.52 -P3306 -uchecksum -pchecksum
10.0.0.51
Version 5.7.28-log
Server ID 51
Uptime 27:57 (started 2020-05-15T13:24:15)
Replication Is not a slave, has 1 slaves connected, is not read_only
Filters
Binary logging ROW
Slave status
Slave mode STRICT
Auto-increment increment 1, offset 1
InnoDB version 5.7.28
+- 10.0.0.52
Version 5.7.28-log
Server ID 52
Uptime 28:18 (started 2020-05-15T13:23:54)
Replication Is a slave, has 0 slaves connected, is not read_only
Filters
Binary logging ROW
Slave status 0 seconds behind, running, no errors
Slave mode STRICT
Auto-increment increment 1, offset 1
InnoDB version 5.7.28
[root@db01 tmp]#
6.检查指定表的重复索引
pt-duplicate-key-checker
db01 [world]>alter table city add index idx(countrycode,population);
[root@db01 tmp]# pt-duplicate-key-checker --host=10.0.0.52 --user='checksum' --password='checksum' --databases=world --tables=city
world.city
CountryCode is a left-prefix of idx
Key definitions:
KEY CountryCode
(CountryCode
),
KEY idx
(CountryCode
,Population
),
Column types:
countrycode
char(3) not null default ''
population
int(11) not null default '0'
To remove this duplicate index, execute:
ALTER TABLE world
.city
DROP INDEX CountryCode
;
Summary of indexes
Size Duplicate Indexes 12564
Total Duplicate Indexes 1
Total Indexes 4
[root@db01 tmp]#
- 监控主从延时
pt-heartbeat
主库:
pt-heartbeat --user=root --ask-pass --host=10.0.0.52 --create-table -D test --interval=1 --update --replace --daemonize
从库:
pt-heartbeat --user=root --ask-pass --host=10.0.0.51 -D test --table=heartbeat --monitor
-
pt-show-grants
pt-show-grants -h10.0.0.52 -P3306 -uchecksum -pchecksum
-- Grants dumped by pt-show-grants
-- Dumped from server 10.0.0.51 via TCP/IP, MySQL 5.7.28-log at 2020-05-15 17:11:06
-- Grants for 'checksum'@'10.0.0.%'
CREATE USER IF NOT EXISTS 'checksum'@'10.0.0.%';
ALTER USER 'checksum'@'10.0.0.%' IDENTIFIED WITH 'mysql_native_password' AS 'E5E390AF1BDF241B51D9C0DBBEA262CC9407A2DF' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT ALL PRIVILEGES ON . TO 'checksum'@'10.0.0.%';
-- Grants for 'mysql.session'@'localhost'
CREATE USER IF NOT EXISTS 'mysql.session'@'localhost';
ALTER USER 'mysql.session'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS 'THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT LOCK;
GRANT SELECT ON mysql
.user
TO 'mysql.session'@'localhost';
GRANT SELECT ON performance_schema
.* TO 'mysql.session'@'localhost';
GRANT SUPER ON . TO 'mysql.session'@'localhost';
-- Grants for 'mysql.sys'@'localhost'
CREATE USER IF NOT EXISTS 'mysql.sys'@'localhost';
ALTER USER 'mysql.sys'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS 'THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT LOCK;
GRANT SELECT ON sys
.sys_config
TO 'mysql.sys'@'localhost';
GRANT TRIGGER ON sys
. TO 'mysql.sys'@'localhost';
GRANT USAGE ON . TO 'mysql.sys'@'localhost';
-- Grants for 'repl'@'10.0.0.%'
CREATE USER IF NOT EXISTS 'repl'@'10.0.0.%';
ALTER USER 'repl'@'10.0.0.%' IDENTIFIED WITH 'mysql_native_password' AS '23AE809DDACAF96AF0FD78ED04B6A265E05AA257' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT REPLICATION SLAVE ON . TO 'repl'@'10.0.0.%';
-- Grants for 'root'@'10.0.0.%'
CREATE USER IF NOT EXISTS 'root'@'10.0.0.%';
ALTER USER 'root'@'10.0.0.%' IDENTIFIED WITH 'mysql_native_password' AS '23AE809DDACAF96AF0FD78ED04B6A265E05AA257' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT ALL PRIVILEGES ON . TO 'root'@'10.0.0.%';
-- Grants for 'root'@'localhost'
CREATE USER IF NOT EXISTS 'root'@'localhost';
ALTER USER 'root'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK;
GRANT ALL PRIVILEGES ON . TO 'root'@'localhost' WITH GRANT OPTION;
GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION;
给出参数建议:
pt-variable-advisor 10.0.0.52 -uchecksum -pchecksum