Appearance
Task 與 TaskRun
Task
是什麼
Rollout 拆出來的最小執行單元。一個 Task = 在一個 DB 上做一件事。
例:Plan 的 target 有 prod.orders 與 prod.users 兩個 DB,Rollout 會自動拆出兩個 Task。
生命週期
text
pending ──> running ──> done
│ │
│ ├──> failed
│ └──> skipped
└──> canceled重要欄位
| 欄位 | 說明 |
|---|---|
rollout | 所屬 Rollout |
stage | 所在 Stage |
target | 對應的 DB(projects/p/databases/d) |
type | DATABASE_SCHEMA_UPDATE / DATABASE_DATA_UPDATE / … |
payload | type-specific 內容(SQL、schema diff、export 條件…) |
last_task_run | 最近一次執行的 TaskRun |
不變式
- Task 屬於某個 Rollout,不可遷移
- Task 的
target與payload在 Rollout 建立時凍結,不可改(需改 → 開新 Plan + Issue) - 一個 Task 在同一時間只能有一個 TaskRun 處於
running狀態
複合主鍵
task 表的 PK 是 (project, id, pipeline)。任何 store 操作 task 必須帶完整 PK(見 Migration / Composite-PK 表清單)。
TaskRun
是什麼
Task 的一次執行紀錄。
一個 Task 可以對應 0..N 個 TaskRun:
0→ 從未執行(pending)1→ 一次過N→ 失敗後重試 N-1 次(每次都留紀錄)
生命週期
text
pending ──> running ──> done
│
├──> failed
└──> canceled重要欄位
| 欄位 | 說明 |
|---|---|
task | 所屬 Task |
attempt | 第幾次嘗試(1 開始) |
started_at / finished_at | 時間戳 |
started_by | 觸發者(user / system) |
executed_sql | 真正跑到 DB 的 SQL(含 substitution) |
result | 結果摘要(影響 row 數、執行時長、錯誤訊息) |
logs | 完整 log(含 advisor / driver / server 端) |
為何要 append-only
關鍵設計決定:TaskRun 是 append-only,重試不覆蓋前次紀錄。
理由:
- 稽核:每次嘗試都要留得下
- 除錯:對比成功 / 失敗的差異
- 信任:使用者看到的是真實發生的歷史
對應主管要求 ① 完整稽核 + ⑤ release monitoring。
複合主鍵
task_run 表的 PK 是 (project, id, task)。
重試規則
DBA 可在 TaskRun failed 時點 Retry。Argus 行為:
- 凍結舊 TaskRun 為
failed(不變) - 建立新 TaskRun,
attempt = old + 1 - 重跑同樣的
executed_sql(不重新從 Plan 取,因為 Plan 可能被改)
⚠️ 重試的前提是「重跑同一段 SQL 是安全的」。 對非 idempotent 的 SQL(
INSERT VALUES、已 commit 一半的 DDL)需謹慎評估,先讀 DB 端實際狀態再決定。
ASCII 示意
text
Rollout #42
├─ Stage: Dev
│ └─ Task #1 (dev.orders)
│ └─ TaskRun #1.1 [done] 2026-05-23 09:00
│
├─ Stage: Staging
│ └─ Task #2 (staging.orders)
│ ├─ TaskRun #2.1 [failed] 2026-05-23 09:15 — deadlock
│ └─ TaskRun #2.2 [done] 2026-05-23 09:20 ← retry
│
└─ Stage: Prod
└─ Task #3 (prod.orders)
└─ TaskRun #3.1 [running]在 UI 上
- Rollout 詳情頁 → 看到所有 Task
- 點 Task → 看到所有 TaskRun(含失敗的)
- 點 TaskRun → 看到 executed SQL + log + result