迁移 FreshRSS 的数据库

/ dousha

比预想中的要简单不少。

刚刚上期我提到了用 FreshRSS 订阅各种信息而且永不清理订阅。这套系统在刚设置好的时候还挺好用,但是随着时间流逝,积攒的数据越来越多,FreshRSS 的响应速度就越来越慢。

这是因为默认情况下,FreshRSS 使用 SQLite 作为数据库后端。尽管 SQLite 本身作为单文件数据库的性能是充分的,但是由于 RSS 阅读器天然对并发写入有一定要求(主要是用于文章拉取和已读标记),SQLite 这种全局锁数据库在处理 1e5 条数据的时候就明显感觉到吃力了。不过直觉上,SQLite 处理 1e7 级别的数据应该是够用的,或许这和整套系统是运行在机械硬盘上也有一定关系。

FreshRSS 支持 PostgreSQL 作为数据库后端。当然,切换数据库后端肯定不是一个在管理页面上点两下鼠标就可以解决的事情。之前读到的文档给出的答案基本上就是:你在安装的时候选了什么数据库就只能用什么数据库;想要切换的话就是全量导出、重装 FreshRSS 再全量导入。

全量导入导出这种事情一听就头大。所以我就本着「没坏就别去修」的心态又硬撑着用了几个月。但最近它已经迟缓到 Nginx 都开始不耐烦地报 504 Gateway Timeout 了。好吧,既然坏了,就可以开始动手修了。

治标的方法当然是配置 Nginx 等待更长时间,但这样做肯定是毫无意义的,换数据库肯定是要做的。再次查阅了文档之后发现:全量导入导出是 FreshRSS 自带的功能;而且你也不需要重装 FreshRSS, 只需要修改一下配置文件就可以

顺便抱怨一句:谁家好人会把数据库迁移操作放在「备份」章节里啊!


简单地改一下 docker-compose.yml:

services:
  freshrss:
    restart: unless-stopped
    logging:
      options:
        max-size: 10m
    ports:
      - 19180:80
    environment:
      - TZ=Asia/Shanghai
      - CRON_MIN=1,31
    volumes:
      - freshrss_data:/var/www/FreshRSS/data
      - freshrss_extensions:/var/www/FreshRSS/extensions
    container_name: freshrss
    image: freshrss/freshrss:1.26.3
    depends_on:
      - postgres
  postgres:
    image: postgres:16-alpine
    restart: always
    container_name: freshrss_postgres
    shm_size: 128mb
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_HOST_AUTH_METHOD: password
    volumes:
      - /mnt/volume:/mnt/volume
volumes:
  freshrss_data: {}
  freshrss_extensions: {}

因为数据库是只能在容器组内访问的(它没有暴露 ports),我就懒得改用户名密码之类的了。

重新部署容器组:

docker compose up -d

然后进入 FreshRSS 容器中:

docker exec -it freshrss sh

执行一下备份操作:

./cli/db-backup.php

注意到官方文档里有 cd /... 的一个操作,在容器中这么做是不必要的。

FreshRSS 的 Docker 镜像非常精简,以至于它里面没有任何编辑器可用,甚至连 ed 这种标准编辑器都没有。所以你会需要用 apt 单独装一个你喜欢的编辑器。记得先 apt update 更新一下软件包数据库。

注意到这里更新的数据以及安装的编辑器会在下一次重建 FreshRSS 容器(如更新 FreshRSS 或者重启 Docker 服务)后丢失。所以如果后续还有修改 FreshRSS 配置的需要的话,你需要每次操作前都检查编辑器在不在。

编辑 ./data/config.php, 修改一下数据库配置:

<?php
return array (
  /* --8<- SNIP --8<- */
  'db' =>
  array (
    'type' => 'pgsql',
    'host' => 'postgres',
    'user' => 'postgres',
    'password' => 'postgres',
    'base' => 'postgres',
    'prefix' => '', // 因为这个 PostgreSQL 实例是 FreshRSS 独享的,故不需要表前缀
    'connection_uri_params' => '',
    'pdo_options' =>
    array (
    ),
  ),
  /* -->8-- SNIP -->8-- */
);

然后恢复之前的备份即可:

./cli/db-restore.php --delete-backup --force-overwrite

切换到 PostgreSQL 之后,FreshRSS 的响应速度有显著的提升。

正在加载评论……

发表评论

您的评论将由管理员审核后方可公开显示。

Your comments will be submitted to a human moderator and will only be shown publicly after approval.