---
title: "รายงานผลการทดสอบ Restore"
titleEn: "Restore Test Report"
clauses: ["ก.1.6.3"]
phase: 3
category: "รายงานอัตโนมัติ"
generated: true
generatedAt: "2026-10-03T02:55:11Z"
---

> สร้างอัตโนมัติเมื่อ 2026-10-03T02:55:11Z

# รายงานผลการทดสอบ Restore

**อ้างอิง TOR:** ข้อ ก.1.6.3

รายงานนี้สร้างโดย `scripts/restore-test.sh` (`npm run report:restore-test`) เพื่อยืนยันว่าข้อมูลที่สำรองไว้กู้คืนได้จริงและครบถ้วน ตาม TOR ข้อ ก.1.6.3 (คู่มือ Backup/Restore และการทดสอบ Restore อย่างน้อย 1 ครั้งพร้อมรายงาน)

## 1. สรุปผล

| รายการ | ค่า |
|---|---|
| ผลการทดสอบ | **ผ่าน (PASS)** |
| เริ่มทดสอบ | 2026-10-03T02:55:09Z |
| สิ้นสุด | 2026-10-03T02:55:11Z |
| ระยะเวลารวม | 1.59 วินาที |
| ระยะเวลากู้คืน (RTO ที่วัดได้) | 0.39 วินาที |
| ฐานข้อมูลต้นทาง (อ่านอย่างเดียว) | `prisma/dev.db` |
| ฐานข้อมูลที่ใช้ทดสอบ (สำเนา) | `prisma/restore-test.db` |
| ไฟล์สำรอง | `backups/.restore-test-20261003-095509-17292/backups/20261003-095509.db` |
| ขนาดไฟล์สำรอง | 43819008 ไบต์ |
| SHA-256 ของไฟล์สำรอง | `d477bb37ca3a890bef8eefd83389d300dc047c747861c79189750f867bfa9017` |
| จำนวนตาราง (ก่อน / หลัง) | 26 / 26 |
| จำนวนแถวรวม (ก่อน / หลัง) | 25935 / 25935 |
| จำนวนตารางที่ไม่ตรง | 0 |
| สภาพแวดล้อม | Darwin 25.4.0, SQLite 3.51.0, bash 3.2.57(1)-release |

## 2. ขอบเขตและวิธีทดสอบ

- ทดสอบกับ **สำเนา** ของฐานข้อมูล (`prisma/restore-test.db`) และสำเนาของไฟล์อัปโหลด — ฐานข้อมูลจริงถูกอ่านเพียงครั้งเดียวเพื่อทำสำเนา ไม่ถูกแก้ไขหรือลบ
- สำรองด้วย `scripts/backup-db.sh` (`sqlite3 .backup` + `tar` ของ `storage/uploads`) และกู้คืนด้วย `scripts/restore-db.sh` ซึ่งเป็นสคริปต์ชุดเดียวกับที่ผู้ดูแลระบบใช้งานจริง
- เกณฑ์ผ่าน: (1) จำนวนแถวทุกตารางหลังกู้คืนตรงกับก่อนสำรอง (2) `PRAGMA integrity_check` = ok (3) ข้อมูลที่เพิ่มหลังการสำรองต้องไม่ปรากฏ (4) SHA-256 ของเนื้อหาฐานข้อมูลตรงกัน (5) จำนวนไฟล์อัปโหลดตรงกัน
- สำเนาและไฟล์สำรองของการทดสอบถูกลบอัตโนมัติเมื่อจบ (ตั้ง `KEEP_RESTORE_TEST_FILES=1` เพื่อเก็บไว้)

## 3. ขั้นตอนและผลการทดสอบ

| # | ขั้นตอน | ผล | รายละเอียด |
|---|---|---|---|
| 1 | ทำสำเนาฐานข้อมูลและไฟล์อัปโหลดเพื่อทดสอบ | สำเร็จ | `prisma/dev.db` → `prisma/restore-test.db` (43819008 ไบต์) และ `storage/uploads` (1 ไฟล์) |
| 2 | สำรองข้อมูลด้วย `scripts/backup-db.sh` | สำเร็จ | `backups/.restore-test-20261003-095509-17292/backups/20261003-095509.db` (43819008 ไบต์) + `20261003-095509-storage.tar` |
| 3 | บันทึกจำนวนแถวทุกตารางก่อนทำลาย | สำเร็จ | 26 ตาราง รวม 25935 แถว; ไฟล์อัปโหลด 1 ไฟล์ |
| 4 | เพิ่มข้อมูลทดสอบหลังการสำรอง (marker) | สำเร็จ | สร้างตาราง `_restore_test_marker` 1 แถว เพื่อพิสูจน์ว่าสถานะย้อนกลับไป ณ เวลาสำรองจริง |
| 5 | จำลองความเสียหาย: ลบไฟล์ฐานข้อมูลและไฟล์อัปโหลด | สำเร็จ | ลบ `prisma/restore-test.db` (+ -wal/-shm) และโฟลเดอร์ไฟล์อัปโหลดของสำเนา |
| 6 | กู้คืนด้วย `scripts/restore-db.sh` | สำเร็จ | ใช้เวลา 0.39 วินาที |
| 7 | เทียบจำนวนแถวรายตาราง ก่อนสำรอง ↔ หลังกู้คืน | สำเร็จ | ตรงกันทั้ง 26 ตาราง (รวม 25935 แถว) |
| 8 | ตรวจ `PRAGMA integrity_check` ของฐานข้อมูลที่กู้คืน | สำเร็จ | ok |
| 9 | ตรวจว่าข้อมูลที่เพิ่มหลังการสำรองหายไป | สำเร็จ | ไม่พบตาราง `_restore_test_marker` (สถานะย้อนกลับไป ณ เวลาสำรอง) |
| 10 | เทียบ SHA-256 ของเนื้อหาทั้งฐานข้อมูล (`.dump`) | สำเร็จ | ตรงกัน |
| 11 | เทียบจำนวนไฟล์อัปโหลด ก่อนสำรอง ↔ หลังกู้คืน | สำเร็จ | 1 ↔ 1 ไฟล์ |

## 4. เปรียบเทียบจำนวนแถวรายตาราง

| ตาราง | ก่อนสำรอง (แถว) | หลังกู้คืน (แถว) | ผล |
|---|---:|---:|---|
| `AiConfigSetting` | 26 | 26 | ตรงกัน |
| `AlertEmailLog` | 2 | 2 | ตรงกัน |
| `ApiRequestLog` | 7236 | 7236 | ตรงกัน |
| `AuditLog` | 121 | 121 | ตรงกัน |
| `Chunk` | 4393 | 4393 | ตรงกัน |
| `Citation` | 3300 | 3300 | ตรงกัน |
| `ConfigSnapshot` | 10 | 10 | ตรงกัน |
| `Conversation` | 490 | 490 | ตรงกัน |
| `DefectLog` | 2 | 2 | ตรงกัน |
| `EvaluationDataset` | 8 | 8 | ตรงกัน |
| `EvaluationItem` | 620 | 620 | ตรงกัน |
| `EvaluationResult` | 2520 | 2520 | ตรงกัน |
| `EvaluationRun` | 30 | 30 | ตรงกัน |
| `Feedback` | 130 | 130 | ตรงกัน |
| `GuardrailTopic` | 15 | 15 | ตรงกัน |
| `IngestionJob` | 4 | 4 | ตรงกัน |
| `IngestionJobItem` | 171 | 171 | ตรงกัน |
| `KnowledgeDocument` | 330 | 330 | ตรงกัน |
| `LlmPricing` | 6 | 6 | ตรงกัน |
| `LoginAttempt` | 72 | 72 | ตรงกัน |
| `Message` | 1268 | 1268 | ตรงกัน |
| `PrivacyRequest` | 1 | 1 | ตรงกัน |
| `PromptVersion` | 6 | 6 | ตรงกัน |
| `TokenUsage` | 5128 | 5128 | ตรงกัน |
| `User` | 44 | 44 | ตรงกัน |
| `_prisma_migrations` | 2 | 2 | ตรงกัน |
| **รวม** | **25935** | **25935** | ตรงกัน |

## 5. การตรวจสอบเพิ่มเติม

| รายการตรวจ | ก่อนสำรอง | หลังกู้คืน |
|---|---|---|
| `PRAGMA integrity_check` | - | ok |
| ตาราง marker `_restore_test_marker` (เพิ่มหลังสำรอง) | ไม่มี | ไม่มี (ถูกต้อง) |
| SHA-256 ของ `.dump` | `e45c2281d64177d2ae4ce32d22e833a82eee83911c242bea6b50a17ea7bc95ec` | `e45c2281d64177d2ae4ce32d22e833a82eee83911c242bea6b50a17ea7bc95ec` |
| จำนวนไฟล์อัปโหลด | 1 | 1 |

## 6. สรุป

ผลการทดสอบ Restore: **ผ่าน (PASS)** — ใช้เวลารวม 1.59 วินาที

- วิธีทำซ้ำ: `npm run report:restore-test` หรือ `bash scripts/restore-test.sh`
- การสำรอง/กู้คืนจริง: `bash scripts/backup-db.sh` และ `bash scripts/restore-db.sh backups/<timestamp>.db` (ดูหน้า `/admin/backup`)
- Production (PostgreSQL 16 + Object Storage ตาม Solution Architecture): ใช้ขั้นตอนเดียวกัน — สำรอง (`pg_dump`/PITR + snapshot ของ bucket) → กู้คืนลง instance แยก → เทียบจำนวนแถวรายตาราง → ออกรายงาน โดยไม่กระทบระบบที่ให้บริการอยู่
