Files
gitea/docs/sqlite-to-postgres-migration.md

186 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SQLite 迁移到 PostgreSQL
本文档适用于已有 Gitea 服务仍在使用旧版 Docker Compose 和 SQLite尚未更新到引入 PostgreSQL 的最新 commit 的场景。
迁移目标是把 `data/gitea/gitea.db` 中的业务数据导入到新的 PostgreSQL 数据库同时继续复用现有的仓库、LFS、附件和配置目录。
> `gitea migrate` 不是 SQLite 到 PostgreSQL 的数据搬迁工具。它只会对当前 Gitea 配置指向的数据库执行 Gitea schema migration。数据库搬迁应使用 `pgloader` 完成。
## 迁移前准备
- 预留维护窗口。迁移期间必须停止 Gitea避免 SQLite 继续写入。
- 保持 `GITEA_VERSION` 不变。不要在同一次操作中同时升级 Gitea 版本和切换数据库。
- 准备 `.env` 中的 PostgreSQL 配置:
```env
POSTGRES_VERSION=16-alpine
POSTGRES_DB=gitea
POSTGRES_USER=gitea
POSTGRES_PASSWORD=<强密码>
```
- 确认可以运行 `sqlite3`,并能拉取或运行 `dimitri/pgloader:latest` 镜像。
- 本文档默认 Docker Compose project 网络名为 `gitea_default`。如果实际名称不同,用下面命令查看后替换:
```bash
docker network ls
```
## 1. 停止旧 Gitea
在仍使用 SQLite 的旧版 compose 下停止 Gitea
```bash
docker compose stop gitea
```
如果启用了 Caddy可以保持 Caddy 运行显示维护页,也可以一起停止:
```bash
docker compose stop caddy
```
## 2. 冷备份 SQLite 和数据目录
```bash
ts=$(date +%Y%m%d-%H%M%S)
mkdir -p backups/$ts
cp data/gitea/gitea.db backups/$ts/gitea.db
cp data/gitea/conf/app.ini backups/$ts/app.ini
tar -czf backups/$ts/gitea-data.tar.gz data/git data/gitea
```
备份完成后,记录 SQLite 中的关键表数量,作为迁移后校验基线:
```bash
sqlite3 data/gitea/gitea.db "select 'user', count(*) from user union all select 'repository', count(*) from repository union all select 'lfs_meta_object', count(*) from lfs_meta_object union all select 'public_key', count(*) from public_key union all select 'issue', count(*) from issue union all select 'release', count(*) from release;"
```
## 3. 更新代码并只启动 PostgreSQL
更新到包含 PostgreSQL 服务的最新 commit并补齐 `.env` 中的 PostgreSQL 配置。
```bash
git pull
```
先只启动 PostgreSQL不要启动 Gitea
```bash
docker compose up -d postgres
```
确认 PostgreSQL 可连接:
```bash
docker compose exec -T postgres psql -U gitea -d gitea -c "select version();"
```
## 4. 确认 PostgreSQL 是空库
检查目标库是否已有表:
```bash
docker compose exec -T postgres psql -U gitea -d gitea -c '\dt'
```
如果已经有 Gitea 业务表,先确认这些表不是生产数据。确认可丢弃后,停止 PostgreSQL备份并移走 `data/postgres/`,再重新启动空库:
```bash
docker compose stop postgres
ts=$(date +%Y%m%d-%H%M%S)
mv data/postgres data/postgres.before-migration-$ts
docker compose up -d postgres
```
再次运行 `\dt`,确认目标库为空。
## 5. 使用 pgloader 导入 SQLite
`<POSTGRES_PASSWORD>` 替换为 `.env` 中的真实密码:
```bash
docker run --rm \
--network gitea_default \
-v "$PWD/data/gitea:/data/gitea:ro" \
dimitri/pgloader:latest \
pgloader sqlite:///data/gitea/gitea.db postgresql://gitea:<POSTGRES_PASSWORD>@postgres:5432/gitea
```
如果 compose project 网络名不是 `gitea_default`,替换 `--network` 参数。
导入完成后,检查目标库关键表数量:
```bash
docker compose exec -T postgres psql -U gitea -d gitea -c "select 'user', count(*) from \"user\" union all select 'repository', count(*) from repository union all select 'lfs_meta_object', count(*) from lfs_meta_object union all select 'public_key', count(*) from public_key union all select 'issue', count(*) from issue union all select 'release', count(*) from release;"
```
这些数量应与第 2 步 SQLite 基线一致。
## 6. 启动 Gitea
确认 `docker-compose.yml` 已通过 `GITEA__database__*` 环境变量指向 PostgreSQL然后启动 Gitea
```bash
docker compose up -d gitea
docker compose logs -f gitea
```
Gitea 启动时会对 PostgreSQL 执行必要的 schema migration。日志中不应出现数据库连接、类型转换、唯一约束或 migration 错误。
如果使用 Caddy
```bash
docker compose up -d caddy
```
## 7. 迁移后验证
- 使用原管理员账号登录 Web UI。
- 确认用户、组织、仓库、Issue、Release、SSH Key 等数据存在。
- 执行一次 HTTP 或 HTTPS clone。
- 执行一次 SSH clone。
- 推送一个普通 commit。
- 如果使用 Git LFS执行一次 LFS push。
- 检查日志:
```bash
docker compose logs gitea postgres
```
## 回滚
如果迁移后验证失败,先停止新 Gitea
```bash
docker compose stop gitea
```
回滚到旧版 SQLite compose或临时移除 `docker-compose.yml` 中的 `GITEA__database__*` 环境变量,避免它覆盖 `app.ini`
恢复备份:
```bash
cp backups/<备份时间>/gitea.db data/gitea/gitea.db
cp backups/<备份时间>/app.ini data/gitea/conf/app.ini
```
再启动旧 SQLite 版本:
```bash
docker compose up -d gitea
```
在迁移完全确认前,不要删除 `data/gitea/gitea.db``backups/` 或迁移前的 `data/postgres.before-migration-*`
## 演练建议
正式迁移前,建议在复制出来的目录中完整演练一次:
```bash
cp -a gitea gitea-migration-dry-run
cd gitea-migration-dry-run
```
演练中也要验证空库检查、pgloader 导入、表数量对比、Gitea 启动和 Web/Git 操作。演练通过后,再在正式目录执行维护窗口迁移。