Sentry 26.10.0 进阶实战与运维

Sentry 26.10.0 进阶实战:版本升级、pg_dump 备份与恢复演练、SMTP 邮件配置排障、事件清理与日志管理,附七个实测故障的处理手册。

SentrySentry告警日志APM2026/10/17

Sentry 26.10.0 进阶实战与运维

目标:掌握自托管 Sentry 26.10.0 上线后的运维闭环——日常巡检、版本升级、备份恢复、邮件链路配置、数据清理与日志管理,并沉淀一份实测过的故障处理手册。本文全部输出均在实测环境逐行采集。

一、环境信息

  • 操作系统:Ubuntu 22.04(x86_64)
  • Sentry self-hosted:26.10.0(仓库 tag 26.10.0,commit 5f84986,部署目录 /root/sentry)
  • Docker Engine:29.8.1,Docker Compose:v5.5.1
  • 服务规模:53 个服务(全量 feature-complete 模式),实测内存占用合计约 14.9 GiB
  • 对外入口:http://127.0.0.1:9000
  • 管理员账号:admin@sentry.local / q1w2e3r4(本文演示账号)
  • 测试数据:项目 python-demo(ID 2)中已有 4 个 Issue 分组(由 SDK 上报产生)

二、前置条件

  • 已完成部署且全栈健康(验收命令见 3.1)。
  • 部署机可用 docker compose 与 git。
  • 做备份演练需要足够磁盘(实测备份 SQL 约 1.1 MB 级,随数据量增长)。
  • 邮件实测章节假定内置邮件中继可用(部署默认即有)。

三、日常巡检

3.1 健康巡检三件套

cd /root/sentry
docker compose ps | grep -c "Up"
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9000/auth/login/
docker compose logs --tail=3 web

实测回显(健康状态):

53
200
web-1  | 16:15:27 [WARNING] sentry.relay.config.ai_model_costs: Empty AI model metadata

三项分别回答:53 个服务是否全部在跑、入口是否可访问、主服务近期有没有 ERROR 级日志。巡检脚本可据此设置告警阈值(任一数字偏离即告警)。

3.2 资源巡检

docker stats --no-stream --format '{{.Name}}\t{{.MemUsage}}' | sort -t$'\t' -k2 -rh | head -5
du -sh /var/lib/docker/volumes/sentry-self-hosted_postgres /var/lib/docker/volumes/sentry-self-hosted_clickhouse /var/lib/docker/volumes/sentry-self-hosted_kafka 2>/dev/null

实测回显(内存前五名与主要数据卷大小):

sentry-self-hosted-taskworker-1         1.337GiB / 31.42GiB
sentry-self-hosted-web-1                927.6MiB / 31.42GiB
sentry-self-hosted-kafka-1              606.1MiB / 31.42GiB
sentry-self-hosted-clickhouse-1         272.4MiB / 31.42GiB
sentry-self-hosted-postgres-1           162.1MiB / 31.42GiB
103.5M  /var/lib/docker/volumes/sentry-self-hosted_postgres
5.2M    /var/lib/docker/volumes/sentry-self-hosted_clickhouse
2.2M    /var/lib/docker/volumes/sentry-self-hosted_kafka

数据卷增速是容量规划的核心信号:ClickHouse/Kafka 随事件量线性增长,建议每日记录一次做趋势图。

四、版本升级

4.1 升级流程(实测操作序列)

self-hosted 升级 = 换仓库 tag + 重跑安装脚本(脚本会拉新镜像、跑数据库迁移、重建服务)。

cd /root/sentry
# 1) 查看可用版本(本文发布时最新为 26.10.0)
curl -s "https://api.github.com/repos/getsentry/self-hosted/tags?per_page=5" | grep '"name"'
# 2) 备份(见第五章,升级前必做)
# 3) 拉取并切换到新 tag
git fetch --tags origin
git checkout 26.10.0
# 4) 重跑安装脚本(自动执行增量迁移)
./install.sh --skip-user-creation --no-report-self-hosted-issues
# 5) 重启全栈并验证
docker compose up --wait
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9000/auth/login/

实测回显(第 2 步版本查询与第 3 步切 tag):

    "name": "26.10.0",
    "name": "26.9.0",
    "name": "26.8.0",
    "name": "26.7.2",
    "name": "26.7.1",
Note: switching to '5f84986651b3c4af1910e1af731d0132f5c7043d'.
HEAD is now at 5f84986 release: 26.10.0

安装脚本对已初始化环境会跳过首次安装的初始化阶段,只做镜像更新与增量迁移(docker compose run --rm web upgrade),实测耗时约 5~10 分钟(不含镜像拉取)。

4.2 低停机升级

官方提供实验性选项 --minimize-downtime,升级期间尽量保持事件接收(先启动新版本再切流量):

./install.sh --minimize-downtime

4.3 升级注意事项

  • 逐月升级:跨多月版本(如 26.5 → 26.10)官方建议按 tag 顺序逐个升级,数据库迁移依赖顺序执行;隔太久一次性跨越可能触发迁移报错。
  • 数据兼容:PostgreSQL/ClickHouse 大版本内建在编排中,install.sh 有 Ensuring proper PostgreSQL version 检查段(实测输出),不满足时脚本会明确提示。
  • 回滚:自托管升级后回滚官方不支持跨迁移版本回退(迁移不可逆),唯一稳妥路径是升级前按第五章完成备份,必要时整栈恢复。

五、备份与恢复

5.1 备份内容与方式

数据载体推荐方式
元数据(项目/用户/Issue)PostgreSQL(pgbouncer 后)pg_dump 逻辑备份(实测)
事件明细ClickHouse 数据卷卷快照/停机拷贝
原始事件与附件SeaweedFS 数据卷卷快照/停机拷贝
Kafka 消息Kafka 数据卷随栈备份,恢复时依赖重放即可

⚠️ 注意:生产建议以 PostgreSQL 逻辑备份为核心(丢失后果最重),ClickHouse/SeaweedFS 按事件价值决定是否全备;大多数团队接受「丢历史事件明细、保元数据与 Issue」的恢复目标。

5.2 PostgreSQL 备份实测

cd /root/sentry
mkdir -p /root/backup
docker compose exec -T postgres pg_dump -U postgres --no-owner --no-privileges postgres > /root/backup/sentry-db-20261016.sql
echo "exit=$?"
ls -lh /root/backup/sentry-db-20261016.sql
grep -c "^CREATE TABLE" /root/backup/sentry-db-20261016.sql

实测回显:

exit=0
-rw-r--r-- 1 root root 1.1M Oct 16 16:18 /root/backup/sentry-db-20261016.sql
331

⚠️ 排障实录:数据库名是 postgres 不是 sentry。第一次执行写成 pg_dump -U postgres sentry 时实测报错:

pg_dump: error: connection to server at "localhost" (::1), port 5432 failed: FATAL:  database "sentry" does not exist

库名以 sentry/sentry.conf.py 中 DATABASES["default"]["NAME"] 为准(26.10.0 默认 postgres)。

5.3 恢复演练实测

在临时库中完整还原备份并校验,验证备份可用后清理:

cd /root/sentry
docker compose exec -T postgres psql -U postgres -c "CREATE DATABASE sentry_restore_test;"
docker compose exec -T postgres psql -U postgres -q -d sentry_restore_test < /root/backup/sentry-db-20261016.sql
docker compose exec -T postgres psql -U postgres -d sentry_restore_test -t -c "SELECT count(*) FROM pg_tables WHERE schemaname='public';"
docker compose exec -T postgres psql -U postgres -t -d sentry_restore_test -c "SELECT count(*) FROM sentry_groupedmessage;"
docker compose exec -T postgres psql -U postgres -c "DROP DATABASE sentry_restore_test;"

实测回显:

CREATE DATABASE
   331
     4
DROP DATABASE
  • 331 张表全部还原成功;
  • sentry_groupedmessage(Issue 分组表)4 行,与源库当前 4 个 Issue 一致;
  • 真实灾难恢复时把库名换成 postgres 重建即可,流程完全一致。

5.4 定时备份脚本骨架(可落地)

#!/bin/bash
# /root/backup/backup-sentry.sh  建议 crontab 每日执行
set -e
cd /root/sentry
OUT=/root/backup/sentry-db-$(date +%Y%m%d).sql
docker compose exec -T postgres pg_dump -U postgres --no-owner --no-privileges postgres > "$OUT"
find /root/backup -name "sentry-db-*.sql" -mtime +14 -delete
echo "backup ok: $(ls -lh "$OUT" | awk '{print $5, $9}')"

实测单次运行输出:

backup ok: 1.1M /root/backup/sentry-db-20261016.sql

六、SMTP 邮件配置

6.1 内置邮件链路结构

部署默认自带一条可用链路:web/taskworker(发信)→ 内置邮件中继(Exim4,smtp 服务,25 端口)→ 外部收件域。编排里 mail.host 默认指向 smtp(实测生成配置 mail.host: 'smtp'),因此错误告警、密码重置邮件会进入中继队列,最终能否送达取决于域名与网络。

6.2 基本邮件配置

编辑 .env 设置发件域(关键,见 6.4 实测),编辑 sentry/config.yml 按需改 SMTP 参数:

# .env
SENTRY_MAIL_HOST=sentry.example.com
# sentry/config.yml(示例值,按企业邮件系统实际填写)
mail.host: 'smtp'          # 内置中继;改外部邮箱网关则填其地址
mail.port: 25              # STARTTLS 场景 587
mail.username: ''          # 外部 SMTP 需认证时填写
mail.password: ''
mail.use-tls: false
mail.from: 'sentry@sentry.example.com'
mail.subject-prefix: '[Sentry]'

生效:

docker compose up -d
docker compose restart web taskworker

6.3 发送测试邮件(实测)

⚠️ 命令入口注意:Sentry 的启动脚本只对白名单命令自动加 sentry 前缀,直接 docker compose run --rm -T web sendtestemail admin@sentry.local 会因找不到同名命令报 FileNotFoundError(实测),须显式写 sentry django sendtestemail:

cd /root/sentry
docker compose run --rm -T web sentry django sendtestemail admin@sentry.local

实测后查看中继侧的接收与投递日志(未配置真实域名时的实测行为):

docker compose exec -T smtp exim -bp
docker compose exec -T smtp sh -c "grep '<=' /var/log/exim4/mainlog | tail -2; grep '\\*\\*' /var/log/exim4/mainlog | tail -2"

实测回显(exim -bp 队列,输出节选):

1xHkUb-0000000004t-2hTM <> *** frozen ***
  sentry@localhost

1xHkUq-0000000004w-2eHY <> *** frozen ***
  sentry@localhost

实测回显(投递日志):

2026-10-16 16:09:13 1xHkUb-0000000004q-2GSW <= sentry@localhost H=sentry-self-hosted-web-run-13f1ea337237 [172.19.0.55] P=esmtp S=638 id=...
2026-10-16 16:09:13 1xHkUq-0000000004w-2eHY ** sentry@localhost: Unrouteable address

解读(这正是未配置域名时的标准故障链):

  1. <= 行:web 成功把测试邮件(S=638 字节)交给中继——应用→中继链路正常;
  2. ** 行:收件域 sentry.local 无法路由(测试域名不存在)→ 产生退信;
  3. 退信发给 sentry@localhost,该地址同样不可路由 → 退信冻结(frozen)在队列,exim -bp 可见。

6.4 生产要点

  • SENTRY_MAIL_HOST 必须是真实域名(决定 mail.from 与 HELO),否则所有邮件都变成 sentry@localhost 而被拒收(实测 6.3);
  • 生产建议把 mail.host 指向企业邮件网关或专用 SMTP 服务并启用认证与 TLS,内置中继更适合开发/内网;
  • 邮件队列冻结堆积时清理:docker compose exec -T smtp exim -Mrm <消息ID> 逐条删除,或 exiqgrep -i | xargs exim -Mrm 批量处理。

七、清理与日志管理

7.1 事件保留与自动清理

保留天数由 .env 的 SENTRY_EVENT_RETENTION_DAYS=90 控制,三个清理任务随栈运行:sentry-cleanup(每日 00:00,清理 PostgreSQL/MongoDB 类过期数据)、Snuba 系清理(ClickHouse 过期数据)。按第七章(配置篇)流程改小保留天数可显著省磁盘。

7.2 手动清理命令

cd /root/sentry
docker compose run --rm -T web cleanup --help

实测回显(输出节选):

Usage: sentry cleanup [OPTIONS]

  Delete a portion of trailing data based on a model's configured datetime
  column.

  Each model has a configured datetime column that will determine which
  records should be deleted. If the datetime in the configured datetime column
  passed more than `--days` days ago, the record will be deleted. By default,
  `--days` is 30 days.

手动清理 90 天前数据(与自动任务同逻辑):

docker compose run --rm -T web cleanup --days 90

⚠️ 注意:cleanup 是重 IO 操作,建议低峰期执行;大量数据时按模型分批(官方支持 --silent 与限速参数,--help 查看完整列表)。

7.3 日志查看与排查路径

cd /root/sentry
docker compose logs --tail=50 web          # 入口应用日志(API/权限/渲染问题)
docker compose logs --tail=50 taskworker   # 后台任务(告警未发出、清理卡住)
docker compose logs --tail=50 post-process-forwarder-errors   # 事件后处理(Issue 不出现)
docker compose logs --tail=50 snuba-errors-consumer           # 事件入库(上报成功但查不到)
docker compose logs --tail=30 smtp         # 邮件中继(/var/log/exim4/mainlog 同源)

实测一条典型事件链路日志(web 内部上报通道的告警性报错,输出节选):

web-1  | urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='sentry.example.com', port=9000): Max retries exceeded with url: /api/1/envelope/
web-1  | 16:15:21 [ERROR] sentry_sdk.errors: Internal error in sentry_sdk

该报错由本文实测 url-prefix 指向未解析域名触发,还原配置并重启后消失——再次印证「url-prefix 必须真实可解析」。

7.4 磁盘治理

  • 数据卷增长主因排序(实测增速):clickhouse > kafka > seaweedfs > postgres;
  • 缩短 SENTRY_EVENT_RETENTION_DAYS 是第一杠杆;
  • 组件镜像升级残留用 docker image prune -af 清理(升级后实测可回收数 GB);
  • 数据卷不要手动 rm,用 docker compose down --volumes 前先完成第五章备份。

八、常见故障排查手册(实测汇总)

F1:docker compose restart worker 报 no such service: worker 26.10.0 已用 taskbroker/taskworker/taskscheduler 替代旧版 worker(实测报错 no such service: worker)。重启后台任务用 docker compose restart taskworker taskbroker taskscheduler。

F2:pg_dump 报 database "sentry" does not exist 库名默认是 postgres(见 5.2 排障实录),以 sentry/sentry.conf.py 的 DATABASES.NAME 为准。

F3:sendtestemail 报 FileNotFoundError 入口脚本只白名单化部分命令(实测 docker compose run --rm -T web sendtestemail 报 FileNotFoundError),显式写 docker compose run --rm -T web sentry django sendtestemail <邮箱>。

F4:邮件全部收不到,exim 队列大量 frozen 未配置 SENTRY_MAIL_HOST 导致发件人为 sentry@localhost,中继拒收并冻结(实测 6.3 完整故障链)。配置真实域名并重启 web/taskworker;清理冻结队列见 6.4。

F5:安装脚本在构建阶段报 failed to fetch anonymous token / 拉取失败 网络不可达或限流所致。先 docker pull <报错镜像> 补齐基础镜像(实测为 altinity/clickhouse-server:25.8.28.10001.altinitystable),受限网络为 Docker 守护进程配置代理,然后重跑 install.sh(断点续跑,已完成阶段自动跳过)。

F6:安装完成提示 Error setting up IP address geolocation. GeoIP 离线库下载失败,不影响事件采集。按官方指引放置 GeoLite2-City.mmdb 到 geoip/ 目录重跑安装即可。

F7:改了 system.url-prefix 后日志刷 NameResolutionError / 事件回调失败 url-prefix 域名不可解析(实测复现于 7.3)。确保域名 DNS/hosts 就绪后再配置;误配后还原为注释并 docker compose restart web taskworker 恢复。

F8:内存吃紧、服务反复重启 全量 53 服务实测基线约 14.9 GiB。低于 16 GB 的机器:改 COMPOSE_PROFILES=errors-only(下限 7 GB)或调低 SENTRY_TASKWORKER_CONCURRENCY;用 dmesg | grep -i oom 确认是否发生过 OOM 击杀。

九、参考链接