InnoDB表全量备份应加--single-transaction以避免锁表,但需禁止DDL操作;MyISAM则必须用--lock-all-tables并协调短暂停写;系统库mysql不可直接还原,仅导出和导入业务库,并手动建库确保字符集一致。

mysqldump 全量备份时加不加 --single-transaction?
取决于你的表引擎和业务是否允许短时一致性停写。InnoDB 表加 --single-transaction 能避免锁表,但前提是备份期间不能有 DDL(如 ALTER TABLE),否则会报错 ERROR 1449 (HY000): Thread x has an open transaction but is not in a transaction。MyISAM 必须用 --lock-all-tables,否则备份可能损坏。
- 线上业务读写频繁且全是 InnoDB → 用
--single-transaction --routines --triggers --events - 混用 MyISAM 或需绝对一致性 → 改用
--lock-all-tables,并协调业务方短暂停写(通常几秒到十几秒) - 跳过日志库、监控库等非业务库:加
--ignore-database=mysql --ignore-database=information_schema
恢复到新服务器前,mysql 系统库要不要还原?
不要直接还原。新服务器的 mysql 库包含用户权限、密码哈希、插件配置等,与旧库结构或认证方式(比如 caching_sha2_password vs mysql_native_password)可能冲突,强行还原会导致无法登录、权限失效甚至 mysqld 启动失败。
- 只导出业务库:
mysqldump --databases db1 db2 > backup.sql - 新服务器上先用
mysql -u root -p -e "CREATE DATABASE db1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"手动建库(注意字符集对齐) - 再导入:
mysql -u root -p db1 - 权限单独处理:用
SHOW CREATE USER 'u'@'%';和SHOW GRANTS FOR 'u'@'%';在旧库查,手动在新库执行
DNS 切换前,应用连接池里的旧地址还活着怎么办?
连接池(如 HikariCP、Druid)默认会复用空闲连接,即使 DNS 已指向新 IP,老连接仍维持在旧服务器上,造成数据写错、主从不一致甚至事务丢失。这不是 DNS 缓存问题,是客户端 TCP 连接未断开。
- 必须滚动重启应用,不能只改 DNS;K8s 环境要触发 Pod 重建,而非仅更新 Service
- 连接池配置里设紧一点的空闲连接超时:
connection-timeout=30000、idle-timeout=600000(10 分钟),避免旧连接滞留太久 - 切前在旧库执行
KILL ALL(MySQL 8.0.16+)或脚本杀掉非系统线程,逼应用重连 - 验证手段:新库执行
SELECT USER(), HOST FROM INFORMATION_SCHEMA.PROCESSLIST;,确认没有来自旧应用节点的连接
从旧库 SELECT @@server_id 到新库 CHANGE REPLICATION SOURCE TO 的坑
如果后续还要搭从库或做双写校验,server_id 冲突会导致复制中断。MySQL 不允许两个实例用相同 server_id,但很多人备份恢复后忘了改。
- 新服务器启动前,在
my.cnf里明确设置:server-id = 2024101502(用日期+序号,别用 1 或 2) - 恢复完立刻检查:
SELECT @@server_id;,不是 1 就算成功 - 如果旧库开了 binlog 且你打算用它当主库继续供其他从库同步,记得在新库关掉
log_bin(除非你真需要它当新主) -
CHANGE REPLICATION SOURCE TO中的SOURCE_HOST填新服务器能解析的域名或 IP,别填 localhost —— 容器或跨网段时会连不上
事情说清了就结束。最常漏的是连接池没重启、server_id 没改、以及把旧 mysql 库一起倒过去——这三个点一踩,后面排查要花的时间远超迁移本身。











