备库重搭
PolarDB-X的存储节点是由Leader+Follower+Logger组成的三节点,其中Follower和Logger统称为备库。如果备库出现复制中断或机器故障等异常,则需用通过重搭备库进行修复。
- 文中出现的命令,需自行将{}中的内容进行替换
- 如果是重搭Logger节点,只需执行以下步骤:
- 重新创建备节点
- 恢复数据
- 初始化集群元信息
- 拉起mysql进程
- 更新Paxos集群信息
- 更新PXD元数据
备库复制线程检查方式
执行pxd check {name of pxd} -t
获取DN名及其的节点角色信息
部署DN时会将host_group中前两个IP作为承载数据的节点,以图中的pxd为例,它有一个DN,DN的名字是pxd_test-dn-0(记为dnName),DN三个节点的角色分布如下:
- 172.16.201.18(记为leaderNode):Leader,容器名为pxd_test-dn-0-Cand-1-17796(记为leaderContainer)
- 172.16.201.11(记为followerNode):Follower
- 172.16.201.19:Logger
登录备库所在的机器,通过DN的名字前缀找到对应的容器,这里需要的是pxd_test-dn-0-Cand-0-15434(记为followerContainer)这个容器,:
执行docker exec -it {followerContainer} bash
登录容器,再执行myc
命令登录DN的数据库,并执行show slave status\G
这条SQL:
重点关注这几个字段:
- Slave_SQL_Running:正常情况应为Yes
- Last_Errono:正常情况应为0
- Last_Error:正常情况应为空
若某个字段的值与正常值情况不一致,则可能是备库复制线程出现了异常,此时就需要考虑进行备库重搭。
重新创建备节点
创建单节点pxd
准备一个单节点创建存储节点的yaml文件,如下所示,注意host_group只需填一个机器:
version: v1
type: polardbx
cluster:
name: pxd_rebuild
dn:
image: polardbx/polardbx-engine-2.0:latest
replica: 1
nodes:
- host_group: [172.16.201.11]
resources:
mem_limit: 2G
创建完成,DN名为pxd_rebuild-dn-0(记为rebuildDNName),容器名为pxd_rebuild-dn-0-Cand-16367(记为rebuildContainer),host是172.16.201.11(记为rebuildNode):
终止mysql进程
在进行数据恢复之前,需要将新节点容器中的mysql进程停止并清空数据文件。登录新节点,在新节点的容器中创建一个标志文件并重启docker容器,以停止mysql进程:
docker exec {rebuildContainer} bash -c "touch /data/mysql/disable_engine"
docker restart {rebuildContainer}
清理数据目录
之后对mysql的数据及日志目录进行清理:
docker exec {rebuildContainer} bash -c "rm -rf /data/mysql/data/*"
docker exec {rebuildContainer} bash -c "rm -rf /data/mysql/log/*"
备份数据
执行主库备份
重搭备库需用从主库进行备份,可能会对主库性能造成一定影响。 备份命令的执行有一些要求:
- 需要用户对当前目录有写入权限
- 需要保证当前磁盘有充足空间
登录leaderNode,执行下列命令,进行备份:
mkdir -p /home/polardbx/rebuild && docker exec {leaderContainer} bash -c "/tools/xstore/current/xtrabackup/8.0-2/xcluster_xtrabackup80/bin/xtrabackup --stream=xbstream --socket=/data/mysql/run/mysql.sock --slave-info --backup --lock-ddl --xtrabackup-plugin-dir=/tools/xstore/current/xtrabackup/8.0-2/xcluster_xtrabackup80/lib/plugin" >/home/polardbx/rebuild/backup.xbstream 2>/home/polardbx/rebuild/backup.log
执行完毕后,会在/home/polardbx/rebuild目录下生成几个文件: 其中backup.xbstream便是生成的备份集,backup.log则是备份的日志,可以查看该日志,若最后输出completed OK则代表备份正常完成。
拷贝数据
若leaderNode和rebuildNode之间可以通过ssh访问,也可直接拷贝,跳过该步骤。这里由于leaderNode和rebuildNode间ssh访问受限,所以将部署机作为中继。
登录到pxd的部署机上,将备份数据从leaderNode拷贝至rebuildNode:
mkdir -p /home/polardbx/rebuild/ && scp {leaderNode}:/home/polardbx/rebuild/backup.xbstream /home/polardbx/rebuild/
ssh {rebuildNode} 'mkdir -p /home/polardbx/rebuild' && scp /home/polardbx/rebuild/backup.xbstream {rebuildNode}:/home/polardbx/rebuild/
恢复数据
解压数据
登录rebuildNode,将备份集拷贝至rebuildContainer并解压到数据目录:
docker cp /home/polardbx/rebuild/backup.xbstream {rebuildContainer}:/data/mysql/
docker exec {rebuildContainer} bash -c "/tools/xstore/current/xtrabackup/8.0-2/xcluster_xtrabackup80/bin/xbstream -x < /data/mysql/backup.xbstream -C /data/mysql/data"
应用数据
之后需要使用备份工具对备份数据进行应用,并修改数据目录的文件权限:
docker exec {rebuildContainer} bash -c "/tools/xstore/current/xtrabackup/8.0-2/xcluster_xtrabackup80/bin/xtrabackup --defaults-file=/data/mysql/conf/my.cnf --prepare --target-dir=/data/mysql/data --xtrabackup-plugin-dir=/tools/xstore/current/xtrabackup/8.0-2/xcluster_xtrabackup80/lib/plugin 2> /data/mysql/log/applybackup.log"
docker exec {rebuildContainer} bash -c "chown -R mysql:mysql /data/mysql/data/*"
初始化集群元信息
执行下列命令获取起始index,输出形如"mysql_bin.xxxxxx xxxx",后面的数字就是起始index,比如下图中的3,将其记为startIndex:
docker exec {rebuildContainer} bash -c "cat /data/mysql/data/xtrabackup_binlog_info"
docker exec {rebuildContainer} bash -c "cat /data/shared/shared-channel.json"
docker exec {rebuildContainer} bash -c "/opt/galaxy_engine/bin/mysqld --defaults-file=/data/mysql/conf/my.cnf --cluster-info={rebuildNode}:{rebuildPort} --cluster-force-change-meta=ON --loose-cluster-force-recover-index={startIndex} --cluster-start-index={startIndex} --cluster-learner-node=ON"
# 初始化命令示例:
docker exec pxd_rebuild-dn-0-Cand-16367 bash -c "/opt/galaxy_engine/bin/mysqld --defaults-file=/data/mysql/conf/my.cnf --cluster-info=172.16.201.11:24367 --cluster-force-change-meta=ON --loose-cluster-force-recover-index=3 --cluster-start-index=3 --cluster-learner-node=ON"
拉起mysql进程
接着需要重新拉起mysql进程,执行下列命令加入标志文件,跳过初始化步骤并重启容器:
docker exec {rebuildContainer} bash -c "rm /data/mysql/disable_engine"
docker exec {rebuildContainer} bash -c "echo 'ok' > /data/mysql/initialized"
docker restart {rebuildContainer}
更新Paxos集群信息
之后需要登录leaderNode,进入leaderContainer,执行myc
命令登录数据库,先执行下列SQL获取当前集群信息:
select * from information_schema.alisql_cluster_global;
返回结果如下,根据followerNode,找到原Follower的IP_PORT信息,记为followerIpPort 接着执行下列命令,更新集群信息:
# 将原follower节点降级为learner并剔除
call dbms_consensus.downgrade_follower('{followerIpPort}');
call dbms_consensus.drop_learner('{followerIpPort}');
# 将新节点以leaner身份加入,并升级为follower
call dbms_consensus.add_learner('{rebuildNode:rebuildPort}');
call dbms_consensus.upgrade_learner('{rebuildNode:rebuildPort}');
执行后再检查一次集群信息,可以看到Follower切换成功:
更新PXD元数据
最后需要更新PXD元数据,可以在部署机上执行如下脚本:
import sqlite3
import os
original_dn_name = "{dnName}"
original_container_name = "{followerContainer}"
rebuild_dn_name = "{rebuildDNName}"
rebuild_container_name = "{rebuildContainer}"
conn = sqlite3.connect(os.path.expanduser("~") + "/.pxd/polardbx.db")
conn.execute("update container set resource_name = ? where resource_name = ? and container_name = ?",
(rebuild_dn_name, original_dn_name, original_container_name,))
conn.execute("update container set resource_name = ? where resource_name = ? and container_name = ?",
(original_dn_name, rebuild_dn_name, rebuild_container_name,))
conn.commit()
conn.close()
注意将其中{}内的变量替换,替换后的脚本如下: 最后删除重建出来的临时节点:
pxd delete pxd_rebuild