VPS वर SQLite डेटाबेस कसा वापरावा?
VPS वर SQLite वापरताना WAL मोड, busy_timeout आणि Litestream बॅकअपची योग्य सेटिंग कशी करावी हे जाणून घ्या. लहान ॲप्लिकेशन्ससाठी हा एक कार्यक्षम पर्याय आहे का ते तपासा.
जेव्हा VPS वर SQLite हे योग्य उत्पादन डेटाबेस असते
बहुतेक लहान ॲप्लिकेशन्ससाठी VPS वर उत्पादनामध्ये (production) SQLite वापरणे हा एक योग्य पर्याय आहे. याचे कारण सोपे आहे: एका मशीनवर एका फाईलमध्ये लिहिणाऱ्या एका प्रोसेसला डेटाबेस सर्व्हरची गरज नसते. यामध्ये देखरेख करण्यासाठी कोणताही डेमन (daemon) नसतो, फायरवॉल करण्यासाठी कोणताही पोर्ट नसतो, पासवर्ड बदलण्याची (rotate) गरज नसते आणि चालू ठेवण्यासाठी दुसऱ्या मशीनची आवश्यकता नसते. क्वेरी ही नेटवर्क राऊंड ट्रिपऐवजी एक फंक्शन कॉल असते, त्यामुळे चाळीस क्वेरी चालवणाऱ्या पेजसाठी तुम्हाला फक्त चाळीस फंक्शन कॉल्सचा खर्च येतो.
याचे मर्यादा आणि वास्तव स्पष्ट आहे. SQLite संपूर्ण डेटाबेस फाईलवर एका वेळी एकाच रायटरला (writer) परवानगी देते आणि ही फाईल दोन मशीन्समध्ये शेअर केली जाऊ शकत नाही. एका ॲप्लिकेशनला चालवणाऱ्या एका VPS साठी या दोन्ही मर्यादा योग्य आहेत. मात्र, जेव्हा तुम्ही या मर्यादेच्या बाहेर जाता, तेव्हा या दोन्ही गोष्टी घातक ठरतात. हे मार्गदर्शक सर्व्हरवर SQLite सुरक्षित करण्यासाठी लागणारी सेटिंग्ज, Litestream सह सतत बॅकअप घेणे आणि तुम्ही कोणत्या टप्प्यावर हे वापरणे थांबवावे, याबद्दल माहिती देते.
प्रथम कमांड लाईन टूल इन्स्टॉल करा. खालील सर्व गोष्टी Ubuntu 24.04 वर चालवल्या गेल्या आहेत.
sudo apt update
sudo apt install -y sqlite3
sqlite3 --versionहे 3. ने सुरू होणारी आवृत्ती, त्यानंतर बिल्ड तारीख आणि सोर्स हॅश प्रिंट करते. जुलै 2026 पर्यंत, Ubuntu 24.04 मध्ये SQLite 3.45.1 उपलब्ध आहे. तुमचे ॲप्लिकेशन बहुधा ही बायनरी वापरत नाही: बहुतेक लँग्वेज रनटाइम्स स्वतःची SQLite लायब्ररीची प्रत बंडल करतात, जी अनेकदा नवीन असते. त्यामुळे कोणत्याही नवीन फिचरवर अवलंबून राहण्यापूर्वी तुमचा डेटाबेस ड्रायव्हर कोणती आवृत्ती दर्शवतो, हे तपासा.
WAL मोड सर्वात आधी का बदलावा
डीफॉल्टनुसार SQLite रोलबॅक जर्नलचा वापर करते. एखादे पेज बदलण्यापूर्वी, ते मूळ पेजची प्रत एका -journal फाईलमध्ये तयार करते आणि त्यानंतर डेटाबेसमध्ये थेट बदल करते. हे सुरक्षितपणे करण्यासाठी, ते संपूर्ण फाईलवर एक्सक्लुझिव्ह लॉक घेते. त्यामुळे, जोपर्यंत रायटिंगची प्रक्रिया सुरू असते, तोपर्यंत प्रत्येक रीडरला थांबावे लागते. लॅपटॉपवर याचा कोणालाही त्रास जाणवत नाही. मात्र, वेब सर्व्हरवर एक संथ रायटिंग प्रक्रिया डेटाबेस वापरणाऱ्या प्रत्येक विनंतीला (request) थांबवून ठेवते.
WAL (write-ahead log) मोड ही प्रक्रिया उलट करतो. रायटर नवीन पेजेस एका वेगळ्या -wal फाईलमध्ये जोडतो आणि मुख्य डेटाबेसमध्ये कोणताही बदल करत नाही. रीडर्स मुख्य फाईल वाचणे सुरू ठेवतात, ज्या स्नॅपशॉटपासून त्यांनी सुरुवात केली होती. त्यामुळे, रीडर्स रायटरला ब्लॉक करत नाहीत आणि रायटर रीडर्सना ब्लॉक करत नाही. त्यानंतर, एक चेकपॉईंट जमा झालेली WAL पेजेस पुन्हा मुख्य डेटाबेसमध्ये कॉपी करतो. हा एक बदल SQLite ला वेब ॲप्लिकेशनसाठी वापरण्यायोग्य बनवण्यासाठी अत्यंत महत्त्वाचा आहे.
WAL मोड सुरू करा आणि तो लागू झाल्याची खात्री करा
mkdir -p ~/app
sqlite3 ~/app/app.db "PRAGMA journal_mode=WAL;"ही कमांड wal प्रिंट करते. हे आउटपुट केवळ सजावट नाही. PRAGMA journal_mode डेटाबेस सध्या ज्या मोडमध्ये आहे तो दर्शवते, त्यामुळे delete हे उत्तर मिळणे म्हणजे बदल अयशस्वी झाला आहे आणि तुम्ही अजूनही रोलबॅक जर्नलवर आहात.
WAL मोड कायमस्वरूपी असतो. ही डेटाबेस हेडरमधील एक फ्लॅग (flag) आहे, कनेक्शन सेटिंग नाही. त्यामुळे तुम्ही प्रत्येक डेटाबेस फाईलसाठी हे एकदाच रन करता आणि त्यानंतरचे प्रत्येक कनेक्शन, रीबूटनंतरही, तो वारशाने घेते. हे नवीन कनेक्शनसह तपासा.
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/आता तीन फाईल्स आहेत: app.db, app.db-wal आणि app.db-shm. -wal फाईलमध्ये अशा कमिट केलेल्या पेजेसचा समावेश असतो ज्यांचे चेकपॉईंटिंग अजून झालेले नाही. -shm ही एक शेअर केलेली मेमरी इंडेक्स आहे, जी प्रत्येक कनेक्शन मॅप करते जेणेकरून WAL मध्ये काय आहे यावर सर्व कनेक्शनचे एकमत राहील. या दोन्ही फाईल्स डेटाबेसचा भाग आहेत आणि त्या तात्पुरत्या (scratch) फाईल्स नाहीत. ॲप्लिकेशन चालू असताना केवळ app.db कॉपी केल्यास तुम्हाला अशी फाईल मिळेल ज्यामध्ये अलीकडील सर्व कमिट्स गहाळ असतील. app.db डिलीट करून इतर दोन फाईल्स तशाच ठेवल्यास, SQLite त्या जुन्या WAL पेजेसना त्या नावाने तयार होणाऱ्या नवीन फाईलवर लागू करेल. डेटाबेस रिसेट करण्याचा प्रयत्न करताना लोक अशा प्रकारे नवीन डेटाबेस खराब करतात.
प्रत्येक प्रोडक्शन ॲपसाठी आवश्यक कनेक्शन सेटिंग्ज
केवळ journal_mode डेटाबेसमध्ये साठवले जाते. खालील इतर सर्व सेटिंग्ज प्रति-कनेक्शन आहेत, याचा अर्थ असा की तुमच्या ॲप्लिकेशनला प्रत्येक कनेक्शन उघडताना हे चालवावे लागते, ज्यामध्ये पूल (pool) बॅकग्राउंडमध्ये तयार करत असलेल्या प्रत्येक कनेक्शनचा समावेश होतो.
PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 5000;
PRAGMA synchronous = NORMAL;
PRAGMA foreign_keys = ON;busy_timeout = 5000 हे SQLite ला लॉक असलेल्या डेटाबेससाठी 5000 मिलिसेकंदपर्यंत पुन्हा प्रयत्न (retry) करण्यास सांगते, त्यानंतरच ते database is locked परत करते. डीफॉल्ट मूल्य 0 आहे, त्यामुळे डीफॉल्टनुसार जेव्हा दोन रायटर्स (writers) ओव्हरलॅप होतात तेव्हा SQLite त्वरित अयशस्वी होते. हे एकच मूल्य सेट केल्याने बहुतेक लॉक त्रुटी दूर होतात ज्यांचे खापर SQLite वर फोडले जाते.
WAL मोडमध्ये synchronous = NORMAL ही योग्य सेटिंग आहे आणि त्यातील तडजोड समजून घेणे महत्त्वाचे आहे. FULL वर, SQLite प्रत्येक कमिटवर WAL वर fsync कॉल करते. NORMAL वर, ते चेकपॉइंट्सवर सिंक करते. SQLite डॉक्युमेंटेशनमध्ये तुम्ही काय गमावता याबद्दल स्पष्टपणे सांगितले आहे: वीज गेल्यावर किंवा हार्ड रीसेट झाल्यावर ट्रान्झॅक्शन्स टिकाऊ (durable) राहत नाहीत. अशा प्रकारे वीज गेल्यामुळे डेटाबेस करप्ट होऊ शकत नाही, तुम्ही फक्त शेवटचे कमिट गमावता जे डिस्कपर्यंत पोहोचले नव्हते. VPS वर ही सहसा योग्य तडजोड असते, कारण यामुळे प्रत्येक रायटिंगच्या प्रक्रियेतून एक fsync कमी होतो.
foreign_keys = ON हे बॅकवर्ड सुसंगततेसाठी डीफॉल्टनुसार बंद असते आणि ते प्रति-कनेक्शन असते. जोपर्यंत प्रत्येक कनेक्शन हे सुरू करत नाही, तोपर्यंत REFERENCES क्लॉजने भरलेली स्कीमा काहीही लागू करत नाही.
आणखी एक सेटिंग नंतरच्या टप्प्यावर महत्त्वाची ठरते. जेव्हा WAL 1000 पेजेसच्या पुढे जाते तेव्हा SQLite आपोआप चेकपॉइंट करते आणि हे काम त्या क्षणी ट्रान्झॅक्शन पूर्ण करणाऱ्या कोणत्याही कनेक्शनद्वारे केले जाते. हे स्वतःहून ठीक आहे. जेव्हा Litestream चालू असते तेव्हा हा प्रश्न निर्माण होतो, कारण Litestream ला चेकपॉइंट्स कधी व्हावेत याचे नियंत्रण हवे असते.
busy_timeout सेट केल्यानंतरही database is locked का येते
ही ती त्रुटी आहे ज्यामुळे वापरकर्ते पुन्हा Postgres कडे वळतात आणि याचे एक विशिष्ट कारण आहे.
busy timeout एक busy handler कार्यान्वित करते, परंतु SQLite ते कॉल करण्याचे आश्वासन देत नाही.
जर SQLite ला असे वाटले की busy handler कार्यान्वित केल्यामुळे डेडलॉक (deadlock) होऊ शकतो, तर ते busy handler कार्यान्वित करण्याऐवजी ॲप्लिकेशनला SQLITE_BUSY परत करते.
हे टाळले जाणारे डेडलॉक तेव्हा घडते जेव्हा ट्रान्झॅक्शन अपग्रेड होते. SQLite मधील एक साधे BEGIN म्हणजे BEGIN DEFERRED. जर त्यानंतरचे पहिले स्टेटमेंट SELECT असेल, तर तुम्ही रीड ट्रान्झॅक्शनमध्ये आहात. जेव्हा त्याच ट्रान्झॅक्शनमधील नंतरचे UPDATE राइट ट्रान्झॅक्शनमध्ये बदलण्याची गरज असते आणि तुमच्या रीडनंतर दुसऱ्या कनेक्शनने काही लिहिले असेल, तेव्हा SQLite तुम्हाला प्रतीक्षा करायला लावू शकत नाही. कारण तुमचा स्नॅपशॉट आधीच कालबाह्य झालेला असतो आणि प्रतीक्षा केल्यास दोन्ही कनेक्शन एकमेकांविरुद्ध डेडलॉकमध्ये अडकतील. दस्तऐवजीकरण थेट परिणाम स्पष्ट करते:
त्यानंतरची राइट स्टेटमेंट्स शक्य असल्यास ट्रान्झॅक्शनला राइट ट्रान्झॅक्शनमध्ये अपग्रेड करतील, अन्यथा SQLITE_BUSY परत करतील.
तुमच्या 5000 मिलिसेकंदच्या टाइमआउटचा विचारही केला जात नाही. त्रुटी त्वरित येते, म्हणूनच सेटिंगचा काहीही उपयोग झाला नाही असे वाटते.
यावर उपाय एकच शब्द आहे.
BEGIN IMMEDIATE;
UPDATE notes SET body = 'edited' WHERE id = 1;
COMMIT;BEGIN IMMEDIATE काहीही वाचण्यापूर्वी, सुरुवातीलाच राइट लॉक घेते. यामध्ये कोणतेही अपग्रेड नसल्यामुळे टाळण्यासारखा डेडलॉक नसतो, त्यामुळे busy handler लागू होते आणि कनेक्शन अयशस्वी होण्याऐवजी स्वतःच्या वारीची प्रतीक्षा करते. फक्त रीड-ओन्ली ट्रान्झॅक्शन्स deferred ठेवा. ज्या ट्रान्झॅक्शनमध्ये राइट ऑपरेशन आहे, ते immediate असावे.
लॉक त्रुटींचे दुसरे कारण शोधणे कठीण असते: संथ कामादरम्यान राइट ट्रान्झॅक्शन उघडे ठेवणे. SQLite राइटर्सना क्रमाने (serialise) लावते, त्यामुळे जे ट्रान्झॅक्शन उघडते, नेटवर्कवर बाह्य API कॉल करते आणि नंतर कमिट करते, ते त्या कॉलच्या कालावधीपर्यंत इतर सर्व राइटर्सना ब्लॉक करते. तुम्हाला जे हवे आहे ते वाचा, ट्रान्झॅक्शन बंद करा, संथ काम पूर्ण करा आणि त्यानंतर निकाल साठवण्यासाठी एक छोटे राइट ट्रान्झॅक्शन उघडा.
Litestream सह सतत बॅकअप
रात्रीची प्रत घेतल्यास एका दिवसापर्यंतचा डेटा गमावला जाऊ शकतो आणि चालू SQLite डेटाबेसवर cp चालवल्यास अशी प्रत तयार होऊ शकते जी उघडता येत नाही. दोन गोष्टी सुरक्षित आहेत. 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 versionv0.5.14 ही ती आवृत्ती आहे ज्याचे अधिकृत Linux इन्स्टॉल पेज जुलै 2026 पर्यंत दस्तऐवजीकरण करते आणि v0.5.15 ही 21 जुलै 2026 रोजी आली. दोन्ही ओळींमधील आवृत्ती रिलीजेस पेजवरील सध्याच्या टॅगशी जुळण्यासाठी बदला आणि जर तुमचा VPS arm64 असेल तर त्याऐवजी संबंधित arm64 पॅकेज घ्या.
कॉन्फिगरेशन फाईल /etc/litestream.yml येथे असते. स्थानिक फाईल रेप्लिकापासून सुरुवात करा, कारण हे क्लाउड क्रेडेंशियल्सची गरज न पडता संपूर्ण लूपची खात्री करते.
dbs:
- path: /home/appuser/app/app.db
replica:
type: file
path: /var/backups/litestream/appलक्षात ठेवा की फील्ड replica आहे, जे एकवचनी आहे. Litestream 0.5 ने 0.3 मालिकेतील replicas ॲरेच्या जागी एकच रेप्लिका ब्लॉक आणला आहे आणि दोन एन्ट्री असलेले कॉन्फिगरेशन आता स्टार्टअपवर अयशस्वी होते. अनेक थर्ड-पार्टी मार्गदर्शकांमध्ये अजूनही जुना ॲरे दाखवला आहे, म्हणून शोध इंजिनवर मिळणाऱ्या पहिल्या उदाहरणाऐवजी वरील फॉरमॅट कॉपी करा. 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हे फोरग्राउंडमध्ये चालते आणि चालू राहते. दुसऱ्या शेलमध्ये, एक रो (row) लिहा आणि रेप्लिकाला नवीन फाईलमध्ये रिस्टोर करा.
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 सेकंद असते, म्हणून प्रतीक्षा करा आणि पुन्हा रिस्टोर करा. तो एक सेकंद तुमचा रिकव्हरी पॉइंट देखील आहे. क्रॅश झाल्यास शेवटच्या सिंक इंटरव्हलपासूनचे बदल गमावले जाऊ शकतात आणि कोणत्याही कॉन्फिगरेशनमुळे हे शून्य करता येत नाही.
खऱ्या स्टोरेजसाठी, रेप्लिका ब्लॉकच्या जागी S3 URL वापरा. हे 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 वाचते, म्हणून त्यांना root च्या मालकीच्या आणि 600 मोड असलेल्या systemd ड्रॉप-इनमध्ये ठेवा.
वरील स्नॅपशॉट व्हॅल्यूज डीफॉल्ट आहेत आणि रिटेंशन डीफॉल्ट अनेकांना आश्चर्यचकित करते. रिटेंशन म्हणजे Litestream किती काळ स्नॅपशॉट्स आणि त्यांच्याशी संबंधित फाईल्स ठेवते, त्यामुळे तुम्ही किती मागे जाऊन रिस्टोर करू शकता हे देखील यावरून ठरते. चोवीस तासांचा अर्थ असा की बुधवारी सकाळी लक्षात आलेले चुकीचे मायग्रेशन सोमवारी स्थितीवरून रिकव्हर करता येणार नाही. 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;"डेटाबेसचा पाथ (path) दिल्यावर, litestream restore हे /etc/litestream.yml मध्ये संबंधित रेप्लिका शोधते आणि ती डाऊनलोड करते. जर फाईल सुस्थितीत असेल, तर PRAGMA integrity_check हे ok प्रिंट करते; इतर कोणताही आउटपुट आल्यास रिस्टोर केलेली प्रत वापरण्यायोग्य नाही असे समजावे. हे काम systemd सर्व्हिस आणि टायमर वापरून ठराविक वेळेच्या अंतराने (schedule) चालवा आणि त्याचा आउटपुट तपासा. जोपर्यंत तुम्ही एकदाही बॅकअप रिस्टोर करत नाही, तोपर्यंत तो काम करतो की नाही हे तुम्हाला कळणार नाही.
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 डेटाबेस डाऊनलोड करेल आणि अस्तित्वात असलेला VPS काहीही करणार नाही. जर तुम्हाला हे एकाच ठिकाणी ठेवायचे असेल, तर litestream replicate मध्ये संबंधित -restore-if-db-not-exists फ्लॅग उपलब्ध आहे.
VPS वर SQLite कोठे अपयशी ठरते
नेटवर्क फाइलसिस्टम्स. ही अशी मर्यादा आहे जी तुम्ही कॉन्फिगरेशनद्वारे बदलू शकत नाही. WAL मोडसाठी डेटाबेस वापरणाऱ्या प्रत्येक प्रोसेसला मेमरीचा एक छोटा भाग शेअर करणे आवश्यक असते, जो -shm फाइलद्वारे उपलब्ध होतो. SQLite दस्तऐवजीकरण हा नियम कोणत्याही अटीशिवाय स्पष्ट करते:
डेटाबेस वापरणाऱ्या सर्व प्रोसेसेस एकाच होस्ट कॉम्प्युटरवर असणे आवश्यक आहे; नेटवर्क फाइलसिस्टमवर WAL कार्य करत नाही.
त्यामुळे, माउंट केलेल्या NFS (नेटवर्क फाइल सिस्टम) किंवा SMB शेअरवरील डेटाबेस खराब (corrupt) होऊ शकतो आणि कोणताही pragma याला रोखू शकत नाही. येथे एक फरक आहे जो लोकांच्या लक्षात येत नाही. नेटवर्क ब्लॉक डिव्हाइस, जे बहुतेक VPS प्रदाते अतिरिक्त स्टोरेज म्हणून जोडतात, ते Linux ला एका सामान्य डिस्कसारखे आणि त्यावर सामान्य फाइलसिस्टम असल्यासारखे दिसते, आणि ते ठीक आहे. परंतु, माउंट केलेले फाइल शेअर तसे नसते.
दुसरा ॲप्लिकेशन सर्व्हर. कोणतीही सेटिंग हे कार्यक्षम बनवू शकत नाही. एकदा का तुम्हाला एकाच डेटावर काम करण्यासाठी दोन मशीनची गरज भासली की, तुम्हाला अशा डेटाबेसची गरज असते जो नेटवर्कवर संवाद साधू शकेल. नियोजनासाठी वेळ असतानाच हा निर्णय घ्या.
जास्त राइट (Write-heavy) वर्कलोड्स. एका वेळी एकच रायटर असणे हा फाइल फॉरमॅटचा गुणधर्म आहे, तो बदलता येण्याजोगा सेटिंग नाही. लहान राइट्स स्वस्त असतात कारण प्रत्येक कमिट ही WAL मध्ये केलेली भर असते, त्यामुळे थ्रूपुट तुमच्या CPU पेक्षा तुमच्या डिस्कच्या स्मॉल-राइट लॅटन्सीवर जास्त अवलंबून असतो. त्यातील फरक कसा असतो हे पाहण्यासाठी VPS वर NVMe विरुद्ध SATA SSD स्टोरेज पहा. लांब चालणारे ट्रान्झॅक्शन्स ही खरी समस्या आहे, कारण ते इतर सर्व रायटर्सना रांगेत उभे करतात.
ॲनालिटिकल क्वेरीज. SQLite हे ट्रान्झॅक्शन्ससाठी बनवलेले रो-स्टोअर आहे. दहा कोटी रो स्कॅन करणारा डॅशबोर्ड हे एका वेगळ्या साधनाने करायचे काम आहे, आणि सर्व्हर कामासाठी DuckDB विरुद्ध SQLite मध्ये ती मर्यादा कोठे येते हे स्पष्ट केले आहे.
रेप्लिकेशन अंतर्गत VACUUM. पूर्ण VACUUM संपूर्ण डेटाबेस फाइल पुन्हा लिहिते, याचा अर्थ Litestream ला ती सर्व पुन्हा अपलोड करावी लागते. रेप्लिकेशन सक्रिय असताना ते थेट चालवू नका, असा सल्ला Litestream दस्तऐवजीकरण देते. रेप्लिकेटर थांबवा, व्हॅक्यूम करा, पुन्हा सुरू करा आणि नवीन पूर्ण स्नॅपशॉटची अपेक्षा ठेवा.
एका डेटाबेसवर दोन रेप्लिकेटर्स. एकाच डेटाबेसवर किंवा एकाच रेप्लिका डेस्टिनेशनवर कधीही दोन Litestream प्रोसेसेस चालवू नका. हे टाळण्याची जबाबदारी तुमची आहे, असे दस्तऐवजीकरण स्पष्टपणे सांगते. असे केल्यास अशी रेप्लिका तयार होते जी तुम्ही रिस्टोअर करू शकत नाही.
Litestream कशाची सुरक्षा करत नाही
Litestream केवळ डेटाबेस फाईलची सुरक्षा करते, इतर कशाचीही नाही. अपलोड केलेल्या फाईल्स, ॲप्लिकेशन कॉन्फिगरेशन, TLS (transport layer security) प्रमाणपत्रे आणि युनिट फाईल्स हाताळण्याची जबाबदारी तुमचीच आहे. यासोबत restic वापरून ऑफ-बॉक्स एनक्रिप्टेड बॅकअप ठराविक वेळापत्रकानुसार घेतल्यास, दोन्ही बाजू सुरक्षित राहतात. जर मशीन नवीन असेल, तर नवीन VPS वरील पहिली दहा मिनिटे या मार्गदर्शिकेमध्ये गृहीत धरलेली युजर अकाउंट आणि फायरवॉलची कामे कशी करावीत, हे स्पष्ट करते.
FAQ
SQLite हे उत्पादन अनुप्रयोगासाठी (production application) पुरेसे आहे का?
एका सर्व्हरवरील एका अनुप्रयोगासाठी, हो, जर तुम्ही WAL मोड सुरू केला, busy timeout सेट केला आणि त्याचे सतत बॅकअप घेतले तर हे शक्य आहे. महत्त्वाच्या मर्यादा संरनात्मक आहेत: एका वेळी एकच लेखक (writer) आणि एकच होस्ट मशीन. ज्या अनुप्रयोगासाठी या मर्यादा पुरेशा आहेत, त्याला नेटवर्क हॉप किंवा देखरेखीसाठी वेगळ्या प्रोसेसची गरज नसलेला डेटाबेस मिळतो. ज्या अनुप्रयोगासाठी या मर्यादा पुरेशा नाहीत, त्याला क्लायंट-सर्व्हर डेटाबेसची आवश्यकता असते आणि कितीही ट्यूनिंग केले तरी ही गरज बदलत नाही.
busy_timeout सेट केल्यानंतरही मला database is locked का मिळतो?
कारण जेव्हा प्रतीक्षा केल्यामुळे डेडलॉक (deadlock) होऊ शकतो, तेव्हा SQLite बिझी हँडलरला वगळते. जो व्यवहार (transaction) केवळ BEGIN ने सुरू होतो तो 'डिफर्ड' (deferred) असतो: सुरुवातीचा SELECT त्याला रीड ट्रान्झॅक्शनमध्ये टाकतो आणि नंतरच्या राइटसाठी अपग्रेड करावे लागते. जर दरम्यानच्या काळात दुसऱ्या कनेक्शनने काही लिहिले असेल, तर SQLite लगेच SQLITE_BUSY परत करते, कारण तुमचा रीड स्नॅपशॉट आधीच जुना झालेला असतो. जो व्यवहार लिहिण्यासाठी (write) असेल तो BEGIN IMMEDIATE ने सुरू करा, जेणेकरून राइट लॉक सुरुवातीलाच घेतला जाईल आणि टाइमआउट लागू होईल.
मी माझा SQLite डेटाबेस नेटवर्क स्टोरेजवर ठेवू शकतो का?
NFS किंवा SMB सारख्या नेटवर्क फाइलसिस्टमवर नाही. WAL मोडसाठी सर्व प्रोसेसना -shm फाइलद्वारे मेमरी शेअर करणे आवश्यक असते आणि SQLite दस्तऐवजीकरणानुसार, डेटाबेस वापरणारी प्रत्येक प्रोसेस एकाच होस्ट संगणकावर असणे आवश्यक आहे. तुमच्या प्रोव्हायडरने जोडलेले नेटवर्क ब्लॉक डिव्हाइस वेगळे असते: Linux ला त्यावर सामान्य फाइलसिस्टम असलेले सामान्य डिस्क दिसते आणि SQLite तिथे काम करते.
मी आधीच रात्रीचे बॅकअप घेत असल्यास मला Litestream ची गरज आहे का?
हे तुम्ही किती डेटा गमावू शकता यावर अवलंबून आहे. रात्रीच्या बॅकअपचा अर्थ असा की तुम्ही चोवीस तासांपर्यंतचा डेटा गमावू शकता. Litestream दर सेकंदाला एकदा सिंक करते, त्यामुळे क्रॅश झाल्यास तुमचे फक्त शेवटच्या सेकंदाचे नुकसान होते. हे cp ने डेटाबेस फाइल कॉपी करण्यापेक्षा अधिक सुरक्षित आहे, कारण कॉपी करताना डेटाबेस लिहिण्याच्या प्रक्रियेत असू शकतो. Litestream फक्त डेटाबेस कव्हर करते, त्यामुळे त्यासोबत सामान्य फाइल बॅकअप सुरू ठेवा.