- Litestream VFS เป็นส่วนขยายแบบปลั๊กอินที่ทำให้สามารถอ่านและคิวรีฐานข้อมูล SQLite ได้โดยตรงจาก object storage (เช่น S3)
- สามารถ คิวรีจากไฟล์แบ็กอัประยะไกลได้ทันที และทำ Point-in-Time Recovery (PITR) ได้โดยไม่ต้องดาวน์โหลดฐานข้อมูลทั้งหมด
- ภายในใช้ ฟอร์แมต LTX เพื่อจัดการชุดของเพจที่เปลี่ยนแปลงอย่างมีประสิทธิภาพ และเพิ่มความเร็วในการกู้คืนด้วย compaction ที่ข้ามเพจซ้ำ
- ใช้ อินเทอร์เฟซ VFS ของ SQLite เพื่อดักจับเฉพาะการอ่าน ส่วนการเขียนยังให้โปรเซส Litestream เดิมจัดการ
- ด้วยการแบ็กอัประดับวินาทีและการอัปเดตดัชนี จึงให้ รีพลิกาที่เกือบเรียลไทม์ และรองรับการคิวรีได้รวดเร็วในสภาพแวดล้อมคลาวด์
ภาพรวมของ Litestream VFS
- Litestream VFS เป็นความสามารถที่ทำให้ SQLite ใช้ URL ของ object storage เป็นแหล่งข้อมูลได้โดยตรง
- เปิดใช้งานจาก SQLite shell ด้วยคำสั่ง
.load litestream.so และ .open file:///my.db?vfs=litestream
- หลังจากนั้นสามารถรันคิวรีโดยอิงจากไฟล์แบ็กอัปที่เก็บไว้บน S3 ได้
- สามารถ คิวรีจากแบ็กอัประยะไกลได้โดยตรง โดยไม่ต้องดาวน์โหลดฐานข้อมูลทั้งหมด
- ในตัวอย่าง ใช้คิวรี
SELECT * FROM sandwich_ratings เพื่อดูข้อมูลบางส่วนที่เก็บอยู่บน S3 ได้ทันที
ความสามารถ Point-in-Time Recovery (PITR)
- ใช้คำสั่ง
PRAGMA litestream_time = '5 minutes ago'; เพื่อ ดูสถานะข้อมูล ณ ช่วงเวลาที่ต้องการ ได้
- ระบุได้ทั้งเวลาแบบสัมพัทธ์ (
5 minutes ago) หรือเวลาแบบแน่นอน (2000-01-01T00:00:00Z)
- ทำให้สามารถทำ Point-in-Time Recovery ได้ทันทีในระดับ SQL
- ในตัวอย่าง หลังจากรัน
UPDATE ผิดพลาด ก็ย้อนกลับไปดูสถานะเมื่อ 5 นาทีก่อนได้และยืนยันว่าข้อมูลถูกต้อง
ฟอร์แมต LTX และการบีบอัดข้อมูล
- Litestream v0.5 ได้รวมฟอร์แมต LTX (Litestream Transaction eXchange) เข้าไว้
- เวอร์ชันก่อนหน้าจะส่งทั้ง SQLite page เต็ม ๆ แต่ LTX จะส่งเฉพาะ ชุดของเพจที่มีลำดับ
- แกนสำคัญของ LTX คือความสามารถ “compaction” ที่เลือกใช้เฉพาะเพจเวอร์ชันล่าสุดตอนกู้คืน
- ตัวอย่าง: จาก
1 2 3 5 3 5 4 5 5 จะใช้เพียง 5, 4, 3, 2, 1 ตัวขวาสุดเท่านั้น
- LTX สามารถบีบอัดได้ไม่ใช่แค่ทั้งฐานข้อมูล แต่รวมถึง ระหว่างชุดไฟล์ LTX ด้วย ทำให้รองรับ การกู้คืนแบบ PITR ได้
- ใน trailer ของไฟล์ LTX จะมีดัชนีออฟเซ็ตของแต่ละเพจรวมอยู่ด้วย ดังนั้น
- จึงอ่านเฉพาะเพจที่ต้องใช้ผ่าน คำขอ S3 Range ได้โดยไม่ต้องดาวน์โหลดทั้งไฟล์
วิธีการทำงานของ VFS
- Litestream VFS ถูกสร้างขึ้นโดยใช้ อินเทอร์เฟซ VFS (Virtual File System) ของ SQLite
- VFS คือโครงสร้างปลั๊กอินที่ทำหน้าที่แยกชั้นการเข้าถึงระบบปฏิบัติการของ SQLite
- Litestream VFS จัดการเฉพาะการ อ่าน (Read) ส่วน การเขียน (Write) ยังเป็นหน้าที่ของโปรเซส Litestream เดิม
- เมื่อ SQLite อ่านเพจ VFS จะทำการแมปตาม ดัชนีของเพจ แทนการใช้ออฟเซ็ตไบต์ที่ร้องขอ
- จากนั้นค้นหาชื่อไฟล์ ออฟเซ็ตจริง และขนาดเพจจากดัชนี แล้วดาวน์โหลดเฉพาะบล็อกนั้นผ่าน Range header ของ S3 API
- มีการใช้ LRU cache เพื่อเก็บ “hot page” ที่ถูกเข้าถึงบ่อยไว้ในหน่วยความจำ ลดจำนวนการเรียก S3 ให้น้อยที่สุด
การรีพลิกาแบบเรียลไทม์และประสิทธิภาพ
- Litestream ทำ แบ็กอัประดับ L0 ทุก ๆ หนึ่งวินาที
- VFS จะโพลเส้นทางบน S3 เป็นระยะเพื่อ อัปเดตดัชนีแบบค่อยเป็นค่อยไป
- ผลลัพธ์คือได้ รีพลิกาที่เกือบเรียลไทม์ (near-realtime replica)
- พร้อมใช้งานได้ทันทีโดยไม่ต้องสตรีมฐานข้อมูลทั้งหมด
- โครงสร้างนี้ช่วยให้ได้ทั้ง การเริ่มต้นที่รวดเร็ว และ เวลาในการกู้คืนที่สั้น
การใช้งานและความสำคัญ
- Litestream เก็บแบ็กอัปของทุกสถานะในฐานข้อมูลไว้ด้วย ความละเอียดระดับวินาที
- หากพลาด
DELETE หรือ UPDATE ก็สามารถกู้กลับไปยังเวลาที่ต้องการได้ทันที
- ด้วยโครงสร้างที่คิวรีได้โดยตรงจาก object storage จึงทำงานได้รวดเร็วแม้ใน สภาพแวดล้อมเซิร์ฟเวอร์แบบ ephemeral
- ใช้ความสามารถพื้นฐานของ SQLite โดยไม่ต้องมีกลไกซับซ้อน จึงให้ ระบบแบ็กอัปและกู้คืนที่เรียบง่ายแต่ทรงพลัง
- มีการใช้งานอยู่ใน API ภายในของ Fly.io ด้วย และสามารถใช้งานได้อย่าง เสถียรในสภาพแวดล้อม production
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ทุกครั้งที่รู้ว่าโค้ดที่ฉันทำช่วยคนอื่นได้ก็รู้สึกดีใจมาก
psanford/sqlite3vfs
SQLite ทำงานเหมือนเดิมตามปกติ และ Litestream ก็ทำงานอย่างโปร่งใสอยู่ด้านบน
นั่นหมายความว่าสามารถทำ การกู้คืนแบบ point-in-time (PITR) ได้ด้วยแค่ SQL และ SQLite pragma
ทำให้ค้นดูข้อมูลในอดีตได้อย่างรวดเร็วโดยไม่ต้องไปแตะชุดข้อมูลโปรดักชันโดยตรง
แค่ระบุ S3 bucket ด้วย environment variable แล้วใน SQLite ก็
.load litestream.soจากนั้นใช้
PRAGMA litestream_time = '5 minutes ago';เพื่อดูข้อมูล ณ เวลาก่อนหน้าได้ทันทีbrew install sqlite3แล้วต้อง ระบุชื่อ init function เองโดยตรง แบบ
.load litestream sqlite3_litestreamvfs_initแค่ตั้งค่า
"LITESTREAM_REPLICA_URL"กับ environment variable ของ AWS keyจากนั้นโหลดส่วนขยายด้วย
temp.loadExtension("/path/to/litestream.dylib", "sqlite3_litestreamvfs_init")แล้วเปิดด้วย
file:my.db?vfs=litestreamก็ใช้ได้เลย.dylibเจอได้อย่างไรกรณีใช้งานของฉันคือใช้ SQLite DB แบบอ่านอย่างเดียว ที่เก็บอยู่บน S3 โดยตรงกับเว็บไซต์
DB จะถูกอัปเดตด้วยงาน cron อะไรทำนองนั้น ส่วนเว็บไซต์ก็อ่านข้อมูลล่าสุดผ่าน Litestream VFS อย่างเดียว
อยากรู้ว่าใช้งานแบบนี้ได้ไหม และมี Python integration module หรือเปล่า
ตอนนี้แอป Flask ของฉันดึงข้อมูลจาก Google Spreadsheet มาแปลงเป็น SQLite แล้วอัปเดตรายวัน
ดูโค้ดแอปของฉัน
และทำงานได้ตรง ๆ ใน SQLite CLI โดยไม่ต้องมีโค้ด Python เพิ่มเติม
ใช้แค่ S3 เป็น external dependency และเข้ากับ SQLite ได้ดี
ดูประสิทธิภาพ SQLite บน ZeroFS
โค้ดตัวอย่าง ncruces/go-sqlite3
ควบคุมผ่าน โค้ดโปรแกรมได้เลยโดยไม่ต้องใช้ environment variable และจัดการหลาย DB พร้อมกันได้
แต่
PRAGMA litestream_timeจะมีผล ในระดับ connection ดังนั้นถ้าใช้ connection pool ต้องระวัง.load litestream.soก็ทำให้นึกถึง ncruces/go-sqlite3 ขึ้นมาทันทีสงสัยว่าการทำให้มันใช้ได้ในสภาพแวดล้อม wasm ยากไหม
ส่วนขยาย “DuckLake” ของ DuckDB จะสร้าง snapshot ในทุกทรานแซ็กชันเพื่อให้ฟีเจอร์ “time travel”
ซึ่งคล้ายกับ PITR ของ Litestream VFS
ในโลก OLTP จะเรียกสิ่งนี้ว่าความสามารถด้านการกู้คืน ส่วนใน OLAP จะเรียกว่า “Time Travel”
DuckLake ใช้ external catalog DB (PostgreSQL/MySQL/SQLite) เพื่อประสานการเข้าถึงแบบหลายโปรเซส
ขณะที่ Litestream เปิดให้หลาย reader เข้าถึงพร้อมกันได้ผ่าน ไฟล์ LTX แบบ immutable บน S3
ทั้งสองโลกกำลังมุ่งไปสู่โครงสร้างแบบ “shared storage + metadata + compaction” เหมือนกัน
อยากให้มี การร่วมมือข้ามโปรเจกต์ แบบนี้มากขึ้น
บันทึกการออกรุ่น v0.5.3
เช่นถ้ากำลังใช้ส่วนขยายค้นหาเวกเตอร์อย่าง sqlite-vec หรือ vss อยู่
จะสามารถแบ็กอัปขึ้น S3 แบบเรียลไทม์ด้วย Litestream และ query จากระยะไกลผ่าน Litestream VFS ได้หรือไม่
คงต้องลองทดสอบดูเอง