Class DatabaseBackupService
.sql 並壓成 .zip,
存到專案根目錄下的 Backup/ 資料夾(檔名為 日期_時間.zip,例:2026-05-23_01.58.49.zip)。
實作方式:沿用 DatabaseBootstrap 呼叫外部 mysql.exe 的相同模式,
改呼叫同一個 bin 目錄下的 mysqldump.exe(自動偵測,亦可由 settings.ini 的
MySQL_DumpBin 覆寫)。匯出以單一資料庫模式(mysqldump ... <DB_Name>),輸出的 SQL
僅含該庫的表結構與資料、不含 CREATE DATABASE 與 USE 語句 —— 還原時需先選定
目標資料庫再匯入(例:mysql -u... <DB_Name> < 檔案.sql)。另帶
--single-transaction 對 InnoDB 做一致性快照、不鎖表,故線上備份不影響玩家。
開關與排程:整個功能受 settings.ini 三鍵控制(皆對應
ServerConstants 欄位、可由日後的 GUI 即時調整):
DbBackupEnabled—— 總開關(預設false)。為了讓 GUI 能不重啟即時開關, 排程一律註冊,是否真的執行於每次觸發時依此旗標判定。DbBackupIntervalMinutes—— 幾分鐘備份一次(預設60;<=0表示不排程)。DbBackupKeep—— 最多保留幾份 zip、自動刪除較舊者(0= 不限、全部保留)。
Timer.WorldTimer 上;首次備份於開服後一個間隔才發生(不在開機瞬間搶資源)。
穩健性:backupNow() 以 AtomicBoolean 防止前一次備份未完成時重入;任何例外
只記錄、不向上拋(背景任務不可中斷)。mysqldump 的輸出由 --result-file 直接寫入暫存
.sql(二進位安全、避開 stdout 管線阻塞),壓成 zip 後刪除暫存檔。
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final record單一備份檔的描述(供 GUI 列出可回溯的備份)。 -
Method Summary
Modifier and TypeMethodDescription立即執行一次資料庫備份(供排程與日後 GUI 手動觸發共用)。static DatabaseBackupService取得單例。列出Backup/下所有備份 zip,依檔名時間戳由新到舊排序。voidreschedule(int min) 依新的備份間隔即時重排程(供 GUI 調整DbBackupIntervalMinutes後立即生效,免重啟)。restoreFrom(String name) 從某個既有備份 zip 還原(覆寫)線上資料庫。voidstart()註冊背景備份排程(由server.Start.run()在Timer.WorldTimer啟動後呼叫一次)。
-
Method Details
-
getInstance
取得單例。 -
start
public void start()註冊背景備份排程(由server.Start.run()在Timer.WorldTimer啟動後呼叫一次)。只要
DbBackupIntervalMinutes > 0就會註冊週期任務;是否真的備份於每次觸發時依DbBackupEnabled判定,故 GUI 之後切換開關可不重啟即生效。<=0則完全不排程。 -
reschedule
public void reschedule(int min) 依新的備份間隔即時重排程(供 GUI 調整DbBackupIntervalMinutes後立即生效,免重啟)。若服務尚未
啟動(開機流程還沒跑到註冊排程那步),則直接返回—— 開機流程會以當下的設定自行排程,無需此處介入。- Parameters:
min- 新的備份間隔(分鐘);<= 0表示停用週期備份(僅取消、不再排程)
-
listBackups
列出Backup/下所有備份 zip,依檔名時間戳由新到舊排序。檔名時間戳格式為
yyyy-MM-dd_HH.mm.ss,字典序即時間序,故以檔名遞減排序即「新→舊」。 備份資料夾不存在(尚未產生任何備份)時回傳空清單;個別檔案讀取屬性失敗時略過該筆並記警告。- Returns:
- 備份檔描述清單(新→舊);無備份或資料夾不存在時為空清單
-
backupNow
立即執行一次資料庫備份(供排程與日後 GUI 手動觸發共用)。前一次備份尚未完成時會略過本次並警告一次。任何例外只記錄、不拋出。
- Returns:
- 成功時回傳產生的 zip 路徑;失敗、被略過或設定不全時回傳
null
-
restoreFrom
從某個既有備份 zip 還原(覆寫)線上資料庫。這是破壞性操作:會把目前資料庫的內容換成備份當時的狀態。沿用
DatabaseBootstrap.importSql(String, String, String, String, String, Properties)的「呼叫外部mysql.exe、把 SQL 餵入 stdin、 去除開頭 UTF-8 BOM」流程:自 zip 取出單一.sql(優先<DB_Name>.sql)後匯入目標資料庫。防護:
- 防重疊:與備份共用
running旗標(compareAndSet),任一還原/備份進行中即拒絕本次("busy")。 - 防路徑穿越:僅接受
.zip結尾、不含/ \ ..的純檔名,且解析後的路徑其父目錄須等於Backup/本身(resolve(name).normalize()後比對父目錄),杜絕以檔名跳出備份資料夾。
- Parameters:
name- 備份檔名(須位於Backup/下、以.zip結尾)- Returns:
- 成功回
null;否則回錯誤碼:"busy"(有另一作業進行中)、"badName"(檔名非法/路徑穿越)、"notfound"(檔案不存在)、"noTool"(找不到 mysql.exe)、"badEntry"(zip 內無可用的 .sql)、"importFailed"(匯入失敗或設定不全)
- 防重疊:與備份共用
-