การสำรองข้อมูลและการกู้คืน¶
การสำรองข้อมูล HEMMS ที่สมบูรณ์มี สองส่วน: ฐานข้อมูล Postgres (เรกคอร์ด การตั้งค่า ร่องรอยการตรวจสอบ) และ filestore ของ Odoo (สิ่งแนบ — ไฟล์ ปจป. ที่สแกน PDF สัญญาบริการที่ลงนาม รูปถ่ายเครื่องมือแพทย์) หากคุณสำรองข้อมูลเพียง อย่างใดอย่างหนึ่ง คุณจะกู้คืนได้ไม่ครบถ้วน
หน้านี้ครอบคลุมว่า make backup-private ทำอะไรจริง ๆ วิธีเพิ่ม filestore เข้าไปในการสำรองข้อมูลนั้น วิธีกู้คืน และความถี่ที่ Trinity Roots แนะนำสำหรับการติดตั้งใน production
อะไรบ้างที่ถูกสำรองข้อมูล¶
| สินทรัพย์ | อยู่ใน | จะสูญเสียอะไรหากหายไป |
|---|---|---|
| ฐานข้อมูล | วอลุ่ม Postgres (db_private_data / db_gov_data) | เรกคอร์ดทั้งหมด: เครื่องมือแพทย์ คำขอ สัญญา audit log ผู้ใช้ สิทธิ์ |
| Filestore | วอลุ่ม Odoo (odoo_private_data / odoo_gov_data) path /var/lib/odoo/.local/share/Odoo/filestore/<dbname>/ | สิ่งแนบทุกชิ้น: PDF ที่ลงนาม รูปถ่าย ไฟล์ XLSX ที่นำเข้า ฐานข้อมูลอ้างอิงไฟล์เหล่านี้ด้วย hash — หากไม่มี filestore การดาวน์โหลดสิ่งแนบจะคืนค่า 404 |
Source addons/ | Git repo บนดิสก์ | โค้ดที่กำหนดเอง — อยู่ใน version control บน GitHub แล้ว ไม่ได้เป็นส่วนหนึ่งของการสำรองข้อมูล |
config/*.conf | repo บนดิสก์ | admin password ข้อมูลรับรองฐานข้อมูล — อยู่ใน version control แล้ว ไม่ได้เป็นส่วนหนึ่งของการสำรองข้อมูล |
target สำรองข้อมูลใน Makefile จับเฉพาะฐานข้อมูลเท่านั้น
make backup-private รัน pg_dump และ ไม่ คัดลอก filestore ซึ่งใช้ได้กับฐานข้อมูล demo ที่อายุสั้น (ข้อมูล demo ที่เพาะไว้จะเติม filestore ตอนติดตั้ง) แต่ ไม่เพียงพอ สำหรับ production ดูที่ การเพิ่ม filestore เข้าไปในการสำรองข้อมูล ด้านล่าง
การสำรองฐานข้อมูล — make backup-private¶
คำสั่งหลัก:
คำสั่งนี้เรียกใช้ scripts/backup_db.sh ซึ่งรัน pg_dump ภายในคอนเทนเนอร์ Postgres และส่งผลลัพธ์ผ่านท่อ ไปยัง gzip:
docker exec hemms_db_private pg_dump -U odoo_private hemms_private \
| gzip > ./backups/private_<timestamp>.sql.gz
จุดที่ผลลัพธ์ตกลง:
สคริปต์จะสร้าง ./backups/ หากยังไม่มี ไฟล์จะถูกประทับเวลา ถึงระดับวินาที ดังนั้นการสำรองข้อมูลสองครั้งในนาทีเดียวกันจะไม่ชนกัน
| Sandbox | คอนเทนเนอร์ | DB user | ชื่อฐานข้อมูล | ชื่อไฟล์สำรอง |
|---|---|---|---|---|
private | hemms_db_private | odoo_private | hemms_private | private_<ts>.sql.gz |
gov | hemms_db_gov | odoo_gov | hemms_gov | gov_<ts>.sql.gz |
การเพิ่ม filestore เข้าไปในการสำรองข้อมูล¶
สำหรับ production ให้ห่อ make backup-private ด้วยการคัดลอก filestore:
#!/usr/bin/env bash
set -euo pipefail
TS=$(date +%Y%m%d_%H%M%S)
SANDBOX=private
DB=hemms_private
CONTAINER_ODOO=hemms_odoo_private
# 1. DB dump (via the Makefile target)
make backup-${SANDBOX}
# 2. Filestore tarball — read from inside the Odoo container
docker exec ${CONTAINER_ODOO} tar -czf - \
-C /var/lib/odoo/.local/share/Odoo/filestore ${DB} \
> ./backups/${SANDBOX}_filestore_${TS}.tar.gz
echo "==> Filestore backup complete: ./backups/${SANDBOX}_filestore_${TS}.tar.gz"
ตอนนี้การสำรองข้อมูลแต่ละครั้งมี สองไฟล์ ที่มีเวลาประทับตรงกัน:
เก็บทั้งสองไว้ด้วยกัน — ต้องกู้คืนเป็นคู่
ขั้นตอนการกู้คืน¶
การกู้คืนที่สะอาดจะลบฐานข้อมูลที่มีอยู่ สร้างใหม่ replay dump และแตก filestore
การกู้คืนเป็นการทำลายข้อมูล
การกู้คืนจะแทนที่ฐานข้อมูลที่ใช้งานอยู่ ให้สำรองข้อมูลใหม่ก่อน (make backup-private) เพื่อให้คุณ roll forward ได้หากการกู้คืน ผิดพลาด หยุด Odoo ก่อนกู้คืน — การเขียนพร้อมกันระหว่างการกู้คืน จะทำให้ฐานข้อมูลเสียหาย
ขั้นที่ 1 — หยุด Odoo ให้ Postgres ทำงานต่อไป¶
ขั้นที่ 2 — ลบและสร้างฐานข้อมูลใหม่¶
docker exec -it hemms_db_private psql -U odoo_private -d postgres \
-c "DROP DATABASE IF EXISTS hemms_private;"
docker exec -it hemms_db_private psql -U odoo_private -d postgres \
-c "CREATE DATABASE hemms_private OWNER odoo_private;"
ขั้นที่ 3 — replay SQL dump¶
gunzip -c ./backups/private_20260523_020005.sql.gz \
| docker exec -i hemms_db_private psql -U odoo_private -d hemms_private
คำสั่งนี้กู้คืนทุกแถวแต่ ไม่ กู้ filestore
ขั้นที่ 4 — กู้คืน filestore¶
# Wipe the existing filestore for this DB first
docker exec hemms_odoo_private rm -rf \
/var/lib/odoo/.local/share/Odoo/filestore/hemms_private
# Unpack the tarball into the same parent directory
docker exec -i hemms_odoo_private tar -xzf - \
-C /var/lib/odoo/.local/share/Odoo/filestore \
< ./backups/private_filestore_20260523_020005.tar.gz
ขั้นที่ 5 — เริ่ม Odoo ตรวจสอบ¶
เปิด UI เข้าสู่ระบบ และสุ่มตรวจ:
- Maintenance → Equipment — จำนวนเรกคอร์ดตรงกับฐานข้อมูลต้นทาง
- เปิดสัญญาบริการที่ลงนามแล้วและคลิกที่สิ่งแนบ — ควร ดาวน์โหลดได้ (พิสูจน์ว่า filestore ครบถ้วน)
- HA Report → Annual Reports — เปิดรายงานของปีที่แล้วและตรวจสอบว่า PDF render ได้
หากสิ่งแนบขึ้น 404 แสดงว่าการกู้คืน filestore ตกขั้นตอนไป — ทำขั้นที่ 4 ซ้ำ
ความถี่ที่แนะนำ¶
| เมื่อใด | ทำอะไร |
|---|---|
| รายคืน | สำรองข้อมูลฐานข้อมูล + filestore ตั้ง cron ให้สคริปต์ที่ห่อไว้ เก็บการสำรองข้อมูลรายวัน 14 ชุด |
| รายสัปดาห์ | เลื่อนการสำรองข้อมูลรายคืนหนึ่งชุดเป็นรายสัปดาห์ เก็บการสำรองข้อมูลรายสัปดาห์ 8 ชุด (≈ 2 เดือน) |
| รายเดือน | เลื่อนการสำรองข้อมูลรายสัปดาห์หนึ่งชุดเป็นรายเดือน เก็บการสำรองข้อมูลรายเดือน 12 ชุด (≈ 1 ปี) |
| ก่อนการติดตั้ง / อัปเกรดโมดูลทุกครั้ง | make backup-private + filestore tarball ทำด้วยมือ ตามที่ต้องการ |
| ก่อนการทดสอบกู้คืนทุกครั้ง | snapshot สถานะที่ใช้งานอยู่ก่อน |
| รายปี — การซ้อมกู้คืนจากภัยพิบัติ | กู้คืนเต็มรูปแบบบน host ที่ไม่ใช่ production วัด RTO บันทึกผล |
การสำรองข้อมูลควรถูก คัดลอกออกจาก Docker host ไปยัง object storage (S3, GCS หรือ NFS share บนเครื่องอื่น) การสำรองข้อมูลบนดิสก์เดียวกัน กับฐานข้อมูลที่ใช้งานอยู่จะไม่รอดจากความเสียหายของดิสก์
การซ้อมกู้คืนจากภัยพิบัติ¶
จัดตารางรายปี การซ้อมจะตอบสองคำถาม: ขั้นตอนการกู้คืน ทำงานได้จริงหรือไม่? และ ใช้เวลานานแค่ไหน?
- เลือก host ที่ไม่ใช่ production (แล็ปท็อปหรือ VM ราคาถูก)
- โคลน repo
make up-privateแต่ อย่าmake install-privateคุณต้องการฐานข้อมูลว่างเพื่อกู้คืนเข้าไป - คัดลอกคู่การสำรองข้อมูลนอกสถานที่ล่าสุดไปยัง
./backups/ - รันขั้นตอนการกู้คืนข้างต้นตั้งแต่ต้นจนจบ จับเวลา
- ตรวจสอบการสุ่มตรวจในขั้นที่ 5
- บันทึก:
- RTO (recovery time objective) — การกู้คืนใช้เวลานานเท่าไร
- RPO (recovery point objective) — ช่องว่างระหว่างการสำรองข้อมูลครั้งล่าสุดกับ เวลาที่ซ้อม
- ขั้นตอนใดก็ตามที่ล้มเหลวหรือทำให้คุณประหลาดใจ — ป้อนกลับเข้าสู่เอกสารนี้
เก็บรายงานการซ้อมไว้กับเอกสาร HA Thailand ของคุณ ผู้ตรวจสอบ HA มองหาหลักฐานว่ามีการซ้อมการกู้คืนจากภัยพิบัติ ไม่ใช่แค่บันทึกไว้
ข้อผิดพลาดที่พบบ่อย¶
เวอร์ชัน pg_dump ไม่ตรงกัน
หากคุณอัปเกรด Postgres บน host หรือในคอนเทนเนอร์ ไฟล์ dump เก่า ยังคง replay ได้ — แต่ไฟล์ dump ใหม่ ไม่สามารถ replay บน Postgres ที่เก่ากว่าได้ ทำให้เวอร์ชันใหญ่ของเวลาที่ dump และเวลาที่กู้คืน ตรงกัน (ปัจจุบันคือ postgres:15)
การใช้ดิสก์ของ filestore โตขึ้นอย่างเงียบ ๆ
PDF ที่ลงนามทุกไฟล์ รูปถ่าย และ XLSX ที่นำเข้าอยู่ใน filestore ตรวจสอบ docker exec hemms_odoo_private du -sh /var/lib/odoo/.local/share/Odoo/filestore/ เป็นรายเดือน หากโรงพยาบาลอัปโหลดรูปถ่ายเครื่องมือแพทย์ความละเอียด 4K filestore อาจ โตเร็วกว่าฐานข้อมูล
การเข้ารหัสการสำรองข้อมูลสำหรับการจัดเก็บนอกสถานที่
ข้อมูลที่เกี่ยวข้องกับผู้ป่วยอยู่ภายใน HEMMS (หมายเลขซีเรียลเครื่องมือแพทย์ ที่เชื่อมโยงกับหอผู้ป่วย สิ่งแนบ) เข้ารหัสการสำรองข้อมูลขณะพักก่อน ส่งออกจาก host — gpg --symmetric backup.sql.gz เป็นขั้นต่ำ
หน้าที่เกี่ยวข้อง¶
- การติดตั้ง — การติดตั้งเริ่มต้น
- คู่มือการอัปเกรด — สำรองข้อมูลก่อนอัปเกรดเสมอ
- การตั้งค่าหลายบริษัท / หลายโรงพยาบาล — ขอบเขตการสำรองข้อมูล รายโรงพยาบาล