跳转到帖子
在手机APP中查看

一个更好的浏览方法。了解更多

PHP论坛人

主屏幕上的全屏APP,带有推送通知、徽章等。

在iOS和iPadOS上安装此APP
  1. 在Safari中轻敲分享图标
  2. 滚动菜单并轻敲添加到主屏幕
  3. 轻敲右上角的添加按钮。
在安卓上安装此APP
  1. 轻敲浏览器右上角的三个点菜单 (⋮) 。
  2. 轻敲添加到主屏幕安装APP
  3. 轻敲安装进行确认。

恢復現有的論壇 DB資料庫 與 Web網站檔案

精选回复

-------------------------------
適用情境與風險提示
-------------------------------

適用以下情境:

VPS遷移:將論壇從舊VPS搬遷到新VPS(例如,升級規格、更換機房、更換 IDC)。

時間點還原:將論壇還原至某個指定日期的備份(例如,誤刪資料、被攻擊前的乾淨備份)。


還原是高風險操作,會「完全刪除」目前的資料庫與網站檔案。

執行前請務必確認備份來源正確,否則一旦操作失誤將無法復原。






-----------------------
前置準備
-----------------------

備份檔案需求

項目:DB.zip
說明:資料庫備份檔(內含 DB.sql)


項目:Web.zip
說明:網站檔案備份檔





-------------------------------
新VPS環境需求
-------------------------------

新VPS需已完成以下基礎建設(參考本系列先前章節):

Nginx 已安裝並完成虛擬主機(vhost)設定

MariaDB(建議與舊VPS相同大版本,例如皆為 11.8.x)已安裝並完成優化

PHP-FPM(版本需與 Invision Community 相容性需求一致,例如 PHP 8.3)已安裝並完成優化

nftables 防火牆與 Fail2ban 部署

已透過 acme.sh 取得該網域的 TLS 憑證,或已備妥憑證還原方案




-------------------------------
安裝必要工具
-------------------------------


apt update


apt install unzip tmux pv -y


pv 為非必要套件,但在還原大型資料庫時可以提供匯入進度條,方便掌握耗時與確認程序沒有卡住,是維運時的常用小工具。



為什麼要裝 tmux?

還原資料庫與解壓大量網站檔案可能耗時數分鐘到數小時。

若直接在 SSH 連線中執行,一旦網路斷線、SSH 逾時,匯入或解壓程序就會被強制中斷,導致資料庫只匯入一半、網站檔案缺漏,且難以察覺。

這是新手與老手都容易忽略的地雷。



請務必在 tmux(或 screen)工作階段中執行所有還原指令:

tmux new -s restore



之後所有操作都在這個 tmux session 內執行。若 SSH 斷線,可重新連線後執行以下指令接回工作階段:

tmux attach -t restore




----------------------------
資料庫快照
----------------------------

若目的VPS資料庫並非全新、空白的,請先匯出現況備份:

mkdir -p /root/pre-restore-snapshot
mariadb-dump -u root -p --single-transaction --routines --triggers --events \
  資料庫名稱 > /root/pre-restore-snapshot/before-restore-$(date +%F-%H%M).sql



說明:--single-transaction 可在不鎖表的情況下對 InnoDB 表取得一致性快照,避免匯出期間影響線上服務(若論壇此時仍在運作)。


資料庫快照將存放在 /root/pre-restore-snapshot 目錄




--------------------------
網站檔案快照
--------------------------

若目的VPS /var/www/域名.com 目錄已有內容,建議先整個搬移而非直接刪除覆蓋:


mv /var/www/域名.com /var/www/域名.com.bak-$(date +%F-%H%M)


待後續驗收全部通過、確認無誤後,再手動刪除這個 .bak 目錄,釋放磁碟空間。


若是全新VPS、目的端本來就沒有任何舊資料(最常見的情境 A),這一節可以跳過,但仍建議養成習慣,因為下一次可能就不是全新VPS了。



目錄整個搬移之後,再建立新的目錄

建立目錄
mkdir -p /var/www/域名.com


將網站目錄與檔案擁有者改為 www-data (與 nginx.conf 的 user 設定一致)

chown -R www-data:www-data /var/www/域名.com

chmod -R 755 /var/www/域名.com






--------------------------------------
停止 Nginx 與 PHP (重要)
--------------------------------------

在進行資料還原前,請務必先停止 Nginx 與 PHP:


systemctl stop nginx


systemctl stop php8.3-fpm





為什麼要先停?

避免還原過程中,網站檔案處於新舊混雜的不一致狀態被外部存取

防止備份檔上傳期間被惡意掃描或下載

避免檔案解壓時與正在處理請求的 PHP-FPM 進程產生讀寫衝突




-----------------------------------------------------------------------
排程任務不會因為停 Nginx 而停止(容易被忽略的一點)
-----------------------------------------------------------------------

停 Nginx 只能阻擋「使用者透過瀏覽器存取」,但IPS論壇的排程任務(task.php)若由 crontab 或 systemd timer 觸發,

並不經過 Nginx,還原期間仍可能在背景執行並寫入資料庫,造成資料不一致。


請先暫停相關排程,而不是直接清空整份 crontab(清空後容易忘記哪些任務原本存在)。

建議的做法是在呼叫 task.php 的那一行前面加上 # 註解


編輯
crontab -e


# 找到類似下面這一行,開頭加上 # 註解來讓它暫時停用
# */1 * * * * /usr/bin/php -d memory_limit=-1 -d max_execution_time=0 /var/www/域名.com/applications/core/interface/task/task.php xxxxx你的驗證金鑰



系統層級的 systemd timer(例如 acme.sh 憑證續簽)通常不會直接寫入論壇資料庫,一般不需要在這個步驟暫停,

但建議用以下指令確認還原期間是否剛好有任務要觸發,避免巧合撞期:

systemctl list-timers --all



若發現有任務排定在還原期間執行,可暫時 systemctl stop xxx.timer,

還原完成後再 systemctl start xxx.timer 恢復。






------------------------------------
還原論壇資料庫(DB)
------------------------------------

建議使用 /tmp 目錄作為暫存區,避免汙染系統目錄

使用SFTP將DB資料庫備份檔上傳到 /tmp,再SSH登入並切換目錄:

cd /tmp




驗證壓縮檔完整性(還原前必做)。

在解壓縮前,先測試壓縮檔是否損毀,避免浪費時間解壓一個壞檔:

unzip -t DB.zip



預期顯示 No errors detected in compressed data of DB.zip.

才代表檔案完整,可繼續下一步。

若有錯誤,請重新從原始備份來源(例如,異地備份儲存)取得乾淨的備份檔,切勿使用已損毀的檔案強行還原。




解壓縮

unzip -o DB.zip





確認檔案完整性

確認解壓縮後的檔案大小是否合理(例如不應為 0 bytes 或遠小於平常的備份大小),避免用損毀或不完整的備份檔覆蓋現有資料庫:


ls -lh DB.sql


du -h DB.sql






----------------------------------------------------
建立乾淨的資料庫(容易被遺漏的關鍵步驟)
----------------------------------------------------

若直接把 SQL 檔匯入「既有的資料庫」,這樣做有一個隱患:

如果備份當下某些資料表已經被刪除或改名,而目的端資料庫仍殘留這些舊資料表,匯入後新舊資料表會並存,造成資料不一致,且不容易發現。


正確做法是先重建一個全新、空白的資料庫再匯入,徹底避免殘留資料:

mariadb -u root -p -e "DROP DATABASE IF EXISTS 資料庫名稱; CREATE DATABASE 資料庫名稱 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"


此指令具破壞性,請再三確認資料庫名稱正確。







---------------------------------------------------------
匯入資料庫
---------------------------------------------------------

上面步驟已將DB資料庫備份檔上傳到 /tmp 目錄

cd /tmp

mariadb -u 資料庫用戶 -p --default-character-set=utf8mb4 資料庫名稱 < DB.sql



若想顯示進度條,可改用
pv DB.sql | mariadb -u root -p --default-character-set=utf8mb4 資料庫名稱




系統會提示輸入該使用者的密碼
(密碼不會出現在 shell 歷史紀錄中,這是刻意使用互動式 -p 而非 -p密碼 寫法的原因,避免密碼被記錄在 ~/.bash_history)。


若備份檔內含大型附件 BLOB 欄位導致匯入時出現 max_allowed_packet 相關錯誤,可在匯入時臨時提高限制:

mariadb -u root -p --max_allowed_packet=512M --default-character-set=utf8mb4 資料庫名稱 < DB.sql




建議將匯入過程的輸出記錄下來,方便日後排查問題,並可搭配 time 指令確認耗時:
time mariadb -u root -p --default-character-set=utf8mb4 資料庫名稱 < DB.sql 2>&1 | tee /tmp/db-import.log



恢復時間取決於資料庫大小,可能需要數分鐘至數小時,

匯入過程請勿中斷(這也是前面強調務必在 tmux 內執行的原因)。



在 2GB RAM VPS上進行大型匯入時,可以另開一個 tmux 視窗監看記憶體用量:

watch -n 5 free -h

若觀察到 swap 用量持續攀升,代表已接近實體記憶體上限










--------------------------------
驗證匯入結果
--------------------------------


mariadb -u 資料庫用戶 -p -e "USE 資料庫名稱; SHOW TABLES;" | wc -l

mariadb -u 資料庫用戶 -p -e "USE 資料庫名稱; SELECT COUNT(*) FROM core_members;"



注意:SHOW TABLES 的輸出第一行是欄位標題(例如 Tables_in_資料庫名稱),

wc -l 算出的行數會比實際資料表數量多 1,比對時請記得扣掉這一行。


確認資料表數量與會員數量是否與來源端記錄相符

(建議在備份產生當下,於來源端也執行一次同樣的指令並記錄下來,才有比對基準),初步判斷匯入是否完整。






---------------------------------------------
刪除資料庫的暫存備份檔
---------------------------------------------

資料匯入完成且驗證無誤後,請立即刪除 /tmp 內的暫存檔,避免資料庫備份檔外洩(內含全站會員個資,外洩風險極高):


cd /tmp

rm DB.zip DB.sql

ls -l



此處刪除的僅是 /tmp 目錄內的「工作副本」,

正式的異地備份(例如異地儲存、加密備份)仍應依既定備份政策保留,切勿因此誤刪唯一的備份來源。





-------------------------------------------
恢復 Web 網站檔案
-------------------------------------------

使用SFTP將網站備份檔(Web.zip)上傳到 /tmp 目錄。

不建議直接上傳到網站根目錄解壓,避免解壓過程中網站處於不完整狀態被存取,且 Nginx 此時應已停止


cd /tmp




驗證壓縮檔完整性(還原前必做)。

在解壓縮前,先測試壓縮檔是否損毀,避免浪費時間解壓一個壞檔:

unzip -t Web.zip




預期顯示 No errors detected in compressed data of Web.zip.

才代表檔案完整,可繼續下一步。

若有錯誤,請重新從原始備份來源(例如,異地備份儲存)取得乾淨的備份檔,切勿使用已損毀的檔案強行還原。





檢查磁碟空間與 inode

df -h /var/www


df -i /var/www



IPS論壇的附件、頭像、快取等目錄常包含數十萬個小檔案,2GB RAM 規格的 VPS 多半搭配較小的硬碟方案,

inode 用盡比磁碟空間用盡更常發生,且發生時系統會出現「No space left on device」這類容易誤判為磁碟滿了的錯誤訊息,請務必一併確認 inode 餘量。





解壓縮並移動到網站目錄

mkdir -p /var/www/域名.com


unzip -o Web.zip -d /var/www/域名.com



解壓完成後,請務必確認 conf_global.php 是否就在 /var/www/域名.com 的最上層,

而不是被多包了一層資料夾(例如變成 /var/www/域名.com/Web/conf_global.php)。

這是製作 zip 備份檔時很常見的失誤,若打包時是對著上一層資料夾壓縮,解壓後就會多一層目錄,導致 Nginx 找不到網站根目錄下的檔案。

可用以下指令快速確認:
ls /var/www/域名.com/conf_global.php


若顯示「找不到檔案」,請進入多出來的那一層子目錄,將內容物移動到正確位置後,再刪除空的子目錄。






刪除網站備份檔

rm -f /tmp/Web.zip






----------------------------------------------
還原完成後的快取與權限處理
----------------------------------------------

重建 IPS論壇 快取

datastore目錄存放IPS論壇自動產生的快取,還原後應清空讓系統重新產生,但須保留 index.html 與 .htaccess 這兩個防護用的空檔案。

正確做法是用 find 排除這兩個檔名後再刪除:

cd /var/www/域名.com/datastore
find . -mindepth 1 -maxdepth 1 ! -name 'index.html' ! -name '.htaccess' -exec rm -rf {} +










---------------------------------------------
變更檔案擁有者
---------------------------------------------


將所有權變更為網頁伺服器使用者,確保 Nginx / PHP-FPM 有正確的讀寫權限:

chown -R www-data:www-data /var/www/域名.com




確認是否都已改為 www-data www-data

ls -l /var/www/域名.com




修改 conf_global.php 的資料庫連線資訊

vi /var/www/域名.com/conf_global.php


修改以下三個欄位

'sql_database' => '資料庫名稱',
'sql_user'     => '資料庫用戶',
'sql_pass'     => '用戶密碼',



容易被忽略的一點:

若是搬遷到新VPS且 MariaDB 監聽位址設定不同,conf_global.php 中的 sql_host 也需一併確認

(例如 localhost 與 127.0.0.1 在部分環境下行為不同,前者通常會走 Unix Socket,後者會走 TCP,連線方式不一致時可能出現 Access Denied 錯誤,

可參考本系列 phpMyAdmin 安裝章節中關於連線方式統一性的說明)。





儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter







為了主機安全,設定標準檔案權限


將所有「目錄」設為 755
find /var/www/域名.com -type d -exec chmod 755 {} \;



將所有「檔案」設為 644
find /var/www/域名.com -type f -exec chmod 644 {} \;










強化 conf_global.php 安全性

conf_global.php 內含資料庫帳密等敏感資訊,權限應比一般檔案更嚴格:

chmod 640 /var/www/域名.com/conf_global.php




640 代表擁有者(www-data)可讀寫、群組可讀、其他人完全無權限,PHP-FPM 以 www-data 身分執行仍可正常讀取。

若主機上沒有其他需要讀取該檔案的群組成員,也可進一步收緊為 600。

















-----------------------------------
啟動服務並檢查
-----------------------------------


systemctl start mariadb


systemctl start php8.3-fpm


systemctl start nginx


啟動順序建議由下層往上層:先確保資料庫可用,再啟動 PHP-FPM,最後才啟動 Nginx,

避免上層服務啟動瞬間就有請求進來卻連不到下層服務。




確認設定語法是否正確
nginx -t





確認啟動無錯誤

systemctl status mariadb


systemctl status php8.3-fpm


systemctl status nginx







-----------------------------
日誌檢查
-----------------------------

若有錯誤先排除


journalctl -u nginx -n 50 --no-pager


journalctl -u php8.3-fpm -n 50 --no-pager


tail -50 /var/log/nginx/error.log












--------------------------------------
使用 phpMyAdmin 進行資料維護
--------------------------------------

依本系列 phpMyAdmin 安裝章節建立的存取模式,phpMyAdmin 預設應為「平時關閉、需要時才暫時開啟」,而非長期暴露在外網。

請使用該章節建立的別名指令臨時開啟存取:

pma-open



開啟後再透過瀏覽器登入進行以下維護操作,完成後務必立即關閉,縮短暴露時間窗口:

https://伺服器IP:888/phpMyAdmin




資料表維護

phpMyAdmin 進入論壇資料庫 → 資料表列表底部 → 全選 → 依序執行

1. 檢查資料表

2. 修復資料表(如有錯誤)

3. 最佳化資料表


若資料表數量較多,頁面可能會分多頁顯示,請逐頁確認,避免遺漏。

同時瀏覽論壇資料庫的編碼與排序,確認為 utf8mb4_unicode_ci,與之前建立資料庫時指定的排序規則一致。



-------------------------------
恢復排程任務
-------------------------------

還原完成後,別忘了把暫停的排程任務復原,這是最容易被遺漏的收尾步驟,

論壇的自動排程任務(清理、通知信、文摘等)就這樣靜悄悄地停擺了好幾天才被發現。


編輯
crontab -e


把先前加上的 # 註解移除,恢復原本的排程行




若有暫停過 systemd timer,記得一併恢復:

systemctl start xxx.timer


systemctl list-timers --all





建議手動觸發一次 task.php,確認 crontab 排程腳本本身可以正常執行,而不是只等下一次排程時間到才發現有問題。

sudo -u www-data /usr/bin/php -d memory_limit=-1 -d max_execution_time=0 \
  /var/www/域名.com/applications/core/interface/task/task.php 數值xxxxxx



確認執行結果,執行完可以看 exit code:

echo $?

0 代表正常結束



更可靠的方式是直接查資料庫,看 task 的 last_run 跟 next_run 時間戳是否有更新

SELECT `key`, `last_run`, `next_run`, `enabled` 
FROM core_tasks 
ORDER BY `last_run` DESC;








---------------------------------------
回到論壇並完整驗收
---------------------------------------

確認論壇正常運作

https://域名.com/




接下來,從這個步驟開始做

Cron執行論壇任務、自動備份DB資料庫、自動備份Web網站檔案

本帖最后于,由Jack编辑

参与讨论

你可立刻发布并稍后注册。 如果你有帐户,立刻登录发布帖子。

游客
抱歉,你的帖子内容包括我们不允许的字词。请编辑你的帖子,删除下面高亮的屏蔽字。
回帖…

帐户

导航

搜索

搜索

配置浏览器推送通知

Chrome (安卓)
  1. 轻敲地址栏旁的锁形图标。
  2. 轻敲权限 → 通知。
  3. 调整你的偏好。
Chrome (台式电脑)
  1. 点击地址栏中的挂锁图标。
  2. 选择网站设置。
  3. 找到通知选项并调整你的偏好。