--regex 参数匹配格式为 db_name.table_name 的完整字符串,需锚定开头^和结尾$,点号须转义,支持PCRE但不支持高级特性,跨库或多表匹配需用括号分组并整体锚定。

mydumper 的 --regex 参数到底匹配什么?
它匹配的是「数据库名.表名」拼接后的完整字符串,格式为 db_name.table_name,不是单独的表名,也不是 SQL 里的反引号包裹形式。很多人误以为写 --regex="^user_.*$" 就能备份所有以 user_ 开头的表,结果一个没备——因为没带上库名前缀。
实操建议:
- 先用
mysql -Nse "SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','performance_schema','sys')"查看实际的db.table全量列表,确认目标格式 - 正则必须锚定开头和结尾(
^和$),否则可能意外命中无关库表,比如myapp.users和myapp_user.sessions都会被users匹配到 - 如果只备份单库下的多表,推荐写成
--regex="^myapp\.user_[a-z]+$",注意点号要转义
为什么 --regex 有时完全不生效?
最常见原因是 mydumper 启动时未正确加载权限或跳过了库级检查。它会在连接后先执行 SHOW DATABASES,再对每个库逐个应用正则过滤——如果用户没有某个库的 USAGE 权限,该库直接被跳过,里面的表自然不会参与匹配。
排查与解决:
- 用相同账号手动执行
SHOW DATABASES,确认能看到所有目标库;若看不到,需授权:GRANT USAGE ON *.* TO 'backup_user'@'%' - 避免混用
--database和--regex:前者会强制限定单库,后者在此上下文中仅作用于该库内的表,但容易让人误解为“全局过滤” - 加
-v 3查看 debug 日志,搜索regex matched或skipping database线索
备份多个不连续的表(如 user_profiles + order_history)怎么写正则?
不能靠 | 简单拼接,因为 ^db1\.user_profiles|db1\.order_history$ 实际匹配的是「以 db1.user_profiles 开头」或「以 db1.order_history 结尾」的任意字符串,逻辑错乱。
正确写法是把 OR 逻辑收进括号并锚定整体:
mydumper --regex="^myapp\.(user_profiles|order_history)$" -o /backup/
注意点:
- 括号必须转义为
\(和\),否则 mydumper 会报Invalid regex - 如果跨库,例如
auth.users和billing.invoices,必须写成^(auth\.users|billing\.invoices)$ - 正则引擎是 PCRE,支持
?、+、*,但不支持 lookaround 等高级特性
和 --tables-list 比,--regex 有什么不可替代的场景?
--tables-list 要求提前生成精确的表名文件,适合静态清单;而 --regex 是运行时动态匹配,适合处理按命名规则自动生成的表(如分表 logs_202401、logs_202402)或灰度环境中的临时测试表。
但要注意:
- 正则匹配发生在连接数据库之后,每次备份都要执行全库
SHOW TABLES,表数量极大时(比如单库上万张表),初始化延迟明显 - MySQL 8.0+ 的隐藏系统表(如
mysql.component)默认不显示在SHOW TABLES中,也不会被--regex扫到,无需额外排除 - 如果你需要排除某些表(比如大日志表),
--regex不支持否定逻辑,得改用--ignore-tables-list或改写正则为显式白名单
正则过滤看着灵活,但真正上线前一定要在测试实例上跑一次完整流程,观察输出目录里是否真有预期的表文件,以及 metadata 文件中记录的 Finished dumping 行是否包含它们——有时候匹配成功了,却因锁表失败或权限不足静默跳过,日志里只有一行 warning。


















