Files
Hulumath-Web/docs/MYSQL8_MIGRATION.md
Jacky 1f98f7152d
CI / test (push) Failing after 1m31s
v0.2 Preview: Construction Plan.
2026-08-08 21:25:27 +08:00

110 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 共用同一数据目录。