SQLite:これで足りる場面
VPS 上の SQLite が専用のデータベースサーバーより優れている場面、WAL を有効にして「database is locked」を避ける方法、PostgreSQL に移行すべきタイミングについて説明します。
更新日 2026年8月23日
SQLite は 1 つのファイルに収まるデータベースです。サービスもポートもパスワードも不要です。ボット、小規模なパネル、書き込み頻度の低いサイトには最適な選択です。メモリを消費せず、VDS-1 には 2 GB しかありませんし、設定する項目もありません。
使うべき場面
適しているケース:
- Telegram や Discord のボット、カウンター、設定の保存。
- 毎分数千回の読み取りと数十回の書き込みがあるサイト。
- 2 台目のサーバーを予定していない、単一マシン上のあらゆるプロジェクト。
適さないケース:
- 複数のプロセスが同時に活発に書き込む場合。
- データベースが数十ギガバイトを超える場合。
- 別のマシンからのネットワークアクセス。SQLite ではそもそもできません。
2 番目と 3 番目のケースでは、PostgreSQL または MySQL を使用してください。
ファイルの扱い
apt install -y sqlite3
sqlite3 /srv/app/data/app.db
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
INSERT INTO users (name) VALUES ('test');
.tables
.schema users
.quit
データベースファイルはマシンのローカルディスク上に置き、アプリケーションのユーザーが所有する必要があります:
chown appuser:appuser /srv/app/data/app.db
chmod 640 /srv/app/data/app.db
データベースを格納するディレクトリにも書き込み権限が必要です。SQLite はその隣に一時的な -wal ファイルと -shm ファイルを作成します。
必須の設定
2 つの pragma 設定でほとんどの問題を解消できます:
PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 5000;
WAL を使うと、書き込み中でも読み取り側が読み取れます。これがないと、読み取り側は書き込み側によってブロックされます。busy_timeout を設定すると、クライアントは即座に失敗する代わりに 5 秒間待機します。コンソールで一度だけではなく、コード内で接続を開くたびに設定してください。
バックアップ
アプリケーションの実行中に通常の cp でファイルをコピーすると、データベースが破損します。安全な専用コマンドがあります:
sqlite3 /srv/app/data/app.db ".backup '/srv/backups/app-$(date +%F).db'"
これを cron に入れ、コピーをマシンの外へ移動してください。VPS には自動バックアップもスナップショットもありません。一般的な方法はデータベースのバックアップで説明しています。
よくあるエラー
| 症状 | 原因 |
|---|---|
database is locked | WAL または busy_timeout がない、あるいは別のプロセスが長時間のトランザクションを保持している |
attempt to write a readonly database | ファイルまたはディレクトリに権限がない |
disk I/O error | ディスク容量不足。「概要」のディスク使用量リングを確認してください |
| 行を削除してもデータベースが大きくなる | 領域は自動的に解放されません:VACUUM |
| コピー後にデータベースが破損 | 実行中に cp でコピーしたためです。.backup のみを使用してください |
移行すべきタイミング
兆候:WAL を有効にしていても database is locked エラーが頻発する、アプリケーションのワーカーが複数ある、レポートの計算に数分かかる。移行方法はデータベースの移行を参照してください。
データベースファイルは、Web サーバーが配信するディレクトリに置いてはいけません。
/var/www/app.dbは、すべてのパスワードとユーザーデータとともに、直接リンクからダウンロードできてしまいます。