温馨提示×

ubuntu php如何备份与恢复数据

小樊
41
2025-12-10 13:57:13
栏目: 编程语言

Ubuntu PHP 项目备份与恢复实操指南

一 备份范围与策略

  • 数据库:优先使用 mysqldump 导出为 .sql.sql.gz,便于迁移与版本控制。
  • 代码与静态资源:打包网站根目录(含 public/、vendor/、storage/ 等),建议用 tar.gzzip
  • 配置与密钥:备份 Nginx/Apache 配置PHP 配置 php.ini、项目 .env/.htaccess/config.php 等敏感文件。
  • 系统级快照:对系统盘做镜像或快照(如 Timeshift/Clonezilla/dd),用于灾难恢复。
  • 保留与异地:按时间保留历史(如近 7 天),并同步到 远程/云存储 提升可靠性。

二 方法一 纯 PHP 脚本备份与恢复(适合共享主机或无 CLI 场景)

  • 备份思路
    • 文件:用 RecursiveDirectoryIterator + ZipArchive 递归打包站点目录。
    • 数据库:用 mysqli 生成 CREATE/INSERT 语句,导出为 .sql;导入前写入 SET FOREIGN_KEY_CHECKS=0; 避免外键冲突。
    • 安全:对备份包用 AES-256-CBC 加密,密钥与脚本分离保存。
    • 自动化:用 crontab 定时执行,记录日志,并清理 7 天 前备份。
  • 示例脚本(backup.php,按需修改路径与数据库信息)
<?php
declare(strict_types=1);
set_time_limit(300);

$backupRoot = '/var/backups/myproj';
$webRoot   = '/var/www/myproj';
$dbHost    = 'localhost';
$dbUser    = 'dbuser';
$dbPass    = 'dbpass';
$dbName    = 'mydb';

$ts   = date('Y-m-d_H-i-s');
$out  = "$backupRoot/{$ts}.zip";
$sql  = "$backupRoot/{$ts}.sql";
$log  = "$backupRoot/backup.log";

function logMsg(string $msg): void {
    global $log;
    file_put_contents($log, date('c') . " $msg\n", FILE_APPEND | LOCK_EX);
}

// 1) 打包文件
$zip = new ZipArchive();
if ($zip->open($out, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
    logMsg("无法创建 ZIP: $out");
    exit(1);
}
$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($webRoot, FilesystemIterator::SKIP_DOTS),
    RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($iterator as $file) {
    if (!$file->isDir()) {
        $zip->addFile($file->getRealPath(), substr($file->getRealPath(), strlen($webRoot) + 1));
    }
}
$zip->close();
chmod($out, 0600);
logMsg("已打包: $out");

// 2) 导出数据库
$cmd = sprintf(
    'mysqldump -h%s -u%s -p%s --single-transaction --routines --triggers --default-character-set=utf8mb4 %s > %s 2>&1',
    escapeshellarg($dbHost), escapeshellarg($dbUser), escapeshellarg($dbPass), escapeshellarg($dbName), escapeshellarg($sql)
);
exec($cmd, $outLines, $ret);
if ($ret !== 0) {
    logMsg("导出数据库失败: " . implode("\n", $outLines));
    exit(1);
}
chmod($sql, 0600);
logMsg("已导出: $sql");

// 3) 可选:加密备份(密钥单独保管)
$keyFile = "$backupRoot/backup.key";
if (!file_exists($keyFile)) {
    $key = random_bytes(32);
    file_put_contents($keyFile, $key, LOCK_EX);
    chmod($keyFile, 0600);
}
$enc = "$out.enc";
$cmd = "openssl enc -aes-256-cbc -salt -in " . escapeshellarg($out) . " -out " . escapeshellarg($enc) . " -pass file:" . escapeshellarg($keyFile) . " 2>&1";
exec($cmd, $outLines, $ret);
if ($ret === 0) {
    unlink($out);
    logMsg("已加密: $enc");
} else {
    logMsg("加密失败: " . implode("\n", $outLines));
}
  • 定时任务(crontab -e)
    • 每天 02:00 执行:0 2 * * * /usr/bin/php /var/backups/myproj/backup.php
  • 恢复脚本要点(restore.php,先解密再导入)
    • 解密:openssl enc -d -aes-256-cbc -in backup-2025-12-10_02-00-00.zip.enc -out backup.zip -pass file:/var/backups/myproj/backup.key
    • 解压:unzip backup.zip -d /var/www/myproj
    • 导入:先 mysql -u$dbUser -p$dbPass -e "DROP DATABASE IF EXISTS $dbName; CREATE DATABASE $dbName CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;",再 mysql -u$dbUser -p$dbPass $dbName < backup.sql
    • 注意外键:导入前 SET FOREIGN_KEY_CHECKS=0;,导入后 SET FOREIGN_KEY_CHECKS=1;

三 方法二 命令行与系统工具备份恢复(推荐,性能与可靠性更佳)

  • 数据库备份与恢复
    • 备份:mysqldump -u root -p --single-transaction --routines --triggers --default-character-set=utf8mb4 mydb > /backups/mydb_$(date +%F).sql
    • 压缩:gzip /backups/mydb_$(date +%F).sql
    • 恢复:mysql -u root -p mydb < /backups/mydb_2025-12-10.sql;若压缩:gunzip < /backups/mydb_2025-12-10.sql.gz | mysql -u root -p mydb
  • 文件与配置备份
    • 站点文件:tar -czvf /backups/files_$(date +%F).tar.gz -C /var/www/myproj .
    • PHP 配置:php --ini | grep "Loaded Configuration File" | awk '{print $4}' | xargs -I {} sudo cp {} {}.bak_$(date +%F)
    • Nginx 配置:sudo tar -czvf /backups/nginx_$(date +%F).tar.gz /etc/nginx /etc/php/$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')/fpm/php.ini
  • 自动化与远程
    • 定时:0 2 * * * /usr/bin/mysqldump -u root -p'******' mydb | gzip > /backups/mydb_$(date +\%F).sql.gz
    • 异地:rsync -avz /backups/ user@backup.example.com:/backups/scp /backups/mydb_2025-12-10.sql.gz user@backup.example.com:/backups/
  • 系统级快照
    • Timeshiftsudo apt install timeshift → 图形/命令行向导选择 RSYNC/BTRFS → 设置计划任务 → 需要时选择还原点恢复。
    • Clonezilla/dd:用于整盘镜像级备份与恢复。

四 恢复流程与验证清单

  • 准备:确认目标环境 PHP 版本扩展数据库版本 与备份时一致;准备 .env 与密钥文件。
  • 恢复顺序:先数据库后代码;导入前临时关闭外键检查,导入后恢复。
  • 权限与所有权:站点目录按 Web 服务用户设置(如 www-data:www-data),备份文件权限 0600
  • 基本验证:登录数据库检查表数量与关键数据;访问站点首页与后台;抽查上传文件与日志。
  • 回滚预案:保留最近 1–2 个可用备份;恢复失败立即切回旧版本并排查。

五 安全与运维要点

  • 最小权限:数据库备份用户仅授予 SELECT/SHOW VIEW/LOCK TABLES/TRIGGER 等必要权限。
  • 凭据安全:避免在代码中硬编码密码;密钥与备份分离,限制备份目录访问。
  • 加密与传输:敏感备份使用 AES-256 加密;跨公网传输用 scp/rsync over SSH
  • 监控与告警:记录日志并接入监控/告警;定期做 恢复演练 验证可用性。
  • 版本与兼容:记录 MySQL/MariaDB、PHP、Nginx/Apache 版本;跨大版本恢复前先小范围测试。

0