Skip to content
VDS · 数据库

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 可以通过直接链接下载,连同所有密码和用户数据。