SQLite في الإنتاج على VPS: الإعداد والحدود
تعرّف إلى إعداد SQLite على VPS مع WAL وbusy_timeout وLitestream، ولماذا يهم إصدار Ubuntu 24.04 SQLite 3.45.1 ومتى تحتاج إلى قاعدة بيانات أخرى.
متى تكون SQLite قاعدة بيانات الإنتاج المناسبة على VPS
يُعد تشغيل SQLite في بيئة الإنتاج على VPS الخيار المناسب لمعظم التطبيقات الصغيرة. والسبب بسيط: العملية الواحدة على جهاز واحد، التي تكتب في ملف واحد، لا تحتاج إلى خادم قاعدة بيانات. لا توجد خدمة خفية تحتاج إلى مراقبة، ولا منفذ يحتاج إلى إعداد قواعد جدار الحماية، ولا كلمة مرور تحتاج إلى تدويرها، ولا جهاز ثانٍ يجب إبقاؤه قيد التشغيل. يُنفَّذ الاستعلام على شكل استدعاء دالة بدلًا من رحلة ذهاب وإياب عبر الشبكة. لذلك، فإن الصفحة التي تنفذ أربعين استعلامًا تستهلك أربعين استدعاء دالة.
التكلفة محدودة وحقيقية. تسمح SQLite بكاتب واحد فقط في كل مرة على مستوى ملف قاعدة البيانات بالكامل، ولا يمكن مشاركة الملف بين جهازين. كلا الحدين مناسب لتطبيق واحد يعمل على VPS واحد. لكن كلاهما يصبح عائقًا حاسمًا بمجرد أن تتجاوز هذا النمط. يغطي هذا الدليل الإعدادات التي تجعل SQLite آمنة على الخادم، والنسخ الاحتياطي المستمر باستخدام Litestream، والنقطة التي ينبغي عندها التوقف عن استخدامها.
ثبّت أداة سطر الأوامر أولًا. نُفّذ كل ما يلي على Ubuntu 24.04.
sudo apt update
sudo apt install -y sqlite3
sqlite3 --versionيطبع ذلك إصدارًا يبدأ بـ 3.، ويتبعه تاريخ البناء وتجزئة المصدر. توفّر Ubuntu 24.04 الإصدار SQLite 3.45.1 اعتبارًا من July 2026. من المحتمل أن تطبيقك لا يستخدم هذه الثنائية؛ إذ إن معظم أوقات تشغيل اللغات تتضمن نسختها الخاصة من مكتبة SQLite، وغالبًا ما تكون أحدث منها. لذلك تحقّق من الإصدار الذي يعرضه برنامج تشغيل قاعدة البيانات لديك قبل الاعتماد على ميزة حديثة.
لماذا يكون وضع WAL أول ما تغيّره
يستخدم SQLite دفتر يوميات التراجع افتراضيًا. قبل تغيير إحدى الصفحات، ينسخ الصفحة الأصلية إلى ملف -journal، ثم يحرّر قاعدة البيانات في موضعها. ولتنفيذ ذلك بأمان، يفرض قفلًا حصريًا على الملف بأكمله، لذلك ينتظر كل قارئ ما دام أي إجراء كتابة قيد التنفيذ. على حاسوب محمول، لا يلاحظ أحد ذلك. أما على خادم ويب، فتؤدي عملية كتابة بطيئة واحدة إلى تعطيل كل طلب يصل إلى قاعدة البيانات.
يعكس وضع WAL (سجل الكتابة المسبقة) هذا الترتيب. يضيف الكاتب الصفحات الجديدة إلى ملف -wal منفصل، ويترك قاعدة البيانات الرئيسية دون تغيير. يواصل القراء قراءة الملف الرئيسي عند اللقطة التي بدأوا بها، لذلك لا يحجب القراء الكاتب، ولا يحجب الكاتب القراء. لاحقًا، تنسخ نقطة تحقق صفحات WAL المتراكمة إلى قاعدة البيانات الرئيسية. هذا التغيير وحده هو العامل الأكبر الذي يجعل SQLite قابلًا للاستخدام خلف تطبيق ويب.
فعّل وضع WAL وتحقق من ثباته
mkdir -p ~/app
sqlite3 ~/app/app.db "PRAGMA journal_mode=WAL;"يطبع الأمر wal. هذا الناتج ليس للزينة. يعرض PRAGMA journal_mode الوضع الفعلي لقاعدة البيانات، لذلك تعني الإجابة delete أن التغيير فشل وأنك ما زلت تستخدم سجل التراجع.
وضع WAL مستمر. فهو علامة في ترويسة قاعدة البيانات، وليس إعدادًا للاتصال. لذلك تشغّله مرة واحدة لكل ملف قاعدة بيانات، وترثه كل الاتصالات اللاحقة، بما في ذلك بعد إعادة التشغيل. أثبت ذلك باستخدام اتصال جديد.
sqlite3 ~/app/app.db "PRAGMA journal_mode;"أنشئ الآن جدولًا وتحقق مما يظهر على القرص.
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/أصبحت هناك 3 ملفات: app.db وapp.db-wal وapp.db-shm. يحتوي ملف -wal على الصفحات المؤكدة التي لم تُنفَّذ لها checkpoint بعد. وملف -shm هو فهرس ذاكرة مشتركة تُجري كل الاتصالات mapping له، حتى تتفق جميعها على محتوى WAL. كلا الملفين جزء من قاعدة البيانات، وليسا ملفين مؤقتين. إذا نسخت app.db وحده أثناء تشغيل التطبيق، فستحصل على ملف يفتقد كل عمليات التأكيد الأخيرة. وإذا حذفت app.db وأبقيت الملفين الآخرين، فسيطبّق SQLite صفحات WAL القديمة على أي ملف جديد يظهر بهذا الاسم. هكذا تتلف قاعدة بيانات جديدة عند محاولة إعادة ضبطها.
إعدادات الاتصال التي يحتاج إليها كل تطبيق في بيئة الإنتاج
يُخزَّن journal_mode فقط في قاعدة البيانات. أما كل إعداد آخر أدناه، فهو خاص بالاتصال. لذلك يجب على تطبيقك تنفيذه على كل اتصال يفتحه، بما في ذلك كل اتصال تنشئه مجموعة الاتصالات في الخلفية.
PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 5000;
PRAGMA synchronous = NORMAL;
PRAGMA foreign_keys = ON;يخبر busy_timeout = 5000 SQLite بإعادة المحاولة عند قفل قاعدة البيانات لمدة تصل إلى 5000 ميلي ثانية قبل أن يعيد database is locked. القيمة الافتراضية هي 0. لذلك يفشل SQLite افتراضيًا فورًا عند تداخل أول عمليتي كتابة. يزيل ضبط هذه القيمة المفردة معظم أخطاء القفل التي تُنسب إلى SQLite نفسه.
يُعد synchronous = NORMAL الإعداد الصحيح في وضع WAL، ومن المهم فهم المفاضلة المرتبطة به. عند FULL، يستدعي SQLite fsync على WAL عند كل عملية تثبيت. وعند NORMAL، يجري المزامنة عند نقاط التحقق بدلًا من ذلك. توضح وثائق SQLite بصرامة ما الذي تتخلى عنه: لا تعود المعاملات متينة بعد انقطاع الطاقة أو إعادة الضبط القسري. لا يمكن أن تتلف قاعدة البيانات بسبب فقدان الطاقة هذا؛ لكنك تفقد آخر عمليات التثبيت التي لم تصل إلى القرص. على VPS، تكون هذه المفاضلة مناسبة عادةً، لأنها تزيل استدعاء fsync من مسار كل عملية كتابة.
يكون foreign_keys = ON معطلًا افتراضيًا للتوافق مع الإصدارات السابقة، وهو خاص بكل اتصال. لا تُنفِّذ قاعدة بيانات تحتوي على مخطط مليء بعبارات REFERENCES أي قيود على الإطلاق حتى يفعّل كل اتصال هذا الإعداد.
يوجد إعداد آخر لا تبرز أهميته إلا لاحقًا. ينفذ SQLite نقاط التحقق تلقائيًا عندما يتجاوز حجم WAL مقدار 1000 صفحة، وتنفذ العملَةَ أيُّ وصلة تنهي معاملة في تلك اللحظة. لا توجد مشكلة في ذلك بحد ذاته. لكن الأمر يصبح مهمًا عند تشغيل Litestream، لأن Litestream يريد التحكم في توقيت تنفيذ نقاط التحقق.
لماذا لا يزال database is locked يحدث بعد ضبط busy_timeout
هذا هو الخطأ الذي يدفع المستخدمين إلى العودة إلى Postgres، وله سبب محدد.
يُثبّت مهلة الانشغال معالجًا للانشغال، لكن SQLite لا يضمن استدعاءه.
إذا قرر SQLite أن استدعاء معالج الانشغال قد يؤدي إلى حالة جمود، فسيرجع SQLITE_BUSY إلى التطبيق بدلًا من استدعاء معالج الانشغال.
تحدث حالة الجمود التي يتجنبها SQLite عند ترقية المعاملة. يعني BEGIN مجردًا في SQLite أن المعاملة هي BEGIN DEFERRED. إذا كانت العبارة الأولى بعده هي SELECT، فأنت داخل معاملة قراءة. عندما تحتاج UPDATE لاحقة في المعاملة نفسها إلى التحول إلى معاملة كتابة، وتكون هناك اتصالات أخرى قد كتبت منذ بدء القراءة، لا يستطيع SQLite جعلك تنتظر؛ لأن اللقطة لديك أصبحت قديمة، والانتظار سيؤدي فقط إلى حالة جمود متبادلة بين الاتصالين. توضح الوثائق النتيجة مباشرة:
ستُرقي عبارات الكتابة اللاحقة المعاملة إلى معاملة كتابة إذا أمكن، أو ستُرجع SQLITE_BUSY.
لا تُستخدم مهلة 5000 ميلي ثانية مطلقًا. يصل الخطأ فورًا، ولذلك يبدو أن الإعداد لم يُطبَّق.
الإصلاح يتكون من كلمة واحدة.
BEGIN IMMEDIATE;
UPDATE notes SET body = 'edited' WHERE id = 1;
COMMIT;يأخذ BEGIN IMMEDIATE قفل الكتابة في البداية، قبل قراءة أي شيء. لا تحدث ترقية، ولذلك لا توجد حالة جمود يجب تجنبها. بالتالي يُطبَّق معالج الانشغال، وينتظر الاتصال دوره بدلًا من فشله. اترك معاملات القراءة للبدء المؤجل. يجب أن تكون أي معاملة تتضمن كتابة فورية.
السبب الثاني لأخطاء الأقفال أصعب في الاكتشاف: إبقاء معاملة كتابة مفتوحة أثناء تنفيذ عمل بطيء. يفرض SQLite التسلسل على عمليات الكتابة، لذلك ستمنع معاملة تُفتح، ثم تستدعي واجهة API خارجية عبر الشبكة، ثم تُجري الإيداع، كل كاتب آخر طوال مدة ذلك الاستدعاء. اقرأ ما تحتاج إليه، وأغلق المعاملة، ونفّذ العمل البطيء، ثم افتح معاملة كتابة قصيرة لتخزين النتيجة.
النسخ الاحتياطي المستمر باستخدام Litestream
تفقد النسخة الليلية ما يصل إلى يوم كامل من عمليات الكتابة، وقد يؤدي تشغيل cp على قاعدة بيانات SQLite قيد الاستخدام إلى إنشاء نسخة لا يمكن فتحها. هناك خياران آمنان. يستخدم sqlite3 app.db ".backup /path/to/backup.db" واجهة النسخ الاحتياطي عبر الإنترنت في SQLite، ويعمل على قاعدة بيانات قيد الاستخدام. أما Litestream فيتقدم خطوة إضافية: فهو يراقب WAL ويرسل التغييرات إلى التخزين الكائني باستمرار، ما يقلل أقصى فقد محتمل للبيانات من يوم إلى نحو ثانية واحدة.
Litestream ملف ثنائي واحد مكتوب بلغة Go ويعمل بجانب تطبيقك. لا يعمل بين التطبيق وقاعدة البيانات. يكتب تطبيقك إلى SQLite كالمعتاد تمامًا، ويقرأ Litestream WAL ويرفع التغييرات.
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الإصدار v0.5.14 هو الإصدار الذي توثقه صفحة التثبيت الرسمية لنظام Linux اعتبارًا من July 2026، وقد صدر الإصدار v0.5.15 في 21 July 2026. غيّر الإصدار في السطرين ليتوافق مع الوسم الحالي في صفحة الإصدارات، واستخدم حزمة arm64 المطابقة بدلًا منها إذا كان VPS لديك يعمل بمعمارية arm64.
يوجد ملف الإعداد في /etc/litestream.yml. ابدأ بنسخة محلية، لأنها تثبت عمل الدورة كاملة من دون الحاجة إلى بيانات اعتماد سحابية.
dbs:
- path: /home/appuser/app/app.db
replica:
type: file
path: /var/backups/litestream/appلاحظ أن الحقل هو replica، بصيغة المفرد. استبدل Litestream 0.5 مصفوفة replicas من السلسلة 0.3 بكتلة نسخة واحدة، وأصبح ملف الإعداد الذي يحتوي على إدخالين يفشل عند بدء التشغيل. لا تزال أدلة كثيرة من جهات خارجية تعرض المصفوفة القديمة، لذلك انسخ البنية أعلاه بدلًا من أول مثال يظهر في نتائج البحث. كما أعادت السلسلة 0.5 تسمية الأمر الفرعي litestream wal إلى litestream ltx، لأن تنسيق النسخ الاحتياطية على القرص تغيّر.
تحقق من إمكانية تحليل ملف الإعداد قبل تفعيل أي شيء.
sudo litestream databases -config /etc/litestream.ymlثم أثبت عمل الدورة ذهابًا وإيابًا يدويًا. يتجاوز هذا الأسلوب ملف الإعداد، وينسخ قاعدة بيانات واحدة إلى مسار واحد.
mkdir -p /tmp/replica
litestream replicate ~/app/app.db file:///tmp/replica/appيعمل ذلك في الواجهة الأمامية ويستمر في التشغيل. في shell ثانية، اكتب صفًا ثم استعد النسخة إلى ملف جديد.
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;"يتضمن العدد الصف الجديد. إذا لم يتضمنه، فلم تتم مزامنة التغيير بعد: يدفع Litestream التغييرات وفق sync-interval الذي تكون قيمته الافتراضية 1 ثانية، لذا انتظر ثم أعد الاستعادة. تمثل تلك الثانية أيضًا نقطة الاستعادة لديك. يؤدي التعطل إلى فقدان عمليات الكتابة من آخر فترة مزامنة كحد أقصى، ولا يمكن لأي إعداد جعل هذا الفقد صفرًا.
بالنسبة إلى التخزين الفعلي، استبدل كتلة النسخة بعنوان URL لـ S3. يعمل ذلك مع Amazon S3 ومع التخزين الكائني المتوافق مع S3 من مزودين آخرين.
dbs:
- path: /home/appuser/app/app.db
replica:
url: s3://your-bucket-name/app
region: us-east-1
snapshot:
interval: 24h
retention: 24hلا تضع بيانات الاعتماد في ذلك الملف. يقرأ Litestream LITESTREAM_ACCESS_KEY_ID وLITESTREAM_SECRET_ACCESS_KEY من البيئة، لذا ضعها في ملف drop-in لـ systemd يملكه root وبصلاحيات mode 600.
قيم اللقطات أعلاه هي القيم الافتراضية، لكن القيمة الافتراضية للاحتفاظ قد تفاجئ المستخدمين. يحدد الاحتفاظ مدة إبقاء Litestream للقطات والملفات التابعة لها، ولذلك يحدد أيضًا المدة التي يمكنك الرجوع إليها عند الاستعادة. تعني مدة أربع وعشرين ساعة أن عملية ترحيل خاطئة تكتشفها صباح Wednesday تصبح غير قابلة للاستعادة من حالة Monday. عيّن retention: 168h لمدة أسبوع، وتحمّل تكلفة التخزين الإضافي.
أثبت صلاحية الاستعادة قبل الحاجة إليها
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;"عند تحديد مسار قاعدة بيانات، يبحث litestream restore عن النسخة المتماثلة المطابقة في /etc/litestream.yml وينزّلها. يعرض PRAGMA integrity_check القيمة ok للملف السليم، وأي مخرجات أخرى تعني أن النسخة المستعادة غير صالحة للاستخدام. شغّل هذا بشكل مجدول باستخدام خدمة ومؤقت systemd واقرأ المخرجات. ما لم تستعد نسخة احتياطية مرة واحدة، فلن تعرف أنها تعمل.
تشغيل Litestream ضمن systemd
تثبّت حزمة Debian وحدة litestream التي تقرأ /etc/litestream.yml.
sudo systemctl enable litestream
sudo systemctl start litestream
sudo journalctl -u litestream -fيعرض الخرج السليم اسم كل قاعدة بيانات من ملف الإعداد، ثم لا يعرض شيئًا باستثناء أسطر المزامنة الدورية. يعني الخطأ no such file or directory في مسار قاعدة البيانات أن المسار في ملف الإعداد غير صحيح، أو أن العملية لا تستطيع قراءته. تعمل الوحدة بحساب root افتراضيًا، وهذا يتطلب صلاحيات أكثر مما تحتاج إليه هذه المهمة. يجب أن يتمكن Litestream من قراءة قاعدة البيانات والدليل الذي يحتويها والكتابة فيهما، لأنه يعمل مع الملفين -wal و-shm الموجودين بجوار قاعدة البيانات. لذلك امنحه حساب المستخدم الذي يستخدمه تطبيقك حاليًا.
# /etc/systemd/system/litestream.service.d/override.conf
[Service]
User=appuser
Group=appuserطبّق ذلك باستخدام sudo systemctl daemon-reload وsudo systemctl restart litestream. يستغرق إعداد حساب خدمة مخصص بأقل قدر من الصلاحيات بضع دقائق. وهذا هو الفرق بين وكيل نسخ احتياطي وعملية ثانية تعمل بحساب root على الخادم.
هناك تفصيل مهم في ترتيب التشغيل إذا أعدت إنشاء الجهاز من الصفر. يجب استعادة قاعدة البيانات قبل بدء التطبيق. يقبل litestream restore الخيار -if-db-not-exists، الذي ينتهي بالرمز 0 عندما يكون الملف موجودًا بالفعل، لذلك من الآمن تشغيله عند كل إقلاع. ضعه في سطر ExecStartPre في وحدة تطبيقك، وعندها ينزّل VPS جديد قاعدة البيانات، بينما لا يفعل الجهاز الموجود شيئًا. يحتوي litestream replicate على خيار -restore-if-db-not-exists مماثل إذا كنت تفضل إبقاء ذلك في مكان واحد.
متى يتعذر استخدام SQLite على VPS
أنظمة الملفات عبر الشبكة. هذا حد لا يمكنك تجاوزه بإعداد. يتطلب وضع WAL أن تشارك كل عملية تستخدم قاعدة البيانات منطقة صغيرة من الذاكرة، ويوفر ملف -shm هذه المنطقة. تنص وثائق SQLite على القاعدة دون استثناء:
يجب أن تكون جميع العمليات التي تستخدم قاعدة البيانات على المضيف نفسه؛ ولا يعمل WAL عبر نظام ملفات شبكي.
لذلك قد تتعرض قاعدة البيانات الموجودة على مشاركة NFS (نظام ملفات شبكي) أو SMB للتلف، ولا تمنع أي pragma ذلك. هناك فرق يغفل عنه بعض المستخدمين. يظهر جهاز كتلي شبكي، وهو ما يرفقه معظم موفري VPS كوحدة تخزين إضافية، في Linux كقرص عادي يحتوي على نظام ملفات عادي، وهذا مناسب. أما مشاركة الملفات المركبة فليست كذلك.
خادم تطبيقات ثانٍ. لا يوجد إعداد يجعل هذا يعمل. عندما تحتاج إلى جهازين يقدمان البيانات نفسها، تحتاج إلى قاعدة بيانات تتواصل عبر الشبكة. اتخذ هذا القرار بينما لا يزال لديك وقت للتخطيط.
أحمال العمل كثيفة الكتابة. السماح بكاتب واحد في كل مرة خاصية في تنسيق الملف، وليس إعدادًا قابلًا للضبط. عمليات الكتابة القصيرة منخفضة التكلفة لأن كل عملية تثبيت تضيف بيانات إلى WAL، لذلك يعتمد معدل النقل على زمن استجابة القرص لعمليات الكتابة الصغيرة أكثر من اعتماده على CPU. راجع تخزين NVMe مقابل SATA SSD على VPS لمعرفة أثر هذا الفرق. تكمن المشكلة الفعلية في المعاملات الطويلة، لأنها تضع كل كاتب آخر في قائمة انتظار خلفها.
الاستعلامات التحليلية. SQLite مخزن صفوف مصمم للمعاملات. أما لوحة المعلومات التي تفحص مئة مليون صف فهي مهمة مختلفة لأداة مختلفة، ويوضح مقارنة DuckDB مع SQLite لأعمال الخادم موضع هذا الحد.
VACUUM أثناء النسخ المتماثل. يعيد VACUUM الكامل كتابة ملف قاعدة البيانات بأكمله، ما يعني أن Litestream يجب أن يرفعه كاملًا مرة أخرى، وتوصي وثائق Litestream بعدم تشغيله في موضعه أثناء تفعيل النسخ المتماثل. أوقف أداة النسخ المتماثل، ونفّذ vacuum، ثم شغّلها مجددًا، وتوقع لقطة كاملة جديدة.
أداتا نسخ متماثل لقاعدة بيانات واحدة. لا تشغّل عمليتي Litestream على قاعدة البيانات نفسها أو على وجهة النسخة المتماثلة نفسها. توضح الوثائق صراحةً أن منع ذلك مسؤوليتك، والنتيجة نسخة متماثلة لا يمكنك استعادتها.
ما لا يغطيه Litestream
يحمي Litestream ملف قاعدة البيانات فقط، ولا يحمي أي شيء آخر. تظل الملفات المرفوعة، وإعدادات التطبيق، وشهادات TLS (أمان طبقة النقل)، وملفات الوحدات من مسؤوليتك. اقرنه بعبارة نسخ احتياطية مشفّرة خارج الخادم باستخدام restic وفق جدول زمني، وبذلك تغطي كلا الجانبين. إذا كانت الآلة جديدة، فتغطي الدقائق العشر الأولى على VPS جديد إعداد حساب المستخدم وقواعد الجدار الناري التي يفترض هذا الدليل أنها أُنجزت مسبقًا.
FAQ
هل تكفي SQLite لتطبيق في بيئة الإنتاج؟
بالنسبة إلى تطبيق واحد على خادم واحد، نعم، شريطة تفعيل وضع WAL، وتعيين مهلة انتظار الانشغال، وإجراء نسخ احتياطي مستمر. القيود المهمة هنا بنيوية: كاتب واحد في كل مرة، وجهاز مضيف واحد. يحصل التطبيق الذي يندرج ضمن هذه القيود على قاعدة بيانات من دون قفزة عبر الشبكة ومن دون عملية منفصلة لمراقبتها. أما التطبيق الذي يتجاوز هذه القيود فيحتاج إلى قاعدة بيانات بنموذج العميل والخادم، ولا يمكن لأي قدر من الضبط تغيير ذلك.
لماذا ما زلت أتلقى database is locked بعد تعيين busy_timeout؟
لأن SQLite تتجاوز معالج الانشغال عندما قد يؤدي الانتظار إلى حالة جمود. تكون المعاملة التي تبدأ بـ BEGIN مجردة مؤجلة: يضعها SELECT الافتتاحي في معاملة قراءة، ثم تحتاج الكتابة اللاحقة إلى الترقية. إذا كتب اتصال آخر في أثناء ذلك، تُرجع SQLite SQLITE_BUSY فورًا بدلًا من استدعاء معالج الانشغال، لأن لقطة القراءة لديك أصبحت قديمة. ابدأ أي معاملة ستنفذ كتابة باستخدام BEGIN IMMEDIATE حتى يُؤخذ قفل الكتابة مسبقًا وتُطبَّق المهلة.
هل يمكنني الاحتفاظ بقاعدة SQLite على وحدة تخزين عبر الشبكة؟
ليس على نظام ملفات عبر الشبكة مثل NFS أو SMB. يحتاج وضع WAL إلى أن تشترك جميع العمليات في الذاكرة من خلال ملف -shm، وتنص وثائق SQLite على أن كل عملية تستخدم قاعدة البيانات يجب أن تكون على جهاز مضيف واحد. أما جهاز الكتل عبر الشبكة الذي يرفقه موفر الخدمة، فهو مختلف: يرى Linux قرصًا عاديًا عليه نظام ملفات عادي، وتعمل SQLite عليه.
هل أحتاج إلى Litestream إذا كنت أجري نسخًا احتياطية ليلية بالفعل؟
يعتمد ذلك على مقدار البيانات الذي يمكنك تحمل فقدانه. تعني المهمة الليلية فقدان ما يصل إلى 24 ساعة من عمليات الكتابة. تزامن Litestream البيانات مرة واحدة تقريبًا كل ثانية، لذلك يكلفك التعطل فقدان الثانية الأخيرة تقريبًا. وهي أكثر أمانًا أيضًا من نسخ ملف قاعدة البيانات باستخدام cp، لأن ذلك قد يلتقط قاعدة البيانات في أثناء الكتابة. يغطي Litestream قاعدة البيانات فقط، لذا واصل تشغيل نسخة احتياطية عامة للملفات إلى جانبها.