首页主机资讯Ubuntu PHP如何实现备份恢复

Ubuntu PHP如何实现备份恢复

时间2025-12-18 21:53:03发布访客分类主机资讯浏览394
导读:Ubuntu PHP 备份与恢复实操指南 一 备份范围与策略 建议将备份划分为三层: 代码与资源(网站根目录,如 /var/www/html); 数据库(如 MySQL/MariaDB,使用 mysqldump 导出为 .sql); P...

Ubuntu PHP 备份与恢复实操指南

一 备份范围与策略

  • 建议将备份划分为三层:
    1. 代码与资源(网站根目录,如 /var/www/html);
    2. 数据库(如 MySQL/MariaDB,使用 mysqldump 导出为 .sql);
    3. PHP 与运行时配置(如 php.ini、PHP-FPM 配置)。
  • 存储与保留:至少保留7天历史,备份文件权限设为600,并同步到异地/云存储
  • 自动化:用 crontab 定时执行备份脚本,并记录日志便于审计与回滚。

二 用 PHP 实现一键备份与恢复

  • 备份脚本 backup.php(示例)

    • 功能:打包网站目录 + 导出数据库 + 可选 AES-256-CBC 加密 + 保留7天 + 写日志。
    • 使用:将脚本放到网站可写目录(如 /var/www/html/tools/),通过 CLI 执行:/usr/bin/php /var/www/html/tools/backup.php
    • 注意:Web 访问需做访问控制权限校验,避免被滥用。
    <
        ?php
    // 配置区
    $backupRoot = '/var/backups/php_site';
                    // 备份根目录(确保可写)
    $wwwRoot   = '/var/www/html';
                            // 网站根目录
    $dbHost    = 'localhost';
        
    $dbName    = 'your_db';
        
    $dbUser    = 'your_user';
        
    $dbPass    = 'your_password';
        
    $keepDays  = 7;
        
    $encrypt   = true;
                                       // 是否加密
    $cipher    = 'aes-256-cbc';
        
    
    // 初始化
    date_default_timezone_set('Asia/Shanghai');
        
    set_time_limit(300);
        
    if (!is_dir($backupRoot)) mkdir($backupRoot, 0700, true);
        
    $ts   = date('Ymd_His');
        
    $log  = "$backupRoot/backup_$ts.log";
        
    $zip  = "$backupRoot/site_$ts.zip";
        
    $sql  = "$backupRoot/db_$ts.sql";
        
    $enc  = "$zip.enc";
    
    
    function logMsg($msg, $log) {
         file_put_contents($log, date('Y-m-d H:i:s') . " $msg\n", FILE_APPEND);
     }
        
    
    // 1) 打包网站文件
    $zipOk = false;
    
    if (class_exists('ZipArchive')) {
        
        $zipArc = new ZipArchive();
        
        if ($zipArc->
    open($zip, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
        
            $files = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($wwwRoot, FilesystemIterator::SKIP_DOTS),
                RecursiveIteratorIterator::LEAVES_ONLY
            );
    
            foreach ($files as $file) {
        
                if (!$file->
    isDir()) {
        
                    $filePath = $file->
        getRealPath();
        
                    $relativePath = substr($filePath, strlen($wwwRoot) + 1);
        
                    $zipArc->
        addFile($filePath, $relativePath);
    
                }
    
            }
        
            $zipOk = $zipArc->
        close();
    
        }
    
    }
        
    logMsg($zipOk ? "ZIP created: $zip" : "ZIP failed", $log);
        
    
    // 2) 导出数据库
    $dumpOk = false;
        
    $cmd = sprintf(
        'mysqldump --single-transaction --routines --triggers --default-character-set=utf8mb4 -h%s -u%s -p%s %s >
         %s 2>
        >
        %s',
        escapeshellarg($dbHost), escapeshellarg($dbUser), escapeshellarg($dbPass), escapeshellarg($dbName), $sql, $log
    );
        
    system($cmd, $ret);
        
    $dumpOk = ($ret === 0);
        
    logMsg($dumpOk ? "DB dumped: $sql" : "DB dump failed", $log);
        
    
    // 3) 可选加密
    $finalArchive = $zip;
        
    if ($encrypt &
        &
     $zipOk) {
        
        $key = random_bytes(32);
         // 生产环境请安全保存此密钥
        $iv  = random_bytes(16);
        
        $data = file_get_contents($zip);
        
        $encData = openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv);
        
        file_put_contents($enc, $iv . $encData);
        
        $finalArchive = $enc;
        
        @unlink($zip);
        
        logMsg("Encrypted ->
         $enc", $log);
    
    }
    
    
    // 4) 清理过期
    $files = glob("$backupRoot/*.{
    zip,sql,enc,log}
        ", GLOB_BRACE);
    
    foreach ($files as $f) {
        
        if (filemtime($f) <
     time() - $keepDays * 86400) {
        
            @unlink($f);
        
            logMsg("Removed expired: $f", $log);
    
        }
    
    }
        
    
    echo "Backup finished. See $log\n";
        
    
  • 恢复脚本 restore.php(示例)

    • 功能:解密(如有)-> 解压覆盖 -> 导入 .sql
    • 使用:将备份包与脚本上传至服务器,执行:/usr/bin/php /var/www/html/tools/restore.php /var/backups/php_site/site_YYYYMMDD_HHIISS.zip[.enc]
    <
        ?php
    // 配置区(与备份端一致)
    $wwwRoot   = '/var/www/html';
        
    $dbHost    = 'localhost';
        
    $dbName    = 'your_db';
        
    $dbUser    = 'your_user';
        
    $dbPass    = 'your_password';
        
    $cipher    = 'aes-256-cbc';
        
    
    date_default_timezone_set('Asia/Shanghai');
        
    set_time_limit(600);
    
    
    function logMsg($msg, $log) {
         file_put_contents($log, date('Y-m-d H:i:s') . " $msg\n", FILE_APPEND);
     }
        
    
    if ($argc <
         2) die("Usage: php restore.php <
        backup.zip|backup.zip.enc>
        \n");
        
    $archive = $argv[1];
        
    $log     = dirname($archive) . '/restore_' . date('Ymd_His') . '.log';
        
    
    // 1) 解密
    $work = $archive;
    
    if (pathinfo($archive, PATHINFO_EXTENSION) === 'enc') {
        
        $key = '';
         // 从安全位置读取密钥(不要硬编码在代码中)
        if (empty($key) || strlen($key) !== 32) die("Missing or invalid 32-byte key.\n");
        
        $data = file_get_contents($archive);
        
        $iv   = substr($data, 0, 16);
        
        $enc  = substr($data, 16);
        
        $dec  = openssl_decrypt($enc, $cipher, $key, OPENSSL_RAW_DATA, $iv);
        
        if ($dec === false) die("Decrypt failed.\n");
        
        $work = $archive . '.dec.zip';
        
        file_put_contents($work, $dec);
        
        logMsg("Decrypted ->
         $work", $log);
    
    }
        
    
    // 2) 解压覆盖
    $zip = new ZipArchive();
        
    if ($zip->
        open($work) !== TRUE) die("Cannot open archive: $work\n");
        
    if (!$zip->
        extractTo($wwwRoot)) die("Extract failed.\n");
        
    $zip->
        close();
        
    logMsg("Extracted to $wwwRoot", $log);
        
    if ($work !== $archive) @unlink($work);
        
    
    // 3) 导入数据库(查找同目录 .sql)
    $sqlFile = null;
    
    foreach (glob(dirname($archive) . '/*.sql') as $f) {
        
        if (time() - filemtime($f) <
     86400 * 2) {
         $sqlFile = $f;
         break;
     }
     // 取最近
    }
        
    if (!$sqlFile) die("No .sql found near $archive\n");
        
    $cmd = sprintf(
        'mysql --default-character-set=utf8mb4 -h%s -u%s -p%s %s <
         %s 2>
        >
        %s',
        escapeshellarg($dbHost), escapeshellarg($dbUser), escapeshellarg($dbPass), escapeshellarg($dbName), $sqlFile, $log
    );
        
    system($cmd, $ret);
        
    logMsg($ret === 0 ? "DB imported: $sqlFile" : "DB import failed", $log);
        
    
    echo "Restore finished. See $log\n";
    
    
  • 定时任务(crontab)

    • 示例:每日 02:00 执行备份,保留 7天,日志与备份统一目录
    • 命令:0 2 * * * /usr/bin/php /var/www/html/tools/backup.php
    • 建议将备份目录加入 /etc/backup.include.gitignore,避免被代码仓库误提交。

三 系统级备份与恢复 PHP 配置

  • 定位配置文件
    • 查看加载的 php.iniphp --ini
    • 常见路径(按 SAPI 与版本区分):
      • CLI:/etc/php/{ 版本号} /cli/php.ini
      • FPM:/etc/php/{ 版本号} /fpm/php.ini/etc/php/{ 版本号} /fpm/pool.d/*.conf
      • Apache:/etc/php/{ 版本号} /apache2/php.ini
  • 备份
    • 打包:sudo tar -czvf php-fpm-backup-$(date +%Y%m%d).tar.gz /etc/php/*/fpm/php-fpm.conf /etc/php/*/fpm/pool.d/ /etc/php/*/fpm/php.ini
    • 或 rsync:sudo rsync -av --progress /etc/php /path/to/backup/php/
  • 恢复
    • 建议先停服务:sudo systemctl stop php{ 版本号} -fpm
    • 解压:sudo tar -xzvf php-fpm-backup-YYYYMMDD.tar.gz -C /
    • 或 rsync:sudo rsync -av --progress /path/to/backup/php/ /etc/php/
    • 启动:sudo systemctl start php{ 版本号} -fpm
  • 版本控制与异地同步
    • 对配置目录做 Git 版本管理,记录每次变更与回滚点。
    • rsync+SSH 将配置同步到远程主机,提升容灾能力。

四 数据库备份恢复与运维要点

  • 数据库备份与恢复
    • 备份:mysqldump -u root -p --single-transaction --routines --triggers --default-character-set=utf8mb4 your_db > backup.sql
    • 恢复:mysql -u root -p your_db < backup.sql
    • 图形化:也可通过 phpMyAdmin 的“导出/导入”完成。
  • 安全与合规
    • 备份文件权限设为 600,存放于受限目录;加密敏感备份,密钥离线保存
    • 恢复前在测试环境验证;导入前可临时关闭外键检查:SET FOREIGN_KEY_CHECKS=0; (导入后恢复为 1)。
  • 系统级灾难恢复
    • 系统镜像:用 Timeshift(BTRFS/RSYNC)或 Clonezilla 做整盘快照/镜像,系统无法启动时可用 Live USB 进入恢复。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: Ubuntu PHP如何实现备份恢复
本文地址: https://pptw.com/jishu/775541.html
Ubuntu PHP如何实现GraphQL查询 Ubuntu PHP如何解决错误

游客 回复需填写必要信息