Umami 跨版本升级踩坑记录:从 v1.38 到 v3.0

技术

前言

Umami 是一款轻量、简洁、隐私友好的开源统计系统,我从 2022 年开始就一直在使用。之前其实尝试过升级,但一直没搞定,索性就一直停在 1.38 没再动。拖久了版本差得越来越多,最近才重新把这件事捡起来,一路更新到 3.0。于是就把这次升级过程中遇到的坑和解决办法顺手记下来,方便以后回看。

备份数据库

每次更新前都建议备份数据库文件,就算操作失误还能回滚。

安装 PostgreSQL

sudo apt install -y postgresql-common ca-certificates
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt install -y postgresql-client

备份数据库文件

pg_dump postgresql://postgres.[项目ID]:[数据库密码]@[区域 ID].pooler.supabase.com:5432/postgres > umami_dump_$(date +"%Y-%m-%d--%H-%M-%S").sql

如果需要恢复备份,比较稳妥的方案是在 Supabase 新建一个项目再导入备份。

导入备份命令如下:

psql postgresql://postgres.[项目ID]:[数据库密码]@[区域 ID].pooler.supabase.com:5432/postgres -f umami_dump_xxxx.sql
警告

清空数据库是一个非常危险的操作,请确保有完整的备份再操作!

也可以清空数据库再导入

do $$ declare
r record;
begin
for r in (select tablename from pg_tables where schemaname = 'public') loop
execute 'drop table if exists ' || quote_ident(r.tablename) || ' cascade';
end loop;
end $$;

升级到 v1.40

由于官方给的 v2 的迁移脚本是根据 v1 最终版本写的,所以先要升级到 v1.40。

修改 Vercel 项目配置

由于 Node.js 18.x 已不受支持,部署前需要先将 Node.js 版本更改为 20.x。

另外,需要检查一下 DATABASE_URL 这个环境变量。它应该是一个标准的 PostgreSQL 连接字符串,格式如下:

postgresql://postgres:[数据库密码]@[数据库服务器]:5432/postgres
注意

密码中如果包含特殊字符(如 @, :, $),需要进行 URL 编码。例如,mypass@123 应该写成 mypass%40123。否则会出现数据库连接错误。

常见特殊字符的 URL 编码如下表:

字符 编码 字符 编码
, %2C 空格 %20
@ %40 [ %5B
: %3A ] %5D
/ %2F %22
? %3F # %23
& %26 $ %24
= %3D + %2B
! %21 %27

更新程序代码

克隆 Fork 的仓库到本地

git clone https://github.com/[你的用户名]/umami.git

添加上游

git remote add upstream https://github.com/umami-software/umami.git

拉取上游提交

git fetch upstream --tags

从上游创建 v1 分支

git checkout v1

推送到 GitHub 仓库

git push -u origin v1

Vercel 构建的时候有个报错:

Attempted import error: 'si' is not exported from 'date-fns/locale' (imported as 'si').

不过不影响正常使用,就不管了。

数据库升级

由于 Umami v1.40 版本中,数据库的表结构有所变化。如果不更新数据库,尝试登录时,后端会报错。

查询资料后发现,在 Supabase 的 SQL Editor 中运行一段更新脚本即可。

-- AlterTable
ALTER TABLE "account" ADD COLUMN "account_uuid" UUID NULL;

-- Backfill UUID
UPDATE "account" SET account_uuid = gen_random_uuid();

-- AlterTable
ALTER TABLE "account" ALTER COLUMN "account_uuid" SET NOT NULL;

-- CreateIndex
CREATE UNIQUE INDEX "account_account_uuid_key" ON "account"("account_uuid");

-- AlterTable
ALTER TABLE "event" ADD COLUMN "event_uuid" UUID NULL;

-- Backfill UUID
UPDATE "event" SET event_uuid = gen_random_uuid();

-- AlterTable
ALTER TABLE "event" ALTER COLUMN "event_uuid" SET NOT NULL;

-- CreateIndex
CREATE UNIQUE INDEX "event_event_uuid_key" ON "event"("event_uuid");

-- CreateIndex
CREATE INDEX "account_account_uuid_idx" ON "account"("account_uuid");

-- CreateIndex
CREATE INDEX "session_session_uuid_idx" ON "session"("session_uuid");

-- CreateIndex
CREATE INDEX "website_website_uuid_idx" ON "website"("website_uuid");

-- CreateIndex
CREATE INDEX "event_event_uuid_idx" ON "event"("event_uuid");

验证更新

登录后台,可以看到版本号为 v1.40.0。

image-20260123201619966

在 Vercel 上,除默认分支外的构建都会部署到预览环境。没问题的话,就可以手动推送到生产环境了。

升级到 v2

更新前先备份数据库文件。

pg_dump postgresql://postgres.[项目ID]:[数据库密码]@[区域 ID].pooler.supabase.com:5432/postgres > umami_dump_$(date +"%Y-%m-%d--%H-%M-%S").sql

修改环境变量

如果设置过自定义 JS 名称( TRACKER_SCRIPT_NAME ),更新 v2.2.0 之后,需要在这个脚本名后加个 .js 才能正常运行。

我之前设置的是这样的:

TRACKER_SCRIPT_NAME=script

需要到 Vercel 里把这个环境变量改为:

TRACKER_SCRIPT_NAME=script.js

更新程序代码

从上游创建 v2 分支:

git fetch upstream --tags
git checkout v2

推送到 GitHub 仓库

git push -u origin v2

数据库升级

更新前先备份数据库文件。

pg_dump postgresql://postgres.[项目ID]:[数据库密码]@[区域 ID].pooler.supabase.com:5432/postgres > umami_dump_$(date +"%Y-%m-%d--%H-%M-%S").sql

使用官方的升级脚本,进行数据库升级。

首先克隆项目并安装。

git clone https://github.com/umami-software/migrate-v1-v2.git
cd migrate-v1-v2
yarn install
yarn build

创建一个 .env 文件,内容如下:

DATABASE_URL=postgresql://postgres.[项目ID]:[数据库密码]@[区域 ID].pooler.supabase.com:5432/postgres

然后运行迁移脚本。

yarn start

ps:不要使用 GitHub Codespaces 运行迁移脚本,会触发 Segmentation fault。使用 WSL 可以正常运行。

可以看到前面的操作都是正常的。

image-20260124140059716

最后一步报错了:

image-20260124132608925

解决方法很简单:

打开 Supabase 的 Table Editor,在 v1_event 表中插入一列,名称为 event_name,类型为 text。

image-20260125112457790

然后重新执行迁移命令即可。

image-20260124132043394

更新成功,可以看到版本是 v2.20.2。

image-20260124132920989

更新后的一些问题

问题 1:FATAL: MaxClientsInSessionMode: max clients reached

隔一段时间就会遇到图表加载缓慢,甚至登录报错的情况,“实时”页面打开就报错。其实这个问题在 v1 的时候就有了,我当时没找到原因就一直没管。

查看 Vercel 日志后发现有一大堆如下报错:

FATAL: MaxClientsInSessionMode: max clients reached - in Session mode max clients are limited to pool_size

问 AI 后得知,Supabase 会话池(Session pooler)不适合多并发,容易导致连接终端超限。对于 Vercel 这种 Serverless 服务,应采用事务池(Transaction pooler)。

解决方案

在 Vercel 项目中,

修改 DATABASE_URL 环境变量:

DATABASE_URL=postgresql://[数据库用户名].[项目ID]:[数据库密码]@aws-0-[区域ID].pooler.supabase.com:6543/[db-name]?pgbouncer=true&connection_limit=1

添加 DIRECT_DATABASE_URL 环境变量:

DIRECT_DATABASE_URL=postgresql://postgres.[项目ID]:[数据库密码]@aws-0-[区域ID].pooler.supabase.com:5432/postgres

然后重新部署。

问题 2:数据库检查成功后,部署长时间卡住

重新部署时,遇到了一个新问题。数据库检查成功后,构建就卡住不动了。甚至构建了 45 分钟都没完成,达到 Vercel 超时时长了。

image-20260124183312581

解决方案

修改 package.json,把 scripts.build 中的 check-db 去掉,改为:

"build": "npm-run-all check-env build-db build-tracker build-geo build-app",

然后重新部署即可。

升级到 v3

更新程序代码

Fork 同步上游最新代码。

修改 package.json,把 scripts.build 中的 check-db 去掉,改为:

"build": "npm-run-all check-env build-db build-tracker build-geo build-app",

在项目目录下添加环境变量 .env 如下:

DATABASE_URL=postgresql://postgres.[项目ID]:[数据库密码]@aws-0-[区域ID].pooler.supabase.com:5432/postgres

这里必须要使用会话池地址(即 5432 端口的地址),使用事务池连接会遇到上面长时间卡住的问题。

数据库迁移

在本地进行数据库迁移:

pnpm prisma migrate deploy

然后在 Vercel 重新部署即可。

验证更新

进入后台,打开分享链接,可以看到游戏机版本号为 v3.0.3。

image-20260125100932921

参考资料

  1. 备份 umami 数据库,并使用 TG Bot 保存 dump 文件 - 竹林里有冰的博客

  2. Apt - PostgreSQL wiki

  3. 更新 Umami 至 v2 - MBRjun-Blog

  4. Cannot log in after updated to the 1.39.1 · Issue #1583 · umami-software/umami

  5. ✗ Failed to run sql file /db/postgresql/data-migration-v2.sql · Issue #2475 · umami-software/umami

  6. Vercel build and local build do not work with 3.0.3 · Issue #3914 · umami-software/umami

  7. Running on Supabase – Docs - Umami

本文作者:Tony

本文链接: https://blog.iamsjy.com/2026/01/25/upgrade-umami-from-v1-to-v3/

文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。

评论