升级
升级就是换 evstats 程序,用同一组环境变量启动。不需要对着生产库执行迁移脚本:启动时它会自己对照表结构,缺什么补什么,改了什么记下来。
常规步骤
- 读更新日志:看这个版本 更新日志 里「需要注意」一节,有没有要回填的语句或默认值变化。
- 停旧进程:发 SIGTERM,等它把内存批次写进 ClickHouse 并确认(最多 15 秒)。
- 换程序:换上新的二进制或新镜像。
- 启动:启动日志和「关于」页里能看到新建的表、补上的列、重建的视图。
- 核对:打开
/health,确认meta和各分片是up、setup是ok。
Compose 部署时:
bash
docker compose pull evstats
docker compose up -d evstats
docker compose logs -f evstats镜像标签 :1 会跟随 1.x 的最新版本;钉了 X.Y.Z 的话先改 compose.yaml 里的标签。
滚动升级
多台进程时一台一台换,上报不用中断:
- 新旧进程可以同时写同一个 ClickHouse。
- 一台停下时,它还没确认的消息由仍在运行的进程接着写。
- 加列用的是
ADD COLUMN IF NOT EXISTS,几台同时启动也不会互相打架。 - 各进程的
data/各自独立,不要共用。
启动会做的
| 情况 | 处理 |
|---|---|
| 缺表 | 建表 |
| 缺列 | 加列,原有的行都还在 |
| 缺配置项 | 补上默认值;你改过的配置保留 |
| 物化视图的定义变了 | 删掉视图再按新定义创建,聚合表里的旧数据保留。新维度只对之后写入的数据生效 |
| 多出来的表或列 | 留着不动,只打日志 |
| 列类型、引擎、排序键、分区和程序期望的不一致 | 这个进程退出,数据不动。按日志提示处理后再启动 |
已经存在的表,保留天数(TTL)不会在启动时被改写。
每一次实际变更都记在 evs_schema_change 表里。「系统 → 关于」列出最近 10 条:时间、库、对象、动作(建表、加列、建视图、重建视图)和语句摘要。
evstats


需要人执行 SQL 的情况
只有两种情况:聚合和明细明显对不上;或者新版本加了固定维度,你又想看历史。需要时,更新日志会给出语句,并写明在哪个分片上执行。执行前先停该项目的采集,或者接受执行期间的少量偏差。
事件日聚合的回填示例(在项目所在的分片上执行):
sql
TRUNCATE TABLE evs_agg_event_daily;
INSERT INTO evs_agg_event_daily
SELECT project_id, event_date, event,
count() AS event_cnt,
uniqExactState(distinct_id) AS user_state
FROM evs_event
WHERE event_type = 'track'
GROUP BY project_id, event_date, event;不要截断 evs_agg_user_first
这张表记录每个人第一次出现的时间,没有保留期限。截断它会让老用户全部变成新访客。
程序和 SDK 分开升级
服务端可以单独升级。采集协议只会增加可以忽略的新字段,旧版本的 SDK 继续能用。仪表盘随 evstats 一起发布,不用单独升级。
兼容承诺
从 v1.0 起:
| 对象 | 承诺 |
|---|---|
| 采集协议 | 只增加可以忽略的字段,旧 SDK 永远能用 |
/api/v1 | 只增加路径和字段,不删、不改含义、不改类型 |
| 配置键 | 不改名。确实要改名时,新旧两个键同时生效一个次版本,启动日志会提示 |
| 表结构 | 启动时只增不删。需要人工回填时,更新日志给出语句 |
| 启动参数 | 只有 -clickhouse、-redis、-port,以及同名环境变量 EVS_CLICKHOUSE、EVS_REDIS、EVS_PORT。都有默认值,启动参数优先于环境变量,不再增加必填项 |
| 升级路径 | 任意 1.x 可以直接升到更新的 1.x,不用逐个版本升 |
破坏以上任何一条,只会发生在 2.0。1.0 之前,次版本也可能带破坏性变更,但更新日志里一定写明迁移方法。版本号遵循 SemVer。