雖然 Windows 2003 已停止支援,但存量系統仍在運行。本文提供 PHP 調用 mysqldump、BAT 腳本封裝、計劃任務部署、舊備份自動清理的完整落地方案。
[Windows 計劃任務]
↓ (排程觸發)
[backup.bat]
↓ (調用)
[php.exe backup.php 數據庫名 保留天數]
↓ (執行)
[mysqldump --no-defaults -u root -p*** db > backup_YYYYMMDD_db.sql]
↓ (清理)
[刪除 N 天前備份檔案]
<?php
/**
* MySQL 備份腳本
* 參數:$argv[1] = 數據庫名,$argv[2] = 保留天數
* 依賴:mysqldump 在系統 PATH 中,或指定完整路徑
*/
if ($argc < 3) {
die("Usage: php backup.php \n");
}
$dbName = $argv[1];
$retentionDays = (int)$argv[2];
// 配置區 (建議改為配置檔)
$config = [
'mysql_dump' => 'mysqldump', // 或完整路徑:'C:\wamp\bin\mysql\mysql5.6.17\bin\mysqldump.exe'
'host' => 'localhost',
'user' => 'root',
'pass' => 'your_password', // ⚠️ 生產環境請用配置檔/環境變數
'backup_dir' => 'E:/wamp/db_backup/',
'charset' => 'utf8',
];
// 1. 確保備份目錄存在
if (!is_dir($config['backup_dir'])) {
mkdir($config['backup_dir'], 0755, true);
}
// 2. 清理過期備份
$oldFile = $config['backup_dir'] . date('Ymd', strtotime("-{$retentionDays} days")) . $dbName . '.sql';
if (file_exists($oldFile)) {
unlink($oldFile);
echo "已刪除過期備份: {$oldFile}\n";
}
// 3. 執行備份
$dateStr = date('Ymd');
$backupFile = $config['backup_dir'] . $dateStr . $dbName . '.sql';
// 構建 mysqldump 命令
// --no-defaults: 忽略配置檔 (避免密碼洩露/編碼問題)
// --single-transaction: InnoDB 熱備份不鎖表 (關鍵!)
// --quick: 大表分批讀取,減少記憶體
$cmd = sprintf(
'"%s" --no-defaults -h%s -u%s -p%s --single-transaction --quick --default-character-set=%s %s > "%s" 2>&1',
$config['mysql_dump'],
$config['host'],
$config['user'],
$config['pass'],
$config['charset'],
$dbName,
$backupFile
);
echo "執行備份命令: {$cmd}\n";
exec($cmd, $output, $returnVar);
if ($returnVar !== 0) {
$error = implode("\n", $output);
error_log("備份失敗 [{$dbName}]: {$error}");
die("備份失敗,返回碼: {$returnVar}\n");
}
echo "備份成功: {$backupFile} (" . filesize($backupFile) . " bytes)\n";
?>
@echo off
REM ===== 配置區 =====
SET PHP_EXE=E:\wamp\php5.4.44\php.exe
SET BACKUP_PHP=E:\wamp\backup.php
SET DB_NAME=zzy
SET RETENTION_DAYS=30
REM ===================
echo [%date% %time%] 開始備份 %DB_NAME%...
"%PHP_EXE%" "%BACKUP_PHP%" %DB_NAME% %RETENTION_DAYS%
IF %ERRORLEVEL% NEQ 0 (
echo [%date% %time%] 備份失敗,錯誤碼 %ERRORLEVEL%
) ELSE (
echo [%date% %time%] 備份完成
)
backup.bat# 方案 A:my.cnf / my.ini [client] 區段 [client] user=backup_user password=secure_password # PHP 中使用 --defaults-extra-file $cmd = '"mysqldump" --defaults-extra-file="E:/wamp/backup.cnf" ...'; # 方案 B:環境變數 (Windows 系統屬性 → 環境變數) # 系統變數:MYSQL_PWD=secure_password # mysqldump 會自動讀取 (不安全,進程列表可見) # 方案 C:專用備份用戶,最小權限 GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON `db`.* TO 'backup_user'@'localhost' IDENTIFIED BY 'strong_pass';
# 關鍵參數組合 --single-transaction # InnoDB 一致性快照,不鎖表 (核心) --quick # 不緩衝結果集,直接寫入文件 --max_allowed_packet=1G # 防止大行截斷 --net_buffer_length=1M # 網絡緩衝 --compress # 壓縮傳輸 (遠程備份) --skip-lock-tables # 配合 single-transaction
# PHP 中直接管道壓縮
$cmd = "... | gzip > \"{$backupFile}.gz\"";
# 或備份後壓縮
exec("gzip \"{$backupFile}\"");
# 解壓還原
# gunzip < backup_20240101_db.sql.gz | mysql -u root -p db
# 推送到遠程服務器 scp backup_20240101_db.sql.gz user@backup-server:/backups/mysql/ # 或使用 rsync 增量同步 rsync -avz /local/backup/ user@backup-server:/backups/mysql/ # 雲存儲 (AWS S3 / 阿里云 OSS / 騰訊云 COS) # AWS CLI 範例 aws s3 cp backup_20240101_db.sql.gz s3://my-bucket/mysql-backups/