MySQL mysqlfailover工具
【1】前期准备
(1.1)架构
描述 | IP | OS_info | mysql_version |
DB3,主库 | 192.168.148.39:3307 | CentOS7.8 | 5.7.31 |
DB4,从库 | 192.168.148.27:3307 | CentOS7.8 | 5.7.31 |
DB5,从库 | 192.168.148.30:3307 | CentOS7.8 | 5.7.31 |
见故障处理(2),8.0+版本不行,换成5.7;
(1.2)下载安装
mkdir -p /data/dba cd /data/dba wget https://cdn.mysql.com/archives/mysql-utilities/mysql-utilities-1.6.5.tar.gz tar -zxf mysql-utilities-1.6.5.tar.gz cd mysql-utilities-1.6.5 python setup.py build python setup.py install mysqlfailover --version
yum安装:
vim /etc/yum.repos.d/mysql
[mysql-tools-community] name=MySQL Tools Community baseurl=http://repo.mysql.com/yum/mysql-tools-community/el/7/$basearch/ enabled=1 gpgcheck=0 gpgkey=file:/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql [mysql-connectors-community] name=MySQL Connectors Community baseurl=http://repo.mysql.com/yum/mysql-connectors-community/el/7/$basearch/ enabled=1 gpgcheck=0 gpgkey=file:/etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
环境变量中已经有了,就表示安装好了;
(1.3)mysql 一主两从架构
根据(1.1)中架构 DB3 为主,DB4/DB5为从;
- DB3:192.168.148.39
- DB4:192.168.148.27
- DB5:192.168.148.30
GTID 相关参数肯定开了;
binlog_format= ROW gtid_mode = on enforce_gtid_consistency = 1 log_slave_updates = 1 master-info-repository=TABLE relay-log-info-repository=TABLE
report_host=192.168.148.39 # 注意,这里每个机器写自己的IP和端口
report_port=3306
搭建架构相关代码如下:
#防火墙 iptables/firewall事项,这里就不多说了,测试使用我已经关闭;
# DB3 create user repl@'192.168.148.%' identified by 'a123456!'; grant replication slave,replication client on *.* to repl@'192.168.148.%'; # DB4/DB5(新机器、无数据的机器)
stop slave;
reset master;
reset slave all;
change master to master_host='192.168.148.39', master_port=3307, master_user='repl', master_password='a123456!', master_auto_position=1;
start slave;
# 查阅--从库执行
show slave status\G
# 查阅--主库执行
show slave hosts;
【2】mysql failover工具
(2.1)mysqlfailover特点
-
持续监控主从主从拓扑结构健康状况,当主节点不可用时,触发自动故障转移
-
只支持GTID全局事务标识符,传统主从模式不支持
-
支持设置故障转移首选及备选节点,支持投票选举方式选择新的主节点以及仅监测模式(不切换主从)
-
支持自定义时间监测间隔
-
支持交互模式以及守护进程的模式开启mysqlfailover
-
支持在切换前或切换后执行指定的脚本
-
支持操作记录到日志不同的粒度以及日志老化
(2.2)mysqlfailover 前置要求
#mysql参数:
report_host=192.168.148.30
report_port=3306 master-info-repository=TABLE relay-log-info-repository=TABLE #权限(mysqlfailover工具检测及切换期间需要,主从都需要) SHOW SLAVE STATUS SHOW MASTER STATUS STOP SLAVE, START SLAVE, WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS, CHANGE MASTER TO REPLICATE SLAVE SUPER, GRANT OPTION, RELOAD, DROP, CREATE, INSERT ,SELECT权限
(2.3)详细参数
--candidates= |
备选从库连接配置, --candidates=user:pwd@host:port,user:pwd@host:port,user:pwd@host:port |
--daemon |
后台运行,未指定就是交互 --daemon start --daemon stop --daemon restart --daemon nodetach 兼容2种模式
|
--discover-slaves-login= |
主库上查询当前注册的从服务,所以这里应该是主库账号密码 从库需要支持 --report-host 和--report-port --discover-slaves-login=user:password |
--exec-after= |
故障转移之后,执行的脚本 脚本返回0表示成功,非0表示返回错误信息 --exec-after=/tmp/a.sh |
--exec-before= |
故障转移之前的脚本 脚本返回0表示成功,非0表示返回错误信息 --exec-after=/tmp/b.sh |
--exec-fail-check= |
此脚本可以额外触发故障转移。返回码0表示故障不发生。非0表示发生。如果该脚本指定,在每个间隔开始检测 |
--exec-post-failover= |
脚本,故障转移完成且应用工具已刷新运行状况报告后要执行的脚本的名称 |
--failover-mode= |
转移模式 auto 默认,故障转移先选第一候选人,如果失败,则从列表里选择其他候选人,如果都没有,则程序报错并且退出转移操作。如果后续有候选者被发现,则继续尝试 elect 类似auto模式,除了如果在指定的候选列表中没有可行的,则不检测剩余的从,报错并且退出切换操作 fail 这种模式会产生一个错误,当主库失败后不会进行故障转移,这种模式只用来进行定期健康监测不进行故障切换
|
--force |
启动控制台模式,是独占的,为了确保独占,master:port 将被插入一个特殊的表,来记录,默认启动时都会查找这个表,如果已存在则控制台无法启动,除非使用—force |
--interval= |
健康检查的间隔,以及执行相关脚本的时间间隔,默认15s,最小间隔5s |
--log= |
指定日志文件 |
--log-age= |
日志保留天数,默认7天 |
--master= |
主库实例地址 --master=user:pwd@host:port |
--max-position= |
默认0,如果该值大于主和从的日志位置之间的最大差值,则意味着从库严重落后主库。 (会有什么后果呢?这个参数影响哪里?) |
--pedantic, -p |
用于在服务器检查期间发现某些不一致(例如从属服务器上的错误事务或SQL线程错误)时停止故障切换。如果不指定就算从库同步失败也会有将从库提升为主的可能 |
--pidfile= |
作为守护进程运行mysqlfailover的PID文件 (如果运行多个mysqlfailover,可能这个参数是关键) |
--ping= |
检测服务器宕机的ping尝试次数,Note: on some platforms this is the same as number of seconds to wait for ping to return. Default is 3 seconds. (这个又是次数又是超时时间,那这个单位是次还是秒。这什么文档) |
--report-values= |
交互界面显示的效果,可以到里面再切换的。如下附图 |
--rpl-user=: |
user:pwd 复制的账号密码,默认空,不知道这个什么用 |
--script-threshold= |
外部脚本触发终止操作,作为判断的返回值。默认 none 如果设置0,那就是0终止,不然就是继续 (不知道这么理解对不对) |
--seconds-behind= |
默认0 ,只用于检测的阈值做报告用,不参与故障转移的过程 |
--slaves= |
从库的连接url,会优先故障转移到最前面的 host user:pwd@host:port, user:pwd@host:port, 多个的话逗号分隔
|
--timeout= |
Maximum timeout in seconds to wait for each replication command to complete. For example, timeout for slave waiting to catch up to master.
|
--verbose, -v |
|
--version |
|
(2.4)核心参数详解
--failover-mode(转移模式) auto:执行故障自动转移到第一候选人。如果没有从可行的,继续从从列表中找到一个可行的候选者。 如果没有从被认为是一个可行的候选者,该程序将生成错误并退出。一旦候选者被发现,该程序将进行故障切换到最佳从上。 该命令测试每个候选从的先决条件。一旦候选从被选中,其他从作为它的从,收集其他从的任何事务交易。该方式,确保候选者是最新的从 elect:这种模式与aoto一样的,除了如果在指定的候选从列表中没有可行的,不检测剩余的从和产生错误并退出。 fail: 这种模式会产生一个错误,当主失败后不会进行故障转移。这种模式被用来只进行定期健康监测不进行故障切换。 --interval 选项来定义检测主状态和产生健康报告的时间间隔,缺省为15s,最小间隔为5s --master=MASTER 主服务器连接配置 --slaves=SLAVES 从服务器连接配置 --candidates=CANDIDATES 候选服务器连接配置 以上3个连接配置值支持是使用下列方式,多个值以逗号分割 <user>[:<password>]@<host>[:<port>][:<socket>] <login-path>[:<port>][:<socket>] <config-path>[<[group]>] --discover-slaves-login=DISCOVER 基于主服务器用户密码查询当前所有注册到主服务器的从库端 使用<user>[:<password>] or <login-path> --ping=PING Number of ping attempts for detecting downed server. 侦测服务器宕机检测,缺省为3s --force override the registration check on master for multiple instances of the console monitoring the same master. 当控制台启动时,主的主机名和端口将被插入一个特殊的表来跟踪记录哪些实例与主联系 在启动时,如果行匹配这些值,控制台无法启动。如果使用--force选项,该行将被删除 --daemon(使用守护进程方式,如未指定,则为交互方式) start 启动守护进程。需要--log选项。 stop 停止守护进程。如果有指定--pidfile选项,该值需要与start指定的一致。 restart 重新启动守护进程。如果有指定--pidfile选项,该值需要与start指定的一致。 nodetach 启动守护进程,但是不会从控制台分离进程。需要--log选项。 --log=<log_file> 指定日志文件 --log-age 选项用于指定日志存放天数,默认是7天。旧的日志自动轮滚掉 --exec-before 故障转移命令之前执行外部脚本 脚本的返回码来确定是否成功执行,0表示成功,非0表示失败并返回错误信息 --exec-after 故障转移命令之后执行外部脚本 脚本的返回码来确定是否成功执行,0表示成功,非0表示失败并返回错误信息 -p, --pedantic fail if some inconsistencies are found (e.g. errant transactions on slaves). 在检查期间如果发现有不一致的情况(从错误的事务或SQL线程错误)阻止故障转移。
【3】实际案例
(3.0)主库构造测试数据
mysql -e "create database testdb;create database tempdb;" mysql -e "create table testdb.repl(id int,ename varchar(50))" mysql -e "insert into testdb.repl values(1,'leshami')" mysql -e "select * from testdb.repl"
# 创建故障转移切换账户
mysql -e "create user failover@'192.168.148.%' identified by 'a123456\!';"
mysql -e "grant all privileges on *.* to failover@'192.168.148.%' with grant option;"
(3.1)交互式 failover 启动
信息也会存在于主库的 mysql.failover_console 表中
命令参考:
mysqlfailover --master=failover:'a123456!'@'192.168.148.39':3307 --discover-slaves-login=failover:'a123456!'
mysqlfailover --master=failover:'a123456!'@'192.168.148.39':3307 --slaves=failover:'a123456!'@'192.168.148.27':3307
实际操作:
[root@DB3 config]# mysqlfailover --master=failover:'a123456!'@'192.168.148.39':3307 --discover-slaves-login=failover:'a123456!' WARNING: Using a password on the command line interface can be insecure. # Discovering slaves for master at 192.168.148.39:3307 # Discovering slave at 192.168.148.27:3307 # Found slave: 192.168.148.27:3307 # Discovering slave at 192.168.148.30:3307 # Found slave: 192.168.148.30:3307 # Checking privileges. Multiple instances of failover console found for master 192.168.148.39:3307. If this is an error, restart the console with --force. Failover mode changed to 'FAIL' for this instance. Console will start in 10 seconds..........starting Console. # WARNING: Errant transaction(s) found on slave(s). # - For slave '192.168.148.30@3307': 3927da7e-7dc8-11ec-a617-000c29e2394e:1
这个 health status 信息也会存在于主库的 mysql.failover_console 表中
默认是10秒一次;
(3.2)守护进程启动
mysqlfailover --master=failover:'a123456!'@'192.168.148.39':3307 --discover-slaves-login=failover:'a123456!' --log=/var/log/mysqlfailover.log --daemon=start # 最佳启动实践 mkdir /etc/mysqlfailover cd /etc/mysqlfailover mysqlfailover --failover-mode=auto --master=failover:'a123456!'@'192.168.148.39':3307 --discover-slaves-login=failover:'a123456!' \ --log=/etc/mysqlfailover/errorlog.log --force --slaves=failover:'a123456!'@'192.168.148.27':3307,failover:'a123456!'@'192.168.148.30':3307 \ --daemon=start --log-age=7 --pidfile=/etc/mysqlfailover/mysqlfailover.pid
相关信息:
[root@DB3 config]# mysqlfailover --master=failover:'a123456!'@'192.168.148.39':3307 --discover-slaves-login=failover:'a123456!' --log=/var/log/mysqlfailover.log --daemon=start WARNING: Using a password on the command line interface can be insecure. NOTE: Log file '/var/log/mysqlfailover.log' does not exist. Will be created. Starting failover daemon... Multiple instances of failover daemon found for master 192.168.148.39:3307. If this is an error, restart the daemon with --force. Failover mode changed to 'FAIL' for this instance. Daemon will start in 10 seconds. . ........starting Daemon.
less /var/log/mysqlfailover.log 日志里会一直有显示监控状态
(3.3)手动故障转移切换(不推荐)
准备工作
mkdir -p /etc/mysqlfailover cd /etc/mysqlfailover cat >force_failover.sh <<eof #!/bin/bash main(){ return 0 } main eof
chmod +x force_failover.sh
实际命令:
mysqlfailover --failover-mode=auto --master=failover:'a123456!'@'192.168.148.39':3307 --discover-slaves-login=failover:'a123456!' \ --log=/etc/mysqlfailover/errorlog.log --force --slaves=failover:'a123456!'@'192.168.148.27':3307,failover:'a123456!'@'192.168.148.30':3307 \ --exec-fail-check="/etc/mysqlfailover/force_failover.sh"
这个 /etc/mysqlfailover/force_failover.sh 脚本里面改成 1了;
如上图,因为加了参数 --exec-fail-check 会一直失败,所以会一直故障转移;
(3.4)自动故障转移
mysqlfailover --failover-mode=auto --master=failover:'a123456!'@'192.168.148.39':3307 --discover-slaves-login=failover:'a123456!' \ --log=/etc/mysqlfailover/errorlog.log --force --slaves=failover:'a123456!'@'192.168.148.27':3307,failover:'a123456!'@'192.168.148.30':3307
然后我们关闭主库 148.39 的mysql 服务
发现,确实自动切换过去了;
再把 148.39 启动回来,并不会自动加入进来;
而且我们发现一个问题,每次都是自动把 27 作为主库了,是因为我在slaves 里面27写在前面吗?
那我可不可以把 30 设置为优先级更高呢?是把 slaves 里 30的IP相关信息写前面就好了嘛?我来试一试
<先把主库重置为 39 ,我们再实验一下>
mysqlfailover --failover-mode=auto --master=failover:'a123456!'@'192.168.148.39':3307 --discover-slaves-login=failover:'a123456!'\
--log=/etc/mysqlfailover/errorlog.log --force --slaves=failover:'a123456!'@'192.168.148.30':3307,failover:'a123456!'@'192.168.148.27':3307
然后继续关闭 39 的mysql 服务,如下图,我们发现果然把30作为新主库了!
【故障处理】
(1)No module named utilities.common.tools
直接用yum安装的mysqldiff会提示No module named utilities.common.tools
解决办法:
yum remove mysql-connector-python -y
#centos 7 rpm -Uvh http://repo.mysql.com/yum/mysql-connectors-community/el/7/x86_64/mysql-connector-python-2.1.8-1.el7.x86_64.rpm
#centos 6
rpm -Uvh http://repo.mysql.com/yum/mysql-connectors-community/el/6/x86_64/mysql-connector-python-2.1.8-1.el6.x86_64.rpmyum
install mysql-utilities
(2)Cannot modify @@session.sql_log_bin inside a transaction
我用mysql8.0实例,是失败的,用5.7可以成功;
[root@DB3 mysql5.7]# mysqlfailover --master=failover:'a123456!'@'192.168.148.39':3306 --slaves=failover:'a123456!'@'192.168.148.27':3306 WARNING: Using a password on the command line interface can be insecure. # Checking privileges. 2022-01-25 18:00:34 PM CRITICAL Query failed. 1694 (HY000): Cannot modify @@session.sql_log_bin inside a transaction ERROR: Query failed. 1694 (HY000): Cannot modify @@session.sql_log_bin inside a transaction
(3)访问拒绝权限问题 Access denied for user 'failover'@'node233.edq.com'
# mysqlrplshow --master=failover:pass@192.168.1.233:3306 --discover-slaves-login=failover:pass WARNING: Using a password on the command line interface can be insecure. # master on 192.168.1.233: ... FAILED. ERROR: Access denied for user 'failover'@'node233.edq.com' (using password: YES)
应对方案,用户需要授予基于主机名的访问权限
mysql> grant all privileges on *.* to 'failover'@'node233.edq.com' identified by 'pass';
(4)权限不足的问题
# ERROR: User root on 192.168.1.233@3306 does not have sufficient privileges to execute the failover command
(required: SUPER, GRANT OPTION, REPLICATION SLAVE, SELECT, RELOAD, DROP, CREATE, INSERT).
2016-10-08 16:18:20 PM CRITICAL Not enough privileges to execute command.
应对方案,用户需要授予with grant option权限
mysql> grant all privileges on *.* to 'root'@'node233.edq.com' identified by 'pass' with grant option;
(5)配置参数问题
[root@node233 ~]# mysqlfailover --master=root:pass@192.168.1.233:3306 --discover-slaves-login=root:pass
WARNING: Using a password on the command line interface can be insecure.
# Discovering slaves for master at 192.168.1.233:3306
# Discovering slave at 192.168.1.245:3306
# Found slave: 192.168.1.245:3306
# Discovering slave at 192.168.1.247:3306
# Found slave: 192.168.1.247:3306
# Checking privileges.
2016-10-08 16:21:40 PM CRITICAL Failover requires --master-info-repository=TABLE for all slaves.
ERROR: Failover requires --master-info-repository=TABLE for all slaves.
应对方案,需要在配置文件中增加上述参数,如本文之前描述
(6)多个mysqlfailover进程启动问题
[root@node233 ~]# mysqlfailover --master=failover:pass@'192.168.1.233':3306 --discover-slaves-login=failover:pass WARNING: Using a password on the command line interface can be insecure. # Discovering slaves for master at 192.168.1.233:3306 # Discovering slave at 192.168.1.245:3306 # Found slave: 192.168.1.245:3306 # Discovering slave at 192.168.1.247:3306 # Found slave: 192.168.1.247:3306 # Checking privileges. Multiple instances of failover console found for master 192.168.1.233:3306. If this is an error, restart the console with --force. Failover mode changed to 'FAIL' for this instance. Console will start in 10 seconds..........starting Console. MySQL Replication Failover Utility Failover Mode = fail Next Interval = Mon Oct 17 17:02:17 2016
如上,如果已经有启动的mysqlfailover,则出现上述failover模式
如果无启动的mysqlfailover,也出现上述情形,建议执行以下命令
mysql > truncate table mysql.failover_console; --该表记录了主节点及端口号
【参考文档】
着重参考:https://blog.csdn.net/leshami/article/details/52848327
详细案例参考:https://cloud.tencent.com/developer/article/1183527
相关使用参考:http://www.ttlsa.com/mysql/mysql-utilities-mysqlfailover/