VPS-এ SQLite production database হিসেবে ব্যবহার করবেন?
একটি VPS-এ ছোট অ্যাপের জন্য SQLite কেন যথেষ্ট, তা জানুন। WAL mode, busy_timeout, Litestream replication এবং কোন সীমায় PostgreSQL দরকার, সেটিও দেখুন।
VPS-এ SQLite কখন production database হিসেবে সঠিক পছন্দ
বেশিরভাগ ছোট অ্যাপ্লিকেশনের জন্য VPS-এ production পরিবেশে SQLite চালানো সঠিক পছন্দ। কারণটি সরল: একটি মেশিনে একটি process যদি একটি file-এ write করে, তাহলে আলাদা database server প্রয়োজন হয় না। supervise করার মতো কোনো daemon নেই, firewall-এ খোলার মতো কোনো port নেই, rotate করার মতো কোনো password নেই, এবং সচল রাখার জন্য দ্বিতীয় কোনো মেশিনও নেই। Query network round trip-এর পরিবর্তে একটি function call হিসেবে চলে। তাই একটি page-এ চল্লিশটি query থাকলে তার খরচ হয় চল্লিশটি function call।
সীমাবদ্ধতাগুলো নির্দিষ্ট এবং বাস্তব। পুরো database file জুড়ে SQLite একবারে একজন writer-কে অনুমতি দেয়, এবং file-টি দুইটি মেশিনের মধ্যে share করা যায় না। একটি VPS-এ একটি application চললে এই দুই সীমাবদ্ধতাই গ্রহণযোগ্য। কিন্তু এই কাঠামো ছাড়িয়ে গেলেই দুটিই গুরুতর বাধা হয়ে দাঁড়ায়। এই guide-এ server-এ SQLite নিরাপদ রাখার settings, Litestream দিয়ে continuous backup এবং কখন থামতে হবে—এসব আলোচনা করা হয়েছে।
প্রথমে command line tool-টি install করুন। নিচের সব command Ubuntu 24.04-এ চালানো হয়েছে।
sudo apt update
sudo apt install -y sqlite3
sqlite3 --versionএটি 3. দিয়ে শুরু হওয়া একটি version, এরপর build date এবং source hash দেখায়। October 2026 অনুযায়ী Ubuntu 24.04-এর সঙ্গে SQLite 3.45.1 সরবরাহ করা হয়। আপনার application সম্ভবত এই binary ব্যবহার করে না। বেশিরভাগ language runtime SQLite library-এর নিজস্ব copy bundle করে, যা প্রায়ই আরও নতুন version হয়। তাই সাম্প্রতিক কোনো feature ব্যবহার করার আগে আপনার database driver যে version report করে, সেটি পরীক্ষা করুন।
WAL mode কেন প্রথমেই পরিবর্তন করবেন
ডিফল্টভাবে SQLite rollback journal ব্যবহার করে। কোনো page পরিবর্তনের আগে এটি মূল page-টি একটি -journal file-এ কপি করে, তারপর database-এ সরাসরি পরিবর্তন করে। নিরাপদে এই কাজ করতে পুরো file-এ exclusive lock নিতে হয়। তাই কোনো write চলার সময় প্রতিটি reader-কে অপেক্ষা করতে হয়। Laptop-এ এটি সাধারণত বোঝা যায় না। Web server-এ database ব্যবহার করা প্রতিটি request-কে একটি ধীর write আটকে দিতে পারে।
WAL (write-ahead log) mode এই ক্রম উল্টে দেয়। একটি writer নতুন page-গুলো আলাদা -wal file-এ যুক্ত করে এবং মূল database অপরিবর্তিত রাখে। Reader-রা যে snapshot দিয়ে শুরু করেছিল, সেই snapshot অনুযায়ী মূল file পড়তে থাকে। তাই reader writer-কে block করে না, এবং writer-ও reader-দের block করে না। পরে একটি checkpoint জমা হওয়া WAL page-গুলো মূল database-এ কপি করে। এই একটি পরিবর্তনই web application-এর পেছনে SQLite ব্যবহারযোগ্য করার প্রধান কারণ।
WAL mode চালু করে পরিবর্তন স্থায়ী হয়েছে কি না নিশ্চিত করুন
mkdir -p ~/app
sqlite3 ~/app/app.db "PRAGMA journal_mode=WAL;"কমান্ডটি wal প্রিন্ট করে। এই আউটপুটের কোনো আলংকারিক উদ্দেশ্য নেই। PRAGMA journal_mode ডেটাবেস বর্তমানে যে mode-এ আছে সেটি ফেরত দেয়। তাই delete উত্তর পাওয়ার অর্থ হলো পরিবর্তন ব্যর্থ হয়েছে এবং আপনি এখনও rollback journal ব্যবহার করছেন।
WAL mode স্থায়ী থাকে। এটি connection setting নয়; ডেটাবেস header-এর একটি flag। তাই প্রতিটি database file-এর জন্য এটি একবার চালালেই হয়। এরপর reboot-এর পরও প্রতিটি connection এটি উত্তরাধিকারসূত্রে পায়। নতুন একটি 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/এখন তিনটি file আছে: app.db, app.db-wal এবং app.db-shm। -wal file-এ এখনও checkpoint না হওয়া committed page থাকে। -shm file হলো shared memory index। প্রতিটি connection এটিকে map করে, যাতে সব connection WAL-এ কী আছে সে বিষয়ে একমত থাকে। উভয় file-ই ডেটাবেসের অংশ; এগুলো অস্থায়ী scratch file নয়। অ্যাপ্লিকেশন চলার সময় শুধু app.db copy করলে এমন একটি file পাবেন, যাতে সাম্প্রতিক সব commit অনুপস্থিত। app.db মুছে ফেলে অন্য দুটি file রেখে দিলে SQLite সেই পুরোনো WAL page-গুলো ওই নামে তৈরি হওয়া নতুন file-এ প্রয়োগ করবে। একটি ডেটাবেস reset করার চেষ্টা করার সময় এভাবেই নতুন database নষ্ট হয়ে যেতে পারে।
উৎপাদন পরিবেশের প্রতিটি অ্যাপের প্রয়োজনীয় connection settings
শুধু journal_mode database-এ সংরক্ষিত থাকে। নিচের অন্য সব setting প্রতিটি connection-এর জন্য আলাদা। অর্থাৎ আপনার অ্যাপ যে প্রতিটি connection খোলে, এমনকি pool যে connection-গুলো পেছনে তৈরি করে, সেগুলোর প্রতিটিতে এই setting প্রয়োগ করতে হবে।
PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 5000;
PRAGMA synchronous = NORMAL;
PRAGMA foreign_keys = ON;busy_timeout = 5000 SQLite-কে database locked থাকলে সর্বোচ্চ 5000 milliseconds পর্যন্ত পুনরায় চেষ্টা করতে বলে। এরপর এটি database is locked ফেরত দেয়। ডিফল্ট মান 0। তাই ডিফল্টভাবে দুইটি writer-এর কাজ একই সময়ে হলে SQLite প্রথমবারেই তাৎক্ষণিকভাবে ব্যর্থ হয়। শুধু এই একটি মান নির্ধারণ করলেই SQLite-এর ওপর দায় চাপানো বেশিরভাগ lock error দূর হয়।
synchronous = NORMAL WAL mode-এর জন্য সঠিক setting। তবে এর বিনিময়ে কী ত্যাগ করতে হয়, তা বোঝা জরুরি। FULL অবস্থায় SQLite প্রতিটি commit-এর সময় WAL-এ fsync চালায়। NORMAL অবস্থায় এটি checkpoint-এর সময় sync করে। SQLite documentation-এ এর সীমাবদ্ধতা স্পষ্টভাবে বলা আছে: power failure বা hard reset-এর পরে transaction আর durable থাকে না। সেই power loss-এর কারণে database corrupted হয় না। শুধু যেসব শেষ commit disk-এ লেখা হয়নি, সেগুলো হারিয়ে যায়। VPS-এ সাধারণত এটি উপযুক্ত বিনিময়। কারণ এতে প্রতিটি write-এর পথ থেকে একটি fsync বাদ যায়।
foreign_keys = ON backward compatibility-এর জন্য ডিফল্টভাবে বন্ধ থাকে এবং এটি প্রতি connection-এ আলাদাভাবে প্রযোজ্য। Schema-তে REFERENCES clause থাকলেও প্রতিটি connection এই setting চালু না করা পর্যন্ত সেগুলো কোনো constraint কার্যকর করে না।
আরেকটি setting পরে গুরুত্বপূর্ণ হয়ে ওঠে। WAL 1000 pages-এর বেশি বড় হলে SQLite স্বয়ংক্রিয়ভাবে checkpoint চালায়। সেই মুহূর্তে যে connection কোনো transaction শেষ করে, সেই connection-ই checkpoint-এর কাজ করে। একা ব্যবহারে এতে সমস্যা নেই। তবে Litestream চললে বিষয়টি গুরুত্বপূর্ণ হয়। কারণ checkpoint কখন হবে, Litestream তা নিয়ন্ত্রণ করতে চায়।
busy_timeout সেট করার পরও database is locked কেন ঘটে
এটি এমন একটি ব্যর্থতা, যার কারণে অনেকে আবার Postgres-এ ফিরে যান। এর একটি নির্দিষ্ট কারণ আছে।
Busy timeout একটি busy handler ইনস্টল করে। তবে SQLite busy handler কল করার নিশ্চয়তা দেয় না।
SQLite যদি নির্ধারণ করে যে busy handler কল করলে deadlock হতে পারে, তাহলে busy handler কল না করে সরাসরি application-এ SQLITE_BUSY ফেরত দেয়।
এটি যে deadlock এড়ায়, তা transaction upgrade করার সময় ঘটে। SQLite-এ খালি BEGIN বলতে BEGIN DEFERRED বোঝায়। এর পরের প্রথম statement যদি SELECT হয়, তাহলে আপনি একটি read transaction-এ আছেন। একই transaction-এ পরে কোনো UPDATE-কে write transaction-এ পরিণত করতে হলে, এবং আপনার read শুরু হওয়ার পর অন্য কোনো connection লিখে থাকলে, SQLite আপনাকে অপেক্ষা করাতে পারে না। কারণ আপনার snapshot ইতিমধ্যে পুরোনো হয়ে গেছে, এবং অপেক্ষা করালে দুই connection পরস্পরের জন্য deadlock তৈরি করবে। Documentation-এ ফলাফলটি সরাসরি বলা হয়েছে:
পরবর্তী write statement-গুলো সম্ভব হলে transaction-কে write transaction-এ upgrade করবে। অন্যথায় SQLITE_BUSY ফেরত দেবে।
আপনার 5000 millisecond timeout একবারও বিবেচনা করা হয় না। Error সঙ্গে সঙ্গে আসে। তাই মনে হয় setting কাজ করেনি।
সমাধানটি এক শব্দের।
BEGIN IMMEDIATE;
UPDATE notes SET body = 'edited' WHERE id = 1;
COMMIT;BEGIN IMMEDIATE শুরুতেই write lock নেয়, কিছু পড়ার আগেই। কোনো upgrade হয় না। তাই এড়ানোর মতো deadlock-ও থাকে না। ফলে busy handler কার্যকর হয় এবং connection ব্যর্থ না হয়ে নিজের পালার জন্য অপেক্ষা করে। Read-only transaction-গুলো deferred রাখুন। যে transaction-এ write থাকে, সেটি immediate হওয়া উচিত।
Lock error-এর দ্বিতীয় কারণটি শনাক্ত করা কঠিন: ধীর কাজ চলাকালে write transaction খোলা রাখা। SQLite writer-দের serialise করে। তাই কোনো transaction শুরু হয়ে network-এর মাধ্যমে external API কল করে, তারপর commit করলে, সেই কল চলার পুরো সময় অন্য সব writer আটকে থাকে। যা প্রয়োজন তা পড়ুন, transaction বন্ধ করুন, ধীর কাজটি সম্পন্ন করুন, তারপর ফলাফল সংরক্ষণের জন্য একটি সংক্ষিপ্ত write transaction খুলুন।
Litestream দিয়ে ধারাবাহিক ব্যাকআপ
প্রতি রাতে একটি কপি করলে সর্বোচ্চ এক দিনের লেখা হারাতে পারেন। চলমান SQLite database-এর বিরুদ্ধে cp চালালে এমন কপি তৈরি হতে পারে যা আর খোলা যাবে না। দুটি পদ্ধতি নিরাপদ। sqlite3 app.db ".backup /path/to/backup.db" SQLite-এর online backup interface ব্যবহার করে এবং ব্যবহৃত database-এর বিরুদ্ধেও কাজ করে। Litestream আরও এক ধাপ এগিয়ে যায়: এটি WAL monitor করে এবং পরিবর্তনগুলো ধারাবাহিকভাবে object storage-এ আপলোড করে। ফলে সর্বোচ্চ সম্ভাব্য data loss এক দিন থেকে কমে প্রায় এক সেকেন্ড হয়।
Litestream একটি Go binary, যা আপনার application-এর পাশে চলে। এটি application এবং database-এর মাঝখানে থাকে না। আপনার application আগের মতোই 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 versionOctober 2026 অনুযায়ী official Linux install page-এ এখনও v0.5.14 release-টির documentation রয়েছে। এর পরে আরও release এসেছে: 21 July 2026-এ v0.5.15 এবং 31 August 2026-এ সর্বশেষ tag v0.5.17। releases page-এর বর্তমান tag অনুযায়ী উভয় line-এ version পরিবর্তন করুন। আপনার VPS যদি arm64 হয়, তার বদলে মিল থাকা arm64 package নিন।
Configuration file-টি /etc/litestream.yml-এ থাকে। প্রথমে একটি local file replica দিয়ে শুরু করুন। এতে cloud credential ছাড়াই পুরো প্রক্রিয়াটি যাচাই করা যায়।
dbs:
- path: /home/appuser/app/app.db
replica:
type: file
path: /var/backups/litestream/appমনে রাখবেন, field-টি replica, singular। Litestream 0.5, 0.3 series-এর replicas array-এর পরিবর্তে একটি single replica block ব্যবহার করে। এখন দুটি entry থাকা config startup-এ ব্যর্থ হয়। অনেক third-party guide এখনও পুরোনো array দেখায়। তাই search-এ পাওয়া প্রথম example কপি না করে উপরের কাঠামো ব্যবহার করুন। 0.5 series-এ litestream wal subcommand-এর নাম পরিবর্তন করে litestream ltx করা হয়েছে, কারণ 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-টি নতুন একটি 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;"এই count-এ নতুন row-টি অন্তর্ভুক্ত থাকে। তা না হলে পরিবর্তন এখনও sync হয়নি। Litestream একটি sync-interval-এ push করে, যার default 1 second। তাই অপেক্ষা করে আবার restore করুন। ওই এক সেকেন্ডই আপনার recovery point। Crash হলে সর্বশেষ sync interval-এর সময় লেখা data সর্বোচ্চ হারাতে পারেন। কোনো configuration-ই এই ক্ষতি শূন্য করতে পারে না।
বাস্তব storage-এর জন্য replica block-টি একটি S3 URL দিয়ে প্রতিস্থাপন করুন। এটি Amazon S3 এবং অন্যান্য provider-এর 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: 24hCredential ওই file-এ রাখবেন না। Litestream environment থেকে LITESTREAM_ACCESS_KEY_ID এবং LITESTREAM_SECRET_ACCESS_KEY পড়ে। তাই এগুলো root-এর মালিকানাধীন এবং mode 600 থাকা systemd drop-in-এ রাখুন।
উপরের snapshot value-গুলো default। Retention-এর default অনেকের জন্য অপ্রত্যাশিত। Retention হলো Litestream কতক্ষণ snapshot এবং সেগুলোর প্রয়োজনীয় file সংরক্ষণ করবে। তাই অতীতে কত দূর পর্যন্ত restore করতে পারবেন, সেটিও এর ওপর নির্ভর করে। Twenty-four hours হলে Monday-এর state থেকে Wednesday সকালে ধরা পড়া একটি খারাপ migration আর restore করা যায় না। Litestream 0.5-এ retention root snapshot block-এর global setting। এটি per-replica setting নয়। এক সপ্তাহের জন্য ওই block-টি retention: 168h-এ পরিবর্তন করুন এবং অতিরিক্ত storage-এর খরচ ধরুন। Replica block-এর ভেতরের একটি retention: line হলো 0.3-series-এর syntax। Litestream 0.5 কোনো error না দেখিয়ে সেটি উপেক্ষা করে এবং 24-hour 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 খুঁজে সেটি ডাউনলোড করে। সুস্থ file হলে PRAGMA integrity_check, ok প্রদর্শন করে। অন্য যেকোনো output দেখালে restored copy ব্যবহারযোগ্য নয়। একটি systemd service ও timer ব্যবহার করে এটি নির্ধারিত সময়সূচিতে চালান এবং output পড়ুন। অন্তত একবার backup restore না করা পর্যন্ত এটি কাজ করে কি না আপনি নিশ্চিতভাবে জানতে পারবেন না।
systemd-এর অধীনে Litestream চালান
Debian package একটি litestream unit ইনস্টল করে, যা /etc/litestream.yml পড়ে।
sudo systemctl enable litestream
sudo systemctl start litestream
sudo journalctl -u litestream -fসুস্থ অবস্থার output configuration-এ থাকা প্রতিটি database-এর নাম দেখায়, এরপর পর্যায়ক্রমিক sync line ছাড়া নীরব থাকে। আপনার database path-এর বিরুদ্ধে no such file or directory error দেখা গেলে configuration-এ path ভুল, অথবা process সেটি পড়তে পারছে না। ডিফল্টভাবে unit root হিসেবে চলে, যা এই কাজের প্রয়োজনের তুলনায় বেশি privilege। Litestream-কে database এবং সেটি ধারণকারী directory—উভয়ই পড়তে ও লিখতে পারতে হবে, কারণ এটি আপনার database-এর পাশে থাকা -wal এবং -shm file নিয়ে কাজ করে। তাই আপনার application যে user account হিসেবে চলে, সেই appuser account ব্যবহার করুন।
# /etc/systemd/system/litestream.service.d/override.conf
[Service]
User=appuser
Group=appusersudo systemctl daemon-reload এবং sudo systemctl restart litestream দিয়ে এটি প্রয়োগ করুন। সর্বনিম্ন privilege-সহ একটি dedicated service account তৈরি করতে কয়েক মিনিট লাগে। এর ফলে সার্ভারে একটি দ্বিতীয় root process চালানোর বদলে একটি backup agent চালানো যায়।
মেশিনটি সম্পূর্ণ নতুন করে পুনর্নির্মাণ করলে একটি ক্রম-সংক্রান্ত বিষয় গুরুত্বপূর্ণ। Application চালু হওয়ার আগে database restore করা দরকার। litestream restore, -if-db-not-exists গ্রহণ করে। File আগে থেকেই থাকলে এটি 0 exit করে, তাই প্রতিটি boot-এ চালানো নিরাপদ। আপনার application-এর unit-এ এটি একটি ExecStartPre line হিসেবে যোগ করুন। এতে একটি নতুন VPS boot-এর সময় database download করবে, আর আগে থেকেই থাকা VPS কোনো কাজ করবে না। এটি এক জায়গায় রাখতে চাইলে litestream replicate-এ এর সমতুল্য -restore-if-db-not-exists flag রয়েছে।
VPS-এ SQLite যেখানে সীমাবদ্ধ
Network filesystem। এটি এমন একটি সীমা, যেটি configuration দিয়ে এড়ানো যায় না। WAL mode-এ database ব্যবহারকারী প্রতিটি process-কে memory-এর একটি ছোট region share করতে হয়। -shm file এই কাজ করে। SQLite documentation কোনো শর্ত ছাড়াই নিয়মটি উল্লেখ করেছে:
একটি database ব্যবহারকারী সব process-কে একই host computer-এ থাকতে হবে; network filesystem-এর উপর WAL কাজ করে না।
তাই mounted NFS (network file system) বা SMB share-এ থাকা database corrupt হতে পারে, এবং কোনো pragma এটি প্রতিরোধ করতে পারে না। এখানে একটি পার্থক্য আছে, যা অনেকেই উপেক্ষা করেন। Network block device, যেটি অধিকাংশ VPS provider অতিরিক্ত storage হিসেবে সংযুক্ত করে, Linux-এর কাছে সাধারণ disk হিসেবে দেখা যায় এবং তাতে সাধারণ filesystem থাকে। এটি ঠিক আছে। কিন্তু mounted file share আলাদা।
দ্বিতীয় application server। কোনো setting দিয়ে এটি কাজ করানো যায় না। একই data পরিবেশন করার জন্য যখন দুটি machine দরকার হয়, তখন network-এর মাধ্যমে কাজ করে এমন database প্রয়োজন। পরিকল্পনা করার সময় থাকা অবস্থাতেই এই পরিবর্তনের সিদ্ধান্ত নিন।
Write-heavy workload। এক সময়ে একজন writer কাজ করতে পারা file format-এর বৈশিষ্ট্য; এটি tunable নয়। প্রতিটি commit WAL-এ append হওয়ায় ছোট write সস্তা। তাই throughput CPU-এর তুলনায় disk-এর small-write latency-এর সঙ্গে বেশি সম্পর্কিত। এই পার্থক্যটি কেমন, তা জানতে VPS-এ NVMe বনাম SATA SSD storage দেখুন। আসল সমস্যা দীর্ঘ transaction, কারণ এগুলো অন্য সব writer-কে queue-তে অপেক্ষা করায়।
Analytical query। SQLite transaction-এর জন্য তৈরি row store। একশো million row scan করা dashboard-এর জন্য ভিন্ন কাজের ভিন্ন tool প্রয়োজন। এই সীমাটি কোথায়, তা server কাজের জন্য DuckDB বনাম SQLite-এ ব্যাখ্যা করা হয়েছে।
Replication-এর অধীনে VACUUM। একটি সম্পূর্ণ VACUUM পুরো database file পুনরায় লেখে। এতে Litestream যে page-level tracking-এর উপর নির্ভর করে তা অকার্যকর হয়। Replication সক্রিয় থাকা অবস্থায় সরাসরি database-এ এটি চালানোর বিরুদ্ধে Litestream documentation পরামর্শ দেয়। পরিবর্তে এটি VACUUM INTO ব্যবহারের সুপারিশ করে। এটি আলাদা file-এ compacted copy লেখে এবং মূল file অপরিবর্তিত রাখে। In-place vacuum করতেই হলে documented procedure একটি restart-এর চেয়ে দীর্ঘ: replicator বন্ধ করুন, vacuum চালান, database-এর পাশে থাকা Litestream-এর hidden tracking directory এবং বিদ্যমান remote replica data মুছে ফেলুন। এরপর আবার এটি চালু করুন, যাতে নতুন full snapshot থেকে শুরু হয়। শেষ ধাপে আগের restore history মুছে যায়।
একটি database-এ দুটি replicator। একই database বা একই replica destination-এর বিরুদ্ধে কখনো দুটি Litestream process চালাবেন না। এটি প্রতিরোধ করার দায়িত্ব আপনার—documentation-এ বিষয়টি স্পষ্টভাবে বলা হয়েছে। অন্যথায় এমন একটি replica তৈরি হতে পারে, যেটি restore করা সম্ভব নয়।
Litestream যা কভার করে না
Litestream শুধু database file সুরক্ষিত রাখে। এর বাইরে কিছু নয়। Uploaded file, application config, TLS (transport layer security) certificate এবং unit file আপনাকেই পরিচালনা করতে হবে। নির্ধারিত সময়সূচিতে restic ব্যবহার করে encrypted off-box backup-এর সঙ্গে এটি ব্যবহার করলে উভয় দিকই কভার হয়। মেশিনটি নতুন হলে নতুন VPS-এ প্রথম দশ মিনিট অংশে user account এবং firewall-এর কাজ দেখানো আছে, যা এই guide-এ আগে থেকেই সম্পন্ন ধরে নেওয়া হয়েছে।
FAQ
একটি production application-এর জন্য SQLite কি যথেষ্ট?
একটি সার্ভারে একটি application-এর জন্য, হ্যাঁ—তবে শর্ত হলো আপনাকে WAL mode চালু করতে হবে, busy timeout সেট করতে হবে এবং ধারাবাহিকভাবে backup নিতে হবে। গুরুত্বপূর্ণ সীমাগুলো কাঠামোগত: একই সময়ে একজন writer এবং একটি host machine। যে application এই সীমার মধ্যে থাকে, সেটি কোনো network hop বা monitor করার জন্য আলাদা process ছাড়াই database পায়। যে application এই সীমার মধ্যে থাকে না, তার client-server database প্রয়োজন; কোনো tuning-ই এটি পরিবর্তন করতে পারে না।
busy_timeout সেট করার পরও আমি কেন database is locked পাচ্ছি?
কারণ অপেক্ষা করলে deadlock হতে পারে এমন পরিস্থিতিতে SQLite busy handler এড়িয়ে যায়। bare BEGIN দিয়ে শুরু হওয়া transaction deferred থাকে: একটি opening SELECT এটিকে read transaction-এ পরিণত করে, এবং পরবর্তী write-কে সেটিকে upgrade করতে হয়। এর মধ্যে অন্য কোনো connection write করলে SQLite আপনার busy handler কল না করে সঙ্গে সঙ্গে SQLITE_BUSY ফেরত দেয়, কারণ আপনার read snapshot ইতিমধ্যে stale হয়ে গেছে। যে transaction write করবে, সেটি BEGIN IMMEDIATE দিয়ে শুরু করুন, যাতে শুরুতেই write lock নেওয়া হয় এবং timeout কার্যকর হয়।
আমি কি network storage-এ আমার SQLite database রাখতে পারি?
NFS বা SMB-এর মতো network filesystem-এ নয়। WAL mode-এর জন্য সব process-কে -shm file-এর মাধ্যমে memory share করতে হয়, এবং SQLite documentation-এ বলা আছে যে database ব্যবহারকারী প্রতিটি process-কে একই host computer-এ থাকতে হবে। আপনার provider সংযুক্ত করে দেওয়া network block device ভিন্ন বিষয়: Linux সেখানে একটি স্বাভাবিক filesystem-সহ স্বাভাবিক disk দেখতে পায়, এবং SQLite সেখানে কাজ করে।
আমি যদি ইতিমধ্যে nightly backup চালাই, তাহলে কি Litestream প্রয়োজন?
আপনি কতটা data হারানো মেনে নিতে পারেন, তার ওপর নির্ভর করে। একটি nightly job-এর অর্থ হলো সর্বোচ্চ twenty-four hours-এর write হারাতে পারেন। Litestream প্রায় প্রতি second-এ sync করে, তাই crash হলে মোটামুটি শেষ second-এর data হারাবেন। cp দিয়ে database file copy করার চেয়েও এটি নিরাপদ, কারণ copy চলমান write-এর মাঝামাঝি অবস্থায় database ধারণ করতে পারে। Litestream শুধু database কভার করে, তাই এর পাশাপাশি একটি সাধারণ file backup চালু রাখুন।