功能特性
- 自動遍歷資料庫所有資料表
- 匯出
CREATE TABLE 結構定義
- 匯出所有資料為
INSERT 語句
- 自動命名備份檔:
YYYYMMDD.sql
- UTF-8 編碼支援
完整程式碼(mysqli 重構版)
<?php
/**
* MySQL 資料庫完整備份腳本
* 輸出:YYYYMMDD.sql 包含結構與資料
*/
// ===== 設定區 =====
$host = 'localhost';
$user = 'root';
$pass = '';
$dbname = 'your_database';
$charset = 'utf8mb4';
// ===================
$mysqli = new mysqli($host, $user, $pass, $dbname);
if ($mysqli->connect_errno) {
die('連線失敗: ' . $mysqli->connect_error);
}
$mysqli->set_charset($charset);
$sql = "SET NAMES $charset;\r\n\r\n";
// 取得所有資料表
$tablesResult = $mysqli->query("SHOW TABLES");
if (!$tablesResult) {
die('SHOW TABLES 失敗: ' . $mysqli->error);
}
while ($tableRow = $tablesResult->fetch_array(MYSQLI_NUM)) {
$table = $tableRow[0];
// 1. 匯出表結構
$createResult = $mysqli->query("SHOW CREATE TABLE `$table`");
if ($createResult) {
$createRow = $createResult->fetch_assoc();
$sql .= $createRow['Create Table'] . ";\r\n\r\n";
$createResult->free();
}
// 2. 匯出資料
$dataResult = $mysqli->query("SELECT * FROM `$table`");
if ($dataResult && $dataResult->num_rows > 0) {
$fields = [];
while ($field = $dataResult->fetch_field()) {
$fields[] = '`' . $field->name . '`';
}
$fieldList = implode(', ', $fields);
while ($row = $dataResult->fetch_assoc()) {
$values = [];
foreach ($row as $val) {
if ($val === null) {
$values[] = 'NULL';
} else {
$values[] = "'" . $mysqli->real_escape_string($val) . "'";
}
}
$sql .= "INSERT INTO `$table` ($fieldList) VALUES (" . implode(', ', $values) . ");\r\n";
}
$dataResult->free();
}
$sql .= "\r\n";
}
$tablesResult->free();
// 寫入檔案
$filename = date('Ymd') . '.sql';
$fp = fopen($filename, 'w');
fwrite($fp, $sql);
fclose($fp);
$mysqli->close();
echo "備份成功!檔案:$filename (" . number_format(strlen($sql) / 1024, 2) . " KB)";
?>
關鍵改進說明
| 原版問題 | 改進方案 |
使用已棄用 mysql_* 函數 | 全面改用 mysqli 物件導向介面 |
| 無字元集設定,中文易亂碼 | 明確 SET NAMES utf8mb4 + set_charset |
| 手動組合欄位名,易出錯 | 使用 fetch_field() 取得標準欄位名 |
| NULL 值處理不當 | 明確判斷 null 輸出 NULL 而非空字串 |
| 無錯誤處理與資源釋放 | 完整錯誤檢查、free() 釋放結果集 |
| 單一巨大字串佔記憶體 | 大型資料庫建議改用檔案流式寫入 |
生產環境強化建議
- 分檔備份:每表一個 .sql 檔,壓縮打包
- 單一事務一致性備份:加入
--single-transaction 邏輯(需 InnoDB)
- 排除不需備份的表:如 log、cache、session 表
- 上傳至異地儲存:S3、FTP、NAS 等
- 定時任務:
crontab -e → 0 2 * * * /usr/bin/php /path/backup.php
- 驗證機制:定期測試還原,確保備份可用性
還原方式
# 命令列還原
mysql -u root -p dbname < 20240115.sql
# 或 PHP 執行
$mysqli->multi_query(file_get_contents('20240115.sql'));