SSD Nodes Learn Hosting plans →
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-07

VPS پر SQLite کو production میں کب استعمال کریں؟

ایک VPS پر چھوٹی apps کے لیے SQLite کیوں موزوں ہے؟ WAL mode، busy_timeout، Litestream replication اور وہ حقیقی حدود جانیں جو scale بڑھنے پر رکاوٹ بنتی ہیں۔

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

VPS پر production database کے طور پر SQLite کب درست انتخاب ہے

زیادہ تر چھوٹی ایپلی کیشنز کے لیے VPS پر production میں SQLite چلانا درست انتخاب ہے، اور وجہ سادہ ہے: ایک مشین پر ایک process کا ایک file میں لکھنا database server کا تقاضا نہیں کرتا۔ نگرانی کے لیے کوئی daemon نہیں ہوتا، firewall میں کھولنے کے لیے کوئی port نہیں ہوتا، rotate کرنے کے لیے کوئی password نہیں ہوتا، اور فعال رکھنے کے لیے دوسری مشین نہیں ہوتی۔ کوئی query network round trip کے بجائے function call ہوتی ہے، اس لیے چالیس queries چلانے والا page چالیس function calls کی لاگت رکھتا ہے۔

اس کی حدود واضح اور حقیقی ہیں۔ پورے database file میں ایک وقت میں صرف ایک writer ہو سکتا ہے، اور یہ file دو مشینوں کے درمیان share نہیں کی جا سکتی۔ ایک VPS پر ایک application چلانے کے لیے دونوں حدود قابل قبول ہیں۔ لیکن جیسے ہی آپ اس ساخت سے آگے بڑھتے ہیں، دونوں حدود فیصلہ کن رکاوٹ بن جاتی ہیں۔ اس guide میں وہ settings شامل ہیں جو server پر SQLite کو محفوظ بناتی ہیں، Litestream کے ذریعے مسلسل backup، اور وہ مرحلہ بھی جہاں آپ کو SQLite کا استعمال روک دینا چاہیے۔

پہلے command line tool install کریں۔ ذیل کے تمام commands Ubuntu 24.04 پر چلائے گئے ہیں۔

sudo apt update
sudo apt install -y sqlite3
sqlite3 --version

یہ ایک ایسی version دکھاتا ہے جو 3. سے شروع ہوتی ہے، اس کے بعد build date اور source hash ہوتا ہے۔ July 2026 تک Ubuntu 24.04 میں SQLite 3.45.1 شامل ہے۔ ممکن ہے آپ کی application یہ binary استعمال نہ کرتی ہو: زیادہ تر language runtimes اپنی SQLite library کی copy شامل کرتے ہیں، جو اکثر زیادہ نئی ہوتی ہے۔ اس لیے کسی حالیہ feature پر انحصار کرنے سے پہلے اپنے database driver کی رپورٹ کردہ version چیک کریں۔

WAL mode میں سب سے پہلے یہی تبدیلی کیوں کی جاتی ہے

ڈیفالٹ طور پر SQLite rollback journal استعمال کرتا ہے۔ کسی page کو تبدیل کرنے سے پہلے یہ اصل page کو ایک -journal file میں copy کرتا ہے، پھر database کو اسی جگہ edit کرتا ہے۔ یہ کام محفوظ طریقے سے کرنے کے لیے پوری file پر exclusive lock لگایا جاتا ہے، اس لیے write جاری ہونے کے دوران ہر reader انتظار کرتا ہے۔ Laptop پر اس کا عموماً پتا نہیں چلتا۔ Web server پر ایک سست write database کو استعمال کرنے والی ہر request کو روک دیتی ہے۔

WAL (write-ahead log) mode اس ترتیب کو الٹ دیتا ہے۔ Writer نئے pages ایک الگ -wal file میں append کرتا ہے اور main database کو تبدیل نہیں کرتا۔ Readers اس snapshot کے مطابق main file پڑھتے رہتے ہیں جو انہوں نے شروع میں حاصل کیا تھا، اس لیے readers writer کو block نہیں کرتے اور writer readers کو block نہیں کرتا۔ بعد میں checkpoint، جمع شدہ WAL pages کو main database میں واپس copy کرتا ہے۔ یہی ایک تبدیلی SQLite کو web application کے پیچھے استعمال کے قابل بنانے میں سب سے بڑا کردار ادا کرتی ہے۔

WAL موڈ فعال کریں اور تصدیق کریں کہ یہ برقرار ہے

mkdir -p ~/app
sqlite3 ~/app/app.db "PRAGMA journal_mode=WAL;"

کمانڈ wal دکھاتی ہے۔ یہ آؤٹ پٹ محض نمائشی نہیں ہے۔ PRAGMA journal_mode وہ موڈ واپس کرتا ہے جس میں database فی الحال کام کر رہا ہے، اس لیے delete کا جواب ملنے کا مطلب ہے کہ تبدیلی ناکام ہو گئی اور آپ اب بھی rollback journal پر ہیں۔

WAL موڈ مستقل رہتا ہے۔ یہ connection setting کے بجائے database header میں موجود ایک flag ہے، اس لیے اسے ہر database file کے لیے صرف ایک بار چلائیں۔ اس کے بعد ہر connection اسے اختیار کرے گا، reboot کے بعد بھی۔ نئی connection کے ذریعے اس کی تصدیق کریں۔

sqlite3 ~/app/app.db "PRAGMA journal_mode;"

اب ایک table بنائیں اور دیکھیں کہ disk پر کیا ظاہر ہوتا ہے۔

sqlite3 ~/app/app.db <<'SQL'
CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT NOT NULL);
INSERT INTO notes (body) VALUES ('first row');
SQL
ls -l ~/app/

اب تین files موجود ہیں: app.db، app.db-wal اور app.db-shm۔ -wal file میں وہ committed pages موجود ہوتے ہیں جن کا ابھی checkpoint نہیں لیا گیا۔ -shm file ایک shared memory index ہے جسے ہر connection map کرتا ہے، تاکہ سب connections WAL کے مواد پر متفق رہیں۔ دونوں files database کا حصہ ہیں، scratch files نہیں۔ Application کے چلتے ہوئے صرف app.db کو copy کرنے سے ایسی file ملے گی جس میں حالیہ commits موجود نہیں ہوں گے۔ app.db کو delete کر کے باقی دونوں files اسی جگہ چھوڑ دیں تو SQLite ان پرانے WAL pages کو اس نام سے بننے والی نئی file پر apply کر دے گا۔ اسی طرح database کو reset کرنے کی کوشش میں لوگ نئی database کو corrupt کر دیتے ہیں۔

ہر production ایپ کے لیے ضروری connection settings

صرف journal_mode database میں محفوظ ہوتا ہے۔ ذیل کی ہر دوسری setting فی connection ہوتی ہے۔ اس کا مطلب ہے کہ آپ کی application کو ہر کھولے گئے connection پر اسے چلانا ہوگا، بشمول ہر اس connection کے جسے pool پس منظر میں بناتا ہے۔

PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 5000;
PRAGMA synchronous = NORMAL;
PRAGMA foreign_keys = ON;

busy_timeout = 5000، SQLite کو locked database کے لیے زیادہ سے زیادہ 5000 milliseconds تک دوبارہ کوشش کرنے کی ہدایت دیتا ہے، اس کے بعد database is locked واپس کرتا ہے۔ default قدر 0 ہے، اس لیے default طور پر جب دو writers ایک ہی وقت میں کام کرتے ہیں تو SQLite پہلی ہی بار فوراً fail ہو جاتا ہے۔ صرف یہ ایک value set کرنے سے lock errors کی زیادہ تر وجوہات ختم ہو جاتی ہیں جن کا الزام SQLite پر عائد کیا جاتا ہے۔

synchronous = NORMAL، WAL mode میں درست setting ہے، اور اس کے trade-off کو سمجھنا ضروری ہے۔ FULL پر SQLite ہر commit کے وقت WAL پر fsync چلاتا ہے۔ NORMAL پر یہ checkpoints کے وقت sync کرتا ہے۔ SQLite documentation واضح طور پر بتاتی ہے کہ اس کے بدلے آپ کیا چھوڑتے ہیں: power failure یا hard reset کے بعد transactions پائیدار نہیں رہتے۔ اس power loss سے database corrupt نہیں ہوتا؛ صرف وہ آخری commits ضائع ہوتے ہیں جو disk تک نہیں پہنچے تھے۔ VPS پر عموماً یہ مناسب trade-off ہے، کیونکہ اس سے ہر write کے راستے سے fsync کا ایک مرحلہ نکل جاتا ہے۔

foreign_keys = ON، backwards compatibility کی خاطر default طور پر off ہوتا ہے، اور یہ فی connection ہوتا ہے۔ REFERENCES clauses سے بھرا ہوا schema اس وقت تک کسی چیز کو enforce نہیں کرتا جب تک ہر connection اسے on نہ کر دے۔

ایک اور setting بعد کے مرحلے میں اہم ہوتی ہے۔ WAL کے 1000 pages سے بڑا ہونے پر SQLite خودکار طور پر checkpoint کرتا ہے، اور یہ کام وہ connection کرتا ہے جو اس لمحے transaction مکمل کرتا ہے۔ اپنے طور پر یہ ٹھیک ہے۔ لیکن جب Litestream چل رہا ہو تو یہ ایک سوال بن جاتا ہے، کیونکہ Litestream چاہتا ہے کہ checkpoints کب ہوں، اس پر اس کا کنٹرول ہو۔

busy_timeout مقرر کرنے کے بعد بھی database is locked کیوں جاری رہتا ہے

یہ وہ failure ہے جس کی وجہ سے لوگ واپس Postgres کی طرف چلے جاتے ہیں، اور اس کی ایک مخصوص وجہ ہے۔

Busy timeout ایک busy handler نصب کرتا ہے، لیکن SQLite یہ ضمانت نہیں دیتا کہ وہ اسے ضرور call کرے گا۔

اگر SQLite یہ تعین کرے کہ busy handler کو call کرنے سے deadlock پیدا ہو سکتا ہے، تو وہ busy handler کو call کرنے کے بجائے application کو SQLITE_BUSY واپس کر دیتا ہے۔

جس deadlock سے یہ بچ رہا ہوتا ہے، وہ transaction کے upgrade ہونے کے وقت پیدا ہوتا ہے۔ SQLite میں صرف BEGIN کا مطلب BEGIN DEFERRED ہے۔ اگر اس کے بعد پہلا statement SELECT ہو، تو آپ read transaction میں ہیں۔ جب اسی transaction میں بعد کا UPDATE write transaction میں تبدیل ہونا چاہے، اور آپ کے read شروع کرنے کے بعد کسی دوسری connection نے write کیا ہو، تو SQLite آپ کو انتظار نہیں کرا سکتا، کیونکہ آپ کا snapshot پہلے ہی outdated ہو چکا ہے اور انتظار صرف دونوں connections کو ایک دوسرے کے خلاف deadlock میں مبتلا کرے گا۔ Documentation نتیجہ براہِ راست بیان کرتی ہے:

بعد کے write statements ممکن ہونے کی صورت میں transaction کو write transaction میں upgrade کریں گے، ورنہ SQLITE_BUSY واپس کریں گے۔

آپ کا 5000 millisecond timeout کبھی consult ہی نہیں کیا جاتا۔ Error فوراً آ جاتا ہے، اسی لیے محسوس ہوتا ہے کہ setting نے کوئی کام نہیں کیا۔

حل ایک لفظ ہے۔

BEGIN IMMEDIATE;
UPDATE notes SET body = 'edited' WHERE id = 1;
COMMIT;

BEGIN IMMEDIATE ابتدا ہی میں write lock حاصل کرتا ہے، یعنی کچھ بھی read کرنے سے پہلے۔ اس لیے upgrade نہیں ہوتا، deadlock سے بچنے کی ضرورت نہیں رہتی، اور busy handler لاگو ہو جاتا ہے۔ Connection failure کے بجائے اپنی باری کا انتظار کرتی ہے۔ Read-only transactions کو deferred رہنے دیں۔ جس transaction میں write شامل ہو، اسے immediate ہونا چاہیے۔

Lock errors کی دوسری وجہ تلاش کرنا زیادہ مشکل ہے: write transaction کو slow work کے دوران کھلا رکھنا۔ SQLite writers کو serialise کرتا ہے، اس لیے جو transaction کھلنے کے بعد network کے ذریعے کسی external API کو call کرے اور پھر commit کرے، وہ اس call کے پورے دورانیے میں ہر دوسرے writer کو block کرے گا۔ مطلوبہ data read کریں، transaction بند کریں، slow work مکمل کریں، پھر result محفوظ کرنے کے لیے ایک مختصر write transaction کھولیں۔

Litestream کے ساتھ مسلسل backup

رات کو بنائی گئی copy میں ایک دن تک کی writes ضائع ہو سکتی ہیں، اور live SQLite database پر cp چلانے سے ایسی copy بن سکتی ہے جو open نہ ہو۔ دو طریقے محفوظ ہیں۔ sqlite3 app.db ".backup /path/to/backup.db"، SQLite کا online backup interface استعمال کرتا ہے اور زیرِ استعمال database پر کام کرتا ہے۔ Litestream اس سے آگے جاتا ہے: یہ WAL کو monitor کرتا ہے اور تبدیلیاں مسلسل object storage میں بھیجتا ہے۔ اس طرح بدترین صورت میں data loss ایک دن سے کم ہو کر تقریباً ایک second رہ جاتا ہے۔

Litestream ایک Go binary ہے جو آپ کی application کے ساتھ چلتا ہے۔ یہ application اور database کے درمیان کام نہیں کرتا۔ آپ کی application پہلے کی طرح SQLite میں writes کرتی ہے، اور Litestream WAL پڑھ کر تبدیل شدہ data upload کرتا ہے۔

cd /tmp
curl -fsSL -O https://github.com/benbjohnson/litestream/releases/download/v0.5.14/litestream-0.5.14-linux-x86_64.deb
sudo dpkg -i litestream-0.5.14-linux-x86_64.deb
litestream version

July 2026 تک official Linux install page میں v0.5.14 درج ہے، جبکہ v0.5.15 21 July 2026 کو جاری ہوا۔ دونوں lines میں version کو releases page پر موجود موجودہ tag کے مطابق تبدیل کریں۔ اگر آپ کا VPS arm64 ہے تو اسی version کا arm64 package استعمال کریں۔

Configuration file /etc/litestream.yml پر موجود ہوتی ہے۔ ابتدا local file replica سے کریں، کیونکہ اس سے cloud credentials کے بغیر پورا عمل verify ہو جاتا ہے۔

dbs:
  - path: /home/appuser/app/app.db
    replica:
      type: file
      path: /var/backups/litestream/app

یاد رکھیں کہ field replica ہے، یعنی singular۔ Litestream 0.5 نے 0.3 series کے replicas array کی جگہ ایک single replica block متعارف کرایا ہے۔ اب دو entries والی config startup پر fail ہو جاتی ہے۔ بہت سی third-party guides اب بھی پرانا array دکھاتی ہیں، اس لیے search میں ملنے والی پہلی example کے بجائے اوپر دیا گیا structure copy کریں۔ 0.5 series نے litestream wal subcommand کا نام بھی litestream ltx کر دیا ہے، کیونکہ disk پر محفوظ backup format تبدیل ہو گیا تھا۔

کسی بھی چیز کو enable کرنے سے پہلے تصدیق کریں کہ config parse ہو رہی ہے۔

sudo litestream databases -config /etc/litestream.yml

اس کے بعد round trip کو manually verify کریں۔ یہ طریقہ config file کو نظرانداز کرتا ہے اور ایک database کو ایک path پر replicate کرتا ہے۔

mkdir -p /tmp/replica
litestream replicate ~/app/app.db file:///tmp/replica/app

یہ command foreground میں چلتی رہتی ہے۔ دوسری shell میں ایک row لکھیں اور replica کو نئی file میں restore کریں۔

sqlite3 ~/app/app.db "INSERT INTO notes (body) VALUES ('written after replication started');"
litestream restore -o /tmp/restored.db file:///tmp/replica/app
sqlite3 /tmp/restored.db "SELECT count(*) FROM notes;"

Count میں نئی row شامل ہونی چاہیے۔ اگر ایسا نہ ہو تو تبدیلی ابھی sync نہیں ہوئی۔ Litestream sync-interval پر data push کرتا ہے، جس کی default value 1 second ہے۔ کچھ دیر انتظار کریں اور دوبارہ restore کریں۔ یہی 1 second آپ کا recovery point بھی ہے۔ Crash کی صورت میں زیادہ سے زیادہ آخری sync interval کے دوران کی writes ضائع ہو سکتی ہیں، اور کوئی configuration اس نقصان کو zero نہیں کر سکتی۔

حقیقی storage کے لیے replica block کو S3 URL سے تبدیل کریں۔ یہ Amazon S3 اور دوسرے providers کے S3-compatible object storage دونوں کے ساتھ کام کرتا ہے۔

dbs:
  - path: /home/appuser/app/app.db
    replica:
      url: s3://your-bucket-name/app
      region: us-east-1

snapshot:
  interval: 24h
  retention: 24h

Credentials کو اس file میں نہ رکھیں۔ Litestream LITESTREAM_ACCESS_KEY_ID اور LITESTREAM_SECRET_ACCESS_KEY کو environment سے پڑھتا ہے۔ انہیں root کی ملکیت والے systemd drop-in میں mode 600 کے ساتھ رکھیں۔

اوپر دی گئی snapshot values defaults ہیں، اور retention کا default اکثر غیر متوقع ہوتا ہے۔ Retention سے مراد وہ مدت ہے جس کے دوران Litestream snapshots اور ان سے متعلق files محفوظ رکھتا ہے۔ اسی سے یہ بھی طے ہوتا ہے کہ آپ ماضی میں کتنی دور تک restore کر سکتے ہیں۔ Twenty-four hours کا مطلب ہے کہ Wednesday morning کو معلوم ہونے والی خراب migration کے بعد Monday کی state سے restore کرنا ممکن نہیں رہے گا۔ retention: 168h کو ایک week مقرر کریں اور اضافی storage کی لاگت قبول کریں۔

ضرورت پڑنے سے پہلے restore کی تصدیق کریں

litestream restore -o /tmp/check.db /home/appuser/app/app.db
sqlite3 /tmp/check.db "PRAGMA integrity_check;"
sqlite3 /tmp/check.db "SELECT count(*) FROM notes;"

Database path دینے پر litestream restore، /etc/litestream.yml میں متعلقہ replica تلاش کرتا ہے اور اسے download کر لیتا ہے۔ صحت مند file کے لیے PRAGMA integrity_check، ok دکھاتا ہے۔ کوئی بھی دوسری output اس بات کی نشاندہی کرتی ہے کہ restore شدہ copy قابل استعمال نہیں ہے۔ اسے systemd service اور timer کے ساتھ مقررہ schedule پر چلائیں اور output پڑھیں۔ جب تک آپ backup کو کم از کم ایک بار restore نہ کر لیں، آپ کو معلوم نہیں ہو سکتا کہ یہ کام کرتا ہے۔

systemd کے تحت Litestream چلائیں

Debian package ایک litestream unit انسٹال کرتا ہے جو /etc/litestream.yml کو پڑھتی ہے۔

sudo systemctl enable litestream
sudo systemctl start litestream
sudo journalctl -u litestream -f

درست output میں config سے ہر database کا نام آتا ہے، پھر periodic sync lines کے علاوہ output خاموش رہتا ہے۔ آپ کے database path کے بارے میں no such file or directory کی error کا مطلب ہے کہ config میں path غلط ہے، یا process اسے پڑھ نہیں سکتا۔ Unit بطور default root کے طور پر چلتی ہے، جو اس کام کے لیے درکار privilege سے زیادہ ہے۔ Litestream کو database اور اسے رکھنے والی directory، دونوں کو read اور write کرنے کی اجازت ہونی چاہیے، کیونکہ یہ آپ کے database کے ساتھ موجود -wal اور -shm files کے ساتھ کام کرتا ہے۔ اس لیے وہی account استعمال کریں جو آپ کی application پہلے سے استعمال کرتی ہے۔

# /etc/systemd/system/litestream.service.d/override.conf
[Service]
User=appuser
Group=appuser

اسے sudo systemctl daemon-reload اور sudo systemctl restart litestream کے ذریعے نافذ کریں۔ least privilege کے ساتھ dedicated service account بنانا چند منٹ لیتا ہے۔ یہی backup agent اور server پر چلنے والے دوسرے root process کے درمیان بنیادی فرق ہے۔

اگر آپ کبھی machine کو مکمل طور پر دوبارہ بنائیں تو ایک ترتیب اہم ہے۔ آپ چاہتے ہیں کہ application شروع ہونے سے پہلے database restore ہو جائے۔ litestream restore، -if-db-not-exists قبول کرتا ہے، جو file پہلے سے موجود ہونے کی صورت میں 0 کے ساتھ exit کرتا ہے۔ اس لیے اسے ہر boot پر محفوظ طریقے سے چلایا جا سکتا ہے۔ اسے اپنی application کی unit میں ExecStartPre line کے طور پر شامل کریں۔ اس طرح نیا VPS database download کر لے گا، جبکہ موجودہ VPS پر کچھ نہیں ہوگا۔ اگر آپ اسے ایک ہی جگہ رکھنا چاہیں تو litestream replicate میں متعلقہ -restore-if-db-not-exists flag موجود ہے۔

VPS پر SQLite کہاں ناکام ہوتا ہے

Network filesystems۔ یہ وہ حد ہے جس کے لیے configuration سے کوئی حل نہیں نکالا جا سکتا۔ WAL mode کے لیے ضروری ہے کہ database استعمال کرنے والا ہر process memory کے ایک چھوٹے حصے تک مشترکہ رسائی رکھے، اور یہی حصہ -shm file فراہم کرتی ہے۔ SQLite documentation میں یہ اصول بغیر کسی استثنا کے بیان کیا گیا ہے:

Database استعمال کرنے والے تمام processes ایک ہی host computer پر ہونے چاہییں؛ WAL، network filesystem پر کام نہیں کرتا۔

اس لیے mounted NFS (network file system) یا SMB share پر موجود database خراب ہو سکتا ہے، اور کوئی pragma اسے نہیں روک سکتا۔ یہاں ایک اہم فرق ہے جسے لوگ نظرانداز کر دیتے ہیں۔ Network block device، جسے زیادہ تر VPS providers اضافی storage کے طور پر attach کرتے ہیں، Linux کو ایک عام disk دکھاتا ہے جس پر عام filesystem ہوتا ہے، اور یہ صورت درست ہے۔ Mounted file share اس سے مختلف ہے۔

دوسرا application server۔ کوئی setting اس arrangement کو قابلِ عمل نہیں بناتی۔ جب ایک ہی data فراہم کرنے کے لیے دو machines درکار ہوں، تو آپ کو ایسی database درکار ہوتی ہے جو network کے ذریعے کام کرے۔ اس تبدیلی کا فیصلہ اس وقت کریں جب planning کے لیے ابھی وقت موجود ہو۔

Write-heavy workloads۔ ایک وقت میں صرف ایک writer کا کام کرنا file format کی خصوصیت ہے، tunable setting نہیں۔ مختصر writes کم لاگت رکھتی ہیں کیونکہ ہر commit، WAL میں append ہوتا ہے؛ اس لیے throughput کا تعلق CPU کے مقابلے میں disk کی small-write latency سے زیادہ ہوتا ہے۔ اس فرق کی وضاحت کے لیے VPS پر NVMe اور SATA SSD storage کا موازنہ دیکھیں۔ اصل مسئلہ طویل transactions ہیں، کیونکہ وہ ہر دوسرے writer کو اپنے پیچھے queue میں کھڑا کر دیتی ہیں۔

Analytical queries۔ SQLite ایک row store ہے جو transactions کے لیے بنایا گیا ہے۔ سو million rows کو scan کرنے والا dashboard ایک مختلف کام ہے اور اس کے لیے مختلف tool درکار ہے۔ server work کے لیے DuckDB اور SQLite کا موازنہ میں بتایا گیا ہے کہ یہ حد کہاں آتی ہے۔

Replication کے دوران VACUUM۔ مکمل VACUUM پورے database file کو دوبارہ لکھتا ہے۔ اس کا مطلب ہے کہ Litestream کو اسے دوبارہ مکمل طور پر upload کرنا پڑتا ہے، اور Litestream documentation replication فعال ہونے کے دوران اسے اسی جگہ چلانے سے منع کرتی ہے۔ Replicator روکیں، vacuum چلائیں، اسے دوبارہ شروع کریں، اور نئے مکمل snapshot کی توقع رکھیں۔

ایک database پر دو replicators۔ ایک ہی database یا ایک ہی replica destination کے خلاف کبھی دو Litestream processes نہ چلائیں۔ Documentation واضح طور پر کہتی ہے کہ اسے روکنے کی ذمہ داری آپ کی ہے، اور اس کا نتیجہ ایسا replica ہوتا ہے جسے restore نہیں کیا جا سکتا۔

Litestream کیا cover نہیں کرتا

Litestream صرف database file کو محفوظ کرتا ہے، اس کے علاوہ کچھ نہیں۔ Uploaded files، application config، TLS (transport layer security) certificates اور unit files کا انتظام آپ کو خود کرنا ہوگا۔ مقررہ schedule کے مطابق اسے restic کے ذریعے encrypted off-box backups کے ساتھ استعمال کریں، تاکہ دونوں حصے محفوظ رہیں۔ اگر machine نئی ہے تو نئے VPS کے پہلے دس منٹ میں user account اور firewall کا وہ کام شامل ہے جسے یہ guide پہلے سے مکمل فرض کرتی ہے۔

FAQ

کیا production application کے لیے SQLite کافی ہے؟

ایک سرور پر ایک application کے لیے ہاں، بشرطیکہ آپ WAL mode فعال کریں، busy timeout مقرر کریں، اور مسلسل backup لیتے رہیں۔ اہم حدود ساختی ہیں: ایک وقت میں صرف ایک writer، اور صرف ایک host machine۔ جو application ان حدود کے اندر ہو، اسے network hop اور نگرانی کے لیے الگ process کے بغیر database مل جاتا ہے۔ جو application ان حدود میں نہ آتی ہو، اسے client-server database درکار ہے؛ tuning کی کوئی مقدار اس حقیقت کو تبدیل نہیں کر سکتی۔

busy_timeout مقرر کرنے کے بعد بھی مجھے database is locked کیوں ملتا ہے؟

کیونکہ انتظار سے deadlock پیدا ہونے کا امکان ہو تو SQLite busy handler کو نظرانداز کر دیتا ہے۔ جو transaction سادہ BEGIN سے شروع ہو، وہ deferred ہوتا ہے: ابتدائی SELECT اسے read transaction میں رکھتا ہے، اور بعد کی write کو upgrade کرنا پڑتا ہے۔ اگر اس دوران کسی دوسرے connection نے write کی ہو تو SQLite آپ کے busy handler کو چلانے کے بجائے فوراً SQLITE_BUSY واپس کرتا ہے، کیونکہ آپ کا read snapshot پہلے ہی پرانا ہو چکا ہوتا ہے۔ جو transaction write کرے گا، اسے BEGIN IMMEDIATE سے شروع کریں تاکہ write lock ابتدا ہی میں حاصل ہو جائے اور timeout مؤثر ہو۔

کیا میں اپنی SQLite database کو network storage پر رکھ سکتا ہوں؟

NFS یا SMB جیسے network filesystem پر نہیں۔ WAL mode کے لیے تمام processes کو -shm file کے ذریعے memory شیئر کرنا ضروری ہے، اور SQLite documentation کے مطابق database استعمال کرنے والا ہر process اسی host computer پر ہونا چاہیے۔ آپ کے provider سے منسلک network block device مختلف چیز ہے: Linux اسے معمول کی disk اور اس پر موجود معمول کے filesystem کے طور پر دیکھتا ہے، اور SQLite وہاں کام کرتا ہے۔

اگر میں پہلے ہی nightly backups چلا رہا ہوں تو کیا مجھے Litestream کی ضرورت ہے؟

یہ اس بات پر منحصر ہے کہ آپ کتنا data ضائع ہونے کا نقصان برداشت کر سکتے ہیں۔ nightly job کا مطلب ہے کہ زیادہ سے زیادہ چوبیس گھنٹے کی writes ضائع ہو سکتی ہیں۔ Litestream تقریباً ہر ایک second میں sync کرتا ہے، اس لیے crash کی صورت میں عموماً صرف آخری second کا data ضائع ہوتا ہے۔ یہ cp کے ذریعے database file copy کرنے سے بھی محفوظ ہے، کیونکہ اس طرح database کو write کے دوران copy کیا جا سکتا ہے۔ Litestream صرف database کا احاطہ کرتا ہے، اس لیے اس کے ساتھ عمومی file backup بھی چلاتے رہیں۔

#sqlite#wal#litestream#backups#production