空库备份需用 mysqldump --no-data --databases --default-character-set=utf8mb4 显式导出建库语句和空表结构,避免漏库、乱码及权限缺失;PHP 中须用 escapeshellarg() 防注入,并单独处理 GRANT 权限。

PHP 创建数据库后立刻备份空库,为什么不能直接 mysqldump?
因为 mysqldump 默认只导出「有数据的表」,如果刚建库、还没建表或表为空,执行 mysqldump -d(仅结构)又不带 --no-create-db 时,可能漏掉 CREATE DATABASE 语句;而带 --create-options 又可能混入引擎/字符集冗余参数,导致还原失败。空库备份的关键不是“有没有数据”,而是“结构定义是否可完整重建库+权限上下文”。
用 PHP 调用 mysqldump 备份空库的 3 个必要参数
必须显式控制三件事:强制输出建库语句、确保导出空表结构、避免依赖当前连接的默认库上下文。推荐组合如下:
-
mysqldump --no-data --skip-triggers --skip-routines --skip-events --databases:强制包含CREATE DATABASE IF NOT EXISTS和USE,且不导任何数据或逻辑对象 - 务必指定
--databases(复数形式),否则mysqldump db1不会输出CREATE DATABASE,还原时需手动建库 - 加上
--default-character-set=utf8mb4,避免服务端默认字符集与客户端不一致导致注释或库名乱码
PHP 中安全调用 mysqldump 的写法(非 exec 简单拼接)
直接拼接 $dbname 到命令行有 SQL 注入风险(库名含破折号、空格、特殊字符时失败甚至被利用)。正确做法是用 escapeshellarg() 包裹,并检查返回值:
$dumpCmd = sprintf(
'mysqldump --no-data --skip-triggers --skip-routines --skip-events --databases %s --default-character-set=utf8mb4 -u %s -p%s %s > %s',
escapeshellarg($dbname),
escapeshellarg($user),
escapeshellarg($pass),
escapeshellarg($dbname),
escapeshellarg($backupPath)
);
$result = shell_exec($dumpCmd . ' 2>&1');
if (strpos($result, 'ERROR') !== false || !file_exists($backupPath)) {
throw new RuntimeException('mysqldump failed: ' . $result);
}
注意:-p 后直接跟密码虽方便,但会暴露在进程列表里;生产环境建议改用配置文件(--defaults-extra-file=/path/to/my.cnf)。
立即学习“PHP免费学习笔记(深入)”;
空库备份后还原时最容易忽略的权限问题
备份文件里只有 CREATE DATABASE 和 CREATE TABLE,不含 GRANT。如果原库绑定了特定用户(如 'app'@'localhost'),还原后该用户无法访问——因为 mysqldump 默认不导权限。需要额外用 mysql -e "SHOW GRANTS FOR 'app'@'localhost';" 单独导出并还原,或在建库后手动执行 GRANT ... ON `mydb`.* TO ...。这点在自动化部署脚本中常被跳过,结果应用连不上空库。











