TxSQL通用备份脚本使用说明

  其他常见问题
内容纲要

概要描述


TDH 容器化集群中的 TxSQL(PhxSQL 三节点架构,承载 Inceptor/Quark 元数据库 metastore_* 等)没有现成的定期备份工具,而且宿主机上通常没有 mysql、mysqldump 客户端,无法直接导出。

本文介绍通用备份脚本 txsql_backup.sh 的获取和使用方法。脚本可以把 TxSQL 逻辑备份到服务器本地磁盘,放到其他集群上不用修改配置即可使用:

  • 自动发现集群中所有 txsql-server-* Pod,跨命名空间查找,支持一个集群有多个 TxSQL 服务。
  • 自动从 Pod 中读取连接地址、端口和密码,不需要手动配置,密码也不会出现在宿主机命令行中。
  • 使用 Pod 内自带的 mysqldump 导出,在宿主机压缩落盘,并校验完整性。
  • 支持按天数保留、防止重复运行,可以直接配置成定时任务。

本文内容已在 TOS 2.1.0、TxSQL 5.6.48(Percona)三节点集群上实测,包括备份,以及在隔离实例中恢复后逐表比对行数。

详细说明


脚本获取

脚本下载

工作原理

  1. 通过 kubectl 找到所有 txsql-server-* Pod,每个服务选一个 Running 的 Pod:
    • 默认模式:优先选本机上的 Pod,经读写 Proxy(默认端口 3316)连接,实际由 Master 提供数据。
    • --via-local 模式:优先选 Slave(read_only=1)Pod,通过 socket 直连 Pod 内的 mysqld,避免给 Master 增加压力。
  2. 在 Pod 内读取 $CONF_DIR/txsql-env.sh、phxsqlproxy.conf 获取 Proxy 地址和端口,密码取 Pod 环境变量 TXSQL_DB_PASSWORD。
  3. 在 Pod 内用自带的 mysqldump 逐库导出(--single-transaction,不锁表),输出经 kubectl exec 流回宿主机,由宿主机 gzip 压缩写盘。
  4. 校验每个文件的 gzip 完整性,以及 mysqldump 的结束标记 -- Dump completed,然后生成 SHA256 校验值和元数据文件。
  5. 全部成功后,把临时目录(.inprogress)改为正式目录,再清理过期备份。

前提条件

  • 在 TDH 集群任意节点上以 root 执行,该节点上的 kubectl 能访问 apiserver。脚本会依次尝试 kubectl -s http://127.0.0.1:8080、--kubeconfig=/srv/kubernetes/kubeconfig、--kubeconfig=/root/.kube/config、kubectl;都不通时,用 --kubectl 参数指定。
  • 宿主机有 bash、gzip、flock、sha256sum(CentOS 7 默认都有)。
  • 备份盘的可用空间大于待备份库的数据量。脚本执行前会检查,空间不足时直接报错退出。

部署

把下载的脚本上传到节点,例如 /opt/scripts/,然后加上执行权限:

chmod +x /opt/scripts/txsql_backup.sh

如果脚本是在 Windows 上编辑后再上传的,先执行 sed -i 's/\r$//' /opt/scripts/txsql_backup.sh 去掉回车符。

查看实例(不备份)

先用 --list 确认脚本能识别 TxSQL 服务:

/opt/scripts/txsql_backup.sh --list

输出示例:

== 服务: txsql1   namespace: default   pod: txsql-server-txsql1-<哈希>-<后缀>
   连接: -h<节点IP> -P3316
   版本: 5.6.48-88.0-log  实际节点: <主机名>  read_only=0
   库: metastore_inceptor1  表数=133  4MB
   ...

执行备份

# 备份所有 TxSQL 服务的所有业务库,保留 7 天
/opt/scripts/txsql_backup.sh -d /mnt/disk2/txsql_backup -k 7

# 只备份 txsql1 服务的指定库
/opt/scripts/txsql_backup.sh -d /mnt/disk2/txsql_backup -s txsql1 -D "metastore_inceptor1"

# 从 Slave 导出,避免给 Master 增加压力
/opt/scripts/txsql_backup.sh -d /mnt/disk2/txsql_backup --via-local

成功时的输出示例:

[txsql1] 连接: -h<节点IP> -P3316 | 实际落到: <主机名> read_only=0 version=5.6.48-88.0-log
[txsql1] 待备份库: metastore_inceptor1 metastore_inceptor2 test
[txsql1] 数据量约 4 MB,备份盘可用 157507 MB
[txsql1] OK   metastore_inceptor1  56K  2s
[txsql1] OK   create_databases.sql
[txsql1] OK   grants
[txsql1] 备份完成: /mnt/disk2/txsql_backup/txsql1/20261111_115525 (84K)
全部备份成功

参数说明

参数 说明 默认值
-d, --backup-dir 备份根目录 依次尝试 /data、/mnt/disk2、/mnt/disk1,用第一个存在的目录下的 txsql_backup
-k, --keep-days 保留天数,0 表示不清理 7
-s, --service 只备份指定服务(如 txsql1、guardian),可重复指定 全部服务
-D, --databases 只备份指定库,多个库用空格分隔并加引号 全部业务库
--include-mysql 同时导出 mysql 系统库 不导出
--no-grants 不导出账号授权 导出
--via-local 优先选 Slave Pod,通过 socket 直连 mysqld 走 Proxy
--kubectl "命令" 自定义 kubectl 命令 自动探测
--namespace 只在指定命名空间查找 全部命名空间
-l, --list 只列出实例和库,不备份 –
-h, --help 查看完整帮助 –

非容器部署,或宿主机已有 mysqldump 时,可以用直连模式:

TXSQL_PASSWORD='<密码>' /opt/scripts/txsql_backup.sh --direct -H <代理地址> -P 3316 \
    --mysqldump <客户端mysqldump路径> -d /mnt/disk2/txsql_backup

直连模式也可以用 --password-file <密码文件> 传入密码(文件只写一行密码,权限设为 600)。

备份产物

<备份根目录>/
├── .txsql_backup.lock              防止重复运行的锁文件
└── <服务名>/
    ├── backup.log                  历次备份日志
    ├── 20261111_023000/            一次成功的备份
    │   ├── <库名>.sql.gz           每个库一个文件,不含 CREATE DATABASE/USE
    │   ├── create_databases.sql    各库建库语句(含字符集)
    │   ├── grants.sql.gz           账号和授权
    │   ├── meta.txt                版本、提供数据的节点、GTID、库表数量等
    │   └── SHA256SUMS
    └── 20261110_023000.FAILED/     失败的备份,保留现场便于排查

<库名>.sql.gz 导出时带存储过程、触发器和事件,用 --set-gtid-purged=OFF,所以可以直接导入开启 GTID 的实例。

判断备份是否成功

  • 退出码:

    退出码 含义
    0 全部成功
    1 参数或环境错误,例如找不到 kubectl、指定的服务不存在
    2 部分或全部备份失败,例如连接失败、校验失败、指定的库不存在
    3 已有备份进程在运行
  • 目录名:成功的备份是 YYYYmmdd_HHMMSS,失败的带 .FAILED 后缀。

  • meta.txt 最后一行是 status : SUCCESS 或 status : FAILED。

  • 校验文件完整性:

    cd <备份目录> && sha256sum -c SHA256SUMS

配置定时任务

crontab -e 中加一行,每天 02:30 执行:

30 2 * * * /opt/scripts/txsql_backup.sh -d /mnt/disk2/txsql_backup -k 7 >/dev/null 2>&1

日志写在 <备份根目录>/<服务名>/backup.log。建议只在一个节点上配置,避免多个节点重复备份。

清理规则

  • 只清理名称符合 YYYYmmdd_HHMMSS(含 .FAILED、.inprogress 后缀)格式、且超过保留天数的目录,不会动其他文件。
  • 无论多旧,始终保留最新一份成功的备份。
  • 只在本次备份成功后才清理。

恢复

恢复元数据库前,先停掉 Inceptor/Quark 等使用方,并先在测试库上验证。

按以下顺序导入:

  1. create_databases.sql:建库。

  2. grants.sql.gz:账号和授权。如果 DEFINER 用户(如 inceptoruser)在目标实例上已经存在,可以跳过。不导入且用户不存在时,导入视图会报错:

    ERROR 1449 (HY000): The user specified as a definer ('inceptoruser'@'%') does not exist
  3. 各库的 <库名>.sql.gz。

宿主机没有 mysql 客户端时,经 Pod 导入:

K="kubectl -s http://127.0.0.1:8080 -n <命名空间>"
P=<所选Pod名>

# 1. 建库
cat create_databases.sql | $K exec -i $P -- \
  sh -c 'MYSQL_PWD="$TXSQL_DB_PASSWORD" mysql -uroot -h<代理地址> -P3316'

# 2. 授权:过滤掉 root、replica 内部账号,避免覆盖目标实例的密码
gunzip -c grants.sql.gz | grep -vE "TO '(root|replica)'@" | $K exec -i $P -- \
  sh -c 'MYSQL_PWD="$TXSQL_DB_PASSWORD" mysql -uroot -h<代理地址> -P3316'

# 3. 导入单个库
gunzip -c metastore_inceptor1.sql.gz | $K exec -i $P -- \
  sh -c 'MYSQL_PWD="$TXSQL_DB_PASSWORD" mysql -uroot -h<代理地址> -P3316 metastore_inceptor1'

<库名>.sql.gz 里没有库名,所以也可以导入到另一个库名下,例如先恢复到临时库,核对无误后再切换。

其他信息


注意事项

  • 备份目录:不指定 -d 时,TDH 节点上通常没有 /data,会落到 /mnt/disk2 或 /mnt/disk1。这些一般是 HDFS、KunDB 的业务数据盘。建议用 -d 明确指定备份目录,并留意磁盘水位。

  • 恢复前确认 TxSQL 写入正常:在测试环境中出现过 TxSQL 一写入就导致 Master mysqld 重启的情况,mysqld 日志关键字为 repl_phx_report_binlog_to_binlogsvr ... send binlog buffer failed ... ret 503 和 fatal error。备份只做读取,不受影响;恢复需要写入,执行前请先确认写入正常。

这篇文章对您有帮助吗?

平均评分 0 / 5. 次数: 0

尚无评价,您可以第一个评哦!

非常抱歉,这篇文章对您没有帮助.

烦请您告诉我们您的建议与意见,以便我们改进,谢谢您。