mysqldump 备份时提示 Access denied
或 Can't connect to MySQL server
权限不足或连接参数错误是备份失败最常见原因。不是所有用户都有
SELECT、
LOCK TABLES或
SHOW VIEW权限,而
mysqldump默认需要这些权限才能完整导出表结构和数据。 检查用户是否具备必要权限:
SHOW GRANTS FOR 'backup_user'@'localhost';重点确认是否包含
SELECT、
LOCK TABLES、
SHOW VIEW、
TRIGGER(若含触发器) 避免用
root直接备份;建议创建专用账号:
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'strong_pass';<br>GRANT SELECT, LOCK TABLES, SHOW VIEW, TRIGGER ON *.* TO 'backup_user'@'localhost';<br>FLUSH PRIVILEGES;连接参数必须显式指定主机、端口、socket(如适用),尤其在 Docker 或多实例环境下:
mysqldump -h 127.0.0.1 -P 3307 -u backup_user -p database_name,不能依赖
localhost自动走 socket 若报
Can't connect to local MySQL server through socket,说明
mysqldump尝试走 Unix socket 但路径不对,加
-h 127.0.0.1强制走 TCP 即可绕过
恢复时执行 source
报错 Unknown command
或 ERROR 1046 (3D000): No database selected
这是 SQL 文件中缺少
USE database_name;或导入方式不匹配导致的典型问题。直接在 MySQL 客户端里用
source执行 dump 文件,要求文件本身包含数据库上下文,否则会找不到目标库。
mysqldump默认不写
USE语句,除非加了
--databases参数;恢复前必须手动选库:
mysql -u user -p<br>mysql> USE target_db;<br>mysql> source /path/to/backup.sql;更稳妥的方式是跳过客户端交互,用管道直接导入:
mysql -u user -p target_db < backup.sql此时
target_db作为命令行参数传入,无需 SQL 文件内含
USE如果 dump 文件由
mysqldump --all-databases生成,则必须用
mysql -u user -p (不带库名),且目标 MySQL 实例不能有同名系统库冲突(如已存在 <code>information_schema会被跳过,但自定义库可能被覆盖)
时间点恢复(PITR)中 mysqlbinlog
解析失败或跳过事务
二进制日志(binlog)是实现增量恢复的关键,但解析过程极易因格式、权限、时间精度等问题中断或遗漏关键事件。
确保 MySQL 启用了 binlog 且格式为ROW(
binlog_format = ROW),
STATEMENT格式在某些函数(如
NOW()、
UUID())下无法精确重放
mysqlbinlog需要读取原始 binlog 文件,MySQL 用户必须对文件有读权限;若 binlog 存在远程服务器上,需先
scp下来再解析,不能直接
mysqlbinlog mysql://...定位起始位置时别只看
datetime:同一秒内可能有多个事件,应结合
position精确定位,例如:
mysqlbinlog --start-datetime="2024-05-20 14:23:00" --stop-position=123456789 mysql-bin.000001 > pitr.sql恢复前务必验证 SQL 内容:
head -n 20 pitr.sql确认开头是
SET @@SESSION.GTID_NEXT或
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;等合法头,避免截断或编码损坏
使用 mysqlpump
或 mydumper
时并发导出报错 Lock wait timeout exceeded
这类工具默认启用并行导出,但未适配长事务或高锁竞争场景,容易与业务写入冲突。
mysqlpump的
--single-transaction是默认开启的,但仅对 InnoDB 有效;若库中混用 MyISAM 表,仍会触发全局读锁,导致超时 —— 应提前确认存储引擎:
SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'db_name';降低并发数是最直接的缓解方式:
mysqlpump --default-parallelism=2 --single-transaction db_name,而非默认的 4 或更高
mydumper需额外注意
--trx-consistency-only和
--no-locks的区别:前者仍尝试一致性快照,后者完全跳过锁,适用于只读从库,但主库用它可能导出非一致状态 若业务无法接受任何锁,考虑在低峰期用
FLUSH TABLES WITH READ LOCK+
SHOW MASTER STATUS手动配合物理拷贝,但要求停写,适合小库快速切换
实际操作中最容易被忽略的是 binlog 的清理策略与备份周期的对齐 —— 如果
expire_logs_days = 3,但全量备份每周一次,那周三做的备份就无法支撑到下周二的 PITR。这点不提前校验,恢复时才发现 binlog 已被 purge,就只能接受数据丢失。
