kita / notes

约 2 分钟

装个 sqlite3 给我返回 502,这只是开始

机器人的数据库开始报 I/O 错误,SQLite 在频繁读写下确实容易这样,我决定换 PostgreSQL。

第一步是导出数据,缺工具:

sqlite3: command not found

那就装。然后:

Err:4 http://mirrors.tencentyun.com/ubuntu noble InRelease
    502 Bad Gateway [IP: 127.0.0.1 7890]

apt 在走本机 7890 端口的代理,而那个代理当时是死的,于是连访问腾讯云自己的内网镜像都失败。我第一反应是镜像站抽风,其实是自己绕自己。

unset http_proxy https_proxy 没用,代理写死在配置文件里(/etc/apt/apt.conf.d/ 下面那个)。绕过去:

apt -o Acquire::http::Proxy=false update
apt -o Acquire::http::Proxy=false install -y sqlite3

导完数据开始改配置。编辑完 data/cmd_config.json 重启,报:

JSONDecodeError: Unexpected UTF-8 BOM ... line 1

BOM。有些编辑器保存 UTF-8 文件时会在开头塞三个字节 EF BB BF,Python 的 json 见到就报错,而你在编辑器里看它完全正常。我盯着文件看了很久,什么都没看出来。

去掉:

sed -i '1s/^\xEF\xBB\xBF//' /root/astrbot/data/cmd_config.json

然后是最费时间的一步。我把数据库配置写得整整齐齐:

"db": {
  "type": "postgresql",
  "host": "...",
  "port": 5432
}

重启,日志里就一句:

Config key removed: db

它不认这个配置块,给我删了。 没有报错,没有提示,就一句"已移除"。我反复检查 JSON 语法、缩进、字段名,全都对,它就是不读。

折腾了很久,最后改用环境变量,这也是最终生效的方案:

docker run -d --name astrbot \
  -e ASTRBOT_DATABASE_TYPE=postgresql \
  -e ASTRBOT_DATABASE_HOST=172.17.0.1 \
  -e ASTRBOT_DATABASE_PORT=5432 \
  -e ASTRBOT_DATABASE_USER=astrbot \
  -e ASTRBOT_DATABASE_NAME=astrbot \
  soulter/astrbot:latest

数据库单独跑官方镜像,数据挂宿主机目录:

postgres:
  image: postgres:15
  volumes:
    - /root/postgres_data:/var/lib/postgresql/data

切过去之后,之前的 I/O 报错没再出现。


这三件事我后来一起想过,问题都出在同一处:我改的东西没被读到。

apt 在走代理而不是直连镜像;文件开头有三个字节的 BOM 让解析直接失败;db 这个键根本没被程序读取。三次都不是"我写得不对",而是"我写的地方不是它读的地方"。

所以后来我改完配置的第一件事变了:不再急着看结果,先找证据证明改动生效了——看日志有没有读到这个配置、看进程有没有真正加载。这步几十秒,能省下我那天晚上的几个小时。

← 回到全部笔记