02. 导入 airport-db.zip

1. 本章目标

本章识别 airport-db.zip 的格式,使用 MySQL Shell 并行导入 AirportDB,并说明压缩包不是官方 MySQL Shell dump 时该如何处理。

AirportDB 大约包含 14 张表和五千多万行。导入耗时取决于 CPU、内存、磁盘和 MySQL 配置,可能持续几十分钟甚至更久。

2. 下载和校验文件

官方示例数据库下载页提供 airport-db.zip。在服务器执行:

cd /srv/airportdb-import
curl -fL -o airport-db.zip https://downloads.mysql.com/docs/airport-db.zip
ls -lh airport-db.zip
sha256sum airport-db.zip

-f 让 HTTP 错误导致命令失败,-L 跟随重定向。保存 SHA256 可以在重复传输或以后重新导入时判断文件是否发生变化。若官方页面发布了校验值,应与官方值比对。

从本地上传时可以使用:

scp airport-db.zip deploy@<服务器公网IP>:/srv/airportdb-import/

3. 不要急着导入,先看压缩包内容

cd /srv/airportdb-import
unzip -l airport-db.zip | head -n 40

官方包解压后应是 MySQL Shell dump 目录,其中包含元数据、DDL 和分块数据文件。MySQL Shell dump 常见的识别特征包括 @.json、@.done.json 等元数据文件。

解压:

unzip airport-db.zip
find /srv/airportdb-import/airport-db -maxdepth 2 -type f | head -n 30
du -sh /srv/airportdb-import/airport-db

如果实际目录名不同,以 unzip -l 的结果为准。

如果压缩包里是 .sql

这不是 MySQL Shell dump。先解压,再使用 mysql 客户端:

mysql -u root -p -e "CREATE DATABASE airportdb_training CHARACTER SET utf8mb4;"
mysql -u root -p airportdb_training < /path/to/airportdb.sql

如果是 .sql.gz:

gzip -dc /path/to/airportdb.sql.gz | mysql -u root -p airportdb_training

不要把 ZIP 文件本身重定向给 mysql。也不要用 Node.js 写循环逐条插入五千万行数据。

4. 连接 MySQL Shell

在服务器本机连接:

mysqlsh root@127.0.0.1:3306

MySQL Shell 会提示输入密码,密码不会出现在 Shell 历史中。进入后查看连接和模式:

\status
\js

util.loadDump() 是 MySQL Shell JavaScript 模式中的工具,不是 SQL 语句。如果当前提示符显示 SQL>,先执行 \js。

5. 先做 dry run

MySQL Shell 支持用 dryRun 检查 dump 和目标实例,而不真正加载:

util.loadDump("/srv/airportdb-import/airport-db", {
  threads: 4,
  dryRun: true
})

重点查看输出中的目标 schema、版本兼容性、所需权限和错误。官方 dump 通常携带 schema 定义,实际 schema 名称以 dump 元数据和 dry run 输出为准,不要凭文件名猜测。

本项目希望应用最终读取 airportdb_training。如果官方 dump 创建的 schema 名称不是这个名字,不要手工编辑 dump 元数据或直接改几十张数据文件。可选择:

  1. 首次先按官方 schema 名导入并验证;
  2. 使用 MySQL Shell 重新导出为你管理的训练库;
  3. 保留官方导入库作为 airportdb_source,将其复制到 airportdb_training 后再进行索引实验。

第 3 章会给出只读账号和训练库边界。最重要的是先确认实际结果,再配置 DB_NAME。

6. 正式并行导入

小型云服务器先使用 4 个线程:

util.loadDump("/srv/airportdb-import/airport-db", {
  threads: 4,
  progressFile: "/srv/airportdb-import/airport-load-progress.json"
})

参数含义:

不要盲目把 threads 调到很大。更多线程会增加连接、内存、CPU 和磁盘 I/O。2 核小服务器从 2~4 开始,观察 top、iostat 和 MySQL 状态后再调整。

导入时可在另一个 SSH 会话观察:

top
df -h
sudo mysql -e "SHOW FULL PROCESSLIST;"

导入完成后,MySQL Shell 会显示加载的数据量、完成对象数和耗时。把终端输出保存到 docs/01-airportdb-import.md 或部署记录中。

7. 中断和继续

如果 SSH 断开或导入失败,先读错误信息并修复根因,例如磁盘空间不足。使用相同 dump 路径和相同 progressFile 再次执行 util.loadDump(),工具会利用进度记录跳过已完成工作。

不要在不理解状态时删除进度文件。删除它会让工具失去恢复依据,也可能导致“目标对象已存在”等错误。

长时间导入建议在 tmux 中运行:

sudo apt install -y tmux
tmux new -s airport-import

按 Ctrl+B,再按 D 可离开会话。重新连接后:

tmux attach -t airport-import

8. 常见失败

Access denied

导入账号需要创建 schema、表和索引的权限。应用只读账号不能用于导入。用管理账号导入,完成后再创建应用账号。

No space left on device

立即检查:

df -h
sudo du -xh /var/lib/mysql /srv/airportdb-import | sort -h | tail

不要未经确认就删除 MySQL 数据目录。扩容磁盘或清理明确可删除的旧下载和日志后再继续。

连接被断开

查看 MySQL 状态和日志:

systemctl status mysql --no-pager
sudo journalctl -u mysql -n 200 --no-pager

检查是否发生 OOM、MySQL 重启或连接数不足。

版本不兼容

比较版本:

mysql --version
mysqlsh --version

优先使用受支持的 MySQL 8.x 与较新的 MySQL Shell。不要通过编辑 dump 元数据绕过兼容检查。

9. 本章验收

退出 MySQL Shell:

\quit

确认 schema 存在:

sudo mysql -e "SHOW DATABASES;"

确认导入目录和进度文件仍在,记录导入耗时与实际 schema 名。下一章会验证表结构、创建 airportdb_training 边界和只读应用账号。

下一章:验证数据并创建只读账号

10. 参考资料