flink cdc读oracle表不锁表,因其基于logminer解析归档/重做日志;但mysql全量读取时默认用全局锁或表级锁,需配置--single-transaction或read-committed隔离级别规避。

直接给 SELECT 权限不够,数据抽取工具(如 Kettle、Flink CDC、Airbyte)在读取时默认会触发表级锁或事务一致性检查,尤其在没加 --single-transaction 或没配隔离级别时,容易卡住线上写入。核心是:既要避免锁表,又要保证读一致性,还得让工具能顺利探测元数据。
为什么 mysqldump 或 Kettle 一跑就锁表?
现象:执行备份或全量抽取时,业务 INSERT/UPDATE 明显变慢,show processlist 看到大量 Waiting for table metadata lock 或长时间 Starting transaction;甚至触发 LOCK TABLES 报错。
- mysqldump 默认行为:不加
--single-transaction时,会先执行FLUSH TABLES WITH READ LOCK(需RELOAD+LOCK TABLES权限),直接全局只读锁 - Kettle 的
Table Input步骤若未显式设事务隔离级别,可能继承连接池默认的REPEATABLE READ,开启长事务导致 MVCC 版本链堆积 - 某些工具(如旧版 DataGrip)连接后自动执行
SHOW CREATE TABLE,若用户没SHOW VIEW权限,会退而尝试锁表查结构
必须授予的最小权限集(不含锁)
只开 SELECT 不够,但加太多又危险。按工具实际行为精准授权:
-
SELECTONdb_name.*:读数据基础权限(注意不是*.*) -
SHOW VIEWONdb_name.*:让工具能读视图定义,避免 fallback 到锁基表 -
TRIGGERONdb_name.*:若表有触发器,Kettle/mysqldump 可能需要导出定义(否则报错或跳过) -
SELECTONINFORMATION_SCHEMA.COLUMNS和INFORMATION_SCHEMA.TABLES:否则工具连字段名都列不出来,会反复重试甚至中断 - 禁止授予:
LOCK TABLES、RELOAD、PROCESS、mysql.*任何权限——这些是锁表/探活/提权高危项
连接层关键配置(比权限还容易漏)
权限给了,工具仍卡住?大概率栽在这三处:
- MySQL 8.0+ 必须用
mysql_native_password插件:CREATE USER 'etl_user'@'192.168.20.%' IDENTIFIED WITH mysql_native_password BY 'xxx';(老客户端不认caching_sha2_password) - 连接字符串里显式指定事务隔离级别:
?sessionVariables=transaction_isolation=READ-COMMITTED(比默认REPEATABLE READ更轻量,减少 undo log 压力) - 禁用自动提交并控制事务粒度:Kettle 中勾选
Execute each row in a separate transaction会放大锁风险;应关闭该选项,改用单事务 +--single-transaction(mysqldump)或READ COMMITTED快照读
验证是否真“无锁”:两个必做检查
别只看工具跑通了就认为 OK。生产环境上线前必须确认:
- 在抽取过程中,执行
SELECT * FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA = 'db_name';,结果应为空(表示没持 MDL 锁) - 观察
SHOW ENGINE INNODB STATUS\G中的TRANSACTIONS部分,活跃事务数应稳定、不持续增长(说明没长事务堆积)
最易被忽略的是:工具连接池的 autoCommit=false 配置一旦开启,又没配超时或手动 commit,会默默拖住事务几天——这种“隐形锁”比显式 LOCK TABLES 更难排查。











