Tới nội dung chính
hstation
Dịch vụDự ánVề tôiBlogThư viện nhạc

Bảo mật và sao lưu · 10 phút đọc · 2026-09-17

Khôi phục website WordPress: sao lưu đủ hai phần và kiểm tra URL thật

Khôi phục chỉ một phần backup có thể làm site trông ổn nhưng ảnh hoặc bài vẫn mất. Bài này chỉ cách kiểm tra database, wp-content/uploads và URL thật để biết restore đã đủ chưa.

Khôi phục website WordPress có một cái bẫy ít ai nói: khôi phục thiếu một nửa mà trang quản trị vẫn trông như đã xong. Bài này dành cho lúc bạn cần khôi phục WordPress từ backup và muốn chắc là đã khôi phục đủ.

Mình dựng một site thử, sao lưu, cố tình gây sự cố, rồi khôi phục từng phần để đo xem cái gì sống lại, cái gì vẫn hỏng. Site thử là WordPress 7.1 chạy trên máy (Apache, MySQL 8.4), 5 bài đăng, 2 ảnh trong thư viện media. Mọi lệnh chạy bằng WP-CLI 2.12. Mọi mã HTTP trong bài là mã máy trả về thật.

Một bản sao lưu WordPress gồm hai phần

Trước khi nói chuyện khôi phục, cần nhớ bản sao lưu phải có đủ hai thứ:

  1. Cơ sở dữ liệu: bài viết, trang, cài đặt, người dùng, và danh sách tệp media. Chỉ là danh sách, không phải bản thân tệp ảnh.
  2. Thư mục `wp-content`: tệp ảnh đã tải lên (nằm trong uploads), theme, plugin.

Thiếu phần nào thì khôi phục thiếu phần đó. Phần dưới đây cho thấy thiếu mỗi phần trông ra sao.

Bước 1: backup database WordPress và thư mục wp-content

Chạy trong thư mục gốc của site, nơi có tệp wp-config.php:

bash
wp db export db.sql
tar -czf wp-content.tar.gz wp-content

Kết quả trên site thử:

  • db.sql: 201.418 byte, xuất trong 269 ms.
  • wp-content.tar.gz: 14.792.218 byte, nén trong 482 ms.

Phần nặng là wp-content: tệp nén của nó lớn gấp khoảng 73 lần tệp cơ sở dữ liệu, dù site thử chỉ có 2 ảnh. Site càng nhiều ảnh thì khoảng cách này càng lớn.

Đã xong khi có đủ hai tệp và cả hai đều lớn hơn 0 byte. Chép cả hai ra khỏi máy chủ; bản sao lưu nằm cùng máy với site thì mất cùng lúc với site.

Hai lỗi mình gặp thật khi chạy trên Windows bằng Git Bash:

  • wp db export báo lỗi kết thúc bằng "operable program or batch file". Nguyên nhân là máy không tìm thấy mysqldump. Sửa bằng cách thêm thư mục bin của MySQL vào PATH.
  • tar báo "Cannot connect to h: resolve failed", vì nó hiểu h:/... là tên một máy từ xa. Sửa bằng cờ --force-local:
bash
tar --force-local -czf wp-content.tar.gz wp-content

Bước 2: sự cố mình tạo ra

Mình xoá vĩnh viễn 3 bài mới nhất và xoá thư mục wp-content/uploads/2026. Ngay sau đó:

  • 3 bài: 404.
  • 2 ảnh: 404.
  • Đếm bài đăng: còn 2.
  • Đếm media: vẫn là 2.

Con số cuối là chỗ đáng chú ý. Thư viện media đếm bản ghi trong cơ sở dữ liệu, không đếm tệp trên đĩa. Tệp ảnh mất sạch mà trang Tất cả tập tin vẫn ghi "2 mục":

Trang Tất cả tập tin trong wp-admin sau khi thư mục ảnh bị xoá. Bảng vẫn ghi 2 mục: Ảnh cửa hàng với tên tệp anh-cua-hang.jpg và Ảnh sản phẩm với tên tệp anh-san-pham.jpg, trạng thái Chưa được đính kèm, ngày 4 phút trước. Ô ảnh thu nhỏ của cả hai dòng chỉ còn biểu tượng ảnh hỏng.
Trang Tất cả tập tin trong wp-admin sau khi thư mục ảnh bị xoá. Bảng vẫn ghi 2 mục: Ảnh cửa hàng với tên tệp anh-cua-hang.jpg và Ảnh sản phẩm với tên tệp anh-san-pham.jpg, trạng thái Chưa được đính kèm, ngày 4 phút trước. Ô ảnh thu nhỏ của cả hai dòng chỉ còn biểu tượng ảnh hỏng.

Khôi phục thiếu kiểu 1: chỉ có tệp

Mình giải nén lại wp-content (mất 340 ms), chưa đụng tới cơ sở dữ liệu:

bash
tar -xzf wp-content.tar.gz
  • 2 ảnh: 200, đã về.
  • 3 bài: vẫn 404.
  • Đếm bài đăng: vẫn 2.

Kiểu thiếu này dễ nhận ra, vì bài biến mất khỏi danh sách bài viết.

Khôi phục thiếu kiểu 2: chỉ khôi phục WordPress database

Mình gây lại đúng sự cố trên. Lần này chỉ chạy lệnh khôi phục WordPress database, mất 1.016 ms:

bash
wp db import db.sql
  • 3 bài: 200, đã về.
  • Đếm bài đăng 5, đếm media 2. Mọi con số trong trang quản trị khớp với trước sự cố.
  • Nhưng 2 ảnh: vẫn 404.

Đây là kiểu khôi phục thiếu nguy hiểm hơn. Nhìn số liệu thì tưởng xong, nhưng mở bài ra thì ảnh chỉ còn dòng chữ thay thế:

Trang bài Bài thử khôi phục số 1 trên site Cửa hàng mẫu sau khi chỉ khôi phục cơ sở dữ liệu. Tiêu đề và dòng Nội dung bài thử số 1 hiện bình thường, nhưng chỗ ảnh chỉ còn biểu tượng ảnh hỏng kèm chữ Ảnh thử 1.
Trang bài Bài thử khôi phục số 1 trên site Cửa hàng mẫu sau khi chỉ khôi phục cơ sở dữ liệu. Tiêu đề và dòng Nội dung bài thử số 1 hiện bình thường, nhưng chỗ ảnh chỉ còn biểu tượng ảnh hỏng kèm chữ Ảnh thử 1.

Bốn trạng thái, đặt cạnh nhau

Cùng một sự cố, đây là thứ mình đo được ở từng trạng thái:

  • Sau sự cố: bài 404, ảnh 404, đếm bài 2, đếm media 2.
  • Chỉ có tệp: bài 404, ảnh 200, đếm bài 2, đếm media 2.
  • Chỉ có cơ sở dữ liệu: bài 200, ảnh 404, đếm bài 5, đếm media 2.
  • Đủ cả hai: bài 200, ảnh 200, đếm bài 5, đếm media 2.

Để ý cột đếm media: nó ghi 2 ở cả bốn trạng thái. Nó không cho bạn biết gì về ảnh.

Khi đang khôi phục thật, hãy tự hỏi: mình vừa khôi phục phần nào? Nếu câu trả lời chỉ là một trong hai, bạn đang ở một trong hai dòng giữa, dù trang quản trị trông ổn đến đâu.

Cách khôi phục website WordPress cho đủ, từng bước

  1. Sao lưu luôn trạng thái đang hỏng bằng hai lệnh ở Bước 1, đặt tên khác đi. Nếu khôi phục sai, bạn vẫn quay lại được chỗ xuất phát.
  2. Nhập cơ sở dữ liệu từ bản sao lưu tốt. Đã xong khi lệnh báo "Success: Imported from 'db.sql'."
bash
wp db import db.sql
  1. Giải nén `wp-content` trong thư mục gốc của site. Đã xong khi lệnh chạy xong không báo lỗi.
bash
tar -xzf wp-content.tar.gz
  1. Chạy ba phép kiểm ở mục dưới. Chỉ coi là xong khi cả ba đạt.

Mình đã chạy theo cả hai thứ tự (tệp trước rồi cơ sở dữ liệu, và ngược lại): cả hai đều cho 3 bài 200, 2 ảnh 200, 5 bài đăng. Bài hiện lại đủ ảnh:

Trang bài Bài thử khôi phục số 1 sau khi khôi phục đủ cả cơ sở dữ liệu lẫn thư mục ảnh. Dưới dòng Nội dung bài thử số 1 là ảnh nền xanh lá có chữ Cua hang hiện đầy đủ.
Trang bài Bài thử khôi phục số 1 sau khi khôi phục đủ cả cơ sở dữ liệu lẫn thư mục ảnh. Dưới dòng Nội dung bài thử số 1 là ảnh nền xanh lá có chữ Cua hang hiện đầy đủ.

Ba phép kiểm sau khi khôi phục website WordPress

  1. Đếm bài đăng và media, so với trước sự cố. Bắt được kiểu thiếu 1, không bắt được kiểu thiếu 2.
bash
wp post list --post_type=post --post_status=publish --format=count
wp post list --post_type=attachment --format=count
  1. Mở thật URL các bài quan trọng, xem mã trả về có phải 200 không.
bash
curl -s -o /dev/null -w "%{http_code}\n" https://ten-mien-cua-ban/duong-dan-bai/
  1. Mở thật URL một vài ảnh, xem mã trả về. Đây là phép duy nhất trong ba phép bắt được kiểu thiếu 2.
bash
curl -s -o /dev/null -w "%{http_code}\n" https://ten-mien-cua-ban/wp-content/uploads/2026/09/ten-anh.jpg

Muốn biết URL ảnh, mở một bài có ảnh, bấm chuột phải vào ảnh và chép địa chỉ ảnh.

Những gì mình chưa kiểm

  • Chưa thử plugin sao lưu nào, chưa thử công cụ sao lưu của hosting hay cPanel.
  • Chưa thử khôi phục website WordPress bị hack. Ca đó khó hơn, vì bản sao lưu có thể đã được tạo sau khi site bị cài mã lạ; chọn bản sao lưu nào là cả một việc riêng mà mình chưa đo.
  • Chưa khôi phục sang máy chủ khác hay đổi tên miền. Chuyện đó khác hẳn, vì URL trong cơ sở dữ liệu phải đổi theo.
  • Site thử nhỏ, cơ sở dữ liệu khoảng 200 KB. Thời gian đo được chỉ để bạn hình dung thứ tự lớn nhỏ, không phải con số cho site thật.

Nếu site của bạn đang báo lỗi chứ không mất dữ liệu, xem bài Lỗi 500 WordPress: đọc debug log khi không vào được wp-admin trước khi nghĩ tới khôi phục.