手动恢复_MariaDB_集群
KEYWORDS: tencent, tstack, solution,
HISTORY:
- Created at 15:26:22 on 2020-02-15.
手动恢复 MariaDB 集群 (TStack K 与 P 版均适用) (2020-02-15)
[ERROR] WSREP: bind: Address already in use
[ERROR] WSREP: failed to open glom backend connection: 98 : error while trying to listen 'tcp://0.0.0.0:4567?socket.non_blocking=1', Asia error 'bind: Address already in use': 98 (Address already in use) at gcomm/src/asio_tcp.cpp:listen():843
[ERROR] WSREP: gcs/src/gcs_core.cpp:gcs_core_open():208: Failed to open backend connection: -98 (Address already in use)
[ERROR] WSREP: gas/src/gcs.cpp:gcs_open():1380: Failed to open channel 'galera_cluster' at 'gcomm://192.168.100.103,192.168.100,101,192.168.100.102': -98 (Address already in use)
[ERROR] WSREP: gcs connect failed: Address already in use
[ERROR] WSREP: wsrep::connect(gcomm://192.168.100.103,192.168.100.101,192.168.100.102) failed: 7
[ERROR] WSREP: Aborting
场景描述 (2020-02-15)
TStack K 版, 监控云, MariaDB 集群中的一个节点启动失败. 在执行启动操作时, /var/log/mariadb/mariadb.log
报错如下. 需要手动恢复 MariaDB 集群.
2020-02-15 12:44:17 140297052874496 [Note] WSREP: (d0e7f692, 'tcp://0.0.0.0:4567') turning message relay requesting off
WSREP_SST: [ERROR] xtrabackup_checkpoints missing, failed innobackupex/SST on donor (20200215 12:44:26.448)
WSREP_SST: [ERROR] Cleanup after exit with status:2 (20200215 12:44:26.451)
2020-02-15 12:44:26 140297042384640 [ERROR] WSREP: Process completed with error: wsrep_sst_xtrabackup-v2 --role 'joiner' --address '172.18.58.243' --datadir '/data/mariadb/data/' --parent '5189' --binlog '/data/mariadb/binlog/mysql-bin' : 2 (No such file or directory)
2020-02-15 12:44:26 140297042384640 [ERROR] WSREP: Failed to read uuid:seqno and wsrep_gtid_domain_id from joiner script.
2020-02-15 12:44:26 140302735898592 [ERROR] WSREP: SST failed: 2 (No such file or directory)
操作示例
本文档理论上 K 版与 P 版的监控云都适用, 但有些环境依然不能同步. 详情参见下一小节.
下述操作以 3 个节点为例进行演示. 在实际生产环境中, 特别是早期的版本, 监控云 MariaDB 集群实际可能只有 2 个节点.
下述指令在执行前请 务必注意 切换到执行节点.
-
在 3 台节点停掉
supervisor
/systemd
管理的mysql
并且确定无残余进程. 在监控云 3 个节点分别执行.# 根据实际生产环境, 选择处理方式 supervisorctl stop mariadb # 没有托管在 supervisor 中的 mariadb systemctl stop mariadb # K 版监控云, 本例所采用的方式. service mariadb stop # 确认无残余进程 ps aux | grep -e mysql -e mariadb
-
找到数据量最多的节点. 在监控云 3 个节点分别执行.
/usr/local/mariadb/bin/mysqld_safe --user=mysql --wsrep-recover=1 && \ tail -n 2 /var/log/mariadb/mariadb.log # 输出类似于 # 200215 14:13:47 mysqld_safe Logging to '/var/log/mariadb/mariadb.log'. # 2020-02-15 14:13:57 140598020413408 [Note] WSREP: Recovered position: f349eed7-22bd-11e8-9fd7-76c4da6ecde0:1775589804 # 200215 14:14:00 mysqld_safe mysqld from pid file /var/run/mariadb/mariadb.pid ended
数字最大的即为数据量最多的节点. 例如, 这里的返回值为
1775589804
的节点.若存在返回值为
-1
的节点, 还需要根据数据量和文件夹更新时间等信息进一步判断. -
修改配置. 在数字最大的节点上执行, 此节点为主节点.
sed -i '/safe_to_bootstrap/s/0/1/' /data/mariadb/data/grastate.dat # 确认修改是否成功 cat /data/mariadb/data/grastate.dat
-
在主节点上启动 MariaDB. 在主节点执行, 即数据量最多的节点.
# 确认该文件夹是否存在, "用户与用户组" 是否为 "mysql:mysql" ls -ld /var/run/mariadb/ /var/run/mariadb/* # 若不是, 执行以下指令修正 #mkdir -p /var/run/mariadb #chown -R mysql:mysql /var/run/mariadb # 确认该文件夹内是否有名为 "mysql" 的文件, 如果有, 则删除 ls -l /var/lock/subsys/ #rm -f /var/lock/subsys/mysql # 在主节点上启动 MariaDB. /usr/local/mariadb/bin/mysqld_safe --user=mysql \ --wsrep-cluster-address='gcomm://' > /dev/null 2>&1 & # 直到连通, 即返回 "active" /usr/local/mariadb/bin/mysqladmin ping
补充说明 (2020-02-23): 在某些情况下, 会遇到数据库启动失败的情况, 除通过日志确认启动失败的原因外, 还可以考虑的处理措施有以下几点:
注意, 下述处理措施存在风险, 请务必谨慎操作.
- 如果日志中显示某个或某些
.ibd
文件影响到数据库服务启动, 可考虑将前缀相同的 2 个文件 (后缀分别为.ibd
和.frm
) 备份后删除, 然后尝试重启数据库, 由数据库同步和恢复. - 如果该节点不是 Venus 节点的话, 如果数据库和 RabbitMQ 启不来, 先把
supervisorctl
所有服务停止, 全力把 MariaDB 和 RabbitMQ 集群启直来. - 如果该节点是 Venus 节点的话, 需要先向客户确认是否有业务的需要, 才可停止
supervisorctl
托管的服务. - (建议向研发确认) 如果节点仍然启动失败, 可考虑在节点上将
/data/mariadb/data/galera.cache
文件移动 (不要直接删除) 到其他目录, 尝试重启.
- 如果日志中显示某个或某些
-
启动另外 2 个节点的数据库. 在主节点之外的另外 2 个节点上执行.
# 确认该文件夹是否存在, 以及属主是否为 "mysql:mysql" ls -ld /var/run/mariadb/ /var/run/mariadb/* # 若不是, 执行以下指令修正 #mkdir -p /var/run/mariadb #chown -R mysql:mysql /var/run/mariadb # 在第 2 和第 3 个节点上分别启动数据库. /usr/local/mariadb/bin/mysqld_safe --datadir=/data/mariadb/data \ --pid-file=/var/run/mariadb/mariadb.pid > /dev/null 2>&1 & # 直到连通, 即返回 "mysqld is alive" /usr/local/mariadb/bin/mysqladmin ping
需要说明的是, 在第 2 和 3 个节点上, 分别启动数据库之后, 可能需要很长的时候,
mysqladmin ping
才能返回mysqld is alive
的结果.在这 2 个节点启动数据库后, 数据同步需要一定的时间, 具体视数据量的大小而定. 具体情况一方面可以查看 3 个节点的日志
/var/log/mariadb/mariadb.log
, 另一方面也可以通过df -h
等指令查看 MariaDB 数据所在分区进行观察.以处理一次故障为例, 数据同步过程持续了约 40 分钟.
如果遇到数据库启动失败的情况, 请参见上一节的 "补充说明".
-
检查集群状态. 在监控云 3 个节点分别执行.
# 确认数量是否为 "3" /usr/local/mariadb/bin/mysql -e 'show status like "wsrep_cluster_size";' \ 2>/dev/null | sed -n '2p' | awk '{print $2}'
-
上述步骤如果返回结果均为
3
. 在主节点执行下述操作.# 杀掉主节点的 "mysql" 进程 ps aux | grep mysql | grep -v grep | awk '{print $2}' | xargs kill # 先行几秒, 确认无残留进程 ps aux | grep -e mysql -e mariadb # 在主节点上以正常方式启动 MariaDB. /usr/local/mariadb/bin/mysqld_safe --datadir=/data/mariadb/data \ --pid-file=/var/run/mariadb/mariadb.pid > /dev/null 2>&1 & # 直到连通, 即返回 "active" /usr/local/mariadb/bin/mysqladmin ping
-
再次检查集群状态. 在监控云 3 个节点分别执行.
# 确认数量是否为 "3" /usr/local/mariadb/bin/mysql -e 'show status like "wsrep_cluster_size";' \ 2>/dev/null | sed -n '2p' | awk '{print $2}'
扩展性内容
本文档理论上 K 版与 P 版的监控云都适用, 但有些环境依然不能同步.
这是因为部分 P 版, 是有设置同步时长的, 如果数据很多, 超时就会被中止.
对于这部分环境, MariaDB 是托管在 supervisor
中的, MariaDB 的启动脚本为 /usr/local/mariadb/scripts/start_cluster.sh
.
如果遇到数据量过大的情况, 可修改此脚本, 搜索 300
(单位应该为 "秒"), 并修改为一个合适的值, 一共 2 处.
除此之外, 也可 "自己通过命令先手动同步, 然后再通过 supervisor
启动".