SQLite:什么时候它就够了
在 VPS 上 SQLite 在哪些场景比单独的数据库服务器更好、如何启用 WAL 并避免“database is locked”,以及什么时候该迁移到 PostgreSQL。
更新于 2026年8月23日
SQLite 是单文件数据库——无需服务、端口和密码。对于机器人、小型面板或写入不频繁的网站来说,它是合适的选择:它不占用内存,而 VDS-1 只有 2 GB 内存,并且无需任何配置。
适用场景
适合:
- Telegram 和 Discord 机器人、计数器、设置;
- 每分钟数千次读取、数十次写入的网站;
- 任何运行在单台机器上、没有第二台服务器计划的项目。
不适合:
- 多个进程同时频繁写入;
- 数据库大小超过几十 GB;
- 从另一台机器进行网络访问——SQLite 根本无法做到这一点。
在第二和第三种情况下,请使用 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 文件。
必需设置
两个 pragma 设置可以消除大部分问题:
PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 5000;
WAL 允许读取者在写入进行时进行读取——没有它,任何读取者都会被写入者阻塞。busy_timeout 让客户端等待五秒钟,而不是立即失败。每次在代码中打开连接时都要设置它们,而不是在控制台中设置一次。
备份
应用程序运行时,您不能使用普通的 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可以通过直接链接下载,连同所有密码和用户数据。