新功能解读系列文章(6):权限预检与修复安全策略——先确认能看见,再决定怎么修
功能简介v4.0.0 对权限预检和修复安全策略做了一次系统性增强核心目标是更符合最小权限原则、更容易排查权限问题、更安全地处理在线修复。主要变化如下能力说明源端/目标端角色区分源端只检查读取权限目标端根据checkObject和datafix检查实际修复所需权限通配/映射规则压缩检查支持db.*、db.t%、srcdb.*:dstdb.*按源端/目标端角色压缩权限检查目标空匹配权限提示指定库表不可见或匹配为空时提示检查权限并给出SHOW GRANTS/GRANT SELECT建议目标端不可见保护目标端表元数据不可见时先提示权限不足不再直接当作缺表生成建表修复 SQL非 data 对象保守修复struct/routine/trigger即使配置datafixtable也强制导出 fix SQL不直接在线修改目标对象这次变化不是简单增加几条权限检查而是让权限预检逻辑真正理解“源端”和“目标端”的职责差异。二、功能作用及使用场景深入解读2.1 为什么需要重新设计权限预检在 v3.x 或更早版本中权限检查容易出现两类问题问题一权限要求过高源端通常只是被读取的一方按最小权限原则只需要读取元数据和数据的权限。但如果源端也被要求具备INSERT、DELETE、ALTER等修复权限就会增加授权成本也不符合生产环境的安全规范。问题二权限不足被误判为对象不存在MySQL 的information_schema查询结果受权限影响。如果当前账号没有权限查看某张表这张表可能不会出现在元数据查询结果中。此时工具如果直接判断“目标端缺表”就可能误生成 CREATE TABLE 修复 SQL导致目标端数据被覆盖或结构被破坏。问题三非 data 对象在线修复风险高checkObjectstruct/routine/trigger涉及 DDL、存储过程、触发器等对象变更。如果配置了datafixtable就直接在线修改目标端对象风险远高于普通数据行修复。因此v4.0.0 的策略是源端尽量只读目标端按需检查对象不可见先怀疑权限不轻易当作不存在非 data 对象只导出 SQL不直接在线执行。2.2 源端/目标端角色区分最小权限原则v4.0.0 在权限预检接口中引入了accessRole概念明确区分source和dest。同样是checkObjectdata源端和目标端需要的权限不同。MySQL-family 权限矩阵场景源端所需权限目标端所需权限checkObjectdata, datafixfileSELECTSELECTcheckObjectdata, datafixtableSELECTSELECT、INSERT、DELETEcheckObjectstruct, datafixfileSELECTSELECTcheckObjectstruct, datafixtableSELECTSELECT、ALTER预检结构修复权限checkObjecttriggerTRIGGERTRIGGERcheckObjectroutine按 MySQL 版本检查例程定义可见性按 MySQL 版本检查例程定义可见性其中一个重要修正是普通checkObjectdata数据校验不再强制要求未实际使用的REPLICATION CLIENT权限datafixtable时 MySQL 目标端也不再误要求ALTER权限。2.3 Oracle 权限也按角色区分Oracle 场景下同样区分源端和目标端角色场景源端所需权限目标端所需权限checkObjectdata, datafixfileSELECT ANY TABLE或对象级SELECTSELECT ANY TABLE或对象级SELECTcheckObjectdata, datafixtableSELECT ANY TABLE或对象级SELECTSELECT ANY TABLE、INSERT ANY TABLE、DELETE ANY TABLE或对象级等价权限checkObjectstruct, datafixtableSELECT ANY TABLE或对象级SELECT结构修复相关ALTER权限这对 Oracle → MySQL 异构迁移尤其重要源端 Oracle 账号通常由业务系统或第三方提供能授予只读权限就不应要求写权限。2.4 通配与映射规则压缩检查gt-checksum 支持多种表选择方式tablesdb.*tablesdb.t%tablessrcdb.*:dstdb.*tablessrcdb.orders:dstdb.orders_newv4.0.0 在权限预检中会保留原始tables规则并按源端/目标端角色压缩检查目标。示例一普通通配tablessbtest.*如果元数据展开后有sbtest.t1、sbtest.t2、sbtest.t3权限检查不会机械地逐表检查三次而是压缩为sbtest.*如果账号拥有GRANT SELECT ON sbtest.*就可以覆盖该库下所有表。示例二源端到目标端映射tablessrcdb.*:dstdb.*权限预检会按角色拆开角色检查目标源端srcdb.*目标端dstdb.*这避免了用源端库名去检查目标端权限或者用目标端库名去检查源端权限的混淆问题。示例三部分通配tablesdb.order%%用于表名部分通配。v4.0.0 会在权限提示中尽量归并为库级授权建议例如GRANT SELECT ON db.* TO source_userhost;注意表名部分通配请使用%不要使用*。db.*表示整库所有表是合法的但db.t*这类写法会被提示改为db.t%。2.5 指定库表不可见或匹配为空时给出授权建议过去当tablessbtest.*匹配不到任何表时用户往往只能看到类似No tables to check的提示但不知道到底是表真的不存在tables配置写错当前账号没有权限看见这些表v4.0.0 对这种场景增加了更明确的权限排查提示。当源端元数据为空或源端元数据非空但指定库表匹配不到时日志会提示current source user may lack SELECT privilegeSHOW GRANTS FOR CURRENT_USER();SHOW GRANTS FOR userhost;并给出类似下面的授权建议GRANT SELECT ON sbtest.* TO source_userhost;终端层面也会给出更清晰的提示gt-checksum: No tables to check. Check whether tables is correct, whether the selected objects exist, and whether the current DB user has privileges on them. See gt-checksum.log for SHOW GRANTS / GRANT SELECT suggestions or set logLeveldebug这样用户可以第一时间从日志中获取可执行的排查方向而不是盲目修改tables配置。2.6 目标端表不可见先提示权限不足不误判为缺表这是 v4.0.0 权限预检中非常关键的一项安全修复。假设配置如下checkObjectstructdatafixfiletablesdb.orders源端表db.orders存在但目标端账号没有权限查看目标端同名表。此时目标端元数据查询可能返回“表不存在”。如果直接当作缺表处理工具可能生成CREATE TABLE IF NOT EXISTS db.orders (...);但实际上目标端表可能已经存在只是当前账号看不见。这类修复 SQL 显然是不安全的。

相关新闻