表库过滤

    从 TiDB 4.0 起,所有 TiDB 生态系统工具都使用一个通用的过滤语法来定义子集。本文档介绍如何使用表库过滤功能。

    在命令行中使用多个 -f--filter 参数,即可在 TiDB 生态工具中应用表库过滤规则。每个过滤规则均采用 db.table 形式,支持通配符(详情见)。以下为各个工具中的使用示例:

    • BR

      1. ./dumpling -f 'foo*.*' -f 'bar*.*' -P 3306 -o /tmp/data/
      2. # ^~~~~~~~~~~~~~~~~~~~~~~
    • TiDB Lightning

      1. ./tidb-lightning -f 'foo*.*' -f 'bar*.*' -d /tmp/data/ --backend tidb
      2. # ^~~~~~~~~~~~~~~~~~~~~~~

    TOML 配置文件

    在 TOML 文件中,表库过滤规则以的形式指定。以下为各个工具中的使用示例:

    • TiDB Lightning:

      1. [mydumper]
      2. filter = ['foo*.*', 'bar*.*']
    • TiCDC

      1. [filter]
      2. rules = ['foo*.*', 'bar*.*']
      3. [[sink.dispatchers]]
      4. matcher = ['db1.*', 'db2.*', 'db3.*']
      5. dispatcher = 'ts'

    直接使用表名

    每条表库过滤规则由“库”和“表”组成,两部分之间以英文句号 (.) 分隔。只有表名与规则完全相符的表才会被接受。

    1. db1.tbl1
    2. db2.tbl2
    3. db3.tbl3

    表名只由有效的组成,例如:

    • 数字(09
    • 字母(azAZ
    • $
    • _
    • 非 ASCII 字符(U+0080U+10FFFF

    其他 ASCII 字符均为保留字。部分标点符号有特殊含义,详情见下一节。

    • *:匹配零个或多个字符。
    • :匹配一个字符。
    • [a-z]:匹配 “a” 和 “z” 之间的一个字符。
    • [!a-z]:匹配不在 “a” 和 “z” 之间的一个字符。

    此处,“字符”指的是一个 Unicode 码位,例如:

    • U+00E9 (é) 是 1 个字符。
    • U+0065 U+0301 (é) 是 2 个字符。
    • U+1F926 U+1F3FF U+200D U+2640 U+FE0F (🤦🏿‍♀️) 是 5 个字符。

    使用文件导入

    如需导入一个文件作为过滤规则,请在规则的开头加上一个 “@” 来指定文件名。库表过滤解析器将导入文件中的每一行都解析为一条额外的过滤规则。

    例如,config/filter.txt 文件有以下内容:

    1. employees.*
    2. *.WorkOrder

    以下两条表库过滤命令是等价的:

    1. ./dumpling -f '@config/filter.txt'
    2. ./dumpling -f 'employees.*' -f '*.WorkOrder'

    导入的文件里不能使用过滤规则导入另一个文件。

    注释与空行

    导入的过滤规则文件中,每一行开头和结尾的空格都会被去除。此外,空行(空字符串)也将被忽略。

    行首的 # 表示该行是注释,会被忽略。而不在行首的 # 则会被认为是语法错误。

    1. # 这是一行注释
    2. db.table # 这一部分不是注释,且可能引起错误

    在一条过滤规则的开头加上 !,则表示符合这条规则的表不会被 TiDB 生态工具处理。通过应用排除规则,库表过滤可以作为屏蔽名单来使用。

    1. *.*
    2. #^ 注意:必须先添加 *.* 规则来包括所有表
    3. !employees.salaries

    转义字符

    如果需要将特殊字符转化为标识符,可以在特殊字符前加上反斜杠 \

    1. db\.with\.dots.*

    为了简化语法并向上兼容,不支持下列字符序列:

    • 在行尾去除空格后使用 \(使用 [ ] 来匹配行尾的空格)。
    • \ 后使用数字或字母 ([0-9a-zA-Z])。特别是类似 C 的转义序列,如 \0\r\n\t 等序列,目前在表库过滤规则中无意义。

    引号包裹的标识符

    除了 \ 之外,还可以用 " 和 来控制特殊字符。

    1. "foo""bar".`foo``bar`
    2. # 等价于:
    3. foo\"bar.foo\`bar

    用引号包裹的标识符不可以跨越多行。

    用引号只包裹标识符的一部分是无效的,例如:

    1. "this is "invalid*.*

    如果你需要使用较复杂的过滤规则,可以将每个匹配模型写为正则表达式,以 / 为分隔符:

    1. /^db\d{2,}$/./^tbl\d{2,}$/

    这类正则表示使用 Go dialect。只要标识符中有一个子字符串与正则表达式匹配,则视为匹配该模型。例如,/b/ 匹配 db01

    当表的名称与过滤列表中所有规则均不匹配时,默认情况下这些表被忽略。

    要建立一个屏蔽名单,必须使用显式的 *.* 作为第一条过滤规则,否则所有表均被排除。

    1. # 所有表均被过滤掉
    2. ./dumpling -f '!*.Password'
    3. # 只有 “Password” 表被过滤掉,其余表仍保留
    4. ./dumpling -f '*.*' -f '!*.Password'

    如果一个表的名称与过滤列表中的多个规则匹配,则以最后匹配的规则为准。例如:

    1. # rule 1
    2. employees.*
    3. # rule 2
    4. !*.dep*
    5. # rule 3
    6. *.departments

    过滤结果如下:

    注意:

    • INFORMATION_SCHEMA
    • PERFORMANCE_SCHEMA
    • METRICS_SCHEMA
    • INSPECTION_SCHEMA
    • mysql