Bytebase 3.23.1 进阶实战与运维

Bytebase 3.23.1 进阶实战与运维手册,覆盖数据目录备份与恢复闭环演练、外置元数据库 pg_dump 导出、版本升级与迁移日志解读、SSO 与 LDAP 接入的许可门禁实测、API Token 集成与用户管理,以及八类高频故障的定位与处置,全程命令实测通过

Bytebase数据库运维PostgreSQLLinux2026/10/17

Bytebase 3.23.1 进阶实战与运维

目标:面向已部署 Bytebase 3.23.1 的运维场景,给出可直接落地的操作手册:数据备份与恢复闭环演练、元数据库导出、版本升级与回滚边界、SSO/LDAP 接入的许可要求实测、API Token 集成与用户管理,以及高频故障的定位处置。已在 Ubuntu 22.04.5 LTS + Bytebase 3.23.1 环境实测通过(受管数据库 PostgreSQL 16.15 / MySQL 8.4.11)。

一、环境信息

项目值
操作系统Ubuntu 22.04.5 LTS(x86_64)
Bytebase 版本3.23.1(升级演练从 3.22.0 升至 3.23.1 实测)
Bytebase 服务地址http://192.168.1.62:8080(本机操作用 http://localhost:8080)
数据目录/opt/bytebase/data(内嵌元数据库 pgdata/ 所在,--data 参数指定)
外置元数据库PostgreSQL 16.15(演练用,PG_URL 接入,48 张元数据表)
管理员账号admin@example.com
API 会话登录 Cookie(Web)与 Bearer Token(集成)两种,见 3.5 节

💡 运维对象两层:数据目录(--data 指向,含内嵌元数据库 pgdata/ 与示例实例数据)与外部元数据库(PG_URL 指向的 PostgreSQL,启用外置元数据库时)。两层的备份方法不同(3.1/3.2 节),但都只关系元数据——被管理的业务库变更历史随业务库自身备份体系走。

二、概览

本章按运维生命周期组织:

  1. 备份与恢复(3.1~3.2):数据目录 tar 备份 + 恢复演练闭环;外置元数据库用 pg_dump;
  2. 升级与回滚(3.3):换版本 + schema 自动迁移,迁移单向、升级前必须备份;
  3. SSO/LDAP 接入(3.4):OIDC/LDAP 的 API 请求结构实测与许可门禁(ENTERPRISE 功能);
  4. API 集成与用户管理(3.5):Bearer Token 获取与调用、创建用户,适用于备份脚本、巡检脚本、CI 平台对接;
  5. 常见故障(第五章):八类高频问题的定位与处置。

所有命令基于部署形态的实测原样(安装与参数基础见《Bytebase 3.23.1 Ubuntu 22.04 安装指南》《Bytebase 3.23.1 配置参数详解》)。

三、逐项实测

3.1 数据目录备份与恢复演练(内嵌元数据库)

备份:停服保证一致性,tar 打包整个数据目录(实测,数据目录约含 pgdata/ 内嵌元数据库与示例实例数据):

docker stop bytebase >/dev/null
tar -czf /opt/bytebase/data-backup-$(date +%F).tar.gz -C /opt/bytebase/data .
ls -lh /opt/bytebase/data-backup-*.tar.gz
docker start bytebase >/dev/null
-rw-r--r-- 1 root root 15M Oct 17 01:12 /opt/bytebase/data-backup-2026-10-17.tar.gz

恢复演练(实测闭环:备份 → 解包到全新目录 → 以新实例启动 → 验证登录与数据):

# 1. 解包备份到新目录
rm -rf /opt/bytebase/restore-test && mkdir -p /opt/bytebase/restore-test
tar -xzf /opt/bytebase/data-backup-2026-10-17.tar.gz -C /opt/bytebase/restore-test
ls /opt/bytebase/restore-test
pgdata
pgdata-sample-managed
# 2. 以恢复出的目录启动一个独立实例(端口错开,不影响生产实例)
docker run -d --name bytebase-restore-test -v /opt/bytebase/restore-test:/var/opt/bytebase \
  -p 18093:8080 bytebase/bytebase:3.23.1
sleep 18
curl -s http://localhost:18093/healthz; echo
OK
# 3. 用备份时刻的账号登录,并查询备份前创建的业务表(实测回显)
curl -s -c /tmp/bb-restore-ck.txt -X POST http://localhost:18093/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"admin@example.com","password":"q1w2e3r4","web":true}' -o /dev/null -w 'login:%{http_code}\n'
curl -s -b /tmp/bb-restore-ck.txt -X POST \
  "http://localhost:18093/v1/projects/prj-demo/instances/sample-b464daf70af19b30/databases/hr_test:query" \
  -H 'Content-Type: application/json' \
  -d '{"statement":"SELECT count(*) AS cnt FROM bb_q3_employees;","limit":10}'
login:200
{"results":[{"columnNames":["cnt"],"columnTypeNames":["INT8"],"rows":[{"values":[{"int64Value":"1"}]}],...}]}

演练结论:恢复出的实例登录成功、备份前创建的表与数据(count=1)完整可用。恢复正式接管时,停掉旧实例、把新实例挂载到恢复目录并映射 8080 端口即可。

定时备份:把 tar 流程注册为每日凌晨任务(crontab -e 追加,真实命令):

15 2 * * * docker stop bytebase >/dev/null && tar -czf /opt/bytebase/data-backup-$(date +\%F).tar.gz -C /opt/bytebase/data . && docker start bytebase >/dev/null

💡 建议保留最近 7 份并异地存放(find /opt/bytebase/data-backup-*.tar.gz -mtime +7 -delete 配合使用)。停服窗口约 10 秒(tar 15M 级别);需要零停机时改用外置元数据库 + pg_dump(3.2 节),Bytebase 主进程无需停止。

3.2 外置元数据库的导出与恢复

启用 PG_URL 外置元数据库时,元数据在外部 PostgreSQL 中,用 pg_dump 在线导出(实测:48 张表导出 2644 行 SQL):

docker exec bytebase-pgmeta pg_dump -U bytebase bytebase > /opt/bytebase/meta-$(date +%F).sql
wc -l /opt/bytebase/meta-2026-10-17.sql
2644 /opt/bytebase/meta-2026-10-17.sql

恢复到新库(同版本 PostgreSQL,先建 UTF-8 空库再导入):

docker exec bytebase-pgmeta psql -U bytebase -c "CREATE DATABASE bytebase_new ENCODING 'UTF8';"
cat /opt/bytebase/meta-2026-10-17.sql | docker exec -i bytebase-pgmeta psql -U bytebase -d bytebase_new
# 切换 Bytebase 的 PG_URL 指向 bytebase_new 并重启即可

💡 该方式零停机(导出期间服务可用);pg_dump 版本须 ≥ 服务端版本。HA 多副本场景(--ha,见《Bytebase 3.23.1 配置参数详解》3.8 节)元数据本就在外部库,直接用本节方法备份。

3.3 版本升级与回滚边界

升级 = 备份 + 换镜像 tag + 重建,schema 由启动时的 migrator 自动逐版本迁移。实测从 3.22.0 升级到 3.23.1 的启动日志(迁移行逐条照抄):

docker logs -f bytebase 2>&1 | grep -E 'Migrat|started on port'
time=2026-10-16T15:57:11.867Z level=INFO source=migrator/migrator.go:135 msg="Migrating 3.23.1."
time=2026-10-16T15:57:11.880Z level=INFO source=migrator/migrator.go:135 msg="Migrating 3.23.2."
time=2026-10-16T15:57:11.886Z level=INFO source=migrator/migrator.go:135 msg="Migrating 3.23.3."
time=2026-10-16T15:57:11.895Z level=INFO source=migrator/migrator.go:135 msg="Migrating 3.23.4."
time=2026-10-16T15:57:11.905Z level=INFO source=migrator/migrator.go:135 msg="Migrating 3.23.5."
Version 3.23.1(16b89d9b49741c65623970038859d0d6397c8fe5) has started on port 8080 🚀

升级后验证(实测):

curl -s http://localhost:8080/healthz
curl -s -X POST http://localhost:8080/v1/auth/login -H 'Content-Type: application/json' \
  -d '{"email":"admin@example.com","password":"q1w2e3r4","web":true}' -o /dev/null -w 'login:%{http_code}\n'
OK
login:200

⚠️ 回滚边界(实测确认):schema 迁移是单向的——升级到 3.23.x 后元数据 schema 已是新版,把镜像 tag 改回旧版本会因 schema 不匹配而无法启动。正确回滚方式:恢复升级前的数据目录备份(3.1 节 tar 包)或外置库的 pg_dump(3.2 节),再以旧版本 tag 启动。升级前备份是硬要求。

3.4 SSO 与 LDAP 接入(许可要求实测)

Bytebase 支持 OIDC/OAuth2/LDAP 三类身份源对接,配置入口为控制台 Settings → Identity Providers(或 API POST /v1/idps)。实测确认:SSO 与 LDAP 均为 ENTERPRISE 许可功能,无许可时创建即被拦截(报错原文,code 7):

OIDC 身份源的正确请求结构(实测:字段结构被服务端接受后走到许可校验;OIDC 通过 issuer 自动发现端点,无需手填 authorize/token URL):

curl -s -b /tmp/bb-cookies.txt -X POST http://localhost:8080/v1/idps \
  -H 'Content-Type: application/json' \
  -d '{"title":"Demo OIDC","type":"OIDC","domain":"example.com","config":{"oidcConfig":{"issuer":"https://dex.example.com","clientId":"bytebase","clientSecret":"s3cret","scopes":["openid","profile","email"]}}}'
{"code":7,"message":"feature FEATURE_ENTERPRISE_SSO is a ENTERPRISE feature, please upgrade to access it"}

LDAP 身份源的正确请求结构(实测同上):

curl -s -b /tmp/bb-cookies.txt -X POST http://localhost:8080/v1/idps \
  -H 'Content-Type: application/json' \
  -d '{"title":"Demo LDAP","type":"LDAP","domain":"example.com","config":{"ldapConfig":{"host":"ldap.example.com","port":"389","bindDn":"cn=admin,dc=example,dc=com","bindPassword":"pass","baseDn":"dc=example,dc=com","userFilter":"(objectClass=person)"}}}'
{"code":7,"message":"feature FEATURE_ENTERPRISE_SSO is a ENTERPRISE feature, please upgrade to access it"}

💡 接入前提:到 Bytebase 官方许可页(hub.bytebase.com)获取许可并在 Settings → License 上传激活(自托管试用流程见《Bytebase 3.23.1 Ubuntu 22.04 安装指南》)。激活后用上面的请求结构创建身份源即可(控制台表单与该 API 字段一一对应:OIDC 填 Issuer/Client ID/Client Secret/Scopes;LDAP 填 Host/Port/Bind DN/Bind Password/Base DN/User Filter)。Community 版的替代方案是控制台本地用户管理(3.5 节的用户创建 API)。

3.5 API Token 集成与用户管理

获取 Bearer Token:登录时不带 web:true,响应直接返回 accessToken(实测 279 字符 JWT,用于 API 集成而非 Web 会话):

TOKEN=$(curl -s -X POST http://localhost:8080/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"admin@example.com","password":"q1w2e3r4"}' | \
  python3 -c "import json,sys; print(json.load(sys.stdin)['accessToken'])")
echo "token-length: ${#TOKEN}"
token-length: 279

用 Bearer Token 调用 API(实测:免 Cookie 调接口,适合脚本与 CI):

curl -s -H "Authorization: Bearer $TOKEN" http://localhost:8080/v1/projects | \
  python3 -c "import json,sys; d=json.load(sys.stdin); print('projects:', len(d.get('projects',[])))"
projects: 3

💡 集成脚本模板(Sheet→Plan→Issue→Rollout→batchRun 全流程)见《Bytebase 3.23.1 快速入门与集成示例》示例 1,把其中 -b /tmp/bb-cookies.txt 换成 -H "Authorization: Bearer $TOKEN" 即为无状态调用。Bytebase 3.23 自托管形态没有官方 CLI 工具,HTTP API(curl 或任意 HTTP 客户端)即官方集成方式;工单页面提供的 CI 平台示例(GitHub Actions/GitLab CI)底层同样是这套 REST API。

用户管理:管理员创建用户(实测回显;控制台路径 Settings → Users):

curl -s -b /tmp/bb-cookies.txt -X POST http://localhost:8080/v1/users \
  -H 'Content-Type: application/json' \
  -d '{"email":"dba2@example.com","password":"q1w2e3r4","title":"DBA Backup"}'
{"name":"users/dba2@example.com","state":"ACTIVE","email":"dba2@example.com","title":"DBA Backup","profile":{},"workspace":"workspaces/6cRCrjH7TsoyiThC"}

💡 密码要求 ≥ 8 位(工作区设置 passwordRestriction.minLength 默认 8,实测);忘记管理员密码且无其他管理员时的恢复入口是 bytebase recovery 子命令(《Bytebase 3.23.1 配置参数详解》3.12 节)。

四、实战示例

4.1 示例:一周滚动备份脚本(可直接部署)

#!/bin/bash
# bytebase-backup.sh — 每日停服备份 + 7 天滚动清理
set -e
D=/opt/bytebase
T=/opt/bytebase/data-backup-$(date +%F).tar.gz
docker stop bytebase >/dev/null
tar -czf "$T" -C $D/data .
docker start bytebase >/dev/null
find $D -name 'data-backup-*.tar.gz' -mtime +7 -delete
ls -lh "$T"

crontab 注册(实测可用形态,每日 02:15 执行):

15 2 * * * /opt/bytebase/bytebase-backup.sh >> /var/log/bytebase-backup.log 2>&1

4.2 示例:巡检脚本(健康 + 登录 + 实例在线三查)

#!/bin/bash
# bytebase-check.sh — 巡检 Bytebase 服务状态
BASE=http://localhost:8080
# 1. 健康检查(必须 OK)
[ "$(curl -s $BASE/healthz)" = "OK" ] && echo '[OK] healthz' || { echo '[FAIL] healthz'; exit 1; }
# 2. API 会话可用性(登录成功)
curl -s -X POST $BASE/v1/auth/login -H 'Content-Type: application/json' \
  -d '{"email":"admin@example.com","password":"q1w2e3r4"}' -o /dev/null \
  -w "login:%{http_code}\n" | grep -q 200 && echo '[OK] login' || echo '[FAIL] login'
# 3. 实例在线(列出实例)
curl -s -X POST $BASE/v1/auth/login -H 'Content-Type: application/json' \
  -d '{"email":"admin@example.com","password":"q1w2e3r4"}' -o /dev/null
curl -s -c /tmp/ck.txt -X POST $BASE/v1/auth/login -H 'Content-Type: application/json' \
  -d '{"email":"admin@example.com","password":"q1w2e3r4","web":true}' -o /dev/null
curl -s -b /tmp/ck.txt $BASE/v1/instances | \
  python3 -c "import json,sys; d=json.load(sys.stdin); print('[OK] instances:', [i['name'] for i in d.get('instances',[])])"

实测输出:

[OK] healthz
[OK] login
[OK] instances: ['instances/mysql-demo', 'instances/pg-demo']

4.3 示例:升级操作完整时序(可照抄执行)

# 1. 备份(升级硬前提)
/opt/bytebase/bytebase-backup.sh
# 2. 记录当前版本
docker exec bytebase bytebase version
# 3. 换镜像 tag 重建(x.y.z 为目标版本号,以 https://github.com/bytebase/bytebase/releases 实际最新版为准)
docker stop bytebase && docker rm bytebase
docker pull bytebase/bytebase:x.y.z
docker run -d --name bytebase --init -v /opt/bytebase/data:/var/opt/bytebase \
  -p 8080:8080 bytebase/bytebase:x.y.z
# 4. 观察迁移日志
docker logs -f bytebase 2>&1 | grep -E 'Migrat|started on port'
# 5. 验证(健康 + 登录 + 实例列表)
curl -s http://localhost:8080/healthz

实测(3.22.0 → 3.23.1)输出见 3.3 节:迁移行 5 条 + 启动横幅 + healthz OK + 登录 200。

五、注意事项与常见问题

以下条目均为本环境实测复现过的问题,报错原文照抄。

Q1:启动报 can't read memory.max from cgroup v2?

内嵌元数据库组件读取 cgroup v2 memory.max 失败(完整报错:[FATAL] ... ["unexpected error"] [error="can't read memory.max from cgroup v2: open /sys/fs/cgroup/memory.max: no such file or directory"])。常规物理机/虚机不会出现;出现在 cgroup 视图受限的运行环境,保证进程能读到自身 cgroup 的 memory.max 后恢复。

Q2:/health 返回 200 但页面打不开管理台,监控却告警正常?

探活端点用错了。/health 返回的是前端 HTML(200 但非健康信号),正确端点是 /healthz(返回纯文本 OK,实测),镜像内置健康检查也用它。

Q3:升级后旧版本起不来?

schema 迁移单向(3.3 节实测:3.22.0 → 3.23.1 依次执行 Migrating 3.23.1~3.23.5)。改回旧 tag 前必须先恢复升级前的备份,否则元数据 schema 与代码版本不匹配无法启动。

Q4:PG_URL 连接失败报 SQLSTATE 28P01?

密码认证失败(实测原文见《Bytebase 3.23.1 配置参数详解》3.10 节)。核对用户名/密码/库名;密码含 @、/、: 需百分号转义;确认库编码 UTF-8、PostgreSQL ≥ 14。

Q5:数据目录里出现属主为 65533(部分系统显示 kernoops)的目录?

那是容器内 bytebase 用户的 uid(启动日志:Recursively change owner of data directory "/var/opt/bytebase/pgdata" to bytebase...)。属主变化正常且必要,不要 chown 回 root,否则内嵌元数据库无法写入。

Q6:8080 端口被占用起不来?

报错两种形态:宿主进程占用 failed to bind host port 0.0.0.0:8080/tcp: address already in use,或另一实例占用 port is already allocated。ss -lntp | grep -w 8080 或 docker ps --format '{{.Names}}\t{{.Ports}}' 定位,改用 --port 或调整端口映射。

Q7:工单审批报 approval template is required?

工作区未配置审批模板(实测 code 13)。配置审批流模板后再走审批,或关闭项目开关 requireIssueApproval 恢复直通;SQL 审核结果本身不是执行拦截(《Bytebase 3.23.1 快速入门与集成示例》3.7 节有行为实测)。

Q8:创建身份源报 feature FEATURE_ENTERPRISE_SSO is a ENTERPRISE feature?

SSO/LDAP 属 ENTERPRISE 许可功能(3.4 节实测,OIDC 与 LDAP 同一开关)。上传许可激活后再配置;Community 版用本地用户管理替代。

六、参考链接