Umami 最近升级大版本,从 v3 开始彻底抛弃了 MySQL / Mariadb,转而使用 Postgresql 作为默认数据库。之前有几个别的服务也推荐使用 Postgresql,一直在纠结要不要切过去,但是每次都被庞大的工作量劝阻了(而且还要学很多东西)。现在只能决定折腾一下数据库的迁移了。

注意:在进行数据库迁移之前,请务必备份数据,以防止意外数据丢失。

以下操作过程均以通过docker compose部署的 Umami 为例,其他部署方式请根据实际情况调整命令,可以参考官方文档

  1. 备份现有数据:在进行任何迁移操作之前,确保已经备份了当前的 Mariadb 数据库数据:
1
mariadb --no-create-info --default-character-set=utf8mb4 --quick --skip-add-locks -u username -p mydb > mydbdump.sql
  1. 安装 Postgresql:通过 docker 安装 Postgresql 数据库:
1
2
3
4
5
6
7
8
9
10
11
12
13
services:
postgresql:
container_name: postgresql
image: postgres:latest
restart: always
volumes:
- ./data:/var/lib/postgresql
- ./conf:/etc/postgresql/conf.d
environment:
TZ: Asia/Shanghai
POSTGRES_USER: root
POSTGRES_PASSWORD: password
...
  1. 创建 Umami 数据库:进入 Postgresql 容器,创建 Umami 所需的数据库和用户:
1
2
3
docker exec -it postgresql psql -U root
CREATE USER umami WITH PASSWORD 'password';
CREATE DATABASE umami OWNER umami;
  1. 准备一个新的 Umami 实例:使用 Postgresql 作为数据库,启动一个新的 Umami 实例(版本和之前使用 MySQL 或者 Mariadb 的版本一致):
1
2
3
4
5
6
7
8
9
10
11
12
services:
umami-postgres:
container_name: umami
image: docker.umami.is/umami-software/umami:postgresql-v2.19.0 # 这里切换成自己之前使用的版本号
restart: always
environment:
DATABASE_URL: postgresql://umami:password@postgresql:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: 7MbJDvq9P7Ercw
TRACKER_SCRIPT_NAME: Bf5ZmaKLu245LG
TZ: Asia/Shanghai
...
  1. 截断 Postgresql 中的表:进入新的 Umami 容器,截断 Postgresql 数据库中的部分表:
1
2
3
docker exec -it postgresql psql -U umami -d umami
truncate table "_prisma_migrations";
truncate table "user";

本文使用pgloader 工具进行数据迁移,确保已经安装了该工具。Debian / Ubuntu 用户可以使用apt命令安装。
除此之外,也可使用 Navicat Premium 等图形化工具进行数据迁移,参考 Docker 部署 Umami,切换数据库至 PgSQL

  1. 创建导入文件:创建pgloader的配置文件umami.load,内容如下:
1
2
3
4
5
6
7
8
9
LOAD DATABASE
FROM mysql://umami:password@172.19.0.2:3306/umami
INTO pgsql://umami:password@172.19.0.22:5432/umami

WITH data only,
create tables,
include no drop

ALTER SCHEMA 'umami' RENAME TO 'public';

在 MariaDB / MySQL 数据库中,website_event表的visit_id字段可以为NULL,而在 Postgresql 中该字段不允许为NULL。所以在执行数据迁移时可能报错。为了解决这个问题,可以在迁移前将visit_id字段中的NULL值更新为一个默认值:

1
UPDATE website_event SET visit_id = UUID() WHERE visit_id IS NULL;

但这可能会导致不可知的数据关联问题,请根据实际情况谨慎操作,也可以选择抛弃这部分数据:

1
DELETE FROM website_event WHERE visit_id IS NULL;
  1. 执行数据迁移:运行pgloader命令,开始迁移数据:
1
pgloader umami.load
  1. 验证数据完整性:迁移完成后,检查 Postgresql 数据库中的数据是否完整,确保所有数据都已成功迁移。例如,可以使用以下命令检查表中的记录数:
1
2
docker exec -it postgresql psql -U umami -d umami
SELECT COUNT(*) FROM website_event;
  1. Umami 服务迁移:停止旧的 Umami 服务,启动新的 Umami 服务,确保其连接到 Postgresql 数据库:
1
2
docker compose down umami-mariadb
docker compose up -d umami-postgres
  1. 升级 Umami 版本:如果需要升级 Umami 版本,可以在新的 Postgresql 实例上进行升级操作,确保数据和配置保持一致。