从 MySQL 转储中提取单张表

你有一个含 127 张表的 7 GB 转储,但本地只需要其中三张——usersordersproducts。本文讲清惯用的 sed/grep 技巧为何会出错,以及如何点几下就把你要的表(连同它们的外键)精确提取出来。

并不是每项工作都需要整个数据库。在本地开发一个功能时,你很少会想让一份完整的生产转储塞满磁盘、还要花一个小时才能导入。你想要的,是这个功能真正会用到的那几张表。

当你在调试某一张表时也是如此——在 orders 里复现一个数据问题,用不着其余那 126 张表——或者做部分迁移时,只有少数几张表要挪到新服务上。所有这些情况里,问题都是同一个:怎样才能只把这几张表干净利落地从一个巨型转储里取出来?

sed/grep 的办法,以及它为何会出错

经典答案是用 sedmysqldump 为每张表写出的段落标题之间切割文件:

# 从一个 mysqldump 文件里取出 users 表
sed -n '/-- Table structure for table `users`/,/-- Table structure for table/p' dump.sql > users.sql

这看着挺聪明,在一个小巧整洁的转储上说不定还真能成一次。可放到一个真实的 7 GB 文件上,它会在许多不易察觉的地方崩掉:

你最后会把 awk 叠在 grep 上、再叠在 sed 上,在子集上反复测试,却仍然不敢相信结果。有更好的办法。

用 DumpCleaner 提取表

DumpCleaner 会正确解析转储——它理解语句边界、多行 INSERT、反引号和注释——所以它总是切在正确的行上。提取你需要的表只需四步:

  1. 把你的 .sql 转储拖进来。DumpCleaner 流式读取文件,所以一个 7 GB 的转储以恒定内存打开,而不是把整个文件都加载进来。
  2. 查看自动检测出的表清单。每张表都会被解析出来,并列出行数和大小——不用在几百万行里滚来滚去找它有什么。
  3. 挑选你想要的表。勾选 usersordersproducts,或者输入正则/排除模式,比如用 *_logs 一次性丢掉整组表。
  4. 包含外键父表并导出。可选地自动把被引用的父表也拉进来,然后导出一个干净、可导入的文件。

有几点让这件事比 shell 工具省心得多:

只要你需要的表——别的一概不要

DumpCleaner 从任意大小的转储中提取指定的表——流式处理、内存恒定,还替你把外键解析妥当。原生 macOS 与 iPadOS 应用,一次性买断。

在 App Store 下载

常见问题

我能一次提取多张表吗?

可以。想勾多少张表都行——把 usersordersproducts 一起勾上——DumpCleaner 会一趟就把它们全写进一个文件。

它会保留外键依赖吗?

可选地会。打开包含外键依赖,你所选表引用的任何父表都会被自动拉进来,于是提取结果导入时不会有约束错误。

我能按模式排除表吗?

可以。用 *_logs*_sessions 这样的排除模式,或用一个正则表达式,来整组丢掉表,而不必一张一张去掉勾选。

它对 PostgreSQL 也适用吗?

适用。DumpCleaner 能读取 MySQL、MariaDB 和 PostgreSQL(pg_dump)转储,并在提取表时处理像 public.users 这样带 schema 限定的名字。

别再和 sed、grep 较劲

拖入、挑选你的表、导出。DumpCleaner 把你需要的表——连同它们的外键——精确地从任何转储里取出来。

在 App Store 下载