zhizhijie
2026-09-21 e2eca00a1443eba3169798bfeaba3f3697a819bd
docs(工具): 新增数据库备份与还原操作步骤 + 日结补记备份刷新
1个文件已修改
1个文件已添加
176 ■■■■■ 已修改文件
docs/工作日结/工作日结_2026-09-21.md 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/工具/数据库备份与还原操作步骤.md 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/¹¤×÷ÈÕ½á/¹¤×÷ÈÕ½á_2026-09-21.md
@@ -121,3 +121,12 @@
**本次无代码改动**,属数据类工作,故不另出《功能测试报告》。
**待用户确认**:① äº¤ä»˜åŒ…是否需要压缩 zip(50 MB â†’ ä¾¿äºŽå¾®ä¿¡/网盘传输);② åŒäº‹çŽ¯å¢ƒè‹¥ä¸º MySQL 5.7,需另出一份 5.7 ä¸“用导出;③ æ˜¯å¦éœ€è¦æŠŠ `docs/`(母版、投资源文件)一并打包 â€”— è¯¥éƒ¨åˆ†å·²åœ¨ git ä»“库内,clone å³å¯èŽ·å¾—ã€‚
### äº”之补充:10:34 å¤æŸ¥å‘现备份已过期,已重新导出
- ç”¨ `CHECKSUM TABLE` å¤æ£€ 10:17 é‚£ä»½å¤‡ä»½æ—¶å‘现 4 å¼ è¡¨æ ¡éªŒå’Œä¸ä¸€è‡´ï¼Œè¿›ä¸€æ­¥æŸ¥ `COUNT(*)`:`audit_result` 3393→3421、`import_batch` 417→419、`investment_system` 148→277、`investment_monthly` 284→284(行数同但内容变),最后写入时间 10:20~10:22
  â†’ å³ **10:17 å¯¼å‡ºä¹‹åŽï¼Œå¦ä¸€ä¸ªä¼šè¯ï¼ˆæäº¤ 2e6830b)又往库里导入了投资系统数据**,旧备份已过期。
- å·²é‡æ–°å¯¼å‡ºï¼š**10:34:57,52,030,977 å­—节,合计 128,962 è¡Œ**(旧份 128,803 è¡Œï¼‰ï¼Œã€Šè¿˜åŽŸè¯´æ˜Žã€‹å·²æŒ‰æ–°æ•°æ®é‡å†™ï¼ˆå«æ–‡ä»¶ SHA256)。
- é‡æ–°éªŒè¯ï¼ˆä¸‰å±‚,全过):结构 `CREATE TABLE` 29/29;逐表 `COUNT(*)` 29/29 ä¸€è‡´ï¼›`CHECKSUM TABLE` 29/29 ä¸€è‡´ï¼›`mysqldump --order-by-primary` æœ‰åºå¯¼å‡ºä¸¤ä»½æ•°æ®æ–‡ä»¶ **SHA256 å®Œå…¨ç›¸åŒ**(逐行内容一致)。
- **经验**:备份只是某一时刻的快照,导完之后只要还在导数据/跑审核就旧了;交付前必须最后再导一次。
- æ–°å¢žæ–‡æ¡£ï¼š`docs/工具/数据库备份与还原操作步骤.md`(备份参数说明 / ä¸‰æ­¥éªŒè¯ / è¿˜åŽŸ / å¸¸è§é—®é¢˜ï¼Œå‘½ä»¤å¯ç›´æŽ¥å¤åˆ¶ï¼‰ã€‚
docs/¹¤¾ß/Êý¾Ý¿â±¸·ÝÓ뻹ԭ²Ù×÷²½Öè.md
New file
@@ -0,0 +1,167 @@
# æ•°æ®åº“备份与还原操作步骤(traffic_audit)
> æ•´ç†äºŽ 2026-09-21。**备份 = ç”¨ mysqldump å¯¼å‡ºå…¨åº“ sql**;**还原 = æŠŠè¿™ä¸ª sql å–‚回 mysql**。
> é¢å‘自己动手操作,命令都可以直接复制。
## 0. çŽ¯å¢ƒé€ŸæŸ¥
| é¡¹ | å€¼ |
| --- | --- |
| æœåŠ¡ç«¯ | MySQL **8.0.29**,`127.0.0.1:3308` |
| åº“ / è´¦å· | åº“ `traffic_audit`,账号 `root` / `123456` |
| **导出工具** | `C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqldump.exe`(**必须用 8.0 è¿™ä¸ª**,与服务端同版本) |
| æ—¥å¸¸æŸ¥æ•°å®¢æˆ·ç«¯ | `D:\mysql\mysql-5.7.41-winx64\bin\mysql.exe` |
**两个坑先记住**
1. è¿žæŽ¥å‚数写 `--host=127.0.0.1`;写成 `-h127.0.0.1` ä¼šè¢«è§£æžæˆä¸»æœºå `127`,直接连不上。
2. è¾“出文件用 `--result-file=` è®© mysqldump è‡ªå·±å†™ï¼Œä¸è¦ç”¨ `>` é‡å®šå‘(中文路径 + PowerShell å¼•号容易翻车)。
---
## 1. å¤‡ä»½ï¼ˆå¯¼å‡ºå…¨åº“)
```powershell
$ts  = Get-Date -Format 'yyyyMMdd_HHmmss'
$dir = 'D:\backup'                                  # è·¯å¾„不要留空格
New-Item -ItemType Directory -Force $dir | Out-Null
$out = Join-Path $dir "traffic_audit_full_$ts.sql"
& 'C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqldump.exe' `
  --host=127.0.0.1 --port=3308 --user=root --password=123456 `
  --default-character-set=utf8mb4 `
  --single-transaction --routines --triggers --events --hex-blob `
  --databases traffic_audit `
  --result-file=$out
"exit=$LASTEXITCODE"
Get-Item $out | Select-Object Name, Length, LastWriteTime
```
**成功判据**:`exit=0`,文件有几十 MB,且文件最后一行是 `-- Dump completed on ...`(没有就是中途断了)。
每个参数的作用:
| å‚æ•° | ä½œç”¨ |
| --- | --- |
| `--host=127.0.0.1 --port=3308` | æœ¬æœºæœåŠ¡ç«¯ç«¯å£ï¼ˆè§ä¸Šã€Œä¸¤ä¸ªå‘ã€ï¼‰ |
| `--default-character-set=utf8mb4` | ä¸­æ–‡ä¸ä¹±ç ï¼Œ**必带** |
| `--single-transaction` | ä¸€è‡´æ€§å¿«ç…§ï¼Œå¯¼å‡ºæœŸé—´ä¸é”è¡¨ï¼Œåˆ«äººç…§æ ·èƒ½ç”¨ç³»ç»Ÿ |
| `--databases traffic_audit` | è¿ž `CREATE DATABASE` + `USE` ä¸€èµ·å¯¼ â†’ åŒäº‹æ‹¿åˆ°**单个文件**就能整库还原 |
| `--routines --triggers --events` | æœ¬åº“目前没有这类对象(均为 0),带上只是防将来有 |
| `--hex-blob` | äºŒè¿›åˆ¶åˆ—安全导出 |
| `--result-file=...` | ç›´æŽ¥å†™æ–‡ä»¶ï¼Œç»•开重定向的编码/引号问题 |
> åªå¯¼æŸå‡ å¼ è¡¨ï¼šæŠŠ `--databases traffic_audit` æ¢æˆ `traffic_audit è¡¨1 è¡¨2`(此时不带建库语句,只导结构和数据)。
---
## 2. éªŒè¯ã€Œæ˜¯ä¸æ˜¯çœŸå¯¼å…¨äº†ã€ï¼ˆä¸‰æ­¥ï¼Œå¼ºåº¦é€’增)
导出完**不要直接发人**,按下面三步核。
### ç¬¬ 1 æ­¥ï¼šç»“构齐不齐
```powershell
# å¤‡ä»½é‡Œçš„ CREATE TABLE æ¡æ•°
(Select-String -Path $out -Pattern '^CREATE TABLE' -Encoding UTF8).Count
# åº“里实际表数
& 'D:\mysql\mysql-5.7.41-winx64\bin\mysql.exe' --host=127.0.0.1 --port=3308 --user=root --password=123456 `
  -N -B -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='traffic_audit';"
```
两个数相等(本库是 **29**)才算结构齐。顺带确认没有 mysqldump å¯¼ä¸å‡ºæ¥çš„对象:
```powershell
& 'D:\mysql\mysql-5.7.41-winx64\bin\mysql.exe' --host=127.0.0.1 --port=3308 --user=root --password=123456 -e `
  "SELECT (SELECT COUNT(*) FROM information_schema.views WHERE table_schema='traffic_audit') è§†å›¾,
          (SELECT COUNT(*) FROM information_schema.routines WHERE routine_schema='traffic_audit') å­˜å‚¨è¿‡ç¨‹,
          (SELECT COUNT(*) FROM information_schema.triggers WHERE trigger_schema='traffic_audit') è§¦å‘器,
          (SELECT COUNT(*) FROM information_schema.events WHERE event_schema='traffic_audit') äº‹ä»¶;"
```
### ç¬¬ 2、3 æ­¥ï¼šè¿˜åŽŸåˆ°ä¸´æ—¶åº“ï¼Œæ¯”è¡Œæ•° + æ¯”内容
原理:把备份里的库名换成 `traffic_audit_vfy` å¯¼è¿›ä¸´æ—¶åº“,与源库逐表比对,比完删库。
```powershell
$root = 'D:\文档\ChatGPT\traffic-audit'
$vfySql = "$root\_tmp\_verify.sql"
# 2.1 æ¢åº“名(用 28591 ç¼–码做「按字节替换」,不会动坏中文)
$enc = [System.Text.Encoding]::GetEncoding(28591)
$s = $enc.GetString([System.IO.File]::ReadAllBytes($out))
[System.IO.File]::WriteAllBytes($vfySql, $enc.GetBytes($s.Replace('`traffic_audit`', '`traffic_audit_vfy`')))
# 2.2 å¯¼å…¥ä¸´æ—¶åº“(cmd çš„ < é‡å®šå‘最省事)
$mysql = 'C:\Program Files\MySQL\MySQL Server 8.0\bin\mysql.exe'
& $mysql --host=127.0.0.1 --port=3308 --user=root --password=123456 -e 'DROP DATABASE IF EXISTS traffic_audit_vfy;'
cmd /c "`"$mysql`" --host=127.0.0.1 --port=3308 --user=root --password=123456 --default-character-set=utf8mb4 < `"$vfySql`""
# 2.3 é€è¡¨æ¯”行数
$tables = & $mysql --host=127.0.0.1 --port=3308 --user=root --password=123456 -N -B `
  -e "SELECT table_name FROM information_schema.tables WHERE table_schema='traffic_audit' ORDER BY table_name;"
& $mysql --host=127.0.0.1 --port=3308 --user=root --password=123456 -B -e (($tables |
  ForEach-Object { "SELECT '$_' è¡¨,(SELECT COUNT(*) FROM traffic_audit.$_) æºåº“,(SELECT COUNT(*) FROM traffic_audit_vfy.$_) å¤‡ä»½" }) -join ' UNION ALL ')
```
逐表两列数字一致 â†’ è¡Œæ•°é½ã€‚
**最强的一步:比内容(SHA256)**。两张表行数一样、内容被改过,上面的方法看不出来,这个方法能:
```powershell
$md = 'C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqldump.exe'
$common = '--host=127.0.0.1','--port=3308','--user=root','--password=123456','--default-character-set=utf8mb4',
          '--single-transaction','--no-create-info','--skip-comments','--order-by-primary','--hex-blob','--compact'
& $md @common traffic_audit     "--result-file=$root\_tmp\_cmp_src.sql"
& $md @common traffic_audit_vfy "--result-file=$root\_tmp\_cmp_vfy.sql"
(Get-FileHash "$root\_tmp\_cmp_src.sql").Hash -eq (Get-FileHash "$root\_tmp\_cmp_vfy.sql").Hash   # True æ‰ç®—å…¨
```
- `--order-by-primary`:按主键排序导出,保证两份文件行顺序一致,才能直接比哈希;本库 29 å¼ è¡¨**都有主键**。
- ç»“æžœ `True` â†’ é€è¡Œå†…容完全一致。
**收尾**(验证完把临时库删掉,别留在服务器上):
```powershell
& 'C:\Program Files\MySQL\MySQL Server 8.0\bin\mysql.exe' --host=127.0.0.1 --port=3308 --user=root --password=123456 `
  -e 'DROP DATABASE IF EXISTS traffic_audit_vfy;'
```
---
## 3. è¿˜åŽŸï¼ˆæŠŠå¤‡ä»½è£…åˆ°è¿™å°æˆ–å¦ä¸€å°æœºå™¨ï¼‰
```powershell
cmd /c "`"C:\Program Files\MySQL\MySQL Server 8.0\bin\mysql.exe`" --host=127.0.0.1 --port=3308 --user=root --password=123456 --default-character-set=utf8mb4 < `"D:\backup\traffic_audit_full_20260921_103457.sql`""
```
- å¤‡ä»½é‡Œå« `CREATE DATABASE`,**空环境**直接跑即可。
- ç›®æ ‡åº“**已有同名库**时:`CREATE DATABASE IF NOT EXISTS` ä¸æŠ¥é”™ï¼Œä½†åŽé¢ `CREATE TABLE` ä¼šå› è¡¨å·²å­˜åœ¨è€Œå¤±è´¥ã€åŠé€”中断。要么先 `DROP DATABASE traffic_audit;`,要么先确认是空环境。
- **不要**拿 `docs/init.sql` åŽ»è¡¥å·²æœ‰æ•°æ®çš„åº“ï¼šå®ƒå¸¦ `DROP TABLE`,是破坏性的。
---
## 4. å¸¸è§é—®é¢˜
| çŽ°è±¡ | åŽŸå›  / å¤„理 |
| --- | --- |
| `mysqldump: [Warning] Using a password on the command line interface can be insecure.` | åªæ˜¯è­¦å‘Šï¼Œä¸å½±å“ç»“果;想消掉可用 `--defaults-extra-file` æ”¾å¯†ç  |
| å¯¼å…¥æŠ¥ `Table 'xxx' already exists` | ç›®æ ‡åº“不是空的(见上) |
| å¯¼å…¥æŠ¥ `Unknown database` | ç”¨ `--databases` å¯¼å‡ºçš„备份不会出现;如果只导了表(没带建库语句),要自己先 `CREATE DATABASE traffic_audit` |
| ä¸­æ–‡å˜é—®å·/乱码 | å¯¼å‡ºã€å¯¼å…¥ä¸¤å¤´éƒ½è¦ `--default-character-set=utf8mb4` |
| å¤‡ä»½æ–‡ä»¶åªæœ‰å‡ ç™¾ KB | åæœ‰å…«ä¹æ˜¯ `--databases` å†™é”™åº“名或连接失败,看退出码和文件末尾有没有 `Dump completed` |
| æƒ³åªå¤‡ä»½ä¸€å¼ è¡¨ | `mysqldump ... traffic_audit è¡¨å --result-file=...` |
---
## 5. æœ¬æ¬¡å®žæµ‹è®°å½•(2026-09-21)
- å¤‡ä»½æ–‡ä»¶ï¼š`_给同事_2026-09-21\traffic_audit_full_20260921.sql`,52,030,977 å­—节(约 49.6 MB),导出时间 10:34:57。
- SHA256:`832B518F45313420...`(完整值见 `_给同事_2026-09-21\还原说明_2026-09-21.md`)。
- éªŒè¯ç»“果:29/29 å¼ è¡¨ç»“构齐、行数一致(合计 128,962 è¡Œï¼‰ã€`CHECKSUM TABLE` ä¸€è‡´ã€é€è¡Œ SHA256 ä¸€è‡´ã€‚
- **经验教训**:10:17 å…ˆå¯¼äº†ä¸€ä»½ï¼Œ10:34 å¤æŸ¥å‘现源库已被改动(`investment_system` 148→277、`audit_result` 3393→3421、`import_batch` 417→419),旧备份已过期。
  â†’ **备份是某一时刻的快照**;只要之后还在往系统里导数据、跑审核,备份就旧了。交付/归档前**最后再导一次**。
> åˆ¤æ–­å¤‡ä»½æ–°æ—§çš„æœ€å¿«åŠžæ³•ï¼šçœ‹æ–‡ä»¶åé‡Œçš„æ—¶é—´æˆ³ï¼Œä¸Ž `import_batch` çš„ `MAX(created_at)` æ¯”一下。