2026年5月17日
2026年5月17日
SQLiteをサーバーで使う方法|sqlite3の基本操作・PHPからの接続・権限・バックアップ
SQLite は、データベース全体を 1 つのファイルに保存する組み込み型のデータベースです。MySQL や PostgreSQL と違い、常駐するサーバープロセスがありません。アプリケーション(PHP や Python など)がライブラリを通してファイルを直接読み書きします。そのため「SQLite サーバーを起動する」「停止する」という作業はなく、サーバーで使うときに考えるのは、ファイルの置き場所と権限、同時に書き込むときの扱い、バックアップの 3 点です。
この記事の手順は Ubuntu 24.04(SQLite 3.45.1、PHP 8.3)で動作を確かめました(2026年11月時点)。
SQLite が向いている用途・向いていない用途
| 向いている | 向いていない |
|---|---|
| 小〜中規模のツールや管理画面のデータ | 多数の利用者が同時に書き込むサービス |
| 設定・キャッシュ・ジョブの記録 | 複数のサーバーから同じデータベースを使う構成 |
| ログの一時集計、開発・検証用のデータベース | ネットワークファイルシステム(NFS など)上での運用 |
SQLite は読み取りを同時に処理できますが、書き込みはデータベース全体で一度に 1 つずつです。書き込みが集中するサイトでは MySQL や MariaDB を選びます。
手順 1: sqlite3 コマンドを入れる
操作用のコマンドラインツール sqlite3 を入れます。
# Ubuntu / Debian
sudo apt update
sudo apt install sqlite3
# RHEL / AlmaLinux / Rocky Linux / Fedora
sudo dnf install sqlite
# 版の確認
sqlite3 --version
libsqlite3-dev(Debian 系)や sqlite-devel(RHEL 系)は、C のプログラムをコンパイルするときに使う開発用ファイルです。コマンドで操作するだけなら不要です。
PHP から使う場合は、PHP の SQLite 拡張も入れます。Ubuntu では php-sqlite3 パッケージに sqlite3 拡張と pdo_sqlite 拡張の両方が含まれます。
sudo apt install php-sqlite3
php -m | grep -i sqlite
pdo_sqlite と sqlite3 が表示されれば使えます。Web サーバー経由の PHP(PHP-FPM など)には、サービスの再起動後に反映されます。
手順 2: データベースを作って操作する
sqlite3 にファイル名を渡すと、そのデータベースを開きます。ファイルがなければ、最初にテーブルを作った時点で作られます。
sqlite3 app.db
sqlite> というプロンプトが出たら、SQL を入力します。SQL の文は ; で終わります。
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
);
INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');
SELECT * FROM users;
SQL とは別に、. で始まる「ドットコマンド」で sqlite3 自体を操作します。ドットコマンドの末尾に ; は付けません。
| コマンド | 内容 |
|---|---|
.tables |
テーブルの一覧 |
.schema users |
テーブルの定義(CREATE 文) |
.mode box |
結果を罫線つきの表で表示(.mode column も可) |
.headers on |
列名を表示 |
.dump |
データベース全体を SQL 文として出力 |
.backup ファイル名 |
データベースを別ファイルにバックアップ |
.quit |
終了 |
シェルから 1 行で実行することもできます。スクリプトや cron で使う場合はこの形が便利です。
sqlite3 app.db "SELECT COUNT(*) FROM users;"
sqlite3 app.db ".tables"
手順 3: PHP(PDO)から接続する
PHP では PDO を使うと、MySQL と同じ書き方で扱えます。データベースのファイルが公開ディレクトリ(ドキュメントルート)の外にある例です。
<?php
// データベースファイルは公開ディレクトリの外に置く
$dbFile = '/var/lib/myapp/app.db';
$pdo = new PDO('sqlite:' . $dbFile, null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_TIMEOUT => 5, // ロック待ちの秒数
]);
$pdo->exec('PRAGMA journal_mode = WAL');
$pdo->exec('PRAGMA foreign_keys = ON');
$pdo->exec('CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
)');
// 値はプレースホルダーで渡す(SQL インジェクション対策)
$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
$stmt->execute([':name' => 'Bob', ':email' => 'bob@example.com']);
$stmt = $pdo->prepare('SELECT id, name, email FROM users WHERE email = :email');
$stmt->execute([':email' => 'bob@example.com']);
print_r($stmt->fetch());
PDO::ATTR_TIMEOUTは、ほかの処理が書き込み中でロックが取れないとき、何秒まで待つかの設定です。指定しないと、すぐに「database is locked」のエラーになりやすくなります。PRAGMA journal_mode = WALは、書き込みの最中も読み取りを止めない「WAL モード」に切り替えます。設定はデータベースファイルに保存されるので、一度実行すれば以後も有効です。PRAGMA foreign_keys = ONは接続ごとに必要です。SQLite は既定では外部キー制約を確認しません。
手順 4: ファイルの置き場所と権限を決める
Web サーバー(PHP)から SQLite を使うときに、つまずきやすいのが権限です。
- ドキュメントルートの外に置く:
/var/www/html/data.dbのように公開ディレクトリに置くと、URL を知られた時点でファイルごとダウンロードされるおそれがあります。/var/lib/myapp/のような公開されない場所に置きます。 - ディレクトリにも書き込み権限が要る: SQLite は書き込みのときに、データベースと同じディレクトリに一時ファイル(
app.db-journal、WAL モードではapp.db-walとapp.db-shm)を作ります。ファイルだけ書き込み可能にしても、ディレクトリに書き込めないと失敗します。
ディレクトリが root の所有で、ファイルだけ www-data の所有にした状態で書き込むと、次のエラーになりました。
SQLSTATE[HY000]: General error: 8 attempt to write a readonly database
PHP-FPM や Apache が www-data ユーザーで動いている場合(Ubuntu / Debian の既定)の設定例です。
sudo mkdir -p /var/lib/myapp
sudo chown www-data:www-data /var/lib/myapp
sudo chmod 750 /var/lib/myapp
# 既存のファイルを置く場合
sudo chown www-data:www-data /var/lib/myapp/app.db
sudo chmod 640 /var/lib/myapp/app.db
RHEL 系の Apache や PHP-FPM は既定で apache ユーザーで動きます。実際のユーザーは ps aux | grep -E 'php-fpm|httpd|apache2' の 1 列目(親プロセスではなく子プロセスの行)で確認してください。SELinux が有効な環境では、ディレクトリに書き込み用のラベル(httpd_sys_rw_content_t など)も必要です。
手順 5: 同時書き込みとロックの扱い
- 書き込みは一度に 1 つです。別の処理が書き込み中だと、待ち時間(手順 3 の
PDO::ATTR_TIMEOUT)を過ぎた時点で「database is locked」になります。 - WAL モードにすると、書き込みの最中でも読み取りは止まりません。Web アプリケーションでは WAL モードが向いています。
- 長いトランザクションはロックを長く持ちます。まとめて書き込むときは 1 つのトランザクションにして、短時間で終えます。
- SQLite の公式ドキュメントでは、WAL モードはネットワークファイルシステム上では動かないとされています。データベースはサーバーのローカルディスクに置きます。
手順 6: バックアップと整合性の確認
書き込み中のデータベースを cp でコピーすると、途中の状態がコピーされたり、WAL モードでは -wal ファイルの内容が抜けたりして、壊れたバックアップになることがあります。SQLite の機能でコピーします。
# 方法 1: .backup コマンド(オンラインバックアップ API を使う)
sqlite3 /var/lib/myapp/app.db ".backup /backup/app-$(date +%Y%m%d).db"
# 方法 2: VACUUM INTO(SQLite 3.27.0 以降。不要な領域を詰めたコピーを作る)
sqlite3 /var/lib/myapp/app.db "VACUUM INTO '/backup/app-vacuum-$(date +%Y%m%d).db'"
# バックアップが壊れていないか確認(ok と表示されれば正常)
sqlite3 /backup/app-$(date +%Y%m%d).db "PRAGMA integrity_check;"
VACUUM INTO の出力先は、存在しないファイルか空のファイルでなければエラーになります。同じ日に 2 回実行する場合はファイル名に時刻も入れます。
SQL 文として残したい場合は .dump を使います。別の SQLite へそのまま読み込めます。
sqlite3 /var/lib/myapp/app.db .dump | gzip > /backup/app-$(date +%Y%m%d).sql.gz
# 復元
gunzip -c /backup/app-20261110.sql.gz | sqlite3 /var/lib/myapp/restored.db
cron で毎日バックアップを取る場合は、.backup の行をスクリプトにして、古いファイルを削除する処理と一緒に登録します。
SQLite と WordPress
WordPress 本体が公式に必要とするデータベースは MySQL か MariaDB です。WordPress.org が公開している「SQLite Database Integration」プラグイン(2026年11月時点で 3.1.3)を使うと SQLite で動かせますが、プラグインの説明では、本番で使う場合は確実なバックアップを取ること、書き込みが多いサイトでは MySQL や MariaDB のほうが向くことが書かれています。有効にすると空の新しいデータベースが作られ、既存の記事は移されません。ローカルの開発環境での使い方は「WordPressのSQLiteドライバーで軽量なローカル開発環境を作る方法」を参照してください。
よくある質問
SQLite のサーバーを起動・停止するにはどうすればよいですか
その必要はありません。SQLite にはサーバープロセスがなく、アプリケーションがファイルを開いたときだけ使われます。nohup sqlite3 … で常駐させたり、kill で止めたりする手順は不要です。
エラーのログはどこに出ますか
SQLite は自分ではログファイルや syslog に書きません。エラーは使っているアプリケーションに返されるので、PHP なら PHP のエラーログ(PHP-FPM のログや Web サーバーのエラーログ)を見ます。
「database is locked」が頻繁に出ます
ロック待ちの時間(PDO::ATTR_TIMEOUT、sqlite3 コマンドなら .timeout 5000)を設定し、WAL モードにし、長いトランザクションがないかを確認します。それでも頻発するなら、書き込みの量が SQLite の向く範囲を超えている可能性があり、MySQL などへの移行を検討します。
まとめ
- SQLite はサーバープロセスを持たない、1 ファイルのデータベースです。
sqlite3コマンドで SQL とドットコマンドを使って操作します。 - PHP からは PDO(
sqlite:で始まる DSN)で接続し、ロック待ちの時間と WAL モードを設定します。 - Web サーバーで使うときは、ドキュメントルートの外に置き、ファイルとディレクトリの両方を実行ユーザーが書き込めるようにします。バックアップは
cpではなく.backupかVACUUM INTOで取ります。
関連記事:
参考: SQLite – Command Line Shell For SQLite、SQLite – Write-Ahead Logging、SQLite – Temporary Files Used By SQLite、SQLite – VACUUM、PHP マニュアル – PDO_SQLITE、WordPress.org – SQLite Database Integration
更新履歴: 2026-11-10 全面改訂(存在しない「SQLite サーバーの起動・停止」の手順、シェルと SQL が混在したコード例、syslog でのログ確認を削除し、PHP からの接続、権限、ロック、バックアップの手順に置き換え)。