Bài 29: Backup database và kiểm tra restore

<style id="sas-global-polish">
html,body{overflow-x:hidden!important;max-width:100%!important}body #masthead.site-header{position:sticky!important;top:0!important;z-index:100!important;background:rgba(255,255,255,.94)!important;border-bottom:1px solid #e6edf6!important;box-shadow:0 10px 30px rgba(15,23,42,.055)!important;backdrop-filter:blur(14px)!important}body #masthead .site-title-centered{max-width:1320px!important;margin:0 auto!important;padding:10px 24px!important;display:flex!important;align-items:center!important;justify-content:space-between!important;gap:28px!important}body #masthead .site-branding{display:flex!important;align-items:center!important;min-width:250px!important;margin:0!important;padding:0!important;text-align:left!important}body #masthead .site-title{margin:0!important;line-height:1!important;display:flex!important;align-items:center!important}body #masthead img.custom-logo{width:190px!important;max-width:190px!important;height:auto!important;display:block!important}body #masthead .site-description,body #masthead .social-links,body #masthead .top-search{display:none!important}body #masthead .main-navbar{flex:1!important;background:transparent!important;border:0!important;box-shadow:none!important;margin:0!important;padding:0!important}body #masthead .main-navbar .container{max-width:none!important;width:100%!important;margin:0!important;padding:0!important;display:flex!important;align-items:center!important;justify-content:flex-end!important}body #site-navigation{display:flex!important;justify-content:flex-end!important;width:auto!important;float:none!important;margin:0!important;padding:0!important}body #site-navigation ul.main-menu{display:flex!important;align-items:center!important;justify-content:flex-end!important;gap:6px!important;margin:0!important;padding:0!important;list-style:none!important;flex-wrap:wrap!important}body #site-navigation ul.main-menu>li{margin:0!important;padding:0!important;float:none!important;display:block!important}body #site-navigation ul.main-menu>li>a{display:flex!important;align-items:center!important;min-height:38px!important;padding:9px 13px!important;border-radius:999px!important;color:#334155!important;font-size:14px!important;font-weight:800!important;line-height:1!important;text-decoration:none!important;background:transparent!important;transition:.18s ease!important}body #site-navigation ul.main-menu>li.current-menu-item>a,body #site-navigation ul.main-menu>li>a:hover{background:#eff6ff!important;color:#1d4ed8!important}body.content-sidebar #primary,body #primary.content-area,body #primary,body .content-area{float:none!important;width:100%!important;max-width:100%!important;display:block!important;padding:0!important;margin:0!important}body #secondary,body aside#secondary,body .sidebar.widget-area,body .widget-area{display:none!important;visibility:hidden!important;width:0!important;max-width:0!important;padding:0!important;margin:0!important}body #content.site-content,body #content .container,body #content .inside,body .site-content,body .container,body .inside,body #main.site-main{width:100%!important;max-width:100%!important;padding-left:0!important;padding-right:0!important;margin-left:0!important;margin-right:0!important}body:not(.page-id-11) .entry-header,body:not(.page-id-11) .entry-content,body:not(.page-id-11) .entry-footer{max-width:980px!important;margin-left:auto!important;margin-right:auto!important;padding-left:22px!important;padding-right:22px!important}body.archive #main,body.blog #main,body.search #main{max-width:1180px!important;margin:0 auto!important;padding:28px 22px!important}@media(max-width:920px){body #masthead .site-title-centered{display:block!important;padding:10px 16px!important}body #masthead .site-branding{justify-content:center!important;margin-bottom:10px!important}body #masthead img.custom-logo{width:170px!important}body #site-navigation,body #site-navigation ul.main-menu{justify-content:center!important}body #site-navigation ul.main-menu>li>a{font-size:13px!important;padding:8px 10px!important}}@media(max-width:560px){body #site-navigation ul.main-menu{gap:4px!important}body #site-navigation ul.main-menu>li>a{font-size:12px!important;padding:7px 9px!important}body #masthead img.custom-logo{width:150px!important}body:not(.page-id-11) .entry-header,body:not(.page-id-11) .entry-content,body:not(.page-id-11) .entry-footer{padding-left:14px!important;padding-right:14px!important}}
</style>
<style>.sas-lesson{max-width:940px;margin:0 auto;padding:38px 18px 78px;font-family:Inter,"Segoe UI",Arial,sans-serif;color:#344054;font-size:17px;line-height:1.86}.sas-lesson h1,.sas-lesson h2,.sas-lesson h3{color:#172033;letter-spacing:-.02em;line-height:1.22}.sas-lesson h1{font-size:clamp(34px,5vw,56px);margin:0 0 18px}.sas-lesson h2{font-size:29px;margin:38px 0 13px}.sas-lesson h3{font-size:22px;margin:26px 0 10px}.sas-lesson .lead{font-size:18px;color:#667085;line-height:1.78}.sas-lesson .box,.sas-lesson .lab,.sas-lesson .warn,.sas-lesson .check,.sas-lesson .note{padding:20px 22px;border:1px solid #e4e7ec;border-radius:18px;background:#f8fafc;margin:23px 0}.sas-lesson .warn{background:#fff7ed;border-color:#fed7aa}.sas-lesson .lab{background:#eff6ff;border-color:#bfdbfe}.sas-lesson .check{background:#ecfdf3;border-color:#bbf7d0}.sas-lesson .note{background:#f5f3ff;border-color:#ddd6fe}.sas-lesson code{background:#eef2ff;padding:2px 6px;border-radius:6px;color:#1e3a8a}.sas-lesson pre{background:#0b1220;color:#dbeafe;padding:18px;border-radius:15px;overflow:auto;font-size:14px;line-height:1.72}.sas-lesson ul,.sas-lesson ol{line-height:1.86}.sas-lesson table{width:100%;border-collapse:collapse;margin:18px 0}.sas-lesson th,.sas-lesson td{border:1px solid #e4e7ec;padding:11px;text-align:left;vertical-align:top}.sas-lesson th{background:#f8fafc;color:#172033}.sas-lesson .next{margin-top:30px;padding:18px;border-radius:16px;background:#eff6ff;border:1px solid #bfdbfe}</style><div class="sas-lesson"><h1>Bài 29: Backup database và kiểm tra restore</h1><p class="lead">Bài này chi tiết hóa Database backup/restore theo hướng thực hành: có lab, lệnh mẫu, tình huống thực tế, checklist và bài tập.</p><div class="box"><strong>Sau bài này anh sẽ biết:</strong><ul><li>Database backup/restore giải quyết vấn đề gì trong DevOps thực tế.</li><li>Các khái niệm/lệnh quan trọng cần nhớ.</li><li>Cách dựng lab nhỏ để thực hành.</li><li>Cách kiểm tra, rollback và ghi chú vận hành.</li></ul></div><h2>1. Bối cảnh thực tế</h2><p>Database backup/restore thuộc nhóm kỹ năng giúp tự động hóa, chuẩn hóa và vận hành hệ thống ở quy mô lớn hơn. Khi server/app nhiều lên, thao tác tay sẽ dễ sai; vì vậy cần quy trình, công cụ và checklist rõ ràng.</p><h2>2. Khái niệm cần nắm</h2><ul><li><strong>State:</strong> trạng thái hiện tại của hệ thống hoặc ứng dụng.</li><li><strong>Config as code:</strong> cấu hình được lưu thành file để review, tái sử dụng.</li><li><strong>Idempotent:</strong> chạy nhiều lần vẫn cho kết quả ổn định.</li><li><strong>Rollback:</strong> quay lại trạng thái an toàn khi triển khai lỗi.</li></ul><h2>3. Lab thực hành</h2><div class="lab"><strong>Mục tiêu:</strong> chạy thử luồng thao tác tối thiểu, hiểu output và biết kiểm tra kết quả.</div><pre># MySQL/MariaDB
mysqldump -u root -p –single-transaction dbname > dbname.sql
mysql -u root -p dbname_restore < dbname.sql

# PostgreSQL
pg_dump -Fc dbname > dbname.dump
createdb dbname_restore
pg_restore -d dbname_restore dbname.dump

ls -lh dbname.sql dbname.dump 2>/dev/null || true
sha256sum dbname.sql 2>/dev/null || true</pre><h2>4. Tình huống thực tế</h2><div class="note"><p>Website có backup database hằng ngày nhưng chưa từng restore. Anh tạo database test, restore backup vào đó và kiểm tra số bảng/dữ liệu để chứng minh backup dùng được.</p></div><h2>5. Quy trình áp dụng an toàn</h2><ol><li>Viết cấu hình hoặc command trong môi trường lab.</li><li>Kiểm tra syntax/plan/status trước khi apply.</li><li>Chạy với phạm vi nhỏ trước.</li><li>Quan sát log, metric và health check.</li><li>Ghi lại thay đổi vào tài liệu vận hành.</li><li>Chuẩn bị rollback hoặc version trước đó.</li></ol><h2>6. Lỗi thường gặp</h2><ul><li>Copy cấu hình từ mạng mà không hiểu biến/môi trường.</li><li>Không lưu file cấu hình vào Git.</li><li>Không kiểm tra log sau khi apply.</li><li>Không có môi trường test/staging.</li></ul><div class="warn"><strong>Lưu ý production:</strong> Công cụ tự động hóa giúp làm nhanh hơn, nhưng cũng có thể làm sai hàng loạt nhanh hơn. Luôn giới hạn phạm vi khi mới triển khai.</div><h2>7. Checklist</h2><div class="check"><ul><li>Có file cấu hình rõ ràng.</li><li>Có bước kiểm tra trước khi apply.</li><li>Có log/health check sau khi apply.</li><li>Có rollback/version cũ.</li><li>Có tài liệu ai chạy, chạy khi nào, kết quả gì.</li></ul></div><h2>8. Bài tập</h2><ol><li>Dựng một lab nhỏ theo lệnh mẫu.</li><li>Chạy lệnh kiểm tra trạng thái trước/sau.</li><li>Tạo một lỗi cấu hình nhỏ và sửa lại.</li><li>Viết checklist production cho chủ đề này.</li></ol><div class="next"><strong>Bài tiếp theo:</strong> Prometheus và Grafana nhập môn</div></div>

Chốt ý nhanh

Chủ đề Điểm cần nhớ
Backup database Chỉ có giá trị khi restore được và restore đúng dữ liệu cần thiết.
Sai lầm phổ biến Ai cũng nghĩ mình có backup, cho đến lúc restore mới biết file hỏng hoặc quy trình thiếu.
Production mindset Backup là một quy trình cần kiểm thử định kỳ, không phải một lệnh chạy xong rồi quên.

Phần thực hành mở rộng: backup database phải đi kèm restore drill

Nếu chỉ dạy cách dump database mà không dạy restore, bài học sẽ thiếu mất nửa quan trọng nhất. Người vận hành cần hiểu backup chỉ là lời hứa; restore mới là bằng chứng.

Lab 1: Dump database bằng mysqldump hoặc pg_dump

mysqldump -u root -p appdb > appdb.sql
pg_dump -U postgres appdb > appdb.sql

Mục tiêu là hiểu output backup đang ở dạng nào: logical SQL dump, không phải snapshot toàn máy.

Lab 2: Kiểm tra file backup sau khi tạo

ls -lh appdb.sql
head -20 appdb.sql
gzip -c appdb.sql > appdb.sql.gz
ls -lh appdb.sql.gz

Đừng chỉ nhìn file có tồn tại. Hãy mở đầu file để xem nó có thực sự là dump hợp lệ không.

Lab 3: Restore vào môi trường test

mysql -u root -p -e "create database appdb_restore_test"
mysql -u root -p appdb_restore_test < appdb.sql

psql -U postgres -c "create database appdb_restore_test"
psql -U postgres appdb_restore_test < appdb.sql

Đây là phần quan trọng nhất: restore vào môi trường riêng để chứng minh backup dùng được.

Lab 4: Kiểm tra tính đúng đắn sau restore

  • đếm số bảng
  • kiểm tra vài record quan trọng
  • xác nhận charset/collation nếu cần
  • kiểm tra user/app có kết nối được không

Lab 5: Tạo checklist backup job

  • chạy lúc nào
  • giữ bao lâu
  • lưu ở đâu
  • mã hóa hay không
  • ai nhận alert nếu backup fail
  • bao lâu test restore một lần

Tình huống thực tế

Một backup job đêm nào cũng sinh file SQL, nhưng thực ra dump bị lỗi quyền ở nửa chừng hoặc dung lượng 0 byte. Không restore test, cả đội vẫn tưởng mọi thứ ổn cho đến ngày sự cố thật xảy ra.

Lỗi phổ biến

  • Có backup nhưng không có restore drill.
  • Lưu backup trên cùng máy với database.
  • Không kiểm tra dung lượng và nội dung file dump.
  • Không alert khi backup fail.

Kết bài

Sau bài này, anh nên có phản xạ rất rõ: backup không được đo bằng số file, mà bằng khả năng khôi phục thật. Từ đây sang Prometheus và Grafana, trọng tâm sẽ dịch sang quan sát hệ thống liên tục để phát hiện vấn đề sớm hơn trước khi phải dùng đến backup.

Tác giả: Mạnh Hoàng

Tôi là Hoàng Mạnh, người sáng lập blog SysadminSkills.com. Tôi viết về quản trị hệ thống, bảo mật máy chủ, DevOps và cách ứng dụng AI để tự động hóa công việc IT. Blog này là nơi tôi chia sẻ những gì đã học được từ thực tế – đơn giản, ngắn gọn và áp dụng được ngay.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *