VPS-ல் SQLite-ஐ production-க்கு பயன்படுத்துவது எப்படி?
VPS-ல் SQLite-ஐ production database-ஆகப் பயன்படுத்தும் முறையை அறியுங்கள். WAL mode, busy_timeout மற்றும் Litestream மூலம் தரவு பாதுகாப்பை உறுதி செய்வது எப்படி என விளக்குகிறோம்.
VPS-ல் SQLite எப்போது சரியான production database ஆகும்
ஒரு VPS-ல் production சூழலில் SQLite-ஐ இயக்குவது பெரும்பாலான சிறிய applications-க்கு சரியான தேர்வாகும். இதற்கான காரணம் எளிமையானது: ஒரே இயந்திரத்தில், ஒரே கோப்பில் எழுதும் ஒரு process-க்கு தனி database server தேவையில்லை. கண்காணிக்க வேண்டிய daemon இல்லை, firewall-ல் திறக்க வேண்டிய port இல்லை, மாற்ற வேண்டிய password இல்லை, உயிர்ப்புடன் வைத்திருக்க வேண்டிய இரண்டாவது இயந்திரம் இல்லை. ஒரு query என்பது network round trip-க்கு பதிலாக ஒரு function call ஆகும். எனவே, நாற்பது queries கொண்ட ஒரு பக்கம் நாற்பது function calls-ன் செலவை மட்டுமே கொண்டிருக்கும்.
இதன் வரம்புகள் சிறியவை மற்றும் தெளிவானவை. SQLite முழு database கோப்பிலும் ஒரு நேரத்தில் ஒரு எழுத்தாளரை (writer) மட்டுமே அனுமதிக்கும், மேலும் இந்த கோப்பை இரண்டு இயந்திரங்களுக்கு இடையே பகிர முடியாது. ஒரு VPS-ல் ஒரு application-ஐ இயக்கும்போது இந்த இரண்டு வரம்புகளும் எந்தப் பாதிப்பையும் ஏற்படுத்தாது. ஆனால், இந்த கட்டமைப்பைத் தாண்டி வளரும்போது இவை பெரும் சிக்கலாக மாறும். இந்த வழிகாட்டி, ஒரு server-ல் SQLite-ஐ பாதுகாப்பாக வைத்திருப்பதற்கான அமைப்புகள், Litestream மூலம் தொடர்ச்சியான backup எடுக்கும் முறை மற்றும் எப்போது நீங்கள் இதை நிறுத்திவிட்டு வேறு database-க்கு மாற வேண்டும் என்பதை விளக்குகிறது.
முதலில் command line tool-ஐ நிறுவவும். கீழே உள்ள அனைத்தும் Ubuntu 24.04-ல் இயக்கப்பட்டவை.
sudo apt update
sudo apt install -y sqlite3
sqlite3 --versionஇது 3.-ல் தொடங்கி, build தேதி மற்றும் source hash-ஐக் கொண்ட ஒரு version-ஐக் காட்டும். அக்டோபர் 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)
தினசரி ஒருமுறை எடுக்கப்படும் பேக்கப், ஒரு நாள் வரையிலான தரவு இழப்பை ஏற்படுத்தலாம். இயங்கிக்கொண்டிருக்கும் 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 பதிப்பு ஆவணம் செய்யப்பட்டுள்ளது. அதன் பிறகு புதிய பதிப்புகள் வந்துள்ளன: 21 ஜூலை 2026 அன்று v0.5.15 மற்றும் 31 ஆகஸ்ட் 2026 அன்று புதிய tag-ஆன v0.5.17 வெளியாகியுள்ளன. 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-க்கு பதிலாக ஒற்றை replica block-ஐ அறிமுகப்படுத்தியது. இரண்டு entries கொண்ட config இப்போது startup-ல் தோல்வியடையும். பல மூன்றாம் தரப்பு வழிகாட்டிகளில் இன்னும் பழைய array முறையே காட்டப்படுகிறது, எனவே தேடலில் கிடைக்கும் முதல் உதாரணத்தைப் பின்பற்றாமல், மேலே உள்ள அமைப்பைப் பயன்படுத்தவும். 0.5 தொடரில் litestream wal subcommand, litestream ltx எனப் பெயர் மாற்றப்பட்டுள்ளது, ஏனெனில் on-disk backup format மாறியுள்ளது.
எதையும் enable செய்வதற்கு முன், 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-வை ஒரு புதிய கோப்பாக 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 இயல்பாக 1 வினாடி இடைவெளியில் sync-interval மூலம் மாற்றங்களை அனுப்பும், எனவே சிறிது காத்திருந்து மீண்டும் restore செய்யவும். அந்த ஒரு வினாடிதான் உங்கள் recovery point. ஒரு crash ஏற்பட்டால், கடைசி sync இடைவெளியில் நடந்த மாற்றங்கள் மட்டுமே இழக்கப்படும்; இதை முற்றிலும் தவிர்க்க எந்த 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-ஐ அந்த கோப்பில் வைக்க வேண்டாம். Litestream LITESTREAM_ACCESS_KEY_ID மற்றும் LITESTREAM_SECRET_ACCESS_KEY ஆகியவற்றை environment-லிருந்து வாசிக்கும், எனவே அவற்றை root உரிமையுள்ள, 600 mode கொண்ட systemd drop-in கோப்பில் வைக்கவும்.
மேலே உள்ள snapshot மதிப்புகள் இயல்பானவை (defaults), ஆனால் retention default பலரை ஆச்சரியப்படுத்தும். Retention என்பது Litestream எவ்வளவு காலம் snapshot-களையும் அதனுடன் தொடர்புடைய கோப்புகளையும் வைத்திருக்கும் என்பதைக் குறிக்கும்; அதாவது, எவ்வளவு காலத்திற்கு முந்தைய நிலைக்கு உங்களால் restore செய்ய முடியும் என்பதை இது தீர்மானிக்கிறது. இருபத்தி நான்கு மணிநேரம் என்பது, புதன்கிழமை காலை நீங்கள் கவனிக்கும் ஒரு தவறான migration-ஐ, திங்கட்கிழமை நிலைக்குத் திரும்பப் பெற முடியாது என்பதைக் குறிக்கிறது. Litestream 0.5-ல், retention என்பது root snapshot block-ல் உள்ள ஒரு global setting ஆகும், இது ஒவ்வொரு replica-க்கும் தனிப்பட்டது அல்ல. ஒரு வாரத்திற்கு, அந்த block-ஐ retention: 168h என மாற்றி, கூடுதல் storage-க்குக் கட்டணம் செலுத்தவும். replica block-க்குள் இருக்கும் retention: வரி 0.3-தொடரின் syntax ஆகும். Litestream 0.5 இதை பிழை காட்டாமல் புறக்கணித்துவிட்டு, 24-மணிநேர default-லேயே இருக்கும்.
தேவைப்படுவதற்கு முன்பே 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சரியான செயல்பாட்டில், config-ல் உள்ள ஒவ்வொரு database-ன் பெயரும் வெளியீட்டில் தோன்றும், அதன் பிறகு அவ்வப்போது sync செய்யப்படும் வரிகளைத் தவிர மற்ற தகவல்கள் வராது. உங்கள் database பாதையில் no such file or directory பிழை ஏற்பட்டால், config-ல் உள்ள பாதை தவறாக உள்ளது அல்லது அந்த process-ஆல் அதை வாசிக்க முடியவில்லை என்று அர்த்தம். இந்த unit இயல்பாக root பயனர் உரிமையில் இயங்குகிறது; ஆனால் இந்த பணிக்கு இவ்வளவு அதிகாரம் தேவையில்லை. Litestream உங்கள் database-ஐயும், அது இருக்கும் directory-யையும் வாசிக்கவும் எழுதவும் வேண்டும். ஏனெனில், இது உங்கள் database-க்கு அருகில் உள்ள -wal மற்றும் -shm கோப்புகளைக் கையாள்கிறது. எனவே, உங்கள் application எந்த பயனர் கணக்கில் இயங்குகிறதோ, அந்த கணக்கையே இதற்கும் வழங்கவும். இந்த உதாரணங்களில் அது appuser ஆகும்.
# /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-ஐ புதிதாக உருவாக்கும்போது, ஒரு வரிசைமுறை (ordering) முக்கியமானது. உங்கள் application தொடங்குவதற்கு முன்பே database restore செய்யப்பட வேண்டும். litestream restore கட்டளையானது -if-db-not-exists-ஐ ஏற்றுக்கொள்கிறது; கோப்பு ஏற்கனவே இருந்தால் அது 0 என்ற exit code-ஐத் தரும், எனவே இதை ஒவ்வொரு 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 சார்ந்திருக்கும் page-level tracking-ஐச் செயலிழக்கச் செய்கிறது. எனவே, replication செயல்பாட்டில் இருக்கும்போது அதை நேரடியாக இயக்க வேண்டாம் என்று Litestream ஆவணங்கள் அறிவுறுத்துகின்றன. அதற்குப் பதிலாக VACUUM INTO-ஐப் பயன்படுத்தப் பரிந்துரைக்கப்படுகிறது; இது சுருக்கப்பட்ட நகலை ஒரு தனி கோப்பில் எழுதும், அசல் கோப்பை மாற்றாது. ஒருவேளை நீங்கள் நேரடியாக vacuum செய்ய வேண்டியிருந்தால், அதற்கான நடைமுறை ஒரு restart-ஐ விட நீண்டது: replicator-ஐ நிறுத்துங்கள், vacuum செய்யுங்கள், தரவுத்தளத்திற்கு அருகில் உள்ள Litestream-ன் மறைக்கப்பட்ட tracking directory மற்றும் ஏற்கனவே உள்ள remote replica தரவுகளை நீக்குங்கள், பிறகு மீண்டும் தொடங்குங்கள். அப்போதுதான் அது புதிய full snapshot-லிருந்து தொடங்கும். அந்த கடைசி படி, நீங்கள் வைத்திருந்த restore வரலாற்றை அழித்துவிடும்.
ஒரே தரவுத்தளத்தில் இரண்டு replicator-கள். ஒரே தரவுத்தளம் அல்லது ஒரே replica இலக்கை நோக்கி இரண்டு Litestream process-களை ஒருபோதும் இயக்க வேண்டாம். இதைத் தடுப்பது உங்கள் பொறுப்பு என்று ஆவணங்கள் தெளிவாகக் கூறுகின்றன; மீறினால், உங்களால் restore செய்ய முடியாத ஒரு 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 தேவைப்படும்; எவ்வளவு மாற்றங்கள் செய்தாலும் இந்த அடிப்படைத் தேவையை மாற்ற முடியாது.
busy_timeout அமைத்த பிறகும் எனக்கு ஏன் database is locked கிடைக்கிறது?
ஏனெனில், காத்திருப்பது deadlock-ஐ ஏற்படுத்தக்கூடும் என்ற சூழலில் SQLite busy handler-ஐத் தவிர்க்கிறது. வெறும் BEGIN உடன் தொடங்கும் ஒரு transaction 'deferred' நிலையில் இருக்கும்: ஒரு தொடக்க SELECT அதை read transaction-ல் வைக்கிறது, பின்னர் நடக்கும் write செயல்பாடு அதை upgrade செய்ய வேண்டும். இடையில் மற்றொரு connection தரவை எழுதியிருந்தால், உங்கள் read snapshot ஏற்கனவே பழையதாகிவிட்டதால், busy handler-ஐ அழைப்பதற்குப் பதிலாக SQLite உடனடியாக SQLITE_BUSY-ஐத் திருப்பித் தருகிறது. எழுதப்போகும் எந்தவொரு transaction-ஐயும் BEGIN IMMEDIATE உடன் தொடங்குங்கள்; அப்போதுதான் write lock ஆரம்பத்திலேயே பெறப்பட்டு, timeout சரியாகச் செயல்படும்.
எனது SQLite database-ஐ network storage-ல் வைத்திருக்க முடியுமா?
NFS அல்லது SMB போன்ற network filesystem-களில் வைத்திருக்க முடியாது. WAL mode-க்கு அனைத்து process-களும் -shm கோப்பின் வழியாக memory-ஐப் பகிர்ந்து கொள்ள வேண்டும். SQLite ஆவணங்களின்படி, database-ஐப் பயன்படுத்தும் ஒவ்வொரு process-ம் ஒரே host computer-ல் இருக்க வேண்டும். உங்கள் provider வழங்கும் network block device என்பது வேறுபட்டது: Linux அதை ஒரு சாதாரண disk-ஆகவும், அதில் உள்ள சாதாரண filesystem-ஆகவும் பார்க்கிறது, எனவே SQLite அங்கு வேலை செய்யும்.
நான் ஏற்கனவே nightly backups எடுத்தால், எனக்கு Litestream தேவையா?
நீங்கள் எவ்வளவு தரவு இழப்பைத் தாங்கிக்கொள்ள முடியும் என்பதைப் பொறுத்தது. ஒரு nightly job என்பது இருபத்தி நான்கு மணிநேரத் தரவு இழப்பு வரை ஏற்படலாம் என்பதாகும். Litestream வினாடிக்கு ஒருமுறை sync செய்வதால், ஒரு crash ஏற்பட்டால் தோராயமாக கடைசி ஒரு வினாடி தரவு மட்டுமே இழக்கப்படும். cp மூலம் database கோப்பை நகலெடுப்பதை விட இது பாதுகாப்பானது, ஏனெனில் அது எழுதும் பணியின் பாதியில் கோப்பை நகலெடுக்கக்கூடும். Litestream database-ஐ மட்டுமே கவனித்துக்கொள்கிறது, எனவே அதனுடன் சேர்த்து பொதுவான file backup-ஐயும் தொடர்ந்து வைத்திருங்கள்.