v0.2 Preview: Construction Plan.
CI / test (push) Failing after 1m31s

This commit is contained in:
2026-08-08 21:25:27 +08:00
parent b88d15698a
commit 1f98f7152d
822 changed files with 96959 additions and 8 deletions
+109
View File
@@ -0,0 +1,109 @@
# MySQL 8.0.35 迁移说明
## 当前状态
生产数据库目标为 MySQL 8.0.35
- Django 驱动:`mysqlclient`
- 字符集:`utf8mb4`
- 排序规则:`utf8mb4_0900_ai_ci`
- 存储引擎:InnoDB
- 事务隔离:READ COMMITTED
- SQL 模式:STRICT_TRANS_TABLES
- 实时匹配:MySQL 8 `SELECT ... FOR UPDATE SKIP LOCKED`
MySQL 5.7 不受支持。生产检查会拒绝版本低于 8.0.35 的数据库。
## 新空库
新安装的 MySQL 8 直接执行:
```bash
set -a
source .env.production
set +a
.venv-production/bin/python backend/manage.py check_mysql
.venv-production/bin/python backend/manage.py migrate --noinput
.venv-production/bin/python backend/manage.py seed_initial_content
.venv-production/bin/python backend/manage.py seed_contests
```
## 从当前 Django SQLite 搬数据
仅适用于本仓库 Django 创建的 `backend/db.sqlite3`,不适用于旧 Flask 的 `miniapp_v3.db`
先在旧 SQLite 环境导出业务数据:
```bash
unset DATABASE_URL
.venv/bin/python backend/manage.py dumpdata \
--natural-foreign \
--natural-primary \
--exclude contenttypes \
--exclude auth.permission \
--exclude admin.logentry \
--exclude sessions.session \
--indent 2 \
--output /tmp/hulumath-django-data.json
```
切换到空 MySQL 8 数据库:
```bash
set -a
source .env.production
set +a
.venv-production/bin/python backend/manage.py check_mysql
.venv-production/bin/python backend/manage.py migrate --noinput
.venv-production/bin/python backend/manage.py loaddata /tmp/hulumath-django-data.json
```
导入后检查:
```bash
.venv-production/bin/python backend/manage.py shell -c "
from accounts.models import User
from math_life.models import StoryRun
from contest.models import ContestAttempt
print({
'users': User.objects.count(),
'story_runs': StoryRun.objects.count(),
'contest_attempts': ContestAttempt.objects.count(),
})
"
```
确认无误后安全删除中间 JSON,因为其中包含用户资料和密码哈希:
```bash
shred -u /tmp/hulumath-django-data.json
```
## 旧 Flask SQLite
旧 Flask `miniapp_v3.db` 的表结构与新 Django 模型不同,不能用 `loaddata`
迁移前必须先确认需要保留的表和字段,再编写一次性 ETL:
```text
读取旧 SQLite
→ 字段清洗与用户映射
→ 写入 MySQL Staging
→ 核对数量和抽样内容
→ 生产停写窗口
→ 最终增量迁移
→ 切换域名
```
如果旧站没有真实用户数据,建议不迁移旧运行数据,直接使用新 MySQL 空库和官方种子。
## 不允许的迁移方式
- 不复制 MySQL 5.7 数据目录给 MySQL 8。
- 不把 SQLite 文件放进 MySQL 数据目录。
- 不直接修改 Django migration 历史记录。
- 不在没有 `mysqldump` 备份时执行生产迁移。
- 不让 MySQL 5.7 与 8.0 共用同一数据目录。