Files
lisglosips/docs/SERVER_B_DATA_SERVICES_RUNBOOK.md

6.7 KiB
Raw Permalink Blame History

Server B MySQL 与 Redis Runbook

对应任务:S04
完成日期:2026-06-20
环境:本地开发 Server B

1. 版本与状态

服务 固定版本 监听
MySQL 8.0.46-0ubuntu0.24.04.2 127.0.0.1:3306、127.0.0.1:33060
Redis 7.0.15-1ubuntu0.24.04.4 127.0.0.1:6379、100.90.90.91:6379

固定包:

apt-mark showhold | grep -E 'mysql|redis'

更新前必须先阅读安全公告、备份并执行恢复演练,然后显式 apt-mark unhold。不要长期忽略安全更新。

版本清单位于:

  • B/etc/lisglosips/versions.env
  • 仓库:infra/server-b/s04/versions.env

2. 数据目录

开发服务器没有独立数据盘。实际数据写入:

  • /data/mysql
  • /data/redis

为兼容 Ubuntu 包、AppArmor 和 systemd,使用 bind mount 保留标准服务路径:

/data/mysql /var/lib/mysql none bind 0 0
/data/redis /var/lib/redis none bind 0 0

服务分别依赖 var-lib-mysql.mountvar-lib-redis.mount。迁移阿里云时必须改用独立数据盘,不能直接复制本地根盘布局。

3. MySQL 基线

配置:/etc/mysql/mysql.conf.d/99-lisglosips.cnf

  • 仅绑定回环地址;
  • 业务库:lisglosipsutf8mb4
  • binlog 已启用,格式 ROW,保留 7 天;
  • sync_binlog=1
  • innodb_flush_log_at_trx_commit=1
  • 数据库默认时区 UTC
  • 禁止 local_infile 和 DNS 主机名解析;
  • 慢查询阈值 1 秒;
  • InnoDB buffer pool 1 GiB,最大连接数 200。

账号:

账号 来源 权限
lisglosips_app 127.0.0.1 SELECT/INSERT/UPDATE/DELETE/EXECUTE
lisglosips_migrate 127.0.0.1 lisglosips.* 全权限,用于迁移

应用账号不能 DDL;S04 已用实际 ALTER 拒绝测试验证。

4. Redis 基线

配置:

  • /etc/redis/redis-lisglosips.conf
  • /etc/redis/users.acl

关键策略:

  • protected mode 开启;
  • AOF everysec 与 RDB 快照同时启用;
  • 最大内存 1536 MiB
  • maxmemory-policy=noeviction,业务热数据和 Stream 不静默淘汰;
  • 默认用户关闭;
  • lisglosips 允许业务命令但移除 dangerous 类命令;
  • lisglo-backup 仅允许 PING、INFO、BGSAVE、LASTSAVE。

Redis 绑定 Tailscale 地址。lisglosips-tailscale-ready.service 会先等待 100.90.90.91/32 出现,避免 Redis 开机首次启动竞态。

5. 凭据

本地 DPAPI 加密文件:

.codex-private/SERVICE_CREDENTIALS.clixml

包含:

  • MYSQL_APP
  • MYSQL_MIGRATE
  • REDIS_APP
  • REDIS_BACKUP

B 机:

文件 权限
/etc/lisglosips/secrets/mysql-app.env root:lisglosips 0640
/etc/lisglosips/secrets/mysql-migrate.env root:root 0600
/etc/lisglosips/secrets/redis.env root:lisglosips 0640
/etc/lisglosips/secrets/redis-backup.env root:root 0600
/etc/redis/users.acl root:redis 0640

禁止在聊天、日志、状态文件、仓库或命令参数中输出密码。

6. 网络安全

  • MySQL 不允许远程连接。
  • Redis 仅允许 A 的 Tailscale IP 100.90.90.90 通过 B 的 nftables 访问。
  • T 对 3306/6379 的连接已验证为超时拒绝。
  • A 第一次访问 B 时可能需要先建立 Tailscale direct 路径:
tailscale ping --c 1 100.90.90.91

稳态 direct 后 Redis 认证连接正常。

7. 自动备份

脚本:

  • /usr/local/sbin/lisglosips-mysql-backup
  • /usr/local/sbin/lisglosips-redis-backup

systemd

  • lisglosips-backup.service
  • lisglosips-backup.timer

每天 03:15 执行,随机延迟最多 15 分钟,保留 14 天。

备份目录:

/data/backups/mysql/YYYYMMDDTHHMMSSZ/
  all-databases.sql.gz
  lisglosips.sql.gz
  metadata.tsv
  SHA256SUMS

/data/backups/redis/YYYYMMDDTHHMMSSZ/
  dump.rdb
  redis-check-rdb.txt
  metadata.txt
  SHA256SUMS

首次有效备份:20260620T120955Z

检查:

sudo systemctl start lisglosips-backup.service
sudo systemctl show -p Result lisglosips-backup.service
sudo systemctl list-timers lisglosips-backup.timer
cd /data/backups/mysql/LATEST_DIRECTORY && sudo sha256sum -c SHA256SUMS
cd /data/backups/redis/LATEST_DIRECTORY && sudo sha256sum -c SHA256SUMS

MySQL 全库备份包含账号密码哈希,只允许 root 读取。Redis ACL 明文密码不进入自动备份,灾难恢复时从 DPAPI 凭据重新生成。

8. 恢复

MySQL 业务库

先创建空的临时数据库进行验证:

sudo mysql -e 'CREATE DATABASE lisglosips_restore_test CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;'
gzip -dc /data/backups/mysql/TIMESTAMP/lisglosips.sql.gz | sudo mysql lisglosips_restore_test
sudo mysql -e 'SHOW TABLES FROM lisglosips_restore_test;'

确认数据后再安排正式恢复窗口。禁止直接将 all-databases.sql.gz 覆盖到运行中的生产实例。

Redis RDB

将备份 dump.rdb 复制到独立临时目录,用 port 0 和独立 Unix socket 启动临时 Redis,验证关键 key 后关闭。不要替换运行中实例的 RDB/AOF。

S04 已完成:

  • MySQL 备份后删除源表,恢复到临时库并验证 token;
  • Redis 备份后删除源 key,恢复到独立实例并验证 token;
  • 两类探针和临时实例均已清理。

9. 健康检查

systemctl is-active mysql redis-server lisglosips-backup.timer
mysqladmin --protocol=socket ping
sudo mysql -e 'SELECT @@version, @@log_bin, @@binlog_format, @@time_zone;'
sudo findmnt /var/lib/mysql
sudo findmnt /var/lib/redis
sudo systemctl show redis-server -p Result -p NRestarts
sudo journalctl -b -u mysql -u redis-server -p err

验收状态:

  • 重启后 MySQL/Redis active
  • Redis 首次启动 NRestarts=0
  • 没有 failed systemd unit
  • AOF 写入和 RDB BGSAVE 均正常;
  • 重启持久化探针通过并已清理。

10. 回滚

S04 前备份:

/var/backups/lisglosips-s04/20260620195847

包含配置基线、迁移前 MySQL/Redis 数据目录压缩包、变更后配置、失败演练样本和 SHA-256 清单。

回滚数据目录必须在维护窗口执行:

  1. 停止 lisglosips-backup.timer、MySQL 和 Redis。
  2. 卸载 /var/lib/mysql/var/lib/redis
  3. 恢复 S04 前 fstab。
  4. 将当前数据目录另行归档,不直接覆盖。
  5. 解压 mysql.pre-s04.tar.gzredis.pre-s04.tar.gz/var/lib
  6. 恢复配置后执行语法检查,再逐个启动服务。

不要在没有完整备份与控制台访问的情况下卸载、覆盖或降级数据库包。

11. 已知事项

  • 早期一次备份使用绝对校验路径,已移至 S04 备份目录下的 failed-backups 留档,不参与恢复。
  • 本地根盘适合开发,不满足生产数据库与录音故障隔离要求。
  • 软件包处于 hold;上线前需建立定期安全更新和预生产验证流程。