VPS-ல் SQLite-ஐ production-க்கு பயன்படுத்துவது எப்படி?
VPS-ல் SQLite-ஐ production database-ஆகப் பயன்படுத்தும் முறையை அறியுங்கள். WAL mode, busy_timeout மற்றும் Litestream மூலம் தரவு பாதுகாப்பை உறுதி செய்வது எப்படி என விளக்குகிறோம்.
VPS-ல் SQLite-ஐ production database-ஆகப் பயன்படுத்துவது எப்போது சரியானது?
பெரும்பாலான சிறிய applications-க்கு VPS-ல் SQLite-ஐ production-ல் இயக்குவது சரியான தேர்வாகும். இதற்கான காரணம் எளிமையானது: ஒரே கணினியில், ஒரே கோப்பில் எழுதும் ஒரு process-க்கு தனி database server தேவையில்லை. கண்காணிக்க வேண்டிய daemon இல்லை, firewall-ல் திறக்க வேண்டிய port இல்லை, மாற்ற வேண்டிய password இல்லை, உயிர்ப்புடன் வைத்திருக்க வேண்டிய இரண்டாவது கணினி இல்லை. ஒரு query என்பது network round trip-க்கு பதிலாக ஒரு function call ஆகும். எனவே, நாற்பது queries இயங்கும் ஒரு page-க்கு நாற்பது function calls மட்டுமே செலவாகும்.
இதன் வரம்புகள் சிறியவை மற்றும் தெளிவானவை. SQLite முழு database கோப்பிலும் ஒரே நேரத்தில் ஒரு எழுத்தாளரை (writer) மட்டுமே அனுமதிக்கும், மேலும் இந்த கோப்பை இரண்டு கணினிகளுக்கு இடையே பகிர முடியாது. ஒரு VPS-ல் ஒரு application-ஐ இயக்கும்போது இந்த இரண்டு வரம்புகளும் எந்தப் பாதிப்பையும் ஏற்படுத்தாது. ஆனால், உங்கள் application இந்த அளவைத் தாண்டும்போது, இந்த வரம்புகள் பெரும் சிக்கலாக மாறும். இந்த வழிகாட்டி, server-ல் SQLite-ஐப் பாதுகாப்பாக வைப்பதற்கான அமைப்புகள், Litestream மூலம் தொடர்ச்சியான backup எடுத்தல் மற்றும் எப்போது நீங்கள் SQLite-ஐத் தவிர்க்க வேண்டும் என்பது குறித்து விளக்குகிறது.
முதலில் command line tool-ஐ நிறுவவும். கீழே உள்ள அனைத்தும் Ubuntu 24.04-ல் இயக்கப்பட்டவை.
sudo apt update
sudo apt install -y sqlite3
sqlite3 --versionஇது 3.-ல் தொடங்கும் ஒரு version-ஐயும், அதைத் தொடர்ந்து build செய்யப்பட்ட தேதியையும், source hash-ஐயும் காட்டும். ஜூலை 2026 நிலவரப்படி, Ubuntu 24.04-ல் SQLite 3.45.1 உள்ளது. உங்கள் application பெரும்பாலும் இந்த binary-ஐப் பயன்படுத்தாது: பெரும்பாலான language runtimes தங்களுக்கென சொந்த SQLite library-ஐக் கொண்டிருக்கும், அவை பெரும்பாலும் புதிய பதிப்பாக இருக்கலாம். எனவே, புதிய வசதிகளைப் பயன்படுத்துவதற்கு முன்பு உங்கள் database driver காட்டும் version-ஐச் சரிபார்க்கவும்.
WAL mode-ஐ ஏன் முதலில் மாற்ற வேண்டும்
இயல்பாக SQLite ஒரு rollback journal-ஐப் பயன்படுத்துகிறது. ஒரு பக்கத்தை (page) மாற்றுவதற்கு முன்பு, அது அசல் பக்கத்தை ஒரு -journal கோப்பில் நகலெடுத்துவிட்டு, பின் தரவுத்தளத்தில் நேரடியாக மாற்றங்களைச் செய்கிறது. இதைச் பாதுகாப்பாகச் செய்ய, முழு கோப்பின் மீதும் ஒரு exclusive lock-ஐ அது எடுக்கும். இதனால், ஒரு write செயல்பாடு நடக்கும்போது அனைத்து reader-களும் காத்திருக்க வேண்டியிருக்கும். ஒரு மடிக்கணினியில் இது பெரிய பாதிப்பை ஏற்படுத்தாது. ஆனால், ஒரு web server-ல், ஒரு மெதுவான write செயல்பாடு தரவுத்தளத்தை அணுகும் அனைத்து request-களையும் நிறுத்திவிடும்.
WAL (write-ahead log) mode இந்த வரிசையை மாற்றியமைக்கிறது. ஒரு writer புதிய பக்கங்களை ஒரு தனி -wal கோப்பில் சேர்க்கிறது; இது முதன்மை தரவுத்தளத்தைத் தொடுவதில்லை. Reader-கள் தாங்கள் தொடங்கிய snapshot நிலையிலேயே முதன்மை கோப்பைப் படிக்கிறார்கள். இதனால் reader-கள் writer-ஐத் தடுப்பதில்லை, writer-ம் reader-களைத் தடுப்பதில்லை. பின்னர், ஒரு checkpoint மூலம் WAL கோப்பில் சேர்ந்த பக்கங்கள் முதன்மை தரவுத்தளத்திற்கு நகலெடுக்கப்படும். இந்த ஒரு மாற்றம் மட்டுமே, ஒரு web application-ன் பின்புலத்தில் SQLite-ஐப் பயன்படுத்தக்கூடியதாக மாற்றுகிறது.
WAL mode-ஐ இயக்கி, அது நிலைபெற்றுள்ளதை உறுதி செய்தல்
mkdir -p ~/app
sqlite3 ~/app/app.db "PRAGMA journal_mode=WAL;"இந்தக் கட்டளை wal-ஐ அச்சிடும். அந்த வெளியீடு வெறும் அலங்காரம் அல்ல. PRAGMA journal_mode என்பது தரவுத்தளம் தற்போது எந்த நிலையில் உள்ளது என்பதைத் தெரிவிக்கும். எனவே, delete என்ற பதில் வந்தால், மாற்றம் தோல்வியடைந்துள்ளது என்றும் நீங்கள் இன்னும் rollback journal முறையிலேயே இருக்கிறீர்கள் என்றும் பொருள்.
WAL mode என்பது நிரந்தரமானது. இது connection அமைப்பைக் காட்டிலும், தரவுத்தள header-ல் உள்ள ஒரு flag ஆகும். எனவே, ஒவ்வொரு தரவுத்தளக் கோப்பிற்கும் இதை ஒருமுறை இயக்கினால் போதும்; அதன் பிறகு வரும் அனைத்து 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/இப்போது மூன்று கோப்புகள் உள்ளன: app.db, app.db-wal மற்றும் app.db-shm. -wal கோப்பு, இன்னும் checkpoint செய்யப்படாத committed பக்கங்களை வைத்திருக்கிறது. -shm கோப்பு என்பது ஒரு shared memory index ஆகும்; ஒவ்வொரு connection-ம் இதை map செய்வதன் மூலம், WAL-ல் என்ன உள்ளது என்பதில் அவை அனைத்தும் ஒருமித்த கருத்துடன் இருக்கின்றன. இவை இரண்டுமே தரவுத்தளத்திற்குச் சொந்தமானவை, இவை தற்காலிகக் கோப்புகள் (scratch files) அல்ல. application இயங்கிக்கொண்டிருக்கும்போது app.db-ஐ மட்டும் தனியாக நகலெடுத்தால், சமீபத்திய commit-கள் விடுபட்ட ஒரு கோப்புதான் உங்களுக்குக் கிடைக்கும். app.db-ஐ மட்டும் நீக்கிவிட்டு மற்ற இரண்டையும் அப்படியே விட்டுவிட்டால், அந்தப் பெயரில் தோன்றும் புதிய கோப்பில் SQLite அந்தப் பழைய WAL பக்கங்களைப் பயன்படுத்தும். தரவுத்தளத்தை reset செய்ய முயற்சிக்கும்போது மக்கள் தவறுதலாகத் தரவுத்தளத்தைச் சிதைப்பது (corrupt) இப்படித்தான்.
ஒவ்வொரு production application-க்கும் தேவையான connection அமைப்புகள்
database-ல் journal_mode மட்டுமே சேமிக்கப்படுகிறது. கீழே உள்ள மற்ற அனைத்து அமைப்புகளும் ஒவ்வொரு connection-க்கும் உரியவை. அதாவது, உங்கள் application திறக்கும் ஒவ்வொரு connection-லும், connection pool பின்னணியில் உருவாக்கும் ஒவ்வொரு connection-லும் இவற்றை இயக்க வேண்டும்.
PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 5000;
PRAGMA synchronous = NORMAL;
PRAGMA foreign_keys = ON;busy_timeout = 5000, ஒரு locked database-ஐ 5000 milliseconds வரை மீண்டும் மீண்டும் முயற்சி செய்யுமாறு SQLite-க்கு அறிவுறுத்துகிறது; அதன் பின்னரே database is locked-ஐத் திருப்பி அனுப்பும். இதன் default மதிப்பு 0 ஆகும், எனவே இரண்டு writers ஒரே நேரத்தில் செயல்படும்போது SQLite உடனடியாகத் தோல்வியடையும். இந்த ஒரு மதிப்பை அமைப்பதன் மூலம், SQLite-ன் மீது சுமத்தப்படும் பெரும்பாலான lock பிழைகளைத் தவிர்க்கலாம்.
WAL mode-ல் synchronous = NORMAL என்பது சரியான அமைப்பாகும், இதன் விளைவுகளைப் புரிந்துகொள்வது அவசியம். FULL நிலையில், ஒவ்வொரு commit-ன் போதும் SQLite WAL-ல் fsync-ஐ அழைக்கும். NORMAL நிலையில், checkpoints-ன் போது மட்டுமே sync செய்யும். மின்சாரம் தடைபட்டாலோ அல்லது hard reset செய்யப்பட்டாலோ transactions-ன் நிலைத்தன்மை (durability) இருக்காது என்று SQLite ஆவணங்கள் தெளிவாகக் கூறுகின்றன. இதனால் database சிதையாது, ஆனால் disk-க்குச் சென்றடையாத கடைசி commit-கள் மட்டும் இழக்கப்படும். VPS-ல் இதுவே சரியான தேர்வாகும், ஏனெனில் இது ஒவ்வொரு write செயல்பாட்டிலிருந்தும் ஒரு fsync-ஐ நீக்குகிறது.
foreign_keys = ON என்பது பின்னோக்கிய இணக்கத்தன்மைக்காக (backwards compatibility) default-ஆக off நிலையில் இருக்கும், இது ஒவ்வொரு connection-க்கும் பொருந்தும். ஒவ்வொரு connection-லும் இதை ஆன் செய்யும் வரை, REFERENCES clauses கொண்ட schema எதையும் அமல்படுத்தாது.
இன்னொரு முக்கியமான அமைப்பு பிற்காலத்தில் மட்டுமே தேவைப்படும். WAL 1000 பக்கங்களுக்கு மேல் வளரும்போது SQLite தானாகவே checkpoints செய்யும், அந்த நேரத்தில் transaction-ஐ முடிக்கும் எந்த connection-ம் இந்த வேலையைச் செய்யும். இது பொதுவாகச் சரியாகவே செயல்படும். ஆனால் Litestream இயங்கும்போது இது ஒரு கேள்வியாக மாறுகிறது, ஏனெனில் checkpoints எப்போது நடக்க வேண்டும் என்பதைக் கட்டுப்படுத்த Litestream விரும்புகிறது.
busy_timeout அமைத்த பிறகும் ஏன் database is locked ஏற்படுகிறது
இந்தத் தோல்விதான் பயனர்களை மீண்டும் Postgres-க்குத் திரும்பச் செய்கிறது, இதற்கு ஒரு குறிப்பிட்ட காரணம் உள்ளது.
ஒரு busy timeout என்பது busy handler-ஐ நிறுவுகிறது, ஆனால் அதை SQLite எப்போதும் அழைக்கும் என்று உத்தரவாதம் அளிக்காது.
busy handler-ஐ அழைப்பது deadlock-க்கு வழிவகுக்கும் என்று SQLite கருதினால், அது busy handler-ஐ அழைப்பதற்குப் பதிலாக நேரடியாக application-க்கு SQLITE_BUSY-ஐத் திருப்பி அனுப்பும்.
ஒரு transaction மேம்படுத்தப்படும்போது (upgrade) இந்த deadlock ஏற்படுகிறது. SQLite-ல் ஒரு வெற்று BEGIN என்பது BEGIN DEFERRED-ஐக் குறிக்கும். அதற்குப் பிறகு வரும் முதல் statement ஒரு SELECT ஆக இருந்தால், நீங்கள் ஒரு read transaction-ல் இருக்கிறீர்கள் என்று அர்த்தம். அதே transaction-ல் பிற்காலத்தில் வரும் ஒரு UPDATE, write transaction-ஆக மாற வேண்டியிருக்கும்போது, உங்கள் read தொடங்கிய பிறகு மற்றொரு connection தரவை எழுதியிருந்தால், SQLite உங்களை காத்திருக்க வைக்க முடியாது. ஏனெனில், உங்கள் snapshot ஏற்கனவே காலாவதியாகிவிட்டது, காத்திருப்பது இரண்டு connection-களுக்கும் இடையே deadlock-ஐ மட்டுமே உருவாக்கும். ஆவணங்கள் இதன் விளைவை நேரடியாகக் குறிப்பிடுகின்றன:
அடுத்தடுத்த write statement-கள் முடிந்தால் transaction-ஐ write transaction-ஆக மேம்படுத்தும், அல்லது SQLITE_BUSY-ஐத் திருப்பி அனுப்பும்.
உங்கள் 5000 millisecond timeout ஒருபோதும் கணக்கில் கொள்ளப்படாது. பிழை உடனடியாக வருவதால்தான், அந்த அமைப்பு எந்த மாற்றத்தையும் செய்யவில்லை என்று தோன்றுகிறது.
இதற்கான தீர்வு ஒரே ஒரு வார்த்தைதான்.
BEGIN IMMEDIATE;
UPDATE notes SET body = 'edited' WHERE id = 1;
COMMIT;BEGIN IMMEDIATE என்பது எதையும் படிப்பதற்கு முன்பே, தொடக்கத்திலேயே write lock-ஐ எடுத்துக்கொள்ளும். இங்கே மேம்படுத்தல் (upgrade) இல்லாததால், தவிர்க்க வேண்டிய deadlock-ம் இல்லை. எனவே, busy handler செயல்படும் மற்றும் connection தோல்வியடைவதற்குப் பதிலாக தனது முறைக்காகக் காத்திருக்கும். Read-only transaction-களை deferred நிலையிலேயே வைத்திருங்கள். எழுதும் செயல்பாடு (write) கொண்ட எந்தவொரு transaction-ம் immediate ஆக இருக்க வேண்டும்.
Lock பிழைகளுக்கான இரண்டாவது காரணம் கண்டறிய கடினமானது: மெதுவான செயல்பாடுகளின் போது write transaction-ஐத் திறந்து வைத்திருப்பது. SQLite எழுதுபவர்களை வரிசைப்படுத்துகிறது (serialise), எனவே ஒரு transaction தொடங்கி, network வழியாக external API-ஐ அழைத்து, பின் commit செய்யும் வரை, அந்த அழைப்பு முடியும் காலம் வரை மற்ற அனைத்து எழுதுபவர்களையும் அது தடுக்கும். உங்களுக்குத் தேவையானதைப் படியுங்கள், transaction-ஐ மூடுங்கள், மெதுவான வேலையைச் செய்யுங்கள், அதன் பிறகு முடிவைச் சேமிக்க ஒரு குறுகிய write transaction-ஐத் தொடங்குங்கள்.
Litestream மூலம் தொடர்ச்சியான பேக்கப் (Continuous backup)
தினசரி ஒருமுறை எடுக்கப்படும் நகல் (nightly copy) ஒரு நாள் முழுவதுமான தரவு மாற்றங்களை இழக்கச் செய்யும். மேலும், இயங்கிக்கொண்டிருக்கும் SQLite database-ல் cp-ஐ இயக்குவது, திறக்க முடியாத ஒரு நகலை உருவாக்கக்கூடும். இரண்டு முறைகள் பாதுகாப்பானவை. sqlite3 app.db ".backup /path/to/backup.db", SQLite-ன் online backup interface-ஐப் பயன்படுத்துகிறது; இது பயன்பாட்டில் உள்ள database-ல் வேலை செய்யும். Litestream இதைவிட ஒரு படி மேலே செல்கிறது: இது WAL-ஐக் கண்காணித்து, மாற்றங்களை object storage-க்குத் தொடர்ச்சியாக அனுப்பி வைக்கிறது. இதனால் தரவு இழப்பு ஒரு நாள் என்ற நிலையிலிருந்து சுமார் ஒரு வினாடி என்ற நிலைக்குக் குறைகிறது.
Litestream என்பது உங்கள் application-க்கு அருகிலேயே இயங்கும் ஒரு Go binary ஆகும். இது application-க்கும் database-க்கும் இடையில் செயல்படாது. உங்கள் application எப்போதும் போல SQLite-ல் எழுதும்; Litestream WAL-ஐ வாசித்து, மாறிய தரவுகளை 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ஜூலை 2026 நிலவரப்படி, அதிகாரப்பூர்வ Linux install பக்கத்தில் v0.5.14 பதிப்பு ஆவணப்படுத்தப்பட்டுள்ளது. v0.5.15 பதிப்பு ஜூலை 21, 2026 அன்று வெளியானது. releases பக்கத்தில் உள்ள தற்போதைய tag-க்கு ஏற்ப இரண்டு வரிகளிலும் உள்ள பதிப்பு எண்ணை மாற்றவும். உங்கள் VPS arm64 ஆக இருந்தால், அதற்குரிய arm64 package-ஐப் பயன்படுத்தவும்.
இதன் configuration file /etc/litestream.yml-ல் அமையும். முதலில் ஒரு local file replica-வுடன் தொடங்கவும்; இது cloud credentials தேவையில்லாமல் முழு சுழற்சியையும் (loop) உறுதிப்படுத்தும்.
dbs:
- path: /home/appuser/app/app.db
replica:
type: file
path: /var/backups/litestream/appஇதில் உள்ள field replica (ஒருமை) என்பதை கவனிக்கவும். Litestream 0.5 பதிப்பு, 0.3 தொடரில் இருந்த replicas array-க்கு பதிலாக ஒரு single replica block-ஐக் கொண்டுவந்தது. இரண்டு entries கொண்ட config இப்போது startup-ல் தோல்வியடையும். பல மூன்றாம் தரப்பு வழிகாட்டிகள் இன்னும் பழைய array-யையே காட்டுகின்றன, எனவே தேடலில் முதலில் கிடைக்கும் உதாரணத்தைப் பின்பற்றாமல், மேலே உள்ள அமைப்பைப் பயன்படுத்தவும். 0.5 தொடரில் litestream wal subcommand, litestream ltx எனப் பெயர் மாற்றப்பட்டுள்ளது, ஏனெனில் on-disk backup format மாறியுள்ளது.
எந்தவொரு செயல்பாட்டையும் தொடங்கும் முன், config சரியாக parse ஆகிறதா என்று சரிபார்க்கவும்.
sudo litestream databases -config /etc/litestream.ymlபின்பு, round trip-ஐ நீங்களே செய்து உறுதிப்படுத்தவும். இந்த வடிவம் config file-ஐத் தவிர்த்து, ஒரு database-ஐ ஒரு path-க்கு replicate செய்கிறது.
mkdir -p /tmp/replica
litestream replicate ~/app/app.db file:///tmp/replica/appஇது 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;"இந்த எண்ணிக்கையில் புதிய row-வும் அடங்கும். இல்லையெனில், மாற்றம் இன்னும் sync ஆகவில்லை என்று பொருள்: Litestream, sync-interval-ஐப் பயன்படுத்தி தரவுகளைத் தள்ளுகிறது (இதன் default மதிப்பு 1 வினாடி). எனவே சிறிது காத்திருந்து மீண்டும் restore செய்யவும். அந்த ஒரு வினாடிதான் உங்கள் recovery point. ஒரு crash ஏற்பட்டால், கடைசி sync interval-ல் நடந்த மாற்றங்கள் மட்டுமே இழக்கப்படும்; இதை பூஜ்ஜியமாக்க எந்த configuration-லும் வழி இல்லை.
உண்மையான storage-க்கு, replica block-ஐ ஒரு S3 URL-ஆக மாற்றவும். இது Amazon S3 மற்றும் பிற நிறுவனங்களின் 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: 24hcredentials-ஐ அந்த file-ல் வைக்க வேண்டாம். Litestream, LITESTREAM_ACCESS_KEY_ID மற்றும் LITESTREAM_SECRET_ACCESS_KEY ஆகியவற்றை environment-லிருந்து வாசிக்கும். எனவே, அவற்றை root-க்குச் சொந்தமான மற்றும் 600 mode கொண்ட ஒரு systemd drop-in file-ல் வைக்கவும்.
மேலே உள்ள snapshot மதிப்புகள் default ஆனவை. retention default பலரை ஆச்சரியப்படுத்தும். Litestream எவ்வளவு காலத்திற்கு snapshot-களையும் அதனுடன் தொடர்புடைய file-களையும் வைத்திருக்கிறது என்பதே retention ஆகும்; இது நீங்கள் எவ்வளவு காலத்திற்கு முந்தைய நிலைக்கு restore செய்ய முடியும் என்பதையும் குறிக்கும். இருபத்தி நான்கு மணிநேரம் என்பது, புதன்கிழமை காலை நீங்கள் கவனிக்கும் ஒரு தவறான migration-ஐ, திங்கட்கிழமை நிலைக்குத் திரும்பப் பெற முடியாது என்பதைக் குறிக்கிறது. retention: 168h-ஐ ஒரு வாரத்திற்கு அமைத்து, கூடுதல் 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-வை கண்டறிந்து பதிவிறக்கம் செய்கிறது. PRAGMA integrity_check கட்டளையானது ஆரோக்கியமான கோப்பில் ok என்பதை அச்சிடும்; வேறு ஏதேனும் வெளியீடு வந்தால், restore செய்யப்பட்ட நகல் பயன்பாட்டிற்கு உகந்ததல்ல என்று பொருள். இதை systemd service மற்றும் timer மூலம் குறிப்பிட்ட கால இடைவெளியில் இயக்கி, அதன் வெளியீட்டைச் சரிபார்க்கவும். ஒருமுறை backup-ஐ restore செய்து பார்க்கும் வரை, அது சரியாகச் செயல்படுகிறதா என்பது உங்களுக்குத் தெரியாது.
systemd-ன் கீழ் Litestream-ஐ இயக்குதல்
Debian தொகுப்பானது litestream unit-ஐ நிறுவுகிறது, இது /etc/litestream.yml-ஐ வாசிக்கிறது.
sudo systemctl enable litestream
sudo systemctl start litestream
sudo journalctl -u litestream -fசரியான செயல்பாட்டின் போது, configuration-ல் உள்ள ஒவ்வொரு database-ன் பெயரும் வெளியீட்டில் காட்டப்படும், அதன் பிறகு அவ்வப்போது sync செய்யப்படும் வரிகள் மட்டுமே தோன்றும். உங்கள் database பாதையில் no such file or directory பிழை ஏற்பட்டால், configuration-ல் உள்ள பாதை தவறாக உள்ளது அல்லது அந்த process-ஆல் அதை வாசிக்க முடியவில்லை என்று பொருள். இந்த unit இயல்பாக root கணக்கில் இயங்குகிறது, ஆனால் இந்த பணிக்குத் தேவையானதை விட இது அதிக அதிகாரம் கொண்டது. Litestream-ஆல் database-ஐயும், அதை உள்ளடக்கிய directory-யையும் வாசிக்கவும் எழுதவும் முடிய வேண்டும். ஏனெனில், இது உங்கள் database-க்கு அருகில் உள்ள -wal மற்றும் -shm கோப்புகளைக் கையாள்கிறது. எனவே, உங்கள் application ஏற்கனவே பயன்படுத்தும் கணக்கையே இதற்கும் வழங்கவும்.
# /etc/systemd/system/litestream.service.d/override.conf
[Service]
User=appuser
Group=appuserஇதை sudo systemctl daemon-reload மற்றும் sudo systemctl restart litestream மூலம் செயல்படுத்தவும். குறைந்தபட்ச அதிகாரங்களுடன் கூடிய பிரத்யேக service கணக்கை அமைப்பதற்குச் சில நிமிடங்கள் மட்டுமே ஆகும். இது ஒரு backup agent-க்கும், server-ல் இயங்கும் இரண்டாவது root process-க்கும் இடையிலான முக்கிய வேறுபாடாகும்.
நீங்கள் ஒரு machine-ஐ முழுமையாக மீண்டும் கட்டமைக்கும்போது, ஒரு வரிசைமுறை விவரம் முக்கியமானது. உங்கள் application தொடங்குவதற்கு முன்பே database restore செய்யப்பட வேண்டும். litestream restore ஆனது -if-db-not-exists-ஐ ஏற்றுக்கொள்கிறது; கோப்பு ஏற்கனவே அங்கு இருந்தால் இது 0 என்ற நிலையைத் தரும், எனவே ஒவ்வொரு boot-இன் போதும் இதை இயக்குவது பாதுகாப்பானது. இதை உங்கள் application-ன் unit-ல் உள்ள ExecStartPre வரியில் சேர்க்கவும். இதன் மூலம், புதிய VPS-ல் database தரவிறக்கம் செய்யப்படும், ஏற்கனவே உள்ள VPS-ல் எந்த மாற்றமும் ஏற்படாது. நீங்கள் அனைத்தையும் ஒரே இடத்தில் வைத்திருக்க விரும்பினால், litestream replicate-ல் இதற்கென -restore-if-db-not-exists flag உள்ளது.
VPS-ல் SQLite எங்கு தோல்வியடைகிறது
Network filesystems. இதை எந்த configuration மூலமும் சரிசெய்ய முடியாது. WAL mode-ல் இயங்கும் ஒவ்வொரு process-ம் ஒரு சிறிய memory பகுதியை பகிர வேண்டும், இதைத்தான் -shm கோப்பு வழங்குகிறது. SQLite ஆவணங்கள் இந்த விதியை எந்த நிபந்தனையும் இன்றி குறிப்பிடுகின்றன:
தரவுத்தளத்தைப் பயன்படுத்தும் அனைத்து process-களும் ஒரே host கணினியில் இருக்க வேண்டும்; network filesystem வழியாக WAL இயங்காது.
எனவே, mounted NFS (network file system) அல்லது SMB share-ல் உள்ள தரவுத்தளம் சிதையக்கூடும், இதை எந்த pragma-வும் தடுக்க முடியாது. இதில் மக்கள் கவனிக்கத் தவறும் ஒரு முக்கிய வேறுபாடு உள்ளது. பெரும்பாலான VPS வழங்குநர்கள் கூடுதல் சேமிப்பகமாக வழங்கும் network block device, Linux-க்கு சாதாரண disk மற்றும் சாதாரண filesystem போலவே தெரியும், இது பாதுகாப்பானது. ஆனால், mounted file share அவ்வாறு இயங்காது.
இரண்டாவது application server. இதைச் செயல்படுத்த எந்த அமைப்பும் இல்லை. ஒரே தரவை இரண்டு இயந்திரங்கள் கையாள வேண்டிய சூழல் ஏற்பட்டால், network வழியாகச் செயல்படும் ஒரு தரவுத்தளம் உங்களுக்குத் தேவை. அதைத் திட்டமிட நேரம் இருக்கும்போதே இந்த மாற்றத்தை முடிவு செய்யுங்கள்.
அதிகமான எழுதும் பணி (Write-heavy workloads). ஒரே நேரத்தில் ஒரு writer மட்டுமே என்பது file format-ன் பண்பு, இதை மாற்ற முடியாது. ஒவ்வொரு commit-ம் WAL-ல் சேர்க்கப்படுவதால், சிறிய அளவிலான எழுதும் பணிகள் (short writes) வேகமானவை. எனவே, throughput என்பது உங்கள் CPU-வை விட disk-ன் small-write latency-ஐப் பொறுத்தே அமையும். அந்த வேறுபாட்டைப் புரிந்துகொள்ள VPS-ல் NVMe மற்றும் SATA SSD சேமிப்பகத்தின் ஒப்பீடு என்பதைப் பார்க்கவும். நீண்ட கால பரிவர்த்தனைகள் (long transactions) தான் உண்மையான சிக்கல், ஏனெனில் அவை மற்ற அனைத்து writer-களையும் வரிசையில் காத்திருக்கச் செய்யும்.
பகுப்பாய்வு வினவல்கள் (Analytical queries). SQLite என்பது பரிவர்த்தனைகளுக்காக உருவாக்கப்பட்ட row store ஆகும். ஒரு கோடிக்கும் அதிகமான வரிசைகளை ஸ்கேன் செய்யும் dashboard-க்கு வேறு கருவி தேவை, அந்த எல்லை எங்கு தொடங்குகிறது என்பதை server பணிகளுக்கு DuckDB மற்றும் SQLite ஒப்பீடு விளக்குகிறது.
VACUUM மற்றும் replication. ஒரு முழுமையான VACUUM தரவுத்தளக் கோப்பை முழுமையாக மீண்டும் எழுதும். அதாவது, Litestream அதை மீண்டும் முழுமையாக upload செய்ய வேண்டியிருக்கும். எனவே, replication செயல்பாட்டில் இருக்கும்போது இதைச் செய்ய வேண்டாம் என்று Litestream ஆவணங்கள் அறிவுறுத்துகின்றன. Replicator-ஐ நிறுத்திவிட்டு, vacuum செய்து, மீண்டும் தொடங்கவும்; அப்போது புதிய full snapshot கிடைக்கும் என்பதை நினைவில் கொள்க.
ஒரே தரவுத்தளத்தில் இரண்டு replicator-கள். ஒரே தரவுத்தளத்திற்கு அல்லது ஒரே replica இலக்கிற்கு எதிராக இரண்டு Litestream process-களை ஒருபோதும் இயக்க வேண்டாம். இதைத் தடுப்பது உங்கள் பொறுப்பு என்று ஆவணங்கள் தெளிவாகக் கூறுகின்றன; மீறினால், உங்களால் மீட்டெடுக்க முடியாத ஒரு replica மட்டுமே எஞ்சியிருக்கும்.
Litestream எவற்றைக் கையாளுவதில்லை
Litestream database கோப்பை மட்டுமே பாதுகாக்கிறது, மற்றவற்றை அல்ல. பதிவேற்றப்பட்ட கோப்புகள், application configuration, TLS (transport layer security) certificates மற்றும் unit files ஆகியவற்றை நீங்களே நிர்வகிக்க வேண்டும். இதனுடன் restic பயன்படுத்தி encrypted off-box backups எடுக்கும் முறையை ஒரு கால அட்டவணையின்படி இணைப்பதன் மூலம், இரண்டு பகுதிகளையும் பாதுகாக்க முடியும். புதிய machine என்றால், புதிய VPS-ல் முதல் பத்து நிமிடங்கள் என்ற வழிகாட்டி, இந்த guide-ல் ஏற்கனவே செய்யப்பட்டதாகக் கருதப்படும் user account மற்றும் firewall பணிகளை விளக்குகிறது.
FAQ
SQLite ஒரு production application-க்கு போதுமானதா?
ஒரே server-ல் இயங்கும் ஒரு 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 தரவை எழுதியிருந்தால், உங்கள் read snapshot ஏற்கனவே பழையதாகிவிட்டதால், SQLite உங்கள் busy handler-ஐ அழைக்காமல் உடனடியாக SQLITE_BUSY-ஐத் திருப்பித் தரும். எழுதப்போகும் எந்தவொரு transaction-ஐயும் BEGIN IMMEDIATE உடன் தொடங்குங்கள்; அப்போதுதான் write lock முன்னரே பெறப்பட்டு, timeout சரியாகச் செயல்படும்.
எனது SQLite database-ஐ network storage-ல் வைத்திருக்கலாமா?
NFS அல்லது SMB போன்ற network filesystem-களில் வைத்திருக்கக்கூடாது. WAL mode-க்கு அனைத்து process-களும் -shm கோப்பு வழியாக நினைவகத்தைப் பகிர்ந்து கொள்ள வேண்டும், மேலும் database-ஐப் பயன்படுத்தும் அனைத்து process-களும் ஒரே host computer-ல் இருக்க வேண்டும் என்று SQLite ஆவணங்கள் குறிப்பிடுகின்றன. உங்கள் provider வழங்கும் network block device இதற்கு மாறுபட்டது: Linux அதை ஒரு சாதாரண disk மற்றும் filesystem-ஆகவே பார்க்கும், எனவே SQLite அங்கு வேலை செய்யும்.
நான் ஏற்கனவே nightly backups எடுத்தால் Litestream தேவையா?
நீங்கள் எவ்வளவு தரவு இழப்பைத் தாங்கிக்கொள்ள முடியும் என்பதைப் பொறுத்தது. Nightly job என்றால் இருபத்தி நான்கு மணிநேரத் தரவு இழப்பு ஏற்பட வாய்ப்புள்ளது. Litestream வினாடிக்கு ஒருமுறை sync செய்வதால், ஒரு crash ஏற்பட்டால் கடைசி ஒரு வினாடி தரவு மட்டுமே இழக்கப்படும். cp மூலம் database கோப்பை நகலெடுப்பதை விட இது பாதுகாப்பானது, ஏனெனில் நகலெடுக்கும்போது database எழுதும் நிலையில் (mid-write) இருக்கலாம். Litestream database-ஐ மட்டுமே கவனிக்கும், எனவே அதனுடன் சேர்த்து பொதுவான file backup-ஐயும் வைத்திருங்கள்.