From 4732c02c09c509691e2f5c9d8c4279fb842165a0 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sun, 4 Oct 2026 18:46:26 +0800 Subject: [PATCH] =?UTF-8?q?feat(ops):=20=E6=9C=AC=E5=9C=B0=E7=94=9F?= =?UTF-8?q?=E4=BA=A7=E9=95=9C=E5=83=8F=E5=90=8C=E6=AD=A5=E8=84=9A=E6=9C=AC?= =?UTF-8?q?=20+=20=E4=B8=8A=E7=BA=BF=E6=B8=85=E5=8D=95=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 生产已部署完成(main@2f610a5,迁移 20261004_0046)。为了让后续测试能在本地跑, 把生产库同步成本地镜像,并把同步流程固化成脚本。 ## 本次建立的本地镜像 `douyu_login_prod` —— 与生产逐项一致:15,182 账号 / 14,323 CK / 15,169 登录记录 / **253,424 条 douyu_tasks(含 837MB JSON,可实测保留策略)** / 迁移 0046 / 907MB。 **已验证本地 `.env` 的 `APP_ENCRYPTION_KEY` 与生产一致** —— 抽样解密正常(CK 前缀 `dy_accounts_main`,长度 1659–1702), 所以镜像里的 CK 可用,CK 相关测试能跑。这一点不成立的话镜像基本没用。 ## 脚本里规避的两个坑 1. **不要把 `mysqldump` 串进 SSH 管道**:实测 ~49KB/s(MySQL 读 + gzip + 网络互相拖), 改成「服务器本地 dump 成文件 + rsync」后 ~8MB/s,**快两个数量级**。 下载那步用 **rsync 而非 scp**:可断点续传,网断了不用重来。 2. 恢复前先 `DROP DATABASE`,避免旧数据残留造成「看起来同步了其实没有」。 ## 文档 `docs/上线清单-S1-S7部署.md` 追加「把生产库同步到本地」一节:用法、 镜像内容、两个前提(密钥必须一致;**不要在镜像库上跑测试套件** —— 测试用独立的 `douyu_login_test`),以及上面两个坑。 --- docs/上线清单-S1-S7部署.md | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/docs/上线清单-S1-S7部署.md b/docs/上线清单-S1-S7部署.md index fbf59ba..0dc75ac 100644 --- a/docs/上线清单-S1-S7部署.md +++ b/docs/上线清单-S1-S7部署.md @@ -199,3 +199,53 @@ docker compose up -d douyu-login # 用旧 tag | **回滚** | 6 个迁移降级,**2 秒**,`bind_status` 原值完好、两列回到 `varchar(32)` | | **回滚前置脚本** | 模拟「部署期间新拿到的 CK」→ 回填 → 降级 → **该 CK 完整幸存** ✓ | | **生产 CK 解密** | 抽样 5 条,**5/5 正常**(长度 1613–1660)✓ | + +--- + +## 附:把生产库同步到本地(测试用) + +生产已于 2026-10-04 部署完成(`main@2f610a5`,迁移 `20261004_0046`)。 +本地已建立一份**与生产逐项一致**的镜像库,方便后续测试在本地跑。 + +```bash +# 重新同步(默认全量,含 douyu_tasks 的 837MB) +scripts/refresh_local_prod_mirror.sh +# 精简版(跳过 douyu_tasks 行,43MB,够绝大多数测试) +scripts/refresh_local_prod_mirror.sh --no-tasks +``` + +然后用镜像库跑应用 / 脚本: + +```bash +DB_NAME=douyu_login_prod ./dev.sh +# 或 +DATABASE_URL="mysql+pymysql://douyu_login:@127.0.0.1:3307/douyu_login_prod?charset=utf8mb4" ... +``` + +### 当前本地镜像的内容(2026-10-04 建立) + +| | 本地 `douyu_login_prod` | +|---|---| +| 迁移版本 | `20261004_0046`(与生产一致) | +| 账号 / 持有 CK | 15,182 / 14,323 | +| 登录记录 | 15,169 | +| `douyu_tasks` | **253,424**(含 837MB JSON —— 可用来实测保留策略) | +| `account_events` | 34(部署后产生的真实事件) | +| 库大小 | 907 MB | + +### 两个关键前提 + +1. **`APP_ENCRYPTION_KEY` 必须与生产一致**,否则镜像里的 CK 解不开、CK 相关测试全废。 + 已验证:当前本地 `.env` 的密钥**与生产一致**(抽样解密正常,CK 前缀 `dy_accounts_main`,长度 1659–1702)。 +2. **不要在镜像库上跑测试套件**。测试用的是独立库 `douyu_login_test` + (由 `TEST_MYSQL_DATABASE` 指定,`init_test_schema` 会 `create_all`)。 + 镜像库只用于手工/联调。 + +### 踩过的坑(脚本里已规避) + +- **不要把 `mysqldump` 串进 SSH 管道**:实测只有 ~49KB/s(MySQL 读 + gzip + 网络互相拖); + 改成"服务器本地 dump 成文件 + rsync"后 ~8MB/s,快两个数量级。 +- 用 **rsync 而非 scp**:可断点续传。 +- **`docker compose run` 默认读 stdin** —— 脚本如果通过 `ssh 'bash -s' < 脚本` 喂进去, + 它会把**脚本剩下的行**当 stdin 吃掉(这就是本次部署 90 秒停机的根因)。 + 正确写法:`docker compose run -T --rm ...