You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PHP将MySQL数据库定期备份至另一数据库?

当然可以用PHP实现跨数据库的定期备份!如果之前导出SQL文件的方式不符合需求,直接把源数据库的数据同步到目标数据库会是更贴合的方案。我之前做过类似的需求,下面给你详细的实现思路和代码示例:

核心实现逻辑

要完成这个备份,核心是同时连接源数据库和目标数据库,然后分两步同步:

  • 同步表结构(如果目标库还没有对应表,或者需要更新结构的话)
  • 同步表数据(支持全量覆盖或增量更新,根据你的需求选择)
具体代码示例

下面是一个基于mysqli扩展的完整实现,你可以根据自己的数据库配置调整:

<?php
// 源数据库配置
$sourceConfig = [
    'host' => 'localhost',
    'user' => 'source_user',
    'pass' => 'source_password',
    'db' => 'source_database'
];

// 目标数据库配置
$targetConfig = [
    'host' => 'remote_host', // 可以是本地或远程服务器
    'user' => 'target_user',
    'pass' => 'target_password',
    'db' => 'target_database'
];

// 连接源数据库
$sourceConn = new mysqli($sourceConfig['host'], $sourceConfig['user'], $sourceConfig['pass'], $sourceConfig['db']);
if ($sourceConn->connect_error) {
    die("源数据库连接失败: " . $sourceConn->connect_error);
}

// 连接目标数据库
$targetConn = new mysqli($targetConfig['host'], $targetConfig['user'], $targetConfig['pass'], $targetConfig['db']);
if ($targetConn->connect_error) {
    die("目标数据库连接失败: " . $targetConn->connect_error);
}

// 获取源数据库所有表
$tablesResult = $sourceConn->query("SHOW TABLES");
if (!$tablesResult) {
    die("获取源表列表失败: " . $sourceConn->error);
}

// 逐个处理每个表
while ($tableRow = $tablesResult->fetch_row()) {
    $tableName = $tableRow[0];
    echo "开始处理表: {$tableName}\n";

    // 1. 同步表结构:获取源表的创建语句,在目标库执行(如果表不存在)
    $createTableResult = $sourceConn->query("SHOW CREATE TABLE `{$tableName}`");
    $createRow = $createTableResult->fetch_assoc();
    $createSql = str_replace($sourceConfig['db'], $targetConfig['db'], $createRow['Create Table']);
    // 改为CREATE TABLE IF NOT EXISTS,避免表已存在时报错
    $createSql = preg_replace('/^CREATE TABLE/', 'CREATE TABLE IF NOT EXISTS', $createSql);
    
    if (!$targetConn->query($createSql)) {
        echo "同步表结构失败({$tableName}): " . $targetConn->error . "\n";
        continue;
    }

    // 2. 同步表数据:全量覆盖(先清空目标表,再插入),如果需要增量可以用INSERT...ON DUPLICATE KEY UPDATE
    // 先清空目标表(可选,如果你需要全量备份的话)
    if (!$targetConn->query("TRUNCATE TABLE `{$tableName}`")) {
        echo "清空目标表失败({$tableName}): " . $targetConn->error . "\n";
        continue;
    }

    // 获取源表数据
    $dataResult = $sourceConn->query("SELECT * FROM `{$tableName}`");
    if (!$dataResult) {
        echo "获取源表数据失败({$tableName}): " . $sourceConn->error . "\n";
        continue;
    }

    $columnCount = $dataResult->field_count;
    if ($columnCount === 0) {
        echo "表{$tableName}无字段,跳过\n";
        continue;
    }

    // 生成插入语句的占位符
    $placeholders = implode(',', array_fill(0, $columnCount, '?'));
    $insertSql = "INSERT INTO `{$tableName}` VALUES ({$placeholders})";
    $stmt = $targetConn->prepare($insertSql);
    if (!$stmt) {
        echo "预处理语句失败({$tableName}): " . $targetConn->error . "\n";
        continue;
    }

    // 批量插入数据
    $rowCount = 0;
    while ($row = $dataResult->fetch_row()) {
        // 绑定参数并执行
        $params = array_merge([str_repeat('s', $columnCount)], $row);
        $refParams = [];
        foreach ($params as $key => $val) {
            $refParams[$key] = &$params[$key];
        }
        call_user_func_array([$stmt, 'bind_param'], $refParams);
        
        if (!$stmt->execute()) {
            echo "插入数据失败({$tableName}): " . $stmt->error . "\n";
            continue;
        }
        $rowCount++;
    }

    echo "表{$tableName}同步完成,共插入{$rowCount}条数据\n";
    $stmt->close();
}

// 关闭连接
$sourceConn->close();
$targetConn->close();
echo "所有表同步完成!\n";
?>
定期执行方案

要实现定期自动备份,你需要借助系统的定时任务工具:

  • Linux/macOS:使用crontab。比如每天凌晨2点执行脚本,编辑crontab:

    crontab -e
    

    添加一行:

    0 2 * * * /usr/bin/php /path/to/your/backup_script.php >> /path/to/backup_log.log 2>&1
    

    这样每天凌晨2点会自动执行脚本,并把日志输出到指定文件。

  • Windows:使用「任务计划程序」。创建一个新任务,设置触发时间(比如每天凌晨2点),操作选择启动程序,程序路径选你的PHP.exe路径,参数填脚本的绝对路径。

注意事项
  • 权限问题:确保源数据库用户有SELECT权限,目标数据库用户有CREATE、INSERT、TRUNCATE(如果用全量覆盖)权限。
  • 大表处理:如果你的表数据量很大,上面的代码一次性读取所有数据可能会导致内存溢出。可以改成分批读取,比如用LIMIT offset, 1000循环读取直到没有数据。
  • 增量备份:如果不需要全量覆盖,而是只同步新增/更新的数据,可以在源表加一个update_time字段,每次备份只同步update_time大于上次备份时间的数据,或者用INSERT ... ON DUPLICATE KEY UPDATE来处理更新。
  • 日志记录:建议在脚本中添加详细的日志记录(比如写入文件),方便出现问题时排查。
  • 事务支持:如果需要保证数据一致性,可以在同步数据时开启事务,比如在清空表和插入数据前后加上$targetConn->begin_transaction()和$targetConn->commit(),出错时回滚。

内容的提问来源于stack exchange,提问作者Rajeev Khulbe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:09:08