必须加--single-transaction,它通过InnoDB的MVCC机制获取一致性快照、全程不锁表;但仅对InnoDB有效,MyISAM表仍会锁表,混用时需配合--lock-all-tables或停写。

mysqldump 导出时要不要加 --single-transaction
加不加这个参数,直接决定你导出的数据是否一致——尤其在有写入的生产库上。
不加 --single-transaction 时,mysqldump 默认用 LOCK TABLES,会阻塞写入,适合停机维护;加了它,则靠 InnoDB 的 MVCC 实现一致性快照,不锁表,但前提是所有表必须是 InnoDB 引擎(MyISAM 不支持)。
- 线上迁移必须加
--single-transaction,否则业务可能卡住 - 如果库中混有 MyISAM 表,加了该参数也无效,
mysqldump会自动退回到锁表模式,并报警告 - 搭配
--skip-lock-tables一起用是冗余的,--single-transaction已隐含跳过锁表
导入时遇到 ERROR 1045 (28000): Access denied 怎么办
这错误不是 dump 文件问题,而是目标 MySQL 实例拒绝了你的连接权限,常见于跨环境迁移(比如从本地导出、往云数据库导入)。
重点检查三件事:
-
mysql命令连接时用的用户名是否有CREATE、INSERT、ALTER权限,而不仅是SELECT - 目标实例是否允许该用户从你的 IP 连接(云厂商常默认只允 localhost 或白名单 IP)
- 如果目标是 MySQL 8.0+,注意认证插件是否为
caching_sha2_password,旧版客户端可能不兼容,可临时用ALTER USER 'xxx'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx';切换
大库导出卡住或超时,怎么调参
默认情况下 mysqldump 会一次性读完整个表再写入文件,内存和网络压力都大;超过几百 MB 就容易被中间网络中断或客户端 timeout 干扰。
关键参数组合如下:
- 加
--compress减小传输体积(服务端和客户端都要支持) - 用
--max-allowed-packet=512M避免单条 insert 超长被截断(值需 ≤ 服务端max_allowed_packet) - 对超大表,拆成多份:先
mysqldump --no-data导结构,再用--where="id BETWEEN 1 AND 100000"分批导数据 - 避免
--extended-insert(默认开启)导致单行 SQL 过长,可加--skip-extended-insert换成多行 insert,方便调试和断点续传
导入后发现中文乱码,SET NAMES utf8mb4 有用吗
没用。dump 文件里如果有 SET NAMES utf8mb4,只影响后续语句的字符集解析,但无法修复已损坏的二进制内容。
乱码根源在导出时没指定正确字符集,解决必须从源头控制:
- 导出务必加
--default-character-set=utf8mb4,且确认源库character_set_server和表/列实际编码确实是utf8mb4 - 导入命令也要显式指定:
mysql --default-character-set=utf8mb4 -u user -p db_name - 如果 dump 文件已生成且内容乱码,说明导出时用了错误 charset,重导是唯一可靠方式
字符集错配是迁移中最隐蔽也最难回溯的问题,一旦忽略,数据就永久损毁了。


















