MySQL的不办connrestorebackup不写值,十有八九是写值权限或路径问题,别急着怀疑数据损坏。不办
我上周刚踩过这个坑。写值生产库做了次备份恢复演练,不办备份文件完好,写值binlog也正常,不办但执行connrestorebackup后,写值目标表就是不办空荡荡的。排查了半天,写值最后发现是不办MySQL的secure_file_priv参数锁死了导入路径。这个参数默认是写值NULL,意味着禁止任何文件导入导出操作。不办你从命令行直接跑没问题,写值但通过连接器调用时,不办它走的是另一套权限校验逻辑。
先检查这个:SHOW VARIABLES LIKE 'secure_file_priv';。如果返回NULL或空值,那你得在my.cnf里显式指定一个目录,比如secure_file_priv=/var/lib/mysql-files,然后把备份文件丢进去。别嫌麻烦,这是MySQL 5.7以后的安全红线,绕不过去。
另一个常见原因是连接器的事务隔离级别。connrestorebackup内部往往先开启一个事务,再逐行插入。如果你的隔离级别是REPEATABLE READ,而备份文件里有大量UPDATE或DELETE语句,那这些操作可能因为MVCC快照机制被静默跳过——不报错,不警告,就是写不进去。解决办法很粗暴:把隔离级别临时改成READ COMMITTED,或者干脆在恢复前SET AUTOCOMMIT=0手动控制提交点。
还有个细节容易被忽略:字符集。备份文件里如果包含utf8mb4的emoji或生僻字,而目标表的字符集是latin1,MySQL会直接丢弃这些字符,而不是报错。你查数据时看到的是NULL或空字符串,但实际是字符集转换失败。用SHOW CREATE TABLE对比一下源表和目标表的CHARSET,不一致就ALTER TABLE改掉,别偷懒。
说到这我得吐槽一句,MySQL的错误日志在这种场景下基本是废的。它只会写“Query OK, 0 rows affected”,根本不告诉你为什么0行。所以排查时别死盯日志,直接查performance_schema里的events_statements_history,看看那条恢复语句的真实执行计划。如果发现Select_scan或Select_full_join的计数异常,那大概率是索引问题导致连接器在扫描阶段就提前终止了。
最后提醒个冷门的:如果你的connrestorebackup是通过存储过程调用的,那注意SQL_SAFE_UPDATES这个会话变量。默认是0,但某些连接池会把它设为1,导致不带WHERE条件的UPDATE或DELETE直接被拦截。你恢复的数据如果包含全表更新,那就会被吞掉。在调用前执行SET SQL_SAFE_UPDATES=0;,一劳永逸。
真遇到不写值的情况,按这个顺序排查:路径权限 → 事务隔离 → 字符集 → 会话变量。八成能解决。剩下的两成,检查一下你的连接器版本——有些老版本对MySQL 8.0的caching_sha2_password认证支持不完整,会导致连接建立成功但数据通道静默关闭。升级驱动,别犹豫。