งูต้นฉบับกำลังย้ายแผ่นข้อมูลทีละหน้าไปยังตู้สำรองอีกใบโดยมีประตูกั้นชัดเจน

Python sqlite3 backup: สำรองฐานข้อมูลทีละหน้าโดยไม่ copy ไฟล์ที่กำลังเขียน

พี่โชว์Engineering

การ copy ไฟล์ฐานข้อมูลขณะที่ SQLite กำลังเขียนอาจได้ไฟล์หลักที่ไม่ตรงกับ WAL หรือ transaction ณ จังหวะเดียวกันครับ Connection.backup ใช้ Online Backup API คัดลอกฐานข้อมูลจาก connection ต้นทางไปปลายทางเป็นชุดหน้าอย่างสอดคล้อง

WHY: ถ่ายสำเนาสมุดบัญชีตามหน้าที่ล็อกไว้

เหมือนพนักงานถ่ายสำเนาสมุดทีละหน้าโดยประสานกับคนเขียน ไม่ใช่คว้ากระดาษจากโต๊ะกลางประโยค Backup API จัดการ snapshot และ lock ภายในให้ แต่เรายังต้องเลือกปลายทาง, ตรวจผล และรักษาสำเนาไม่ให้ถูกเขียนทับโดยงานอื่น

import sqlite3
import unittest


def snapshot(source: sqlite3.Connection) -> sqlite3.Connection:
    destination = sqlite3.connect(":memory:")
    source.backup(destination, pages=1)
    return destination


class BackupTests(unittest.TestCase):
    def test_backup_is_independent_snapshot(self):
        source = sqlite3.connect(":memory:")
        self.addCleanup(source.close)
        source.execute("create table jobs (id integer primary key, name text)")
        source.executemany("insert into jobs(name) values (?)", [("build",), ("test",)])
        source.commit()

        copy = snapshot(source)
        self.addCleanup(copy.close)
        source.execute("insert into jobs(name) values ('deploy')")
        source.commit()

        names = [row[0] for row in copy.execute("select name from jobs order by id")]
        self.assertEqual(names, ["build", "test"])
        self.assertEqual(copy.execute("pragma integrity_check").fetchone()[0], "ok")


if __name__ == "__main__":
    unittest.main()

Backup ผ่าน ไม่ได้แปลว่า restore ผ่าน

กำหนดเส้นทางปลายทางนอก directory ที่ source ใช้และใช้ชื่อชั่วคราวก่อน atomic rename เมื่อเสร็จ ตรวจ PRAGMA integrity_check, schema/version และลอง query ที่เป็นตัวแทน การสำรองที่ไม่เคย restore เหมือนมีร่มที่ไม่เคยกางจนวันฝนตกครับ

pages และ sleep ช่วยแบ่งงานเพื่อลดช่วง lock แต่ไม่ใช่ SLA สำเร็จรูป ต้องวัดกับ write load จริง เข้ารหัสและจำกัดสิทธิ์ไฟล์ backup แยกจากฐานข้อมูลสด เพราะสำเนามักรวมข้อมูลลับเต็มชุด และบันทึก retention/rotation ให้ชัด

Recap

  • ใช้ Backup API แทน copy ไฟล์ฐานข้อมูลที่ยังเปิดใช้งาน
  • commit state ที่ต้องการก่อนเริ่ม snapshot
  • ตรวจ integrity และทำ restore drill จริง
  • ปกป้อง encryption, access และ retention ของสำเนา