VPS पर प्रोडक्शन के लिए SQLite का उपयोग कैसे करें
VPS पर SQLite का उपयोग करने के लिए WAL मोड, busy_timeout सेटिंग्स और Litestream बैकअप की जानकारी प्राप्त करें। जानें कि किन सीमाओं के कारण यह छोटे ऐप्स के लिए सबसे अच्छा है।
जब VPS पर SQLite एक सही प्रोडक्शन डेटाबेस हो
VPS पर प्रोडक्शन में SQLite का उपयोग करना अधिकांश छोटे अनुप्रयोगों के लिए एक सही विकल्प है, और इसका कारण सरल है: एक मशीन पर एक प्रोसेस जो एक फाइल में लिखती है, उसे किसी डेटाबेस सर्वर की आवश्यकता नहीं होती। इसमें न तो किसी डेमन (daemon) की निगरानी करनी होती है, न ही किसी पोर्ट को फायरवॉल करना होता है, न ही पासवर्ड रोटेट करना होता है, और न ही किसी दूसरी मशीन को चालू रखना होता है। एक क्वेरी नेटवर्क राउंड ट्रिप के बजाय एक फंक्शन कॉल होती है, इसलिए एक पेज जो चालीस क्वेरी चलाता है, उसकी लागत केवल चालीस फंक्शन कॉल होती है।
इसकी सीमाएं सीमित और स्पष्ट हैं। 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 mode को सबसे पहले क्यों बदलें
डिफ़ॉल्ट रूप से SQLite एक rollback journal का उपयोग करता है। किसी page को बदलने से पहले, यह मूल page की एक प्रति -journal फ़ाइल में बनाता है, और फिर डेटाबेस में सीधे बदलाव करता है। इसे सुरक्षित रूप से करने के लिए, यह पूरी फ़ाइल पर एक exclusive lock लगा देता है, इसलिए जब भी कोई write प्रक्रिया चल रही होती है, तो हर reader को इंतज़ार करना पड़ता है। लैपटॉप पर किसी को इसका पता नहीं चलता। वेब सर्वर पर, एक धीमी write प्रक्रिया उन सभी requests को रोक देती है जो डेटाबेस का उपयोग करती हैं।
WAL (write-ahead log) mode इस क्रम को उलट देता है। एक writer नए pages को एक अलग -wal फ़ाइल में जोड़ता है और मुख्य डेटाबेस को वैसे ही रहने देता है। Readers मुख्य फ़ाइल को उसी snapshot से पढ़ते रहते हैं जिससे उन्होंने शुरुआत की थी, इसलिए readers writer को ब्लॉक नहीं करते और writer readers को ब्लॉक नहीं करता। बाद में, एक checkpoint जमा हुए WAL pages को वापस मुख्य डेटाबेस में कॉपी कर देता है। यह एक बदलाव ही वह मुख्य कारण है जो SQLite को वेब एप्लिकेशन के पीछे उपयोग करने योग्य बनाता है।
WAL mode को चालू करें और पुष्टि करें कि यह लागू हो गया है
mkdir -p ~/app
sqlite3 ~/app/app.db "PRAGMA journal_mode=WAL;"यह कमांड wal प्रिंट करती है। वह आउटपुट केवल सजावट नहीं है। PRAGMA journal_mode वह मोड लौटाता है जिसमें डेटाबेस वास्तव में है, इसलिए delete का उत्तर मिलने का अर्थ है कि परिवर्तन विफल रहा और आप अभी भी rollback journal पर हैं।
WAL mode स्थायी होता है। यह एक connection setting के बजाय डेटाबेस हेडर में एक flag है, इसलिए आप इसे प्रति डेटाबेस फ़ाइल एक बार चलाते हैं और बाद के सभी connections इसे inherit कर लेते हैं, reboot के बाद भी। एक नए connection के साथ इसे सिद्ध करें।
sqlite3 ~/app/app.db "PRAGMA journal_mode;"अब एक table बनाएँ और देखें कि डिस्क पर क्या दिखाई देता है।
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 फ़ाइल में वे committed pages होते हैं जिन्हें अभी तक checkpoint नहीं किया गया है। -shm फ़ाइल एक shared memory index है जिसे हर connection map करता है ताकि वे सभी इस बात पर सहमत हों कि WAL में क्या है। दोनों डेटाबेस का हिस्सा हैं और ये अस्थायी (scratch) फ़ाइलें नहीं हैं। जब application चल रहा हो, तब केवल app.db को copy करने पर आपको ऐसी फ़ाइल मिलेगी जिसमें हाल के सभी commits गायब होंगे। app.db को हटा दें और बाकी दोनों को वहीं रहने दें, तो SQLite उन पुराने WAL pages को उस नाम से बनने वाली किसी भी नई फ़ाइल पर लागू कर देगा; इसी तरह लोग डेटाबेस को reset करने की कोशिश में उसे corrupt कर देते हैं।
प्रोडक्शन ऐप के लिए आवश्यक कनेक्शन सेटिंग्स
डेटाबेस में केवल journal_mode स्टोर किया जाता है। नीचे दी गई अन्य सभी सेटिंग्स प्रति-कनेक्शन (per connection) होती हैं, जिसका अर्थ है कि आपके एप्लिकेशन को इसे हर उस कनेक्शन पर चलाना होगा जिसे वह खोलता है, जिसमें बैकग्राउंड में पूल द्वारा बनाया गया हर कनेक्शन भी शामिल है।
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 है, इसलिए डिफ़ॉल्ट रूप से SQLite पहली बार दो राइटर्स के ओवरलैप होने पर तुरंत विफल हो जाता है। इस एक मान को सेट करने से अधिकांश लॉक एरर दूर हो जाते हैं जिन्हें अक्सर SQLite की समस्या मान लिया जाता है।
WAL मोड में synchronous = NORMAL सही सेटिंग है, और इसके प्रभाव को समझना महत्वपूर्ण है। FULL पर, SQLite हर कमिट (commit) पर 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 को कॉल करने के बजाय सीधे application को SQLITE_BUSY लौटा देगा।
यह deadlock तब होता है जब कोई transaction अपग्रेड होता है। SQLite में एक साधारण BEGIN का अर्थ BEGIN DEFERRED होता है। यदि इसके बाद पहला statement एक SELECT है, तो आप एक read transaction में हैं। जब उसी transaction में बाद में कोई UPDATE एक write transaction बनना चाहता है, और आपके read शुरू होने के बाद किसी अन्य connection ने लिख दिया है, तो SQLite आपको प्रतीक्षा नहीं करवा सकता। ऐसा इसलिए है क्योंकि आपका snapshot पहले ही पुराना हो चुका है और प्रतीक्षा करने से दोनों connections के बीच deadlock हो जाएगा। documentation सीधे परिणाम बताती है:
बाद के write statements यदि संभव हो तो transaction को write transaction में अपग्रेड कर देंगे, अन्यथा SQLITE_BUSY लौटा देंगे।
आपका 5000 millisecond का timeout कभी काम नहीं आता। error तुरंत आ जाती है, इसीलिए ऐसा लगता है कि setting ने कुछ नहीं किया।
इसका समाधान एक शब्द है।
BEGIN IMMEDIATE;
UPDATE notes SET body = 'edited' WHERE id = 1;
COMMIT;BEGIN IMMEDIATE कुछ भी पढ़ने से पहले ही शुरुआत में write lock ले लेता है। इसमें कोई अपग्रेड नहीं होता, इसलिए बचने के लिए कोई deadlock नहीं होता, और busy handler लागू हो जाता है। इस प्रकार connection विफल होने के बजाय अपनी बारी की प्रतीक्षा करता है। read-only transactions को deferred रखें। जिस भी transaction में write शामिल हो, उसे immediate होना चाहिए।
lock errors का दूसरा कारण पहचानना कठिन है: धीमी प्रक्रिया के दौरान write transaction को खुला रखना। SQLite writers को serialize करता है, इसलिए जो transaction खुलता है, network पर external API को कॉल करता है, और फिर commit करता है, वह उस कॉल की अवधि के लिए अन्य सभी writers को block कर देगा। जो आवश्यक है उसे पढ़ें, transaction बंद करें, धीमी प्रक्रिया पूरी करें, और फिर परिणाम store करने के लिए एक छोटा write transaction खोलें।
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 है, जो एकवचन (singular) है। 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 को एक सप्ताह के लिए सेट करें और अतिरिक्त स्टोरेज के लिए भुगतान करें।
जरूरत पड़ने से पहले 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 को ढूँढता है और उसे pull करता है। PRAGMA integrity_check एक सही file पर ok प्रिंट करता है, और यदि कोई अन्य output आता है, तो इसका अर्थ है कि restored copy उपयोग के योग्य नहीं है। इसे एक systemd service और timer के साथ schedule पर चलाएं और output को देखें। जब तक आप एक बार backup restore नहीं कर लेते, तब तक आप यह नहीं जान सकते कि वह काम करता है या नहीं।
systemd के अंतर्गत Litestream चलाना
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 को डेटाबेस और उसे रखने वाली निर्देशिका (directory) दोनों को पढ़ने और लिखने में सक्षम होना चाहिए, क्योंकि यह आपके डेटाबेस के बगल में -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 फ्लैग है।
जहाँ SQLite एक VPS पर विफल हो जाता है
Network filesystems. यह वह सीमा है जिसे आप कॉन्फ़िगरेशन से ठीक नहीं कर सकते। WAL मोड के लिए आवश्यक है कि डेटाबेस का उपयोग करने वाली प्रत्येक प्रक्रिया मेमोरी के एक छोटे हिस्से को साझा करे, जो कि -shm फ़ाइल प्रदान करती है। SQLite दस्तावेज़ीकरण इस नियम को बिना किसी शर्त के स्पष्ट करता है:
डेटाबेस का उपयोग करने वाली सभी प्रक्रियाएँ एक ही होस्ट कंप्यूटर पर होनी चाहिए; WAL नेटवर्क फ़ाइल सिस्टम पर काम नहीं करता है।
इसलिए, माउंट किए गए NFS (network file system) या SMB शेयर पर रखा गया डेटाबेस करप्ट हो सकता है, और कोई भी pragma इसे रोक नहीं सकता। यहाँ एक अंतर है जिसे लोग अक्सर अनदेखा कर देते हैं। एक नेटवर्क block डिवाइस, जिसे अधिकांश VPS प्रदाता अतिरिक्त स्टोरेज के रूप में जोड़ते हैं, Linux को एक सामान्य डिस्क के रूप में दिखता है जिस पर एक सामान्य फ़ाइल सिस्टम होता है, और यह ठीक है। एक माउंट किया गया file share ऐसा नहीं है।
दूसरा एप्लिकेशन सर्वर। कोई भी सेटिंग इसे काम करने योग्य नहीं बनाती है। जब आपको एक ही डेटा को सर्व करने के लिए दो मशीनों की आवश्यकता होती है, तो आपको एक ऐसे डेटाबेस की आवश्यकता होती है जो नेटवर्क पर संचार कर सके। उस बदलाव का निर्णय तब लें जब आपके पास इसकी योजना बनाने का समय हो।
Write-heavy workloads. एक समय में केवल एक राइटर होना फ़ाइल फॉर्मेट की एक विशेषता है, न कि कोई ट्यूनेबल सेटिंग। छोटे राइट्स सस्ते होते हैं क्योंकि प्रत्येक कमिट WAL में एक append होता है, इसलिए थ्रूपुट आपके CPU की तुलना में आपकी डिस्क की small-write लेटेंसी पर अधिक निर्भर करता है। देखें VPS पर NVMe बनाम SATA SSD स्टोरेज कि वह अंतर कैसा दिखता है। लंबे ट्रांजेक्शन असली समस्या हैं, क्योंकि वे अन्य सभी राइटर्स को अपने पीछे कतार में खड़ा कर देते हैं।
Analytical queries. SQLite ट्रांजेक्शन के लिए बनाया गया एक row store है। दस करोड़ पंक्तियों को स्कैन करने वाला डैशबोर्ड एक अलग टूल के लिए एक अलग काम है, और सर्वर कार्य के लिए DuckDB बनाम SQLite इस बात को कवर करता है कि वह सीमा कहाँ है।
VACUUM रेप्लिकेशन के तहत। एक पूर्ण VACUUM पूरी डेटाबेस फ़ाइल को फिर से लिखता है, जिसका अर्थ है कि Litestream को इसे फिर से अपलोड करना होगा, और Litestream दस्तावेज़ीकरण रेप्लिकेशन सक्रिय होने के दौरान इसे चलाने के खिलाफ सलाह देता है। रेप्लिकेटर को रोकें, vacuum करें, इसे फिर से शुरू करें, और एक नए पूर्ण स्नैपशॉट की अपेक्षा करें।
एक डेटाबेस पर दो रेप्लिकेटर। कभी भी एक ही डेटाबेस या एक ही रेप्लिका डेस्टिनेशन पर दो Litestream प्रक्रियाएँ न चलाएँ। दस्तावेज़ीकरण स्पष्ट है कि इसे रोकना आपकी जिम्मेदारी है, और इसका परिणाम एक ऐसा रेप्लिका होगा जिसे आप रिस्टोर नहीं कर पाएंगे।
Litestream क्या कवर नहीं करता है
Litestream केवल database file की सुरक्षा करता है, और कुछ नहीं। अपलोड की गई फाइलें, application config, TLS (transport layer security) certificates और unit files को मैनेज करना अभी भी आपकी जिम्मेदारी है। इसे restic का उपयोग करके encrypted off-box backups के साथ एक schedule पर जोड़ें, जिससे दोनों हिस्से सुरक्षित हो जाएंगे। यदि machine नई है, तो एक नए VPS पर शुरुआती दस मिनट में उन user account और firewall कार्यों को कवर किया गया है जिन्हें यह guide पहले से पूरा मानकर चलती है।
FAQ
क्या SQLite प्रोडक्शन एप्लिकेशन के लिए पर्याप्त है?
एक सर्वर पर एक एप्लिकेशन के लिए, हाँ, बशर्ते आप WAL मोड चालू करें, busy timeout सेट करें और लगातार बैकअप लें। जो सीमाएं मायने रखती हैं वे संरचनात्मक हैं: एक समय में केवल एक राइटर और केवल एक होस्ट मशीन। जो एप्लिकेशन इन सीमाओं के भीतर फिट बैठता है, उसे बिना किसी नेटवर्क हॉप और बिना किसी अलग मॉनिटरिंग प्रोसेस के डेटाबेस मिल जाता है। जो एप्लिकेशन इन सीमाओं में फिट नहीं होता, उसे क्लाइंट-सर्वर डेटाबेस की आवश्यकता होती है, और किसी भी तरह की ट्यूनिंग इसे नहीं बदल सकती।
busy_timeout सेट करने के बाद भी मुझे database is locked क्यों मिलता है?
क्योंकि जब प्रतीक्षा करने से डेडलॉक हो सकता है, तो SQLite बिजी हैंडलर को छोड़ देता है। जो ट्रांजेक्शन एक साधारण BEGIN से शुरू होता है, वह 'डेफर्ड' (deferred) होता है: एक शुरुआती SELECT उसे रीड ट्रांजेक्शन में डाल देता है, और बाद में राइट करने के लिए अपग्रेड की आवश्यकता होती है। यदि बीच में किसी अन्य कनेक्शन ने राइट किया है, तो SQLite आपके बिजी हैंडलर को कॉल करने के बजाय तुरंत SQLITE_BUSY लौटा देता है, क्योंकि आपका रीड स्नैपशॉट पहले ही पुराना हो चुका होता है। किसी भी ऐसे ट्रांजेक्शन को BEGIN IMMEDIATE के साथ शुरू करें जिसमें राइट करना हो, ताकि राइट लॉक पहले ही ले लिया जाए और टाइमआउट लागू हो सके।
क्या मैं अपने SQLite डेटाबेस को नेटवर्क स्टोरेज पर रख सकता हूँ?
NFS या SMB जैसे नेटवर्क फाइलसिस्टम पर नहीं। WAL मोड के लिए यह आवश्यक है कि सभी प्रोसेस -shm फाइल के माध्यम से मेमोरी साझा करें, और SQLite डॉक्यूमेंटेशन स्पष्ट करता है कि डेटाबेस का उपयोग करने वाली प्रत्येक प्रोसेस एक ही होस्ट कंप्यूटर पर होनी चाहिए। आपके प्रोवाइडर द्वारा अटैच किया गया नेटवर्क ब्लॉक डिवाइस एक अलग चीज है: Linux इसे एक सामान्य डिस्क के रूप में देखता है जिस पर सामान्य फाइलसिस्टम होता है, और SQLite वहाँ काम करता है।
यदि मैं पहले से ही नाइटली बैकअप चला रहा हूँ, तो क्या मुझे Litestream की आवश्यकता है?
यह इस बात पर निर्भर करता है कि आप कितना डेटा खोने का जोखिम उठा सकते हैं। नाइटली जॉब का मतलब है चौबीस घंटे तक के राइट्स का नुकसान। Litestream लगभग हर सेकंड सिंक करता है, इसलिए क्रैश होने पर आप केवल आखिरी सेकंड का डेटा खोते हैं। यह cp के साथ डेटाबेस फाइल को कॉपी करने से भी अधिक सुरक्षित है, क्योंकि वह राइटिंग के दौरान डेटाबेस को कैप्चर कर सकता है। Litestream केवल डेटाबेस को कवर करता है, इसलिए इसके साथ-साथ एक सामान्य फाइल बैकअप भी चालू रखें।