@fx-data/ai-diagnostics 0.1.20261026070913 → 0.1.20261107142011
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT_SETUP.md +9 -6
- package/README.md +5 -5
- package/bin/core-ai.mjs +241 -25
- package/content/AGENTS.md +37 -57
- package/content/README.md +10 -41
- package/content/docs/architecture.md +45 -74
- package/content/docs/diagnostic-feedback.md +20 -38
- package/content/docs/diagnostic-report.md +19 -46
- package/content/docs/index.md +40 -128
- package/content/docs/scenario-guide.md +34 -52
- package/content/knowledge/README.md +49 -0
- package/content/knowledge/cases/README.md +60 -0
- package/content/knowledge/cases/dashboard-parameter-deep-binding.md +32 -0
- package/content/knowledge/common/README.md +31 -0
- package/content/knowledge/common/concepts.md +49 -0
- package/content/knowledge/common/{knowledge-applicability.md → conclusions.md} +10 -6
- package/content/knowledge/common/queries.md +98 -0
- package/content/knowledge/common/signals.md +58 -0
- package/content/knowledge/common/topics/baseline-comparison.md +23 -0
- package/content/knowledge/common/topics/large-results.md +12 -0
- package/content/knowledge/common/topics/linked-traces.md +11 -0
- package/content/knowledge/common/topics/query-budget.md +18 -0
- package/content/knowledge/common/topics/query-example.md +69 -0
- package/content/knowledge/common/topics/setup-signoz-mcp.md +102 -0
- package/content/knowledge/common/topics/start-and-anchors.md +19 -0
- package/content/knowledge/common/workflow.md +22 -0
- package/content/knowledge/component/README.md +26 -0
- package/content/knowledge/component/concepts.md +22 -0
- package/content/knowledge/component/conclusions.md +11 -0
- package/content/knowledge/component/queries.md +7 -0
- package/content/knowledge/component/signals.md +75 -0
- package/content/knowledge/component/workflow.md +23 -0
- package/content/knowledge/dashboard/README.md +31 -0
- package/content/knowledge/dashboard/concepts.md +26 -0
- package/content/knowledge/dashboard/conclusions.md +21 -0
- package/content/knowledge/dashboard/queries.md +69 -0
- package/content/knowledge/dashboard/signals.md +76 -0
- package/content/knowledge/dashboard/topics/component-comparison.md +9 -0
- package/content/knowledge/dashboard/topics/dynamic-fields.md +21 -0
- package/content/knowledge/dashboard/topics/filter-tree.md +35 -0
- package/content/knowledge/dashboard/topics/name-binding.md +9 -0
- package/content/knowledge/dashboard/workflow.md +35 -0
- package/content/knowledge/dataset/README.md +27 -0
- package/content/knowledge/dataset/concepts.md +30 -0
- package/content/knowledge/dataset/conclusions.md +11 -0
- package/content/knowledge/dataset/queries.md +7 -0
- package/content/knowledge/dataset/signals.md +61 -0
- package/content/knowledge/dataset/topics/steps.md +59 -0
- package/content/knowledge/dataset/workflow.md +27 -0
- package/content/knowledge/engine/README.md +27 -0
- package/content/knowledge/engine/concepts.md +80 -0
- package/content/knowledge/engine/conclusions.md +49 -0
- package/content/knowledge/engine/queries.md +117 -0
- package/content/knowledge/engine/signals.md +73 -0
- package/content/knowledge/engine/topics/metric-fields.md +104 -0
- package/content/knowledge/engine/topics/patterns.md +50 -0
- package/content/knowledge/engine/workflow.md +20 -0
- package/content/knowledge/signal-index.md +117 -0
- package/content/knowledge/update/README.md +39 -0
- package/content/knowledge/update/concepts.md +93 -0
- package/content/knowledge/update/conclusions.md +59 -0
- package/content/knowledge/update/queries.md +103 -0
- package/content/knowledge/update/signals.md +57 -0
- package/content/knowledge/update/topics/correlations.md +63 -0
- package/content/knowledge/update/topics/discover-executions.md +31 -0
- package/content/knowledge/update/topics/events-execution.md +136 -0
- package/content/knowledge/update/topics/events-intake.md +102 -0
- package/content/knowledge/update/topics/events-outcome.md +163 -0
- package/content/knowledge/update/topics/lifecycle.md +58 -0
- package/content/knowledge/update/topics/scene-producers.md +258 -0
- package/content/knowledge/update/workflow.md +29 -0
- package/content-manifest.json +73 -192
- package/package.json +2 -2
- package/content/.agents/skills/analyze-analysis-table-update-runtime/SKILL.md +0 -35
- package/content/.agents/skills/analyze-analysis-table-update-runtime/agents/openai.yaml +0 -7
- package/content/.agents/skills/analyze-analysis-table-update-runtime/references/discover-update-executions.md +0 -34
- package/content/.agents/skills/analyze-analysis-table-update-runtime/references/update-diagnostic-contract.md +0 -101
- package/content/.agents/skills/analyze-engine-metric/SKILL.md +0 -76
- package/content/.agents/skills/analyze-engine-metric/agents/openai.yaml +0 -13
- package/content/.agents/skills/analyze-engine-metric/scripts/analyze_engine_metric.py +0 -270
- package/content/.agents/skills/analyze-engine-metric/scripts/engine_metric_analysis/__init__.py +0 -11
- package/content/.agents/skills/analyze-engine-metric/scripts/engine_metric_analysis/metric_analyzer.py +0 -791
- package/content/.agents/skills/analyze-engine-metric/scripts/engine_metric_analysis/signoz_extract.py +0 -278
- package/content/.agents/skills/diagnose-component-performance/SKILL.md +0 -52
- package/content/.agents/skills/diagnose-component-performance/agents/openai.yaml +0 -7
- package/content/.agents/skills/diagnose-component-performance/references/experience.md +0 -34
- package/content/.agents/skills/diagnose-dashboard-performance/SKILL.md +0 -92
- package/content/.agents/skills/diagnose-dashboard-performance/agents/openai.yaml +0 -7
- package/content/.agents/skills/diagnose-dashboard-performance/references/experience.md +0 -63
- package/content/.agents/skills/diagnose-dataset-performance/SKILL.md +0 -52
- package/content/.agents/skills/diagnose-dataset-performance/agents/openai.yaml +0 -7
- package/content/.agents/skills/diagnose-dataset-performance/references/experience.md +0 -33
- package/content/.agents/skills/diagnose-performance/SKILL.md +0 -77
- package/content/.agents/skills/diagnose-performance/agents/openai.yaml +0 -7
- package/content/.agents/skills/diagnose-update-performance/SKILL.md +0 -55
- package/content/.agents/skills/diagnose-update-performance/agents/openai.yaml +0 -7
- package/content/.agents/skills/diagnose-update-performance/references/experience.md +0 -47
- package/content/.agents/skills/setup-signoz-mcp/SKILL.md +0 -30
- package/content/.agents/skills/setup-signoz-mcp/agents/openai.yaml +0 -7
- package/content/.agents/skills/setup-signoz-mcp/references/installation.md +0 -75
- package/content/.agents/skills/setup-signoz-mcp/references/windows-artifact.md +0 -14
- package/content/docs/npm-cli.md +0 -202
- package/content/docs/roadmap.md +0 -44
- package/content/docs/skill-writing-guide.md +0 -65
- package/content/knowledge/common/signoz-environments.json +0 -52
- package/content/knowledge/common/signoz-environments.md +0 -55
- package/content/knowledge/common/signoz-query-example.md +0 -41
- package/content/knowledge/common/signoz-query-policy.md +0 -145
- package/content/knowledge/common/trace-routing.md +0 -63
- package/content/knowledge/component/observability.md +0 -60
- package/content/knowledge/dashboard/observability.md +0 -168
- package/content/knowledge/dashboard/query-examples.md +0 -63
- package/content/knowledge/dataset/observability.md +0 -68
- package/content/knowledge/engine/metric-artifacts.md +0 -25
- package/content/knowledge/engine/metric-retrieval.md +0 -107
- package/content/knowledge/engine/metric-semantics.md +0 -172
- package/content/knowledge/engine/performance-patterns.md +0 -86
- package/content/knowledge/update/diagnostic/manifest.json +0 -209
- package/content/knowledge/update/diagnostic/observability/edges/edge-attempt-to-capacity-deferral.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-attempt-to-lock-requeue.json +0 -18
- package/content/knowledge/update/diagnostic/observability/edges/edge-attempt-to-merge.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-candidate-to-effective-root.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-capacity-deferral-to-attempt.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-chain-node-to-execution-detail.json +0 -18
- package/content/knowledge/update/diagnostic/observability/edges/edge-dlx-recovery-to-attempt.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-effective-execution-to-listener-before.json +0 -21
- package/content/knowledge/update/diagnostic/observability/edges/edge-effective-root-to-chain.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-engine-task-to-primary-result.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-execution-detail-to-publication.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-init-recovery-to-publication.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-listener-complete-to-child-release.json +0 -21
- package/content/knowledge/update/diagnostic/observability/edges/edge-listener-to-derived-chain.json +0 -21
- package/content/knowledge/update/diagnostic/observability/edges/edge-load-decision-to-load-operation.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-load-operation-to-engine-task.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-lock-requeue-to-attempt.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-logical-parent-to-child.json +0 -18
- package/content/knowledge/update/diagnostic/observability/edges/edge-merge-member-to-effective-execution.json +0 -18
- package/content/knowledge/update/diagnostic/observability/edges/edge-merge-to-load-decision.json +0 -17
- package/content/knowledge/update/diagnostic/observability/edges/edge-no-load-to-primary-result.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-primary-result-to-child-frontier.json +0 -18
- package/content/knowledge/update/diagnostic/observability/edges/edge-primary-result-to-listener.json +0 -23
- package/content/knowledge/update/diagnostic/observability/edges/edge-publication-to-attempt.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-ready-recovery-to-publication.json +0 -16
- package/content/knowledge/update/diagnostic/observability/edges/edge-request-to-candidate-root.json +0 -16
- package/content/knowledge/update/diagnostic/observability/identity-units/candidate-root.json +0 -13
- package/content/knowledge/update/diagnostic/observability/identity-units/dag-node.json +0 -14
- package/content/knowledge/update/diagnostic/observability/identity-units/effective-root.json +0 -14
- package/content/knowledge/update/diagnostic/observability/identity-units/engine-task.json +0 -13
- package/content/knowledge/update/diagnostic/observability/identity-units/execution-attempt.json +0 -12
- package/content/knowledge/update/diagnostic/observability/identity-units/execution-detail.json +0 -13
- package/content/knowledge/update/diagnostic/observability/identity-units/listener-invocation.json +0 -11
- package/content/knowledge/update/diagnostic/observability/identity-units/load-decision.json +0 -12
- package/content/knowledge/update/diagnostic/observability/identity-units/load-operation.json +0 -11
- package/content/knowledge/update/diagnostic/observability/identity-units/logical-dag-edge.json +0 -11
- package/content/knowledge/update/diagnostic/observability/identity-units/merge-decision.json +0 -12
- package/content/knowledge/update/diagnostic/observability/identity-units/node-primary-result.json +0 -12
- package/content/knowledge/update/diagnostic/observability/identity-units/queue-publication.json +0 -11
- package/content/knowledge/update/diagnostic/observability/identity-units/requeue.json +0 -11
- package/content/knowledge/update/diagnostic/observability/identity-units/update-chain.json +0 -13
- package/content/knowledge/update/diagnostic/observability/identity-units/update-request.json +0 -12
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-after-commit-delivery.json +0 -131
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-attempt-consumed.json +0 -175
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-candidate-root-filter.json +0 -119
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-capacity-deferred.json +0 -121
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-child-release.json +0 -146
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-dlx-recovery.json +0 -100
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-effective-root-selection.json +0 -111
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-engine-handoff.json +0 -171
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-execution-frontier-persisted.json +0 -115
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-init-recovery.json +0 -93
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-intent-accepted.json +0 -151
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-listener-derived-chain.json +0 -112
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-listener-invocation.json +0 -154
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-load-decision.json +0 -155
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-load-operation.json +0 -108
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-lock-requeued.json +0 -108
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-logical-dependency-expansion.json +0 -129
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-merge-decision.json +0 -174
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-primary-node-result.json +0 -318
- package/content/knowledge/update/diagnostic/observability/lookups/analysis-update-ready-recovery.json +0 -92
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-business-attempt.json +0 -33
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-capacity-cycle.json +0 -31
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-child-release.json +0 -32
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-commit-publication.json +0 -29
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-control-planning.json +0 -30
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-engine-task.json +0 -27
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-listener-callback.json +0 -27
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-load-operation.json +0 -27
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-lock-cycle.json +0 -31
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-main-queue-wait.json +0 -32
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-merge-evaluation.json +0 -29
- package/content/knowledge/update/diagnostic/observability/performance-segments/analysis-update-segment-parent-dependency-wait.json +0 -31
- package/content/knowledge/update/diagnostic/observability-index.json +0 -558
- package/content/knowledge/update/diagnostic/recipe-index.json +0 -85
- package/content/knowledge/update/diagnostic/recipes/dag-chain.json +0 -676
- package/content/knowledge/update/diagnostic/recipes/performance-window.json +0 -1128
- package/content/knowledge/update/diagnostic/recipes/scene-origin-async-message-or-callback.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/scene-origin-derived-update-chain.json +0 -510
- package/content/knowledge/update/diagnostic/recipes/scene-origin-direct-service-call.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/scene-origin-http.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/scene-origin-internal-event.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/scene-origin-job.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/scene-origin-recovery-or-migration.json +0 -438
- package/content/knowledge/update/diagnostic/recipes/table-history.json +0 -508
- package/content/knowledge/update/diagnostic/recipes/table-in-chain.json +0 -595
- package/content/knowledge/update/diagnostic/scene-index.json +0 -252
- package/content/knowledge/update/diagnostic/scenes/active.json +0 -47
- package/content/knowledge/update/diagnostic/scenes/add.json +0 -140
- package/content/knowledge/update/diagnostic/scenes/agent.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/archive.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/auth-change.json +0 -116
- package/content/knowledge/update/diagnostic/scenes/call-back.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/case-install.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/case-replace.json +0 -7
- package/content/knowledge/update/diagnostic/scenes/cdc-schedule.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/compute-model.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/copy-data.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/corp-linked.json +0 -7
- package/content/knowledge/update/diagnostic/scenes/corp-member-add.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/corp-member-del.json +0 -7
- package/content/knowledge/update/diagnostic/scenes/corp-member-modify.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/corp-member-sync.json +0 -152
- package/content/knowledge/update/diagnostic/scenes/corp-setting-member-rename.json +0 -152
- package/content/knowledge/update/diagnostic/scenes/corp-setting.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/cross-project-allow.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/default.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/del.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/dynamic-time.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/edit.json +0 -92
- package/content/knowledge/update/diagnostic/scenes/excel-append.json +0 -44
- package/content/knowledge/update/diagnostic/scenes/excel-save.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/folder-copy.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/global.json +0 -56
- package/content/knowledge/update/diagnostic/scenes/handover.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/history-handle.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/manual-update.json +0 -44
- package/content/knowledge/update/diagnostic/scenes/migration.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/param-change.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/polars-error.json +0 -32
- package/content/knowledge/update/diagnostic/scenes/preview-exception.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/preview-invalid.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/project-excel-move.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/re-check.json +0 -7
- package/content/knowledge/update/diagnostic/scenes/replace.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/rollback.json +0 -68
- package/content/knowledge/update/diagnostic/scenes/save-as.json +0 -44
- package/content/knowledge/update/diagnostic/scenes/schedu.json +0 -56
- package/content/knowledge/update/diagnostic/scenes/table-move-other-workspace.json +0 -20
- package/content/knowledge/update/diagnostic/scenes/user-holder-to-normal.json +0 -20
- package/content/knowledge/update/observability.md +0 -16
- package/content/knowledge/update/runtime-evidence.md +0 -32
- package/content/scripts/receive_tool_result.py +0 -57
- /package/content/{.agents/skills/setup-signoz-mcp/scripts → scripts}/install_signoz_mcp.ps1 +0 -0
- /package/content/{.agents/skills/setup-signoz-mcp/scripts → scripts}/install_signoz_mcp.py +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# 更新事件:消费、重排队与合并
|
|
2
|
+
|
|
3
|
+
主队列消息被消费,到因租户限流、拿不到锁而重新排队,再到巡检和死信队列的恢复,以及同一节点多次请求的合并。整体流程见[一次更新怎么走完](lifecycle.md),事件之间的关联见[关联边与性能片段](correlations.md)。
|
|
4
|
+
|
|
5
|
+
## 目录
|
|
6
|
+
|
|
7
|
+
- [attempt-consumed](#attempt-consumed)
|
|
8
|
+
- [capacity-deferred](#capacity-deferred)
|
|
9
|
+
- [lock-requeued](#lock-requeued)
|
|
10
|
+
- [ready-recovery](#ready-recovery)
|
|
11
|
+
- [init-recovery](#init-recovery)
|
|
12
|
+
- [dlx-recovery](#dlx-recovery)
|
|
13
|
+
- [merge-decision](#merge-decision)
|
|
14
|
+
|
|
15
|
+
## attempt-consumed
|
|
16
|
+
|
|
17
|
+
主队列每投递一次消息,就是一次“尝试”。消费者先看租户并发额度,拿到额度才继续去加锁、合并、执行。
|
|
18
|
+
|
|
19
|
+
- 计数单位:`execution-attempt`(没有尝试 ID;同一条执行明细被重复投递,就是多次尝试)
|
|
20
|
+
- 队列 span:`node-task-queue receive`
|
|
21
|
+
- span:`update`
|
|
22
|
+
- 属性:`corpId`、`tableId`
|
|
23
|
+
- 日志 signature:`handle nodeTaskId {}, executeId {}`
|
|
24
|
+
- 其他日志:`nodeTaskKey {} has been executed`、`exec fail, nodeTaskId {}, chainId {}, id {},do not callback children node `(ERROR)、`handle msg error`(ERROR)、`send execute info to dlx, nodeTaskId {}, id {}, chainId {}`、`ignore execute info, nodeTaskId {}, executeId {}, chainId {}`(ERROR)
|
|
25
|
+
- 什么时候出现:
|
|
26
|
+
- 每投递一次,先有队列 span `node-task-queue receive`(Consumer),它在发布这条消息的那条 trace 里,例如提交时挂在 `dispatch_submit` 下;这个 span 总带 `corpId` 和 `tableId`。
|
|
27
|
+
- 随后消费者另开一条 trace,根 span 是 `update`(Consumer),用链接(link)指回队列 span,所以执行细节在 `update` 这条 trace 里,要靠链接才能找到。
|
|
28
|
+
- `update` 上的 `corpId`、`tableId`、`dagId` 等属性只有节点真正执行后才写入。没有这些属性的 `update` 多半是只做了限流转发、重新排队或被判定已执行,没有走到执行,不能当作缺数据。
|
|
29
|
+
- `handle nodeTaskId` 在拿到额度之前就打,所以它出现不代表节点真的执行了。
|
|
30
|
+
- 分支(按消费结果):
|
|
31
|
+
- 没有租户额度:转到慢队列([capacity-deferred](#capacity-deferred))。
|
|
32
|
+
- 拿不到节点运行锁:抛重排队异常,消息重新发回主队列([lock-requeued](#lock-requeued))。
|
|
33
|
+
- 同一链、同一节点本轮已执行过(1 小时内的标记):打 `nodeTaskKey {} has been executed`,删除这条明细,不再执行。
|
|
34
|
+
- 引擎主节点不可用(节点失败后的存活检查没通过),或依赖来源(血缘)不可用:打 `send execute info to dlx`,清掉“已执行”标记,消息拒收并进死信队列([dlx-recovery](#dlx-recovery))。
|
|
35
|
+
- 普通业务失败:节点内部消化成 FAIL 结果,不往外抛,所以队列层看不到失败;见[节点主结果](events-outcome.md#primary-node-result)。
|
|
36
|
+
- 其他未预期异常:打 `handle msg error` 和 `ignore execute info`,这条消息被丢弃,没有自动重试。重排队和被丢弃这两种情况,都会在当前的 `update` span 上记录异常并置为 ERROR,所以 `update` 报错不一定是节点业务失败。
|
|
37
|
+
- 不能说明:没有尝试序号,同一明细多次投递只能按时间排序;`corpId`、`tableId` 写在队列 span 上,查询前先确认它们实际落在哪个 span。
|
|
38
|
+
|
|
39
|
+
## capacity-deferred
|
|
40
|
+
|
|
41
|
+
租户的并发额度用完后,这条消息转到慢队列等待,不在主队列里执行。
|
|
42
|
+
|
|
43
|
+
- 计数单位:`requeue`
|
|
44
|
+
- 队列 span:`slow-node-task-queue receive`
|
|
45
|
+
- span:无
|
|
46
|
+
- 属性:无
|
|
47
|
+
- 日志 signature:`Tenant limit exceeded: tenant {}, nodeTaskId {}, executeId {}`
|
|
48
|
+
- 其他日志:`receive executeInfo at slow queue, nodeTaskId = {}, executeId = {}, chainId = {}`、`reject because of shutdownSignalException`(ERROR)、`sth other error happened, msg = {}`(ERROR)
|
|
49
|
+
- 什么时候出现:
|
|
50
|
+
- 只有配置了租户并发上限(大于 0)才会限流;没有配置时所有消息都有额度,不会出现这类日志。
|
|
51
|
+
- 超限时先把消息发到慢队列,再打 `Tenant limit exceeded`。
|
|
52
|
+
- 租户额度按租约发放,默认 20 秒、每 10 秒续约,持有额度的消费者异常退出后额度自动回收。
|
|
53
|
+
- 慢队列只有一个消费者,每收到一条打 `receive executeInfo at slow queue`;额度可用就发回主队列,仍不可用就再发回慢队列,如此循环,所以一条消息在慢队列里可能出现很多次。
|
|
54
|
+
- 慢队列消费不开 `update` trace,也没有 `corpId`、`tableId`。
|
|
55
|
+
- 分支:收到关闭信号时把消息重新发回慢队列;其他异常只记 ERROR,不重发。
|
|
56
|
+
- 不能说明:慢队列每转一圈是一次重排队,不是一次执行尝试;日志条数多只说明等得久,不说明有多少个不同节点。
|
|
57
|
+
|
|
58
|
+
## lock-requeued
|
|
59
|
+
|
|
60
|
+
同一个节点同一时间只能被一个消费者处理;等锁超时的消息被重新发回主队列。
|
|
61
|
+
|
|
62
|
+
- 计数单位:`requeue`
|
|
63
|
+
- span:无
|
|
64
|
+
- 属性:无
|
|
65
|
+
- 日志 signature:`resend execute info, nodeTaskId {}, id {}, chainId {}`
|
|
66
|
+
- 其他日志:`handle msg error`(ERROR,紧挨着出现)
|
|
67
|
+
- 什么时候出现:
|
|
68
|
+
- 节点运行锁等待超过 30 秒(默认,配置项 `waitTime`)、或节点的“计算来源”被别人占着、或拿锁后发现计算来源变了,都会走这里。
|
|
69
|
+
- 重新发回主队列后,之后的投递是新的一次尝试。
|
|
70
|
+
- 不能说明:`update` 上的 `requeue` 属性不由这个分支设置,现行路径里基本恒为 `false`,不能用它判断是否发生过重排队;没有重排队序号,只能按明细 ID 加时间排。
|
|
71
|
+
|
|
72
|
+
## ready-recovery
|
|
73
|
+
|
|
74
|
+
根节点明细落库后消息没发出去(发布失败或进程在发布前退出),由定时巡检补发。
|
|
75
|
+
|
|
76
|
+
- 计数单位:`requeue`
|
|
77
|
+
- span:无
|
|
78
|
+
- 属性:无
|
|
79
|
+
- 日志 signature:`[inspect ready] send nodeTaskId {} , executeId {}`
|
|
80
|
+
- 其他日志:`find ready execute size {}`、`[inspect ready] error`(ERROR)
|
|
81
|
+
- 什么时候出现:
|
|
82
|
+
- 服务启动时跑一次,之后每 30 分钟跑一次(固定间隔);每次先打 `find ready execute size N`,N 为 0 说明没有需要补发的明细(巡检日志没有 trace)。
|
|
83
|
+
- 只处理“就绪且待发送”的明细(根节点落库时的状态);找到后加锁、补发、把标记改成已发送。
|
|
84
|
+
- 分支:检查时明细已变化或消失,就跳过。
|
|
85
|
+
- 不能说明:只覆盖根节点;子节点创建时就是“已发送”,发布失败后不会被这个巡检补上。没有补发 ID,也没有 broker 确认。
|
|
86
|
+
|
|
87
|
+
## init-recovery
|
|
88
|
+
|
|
89
|
+
子节点自己的父表都完成了,但还在等其他链合并,这类明细状态是“等待”(INIT);巡检会重新判断并放行。
|
|
90
|
+
|
|
91
|
+
- 计数单位:`requeue`
|
|
92
|
+
- span:无
|
|
93
|
+
- 属性:无
|
|
94
|
+
- 日志 signature:`send nodeTaskId {} , executeId {}`
|
|
95
|
+
- 其他日志:`find init execute size {}`、`inspectInit error`(ERROR)
|
|
96
|
+
- 什么时候出现:
|
|
97
|
+
- 只在服务启动时跑一次,且只处理“昨天 0 点到今天 0 点之间”创建的等待明细;跑完之后不会定时重复。
|
|
98
|
+
- 重新判断为就绪才补发,补发时打 `send nodeTaskId ...`,和提交后的正常发布日志是同一个模板。
|
|
99
|
+
- 分支:父表仍有未完成的,明细保持等待,等下一次启动或其他链的释放。
|
|
100
|
+
- 不能说明:同一个日志模板既可能是正常发布,也可能是等待恢复,必须结合前后事件区分;今天创建的等待明细在今天内不会被巡检捞起。
|
|
101
|
+
|
|
102
|
+
## dlx-recovery
|
|
103
|
+
|
|
104
|
+
引擎、依赖来源不可用时,消息被拒收进死信队列;死信队列的消费者等条件恢复后再发回主队列。
|
|
105
|
+
|
|
106
|
+
- 计数单位:`requeue`
|
|
107
|
+
- 队列 span:`node-task-queue_dlx_queue receive`
|
|
108
|
+
- span:无
|
|
109
|
+
- 属性:无
|
|
110
|
+
- 日志 signature:`receive msg at dlx queue, msgId = {}`、`send execute info to fast, msgId = {}`
|
|
111
|
+
- 什么时候出现:
|
|
112
|
+
- 死信队列只有一个消费者;每收到一条先检查执行条件,不满足就每分钟重试一次、没有次数上限;满足后发回主队列。
|
|
113
|
+
- 它会开自己的 `update` trace,没有节点执行属性。
|
|
114
|
+
- 队列名带死信后缀;在配置了队列前缀的环境里 span 名也会带前缀。
|
|
115
|
+
- 分支:检查或重发出错,只记 ERROR,这条消息不会再被处理。
|
|
116
|
+
- 不能说明:`msgId` 就是执行明细 ID,不是死信的重试序号;只在基础设施不可用时才走这里,普通业务失败不会进死信队列。
|
|
117
|
+
|
|
118
|
+
## merge-decision
|
|
119
|
+
|
|
120
|
+
同一节点在不同请求里重复提交时,只执行一次,把几条明细合并成一个任务。
|
|
121
|
+
|
|
122
|
+
- 计数单位:`merge-decision`
|
|
123
|
+
- span:无
|
|
124
|
+
- 属性:`merge_count`、`merge_round_count`、`wait_merge_time`
|
|
125
|
+
- 日志 signature:`merge isolationMode {}, executeId {} nodeTaskId: {}, merge mergeExecuteIds {} chainIds {}`
|
|
126
|
+
- 其他日志:`nodeTaskId {}, merge chainIds {}`、`nodeTaskId {}, id {}, already merged by other task`
|
|
127
|
+
- 什么时候出现:
|
|
128
|
+
- 拿到节点运行锁、没有被转发或重排队之后,每次都要做一次合并判断,打 `merge isolationMode ...`。日志里的 `mergeExecuteIds`、`chainIds` 是这次合并的成员。
|
|
129
|
+
- 场景允许合并(`ALLOW_MERGE`,或在动态配置里放开),才会把同节点其他明细一并纳入;否则只处理自己这一条。
|
|
130
|
+
- 合并了不止一个明细时,才会打 `nodeTaskId {}, merge chainIds {}`,并在 `update` span 上写 `merge_count`(合并的链数)、`merge_round_count`(合并轮次)、`wait_merge_time`(最早成员等待的毫秒数;只有跨链合并才大于 0)。
|
|
131
|
+
- 绝大多数 `update` 没有 `merge_count`:只有真正合并了多条明细的才会有。
|
|
132
|
+
- 分支:
|
|
133
|
+
- 这条明细已被其他任务合并执行:打 `already merged by other task`,这次不执行节点,成员由执行它们的任务清理。
|
|
134
|
+
- 合并轮次达到上限(默认 5 轮):本来要等其他链的子节点直接放行,不再跨链等待。
|
|
135
|
+
- 跨链合并等待窗口默认 15 分钟:窗口内其他链的祖先还没完成,子节点以“等待”状态保存,之后由就绪投递或[等待恢复](#init-recovery)放行。
|
|
136
|
+
- 不能说明:合并不等于一次请求、一条链或一次物理加载;单成员的合并没有这些属性,不能因为属性缺失就判断没有发生合并判断。
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# 更新事件:受理与入队
|
|
2
|
+
|
|
3
|
+
从业务模块提交更新,到根节点落库、消息发布到队列。整体流程见[一次更新怎么走完](lifecycle.md),事件之间的关联见[关联边与性能片段](correlations.md)。
|
|
4
|
+
|
|
5
|
+
## 目录
|
|
6
|
+
|
|
7
|
+
- [intent-accepted](#intent-accepted)
|
|
8
|
+
- [candidate-root-filter](#candidate-root-filter)
|
|
9
|
+
- [effective-root-selection](#effective-root-selection)
|
|
10
|
+
- [logical-dependency-expansion](#logical-dependency-expansion)
|
|
11
|
+
- [execution-frontier-persisted](#execution-frontier-persisted)
|
|
12
|
+
- [after-commit-delivery](#after-commit-delivery)
|
|
13
|
+
|
|
14
|
+
## intent-accepted
|
|
15
|
+
|
|
16
|
+
受理一次更新请求:业务模块带着一批候选表和更新场景(`updateScene`)调用调度入口,调度生成一条更新链并返回链 ID(即 `dagId`)。
|
|
17
|
+
|
|
18
|
+
- 计数单位:`update-request`(没有请求 ID;受理后生成的 `dagId` 标识这条链)
|
|
19
|
+
- span:`dispatch_submit`
|
|
20
|
+
- 属性:`dagId`、`totalSize`、`updateScene`
|
|
21
|
+
- 日志 signature:`dispatch receive request, chainId {}, root size {},`、`submit root task success, chain {} root size {}, cost {}`
|
|
22
|
+
- 其他日志:`dispatch request rootIds is empty`(WARN)、`transaction is active `(WARN,带堆栈)
|
|
23
|
+
- 什么时候出现:
|
|
24
|
+
- 受理日志在候选不为空时先打;`dispatch_submit` 的三个属性和“success”日志只在提交流程正常走完后才有。
|
|
25
|
+
- `totalSize` 是这条链涉及的表总数:请求的根表加上它们的全部下游。
|
|
26
|
+
- `cost` 是提交流程本身的耗时(毫秒),不含后续排队和执行。
|
|
27
|
+
- 分支:
|
|
28
|
+
- 候选为空:只打 `dispatch request rootIds is empty`,不生成明细,也不会有 `dispatch_submit`;调用方仍拿到一个链 ID。
|
|
29
|
+
- 提交时外层已有数据库事务:打 `transaction is active ` 警告,说明业务方把提交包进了事务(不符合规范,会影响消息发布时机)。
|
|
30
|
+
- 提交中途失败:没有 `dagId` / `totalSize` 属性,也没有“success”日志。
|
|
31
|
+
- 真实 trace 里的样子:`dispatch_submit` 下面挂着 `dispatch_get_descendants`(查全部下游)、每个监听器一个 `trigger_listener_<名称>`(`onStart`,各一次);队列消费 span `node-task-queue receive` 也挂在它下面。
|
|
32
|
+
- 不能说明:请求里有多少表真的会被更新(后面还有过滤和合并);没有请求 ID,不能仅凭 `dagId` 还原“是谁在什么时候发起的”。
|
|
33
|
+
|
|
34
|
+
## candidate-root-filter
|
|
35
|
+
|
|
36
|
+
入口先过滤候选表:不需要更新的表、库里已经不存在的表直接丢掉。
|
|
37
|
+
|
|
38
|
+
- 计数单位:`candidate-root`
|
|
39
|
+
- span:无
|
|
40
|
+
- 属性:无
|
|
41
|
+
- 日志 signature:`table don't need update, tableId = {}, tenantId = {}`、`table is not exist in db, can't update, tableId = {}, tenantId = {}`
|
|
42
|
+
- 什么时候出现:只有走公共入口过滤的调用才会过滤;被保留的候选没有日志,所以日志条数不是候选数。
|
|
43
|
+
- 分支:判断“是否需要更新”本身出错时,保守地当作需要更新,继续调度。
|
|
44
|
+
- 不能说明:日志里的 `tableId`、`tenantId` 只是占位参数,表和租户相同不代表属于同一次请求。
|
|
45
|
+
|
|
46
|
+
## effective-root-selection
|
|
47
|
+
|
|
48
|
+
从候选表里挑出真正的根:如果某张候选表的祖先也在候选里,它就不是根,由祖先更新完成后再释放。
|
|
49
|
+
|
|
50
|
+
- 计数单位:`effective-root`
|
|
51
|
+
- span:`dispatch_gen_roots`
|
|
52
|
+
- 属性:无
|
|
53
|
+
- 日志 signature:无
|
|
54
|
+
- 其他日志:`no root task, check lineage {} `(ERROR)
|
|
55
|
+
- 什么时候出现:
|
|
56
|
+
- 候选加上共享计算来源后只有一张表时,直接把它当根,不产生 `dispatch_gen_roots`;所以 `dispatch_submit` 的次数比这个 span 多。
|
|
57
|
+
- 有多张表时,`dispatch_gen_roots` 内部会调用一次批量祖先查询(`dispatch_get_ancestors_batch`)。
|
|
58
|
+
- 分支:候选非空却没有选出根(血缘异常)时,打 ERROR 日志,退回“全部候选都当根”,提交继续。
|
|
59
|
+
- 不能说明:span 不带候选表和根表的 ID,不能用它数根的个数;选根也不保证这些表最终都会执行。
|
|
60
|
+
|
|
61
|
+
## logical-dependency-expansion
|
|
62
|
+
|
|
63
|
+
查依赖:向上查祖先(用来判断父表是否已完成)、向下查子孙(用来算 `totalSize` 和释放子节点)。
|
|
64
|
+
|
|
65
|
+
- 计数单位:`logical-dag-edge`
|
|
66
|
+
- span:`dispatch_get_ancestors`、`dispatch_get_ancestors_batch`、`dispatch_get_descendants`
|
|
67
|
+
- 属性:无
|
|
68
|
+
- 日志 signature:`getAncestors error {}`、`getDescendants error {}`
|
|
69
|
+
- 什么时候出现:每次向依赖来源(血缘)发起查询就产生一个对应 span。提交时查子孙(`dispatch_get_descendants`),选根和释放子节点时批量查祖先(`dispatch_get_ancestors_batch`);单表祖先查询(`dispatch_get_ancestors`)只在 INIT 巡检里用到,平时几乎看不到。
|
|
70
|
+
- 分支:依赖来源不可用时打 ERROR 日志并按“依赖不可用”处理,当前阶段未知,消息可能转入死信队列恢复(见 [dlx-recovery](events-execution.md#dlx-recovery))。
|
|
71
|
+
- 不能说明:span 不带父子表对、链范围或结果数量;血缘是每次现查的,不是历史快照,不能用现在的血缘还原当时的依赖。
|
|
72
|
+
|
|
73
|
+
## execution-frontier-persisted
|
|
74
|
+
|
|
75
|
+
根节点的执行明细落库。明细是“待执行的节点”的临时记录:执行完进入下一步后会被删除,不是历史台账。
|
|
76
|
+
|
|
77
|
+
- 计数单位:`execution-detail`
|
|
78
|
+
- span:无
|
|
79
|
+
- 属性:无
|
|
80
|
+
- 日志 signature:无
|
|
81
|
+
- 什么时候出现:没有专门的信号标记“明细已写入”;`dispatch_submit` 覆盖了落库、监听器启动和发布调度,空根列表时也会出现,不能当作落库证明。
|
|
82
|
+
- 分支:明细事务失败,则没有明细、也不会发布消息,调用方可以稍后重新提交。
|
|
83
|
+
- 不能说明:明细表里的状态只是当前进度,不能当作更新历史。
|
|
84
|
+
|
|
85
|
+
## after-commit-delivery
|
|
86
|
+
|
|
87
|
+
明细提交成功后,把消息发布到主队列。
|
|
88
|
+
|
|
89
|
+
- 计数单位:`queue-publication`
|
|
90
|
+
- span:无
|
|
91
|
+
- 属性:无
|
|
92
|
+
- 日志 signature:`send nodeTaskId {} , executeId {}`
|
|
93
|
+
- 什么时候出现:
|
|
94
|
+
- 外层有事务时,发布动作等事务提交后再执行;没有事务就立即执行。
|
|
95
|
+
- 发布后,如果这条明细在落库时标记为“待发送”(`PENDING_SENT`),会把标记更新为“已发送”(`SENT`)。
|
|
96
|
+
- 每发布一条消息打一行日志。
|
|
97
|
+
- 分支:
|
|
98
|
+
- 发布线程池拒绝、发布失败:打 ERROR 日志(`[DispatchAfterCommitSubmitExecutor] submit rejected` / `submit failed`、`[DispatchAfterCommitAction] after commit action failed`),根节点仍是“待发送”,由 [ready-recovery](events-execution.md#ready-recovery) 补发。
|
|
99
|
+
- 发布成功但更新“已发送”标记失败:消息可能已投递而明细仍是“待发送”,之后可能重复补发,靠消费端去重。
|
|
100
|
+
- 子节点发布失败:子节点创建时就是“已发送”,补发巡检不会再管它,当前没有对应的自动补发路径。
|
|
101
|
+
- 不能说明:日志只说明“发布调用返回了”,不代表消息被 broker 确认或被消费;发布次数不是尝试次数,补发和重复投递都会增加它。
|
|
102
|
+
- 同一行日志模板还会出现在 [init-recovery](events-execution.md#init-recovery) 里,不能只靠文本区分两者,要结合前后事件。
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# 更新事件:load、引擎与结果
|
|
2
|
+
|
|
3
|
+
节点真正执行时的几个环节:决定要不要加载数据、提交给引擎写入、得出节点结果、通知监听器,再释放下游子节点。整体流程见[一次更新怎么走完](lifecycle.md),事件之间的关联见[关联边与性能片段](correlations.md)。
|
|
4
|
+
|
|
5
|
+
## 目录
|
|
6
|
+
|
|
7
|
+
- [load-decision](#load-decision)
|
|
8
|
+
- [load-operation](#load-operation)
|
|
9
|
+
- [result-publish](#result-publish)
|
|
10
|
+
- [engine-handoff](#engine-handoff)
|
|
11
|
+
- [primary-node-result](#primary-node-result)
|
|
12
|
+
- [listener-invocation](#listener-invocation)
|
|
13
|
+
- [child-release](#child-release)
|
|
14
|
+
- [listener-derived-chain](#listener-derived-chain)
|
|
15
|
+
|
|
16
|
+
## load-decision
|
|
17
|
+
|
|
18
|
+
节点执行时先决定这次要不要真的把数据写进引擎:失败、直通、跳过、复用已有结果、不需要加载,或者调用加载。
|
|
19
|
+
|
|
20
|
+
- 计数单位:`load-decision`
|
|
21
|
+
- span:无
|
|
22
|
+
- 属性:`active`、`loadData`、`execution.mode`、`loadDataSkipReason`、`skip`、`dataModify`
|
|
23
|
+
- 日志 signature:无
|
|
24
|
+
- 什么时候出现:这些属性在节点执行结束时统一写到 `update` span 上,是“结果”,不是决定发生时的实时信号。
|
|
25
|
+
- `execution.mode`:这次结果怎么落。`WRITE` 是自己算并写进引擎,包括引用失败后回退来写;`REF` 是不写数据、直接指向已有结果,见 [result-publish](#result-publish);空字符串是进了准备、但没走到这一步(主动不加载、不需要加载或之前就失败);没有这个属性是连准备都没进。
|
|
26
|
+
- `loadData`:是否完成加载或结果复用。`true` 包括实际写入、引用成功和数据未变而跳过写入;`false` 表示不加载或执行失败,不代表没有发起引擎写入。
|
|
27
|
+
- `loadDataSkipReason`:主动不加载的原因,只在 `loadData=false` 且有明确原因时出现。`INACTIVE` 表不活跃,`ASSET_AUTH_UNCHANGED` 资产权限没变化,`PASS_THROUGH` 直通表,`MIGRATION_TARGET_ABSENT`、`MIGRATION_SOURCE_SCHEMA_ABSENT`、`MIGRATION_SOURCE_TABLE_ABSENT` 是迁移场景里目标或来源不存在。
|
|
28
|
+
- `skip`:引擎写入时发现数据没变,没有真的写,对应日志 `reason: skip write (parent data unchanged)`。REF 时总是 `false`。
|
|
29
|
+
- `dataModify`:`1` 变了,`0` 没变,`-1` 无法判断。主动不加载记 `0`;REF 时读的位置或版本换了记 `1`,没换又缺少变化依据记 `-1`。
|
|
30
|
+
- `active`:这张表当前是不是活跃表。
|
|
31
|
+
- 读法:`loadData=false` 时,先看 `loadDataSkipReason`;没有原因时,结合错误和加载日志区分不需要加载与执行失败,不能据此判断失败阶段。实际写入结合 `execution.mode`、`skip` 和写入统计判断;REF 的 `dataModify=1` 只说明换了读的版本。
|
|
32
|
+
- 分支:
|
|
33
|
+
- 同一合并链里有父节点失败:当前节点直接判失败,不加载,见 [primary-node-result](#primary-node-result)。
|
|
34
|
+
- 语法检查或加载前校验失败:记业务失败,不加载。
|
|
35
|
+
- 直通、不活跃、权限没变、复用已有结果、物理上已可用:可能成功,但没有写入,也没有引擎任务。
|
|
36
|
+
- 不能说明:`loadData=true` 不代表写了新数据,要看 `execution.mode`、`skip` 和 `dataModify`。
|
|
37
|
+
|
|
38
|
+
## load-operation
|
|
39
|
+
|
|
40
|
+
决定要加载之后,调用对应表类型的加载逻辑,把数据写进引擎。这一步有稳定的“开始/结束”日志,可以用来圈定一次加载。
|
|
41
|
+
|
|
42
|
+
- 计数单位:`load-operation`
|
|
43
|
+
- span:无
|
|
44
|
+
- 属性:`execution.mode`
|
|
45
|
+
- 日志 signature:`table load start`、`table load success`、`table load fail`
|
|
46
|
+
- 其他日志:`Full Load:id = {}, transferName = {}, executionMode={}, computeFromTableId={}`
|
|
47
|
+
- 什么时候出现:
|
|
48
|
+
- 加载日志是一块多行文本,标题行形如 `*************** table load start ***************`,后面依次是 `table:`(节点表 ID,和 `exec nodeTaskId` 里的一致)、`tenantId:`、`transferName:`,成功时还有 `cost: N ms`。这条日志带 `trace_id` 和 `span_id`,`span_id` 就是 `dispatch_node_task_exec`,可以直接对回执行 trace。
|
|
49
|
+
- 正常加载:先 `table load start`,结束时 `table load success` 并带 `cost`(毫秒,即这次加载耗时)。
|
|
50
|
+
- 失败:节点失败时打 `table load fail`,没有 `cost`。
|
|
51
|
+
- 成功日志也会出现在没有物理写入的情况,靠 `cost:` 或 `reason:` 那一行区分:`cost: don't need update polars` 表示不需要更新引擎;`cost: don't active` 表示表不活跃;`reason: skip write (parent data unchanged)` 表示父表数据没变、跳过写入;`reason: skip write (SHARED_RESULT)` 表示数据门户复制的表复用来源结果(见 [result-publish](#result-publish)),其他 REF 打的是普通的 `cost: N ms`;同时给出 `computeFromTableId`、`engineId`、`schema`、`version`。
|
|
52
|
+
- `Full Load:id = ...` 在判断是否需要加载之前就打了,带 `executionMode` 和 `computeFromTableId`,不能单独当作物理加载的证明。
|
|
53
|
+
- 分支:
|
|
54
|
+
- 加载失败:节点得到 FAIL 结果;如果失败属于“引擎主节点或依赖来源不可用”,则走死信队列而不是节点失败,见 [attempt-consumed](events-execution.md#attempt-consumed)。
|
|
55
|
+
- 不能说明:`table load success` 不等于有数据写入,要同时看 `cost:` / `reason:` 行和 `execution.mode`;`update.load_data` 这类汇总指标没有表、链、尝试标识,圈不出某一次加载。关系(relation)加载另有 `relation load start/success/fail` 日志,和这里不是同一类。
|
|
56
|
+
|
|
57
|
+
## result-publish
|
|
58
|
+
|
|
59
|
+
REF 不写数据,而是选定来源的一个版本,给它打保护 tag,再把本表的读取位置提交过去;提交成功后释放旧版本的 tag,旧物理表没人读了才删。WRITE 后读取位置变了(比如从引用改回自己算)也走这里的提交和释放。
|
|
60
|
+
|
|
61
|
+
- 计数单位:`result-publish`
|
|
62
|
+
- span:`result.binding.commit`、`result.snapshot.retain_selected`、`result.snapshot.tag.<操作>`、`result.snapshot.release`、`result.snapshot.discard_unused`
|
|
63
|
+
- 属性:`result.binding.committed`、`result.writer.table_id`、`result.tag.name`(都在上面这些结果 span 上,`update` span 上没有)
|
|
64
|
+
- 日志 signature:`[ResultBinding] event=COMMIT_RESULT committed={}`、`[ResultBinding] event=COMMIT_REJECTED reason=SOURCE_CHANGED`、`[Snapshot tag {}]`、`[ResultRetention] event=RELEASE_REQUESTED`、`[ResultRetention] event=RELEASED`、`[ResultRetention] event=ORPHAN_CLEANUP_REQUESTED`
|
|
65
|
+
- 其他日志:`[ResultBinding] event=WRITE_DECISION`、`[ResultRetention] event=COPIED`
|
|
66
|
+
- 什么时候出现:日志都带 `trace_id`,按本表 ID、物理表 ID、版本号或 tag 名搜。
|
|
67
|
+
- 走 REF 的表:只选了上游字段(最多改名)、没有其他步骤的分析表,原样引用上游结果,配置 `update.materialization.always-materialize=true` 时改为照常写入;数据门户复制出的表和来源共享计算,直接复用来源结果,加载日志是 `reason: skip write (SHARED_RESULT)`,共享失效后按自己的配置重算;镜像表和企业数据表指向来源结果;云 JDBC 数据源的隐藏表直接引用同步下来的数据。
|
|
68
|
+
- tag:湖存储的结果按 `reference-<本表ID>-<版本号>` 打 tag,一张引用表的一个版本一个,防止这个版本被引擎回收。`[Snapshot tag ...]` 记请求和成功或失败;失败那条是 WARN,引擎可能已经执行,tag 状态不确定。NAS 存储没有 tag,改为复制一份副本(`event=COPIED`)。
|
|
69
|
+
- 提交:`COMMIT_RESULT committed=true` 是本表读取位置真的换了,日志里有前后绑定;`committed=false` 或 `COMMIT_REJECTED reason=SOURCE_CHANGED` 是加载期间来源或本表变了、拒绝提交,不是引擎故障,本表继续读旧版本。
|
|
70
|
+
- 释放:`RELEASE_REQUESTED` 带原因,常见的是 `RESULT_COMMITTED`(提交成功,释放旧版本)和 `BINDING_UNCOMMITTED`(没提交成功,释放这次新打的 tag),另有 `TABLE_DELETED` 等。`RELEASED` 是 tag 已删,`ORPHAN_CLEANUP_REQUESTED` 是旧物理表已发起删除,都不代表引擎已回收快照。
|
|
71
|
+
- 统计:REF 不在本节点计算,没有本节点的引擎任务,不查 Metric。行数取来源的统计(数据源直引时现数一次);峰值内存在原样引用和数据源直引时记 0,门户共享时继承来源。
|
|
72
|
+
- 分支:
|
|
73
|
+
- 选定版本已不存在:最多重选 3 次;仍不行、且来源还是最初的最新版本时,回退照常写入(`execution.mode` 变成 `WRITE`)。来源已变、校验失败或其他引擎错误不回退,节点失败,旧绑定和旧 tag 保留。
|
|
74
|
+
- 不能说明:tag 成功不等于本表已切换,要看 `COMMIT_RESULT committed=true`;`RELEASED` 不等于快照已被回收。同一 trace 里的这些日志可能来自 DAG 里的多张表,按 tableId 对。
|
|
75
|
+
|
|
76
|
+
## engine-handoff
|
|
77
|
+
|
|
78
|
+
写入走 Polars 引擎时,服务端把写任务交给引擎事务,提交后拿回写入结果。
|
|
79
|
+
|
|
80
|
+
- 计数单位:`engine-task`
|
|
81
|
+
- span:`DataFlowExecutor`、`execute`
|
|
82
|
+
- 属性:`write_metric`、`metric`、`polarsNode`、`compute.retry.pipeline_parallelism_reduced`
|
|
83
|
+
- 日志 signature:`table {} load fail!`、`table {} load success.`
|
|
84
|
+
- 什么时候出现:
|
|
85
|
+
- `DataFlowExecutor` 是 `dispatch_node_task_exec` 的子 span,`execute` 是它的子 span;`execute` 这个名字在别处也有,要看它的父 span 是不是 `DataFlowExecutor` 才算引擎写入。
|
|
86
|
+
- 写入完成后,`write_metric` 记录引擎返回的写入统计;`polarsNode` 记录执行的引擎节点名。
|
|
87
|
+
- 结果里的 `taskId` 会写进节点结果埋点。
|
|
88
|
+
- 分支:
|
|
89
|
+
- 可重试的引擎失败:服务端可以重试,每次重试产生新的引擎任务 ID,成功结果只暴露最后返回的那个。
|
|
90
|
+
- 数据源湖(MPP)写入遇到引擎任务内存不足:允许重试一次,并把流水线并行度降为 1,同时写 `compute.retry.pipeline_parallelism_reduced`。这只针对这一类写入,不是所有 OOM 的通用重试策略。
|
|
91
|
+
- 引擎写入失败:事务回滚,服务端加载失败;要继续追查,需要具体的引擎任务或请求标识,否则停在服务端边界。
|
|
92
|
+
- 不能说明:直通、不活跃、不需要加载等没有引擎任务;失败或重试过的任务不会都留下标识,引擎内部细节不在这里。
|
|
93
|
+
|
|
94
|
+
## primary-node-result
|
|
95
|
+
|
|
96
|
+
节点执行得出的主结果:成功或失败。这一步之后才会通知监听器、释放子节点。
|
|
97
|
+
|
|
98
|
+
- 计数单位:`node-primary-result`
|
|
99
|
+
- span:`dispatch_node_task_exec`
|
|
100
|
+
- 属性:`dagId`、`tableId`、`tableName`、`userId`、`rowCount`、`updateType`、`requeue`、`active`、`rootErrorId`、`dispatchConsumed`、`businessConsumed`
|
|
101
|
+
- 日志 signature:`finish to exec task, nodeTaskId = {}, chainId = {}, cost = {}ms`、`task exec error, nodeTaskId {}, chainIds {}, {}`
|
|
102
|
+
- 其他日志:`begin to exec task, nodeTaskId = {}, chainId = {}`、`exec nodeTaskId {}, executeIds {}`、`execute task error, msg = {}`(ERROR,带异常堆栈)、`Task is failed by its parent failed, curId {}, fail parent {}, chainId {}`(ERROR)、`exec fail, nodeTaskId {}, chainId {}, id {},do not callback children node `(ERROR)
|
|
103
|
+
- 什么时候出现:
|
|
104
|
+
- `dispatch_node_task_exec` 是节点真正执行的 span,在 `update` 这条 trace 里,里面有语法检查、加载、引擎写入和监听器 span;整次尝试的 `update` 总耗时一般略大于它。
|
|
105
|
+
- 上面列的属性都写在 `update` span 上,而不是 `dispatch_node_task_exec` 上,并且按进度逐步写入:`loadData` 等在完成回调里无条件写;`dagId`、`tableName`、`userId`、`rowCount`、`updateType`、`requeue`、`active`、`rootErrorId` 要先取得这张表的更新配置才写;`dispatchConsumed`、`businessConsumed` 要走到成功或失败回调才写。节点在准备阶段就失败(例如表已失效)时,`update` 上只有 `loadData`。各属性含义:`updateType` 是更新场景名(如 `ACTIVE`、`SCHEDU`),`rowCount` 成功时是行数、失败时是 -1,`dispatchConsumed` 是整个消费线程的耗时、`businessConsumed` 是节点业务执行的耗时(毫秒),`rootErrorId` 只在失败时有,是导致失败的根表。
|
|
106
|
+
- 执行入口先打 `exec nodeTaskId ... executeIds [...]`(`executeIds` 是被合并的所有明细),再打 `begin to exec task`,成功后打 `finish to exec task`(`cost` 是节点耗时,毫秒)。
|
|
107
|
+
- 失败时打两条 ERROR:一条 `execute task error, msg = ...` 带堆栈(SigNoZ 里有 `exception.type`、`exception.message`、`exception.stacktrace`),一条 `task exec error, ...` 只有摘要。
|
|
108
|
+
- 节点结果还会生成一条 XS03 埋点,字段包括 `dagId`、`tableId`、`status`、`rows`、`actualWrite`、`dataModify`、`errorMsg`、`requeue`、`triggerId`、`tenantId`、`dispatchConsumed`、`businessConsumed`、`polarsConsumed`。埋点是否能在 SigNoZ 里查到没有核实,不要当作首查依据。
|
|
109
|
+
- 分支:
|
|
110
|
+
- 父节点(同一合并链内)失败:当前节点直接失败,打 `Task is failed by its parent failed`,并把根因表写进 `rootErrorId`。
|
|
111
|
+
- 普通业务失败:转成 FAIL 结果,不再往队列层抛,所以消费者看不到异常。
|
|
112
|
+
- 停止工作(引擎主节点不可用):不当作节点结果,异常继续向上抛,消息进死信队列;这种情况没有 XS03 埋点。
|
|
113
|
+
- 不能说明:节点成功不代表整条链完成、数据真的变化、监听器成功或有引擎任务;`status` 只区分成功和失败,监听器结果另算。
|
|
114
|
+
|
|
115
|
+
## listener-invocation
|
|
116
|
+
|
|
117
|
+
节点结果之后,按固定顺序依次触发一组监听器,各自处理自己的后续工作(刷新配置、推送状态、触发工作流、写指标等)。
|
|
118
|
+
|
|
119
|
+
- 计数单位:`listener-invocation`
|
|
120
|
+
- span:`trigger_listener_<监听器名>`
|
|
121
|
+
- 属性:无
|
|
122
|
+
- 日志 signature:无
|
|
123
|
+
- 什么时候出现:
|
|
124
|
+
- 每次触发一个监听器就产生一个 `trigger_listener_<名称>` span,例如 `trigger_listener_UPDATE_METRIC`、`trigger_listener_WORK_FLOW`、`trigger_listener_CORP_SETTING`。
|
|
125
|
+
- 一次更新链的提交(`dispatch_submit`)里每个监听器各触发一次(开始),一个被执行的节点里每个监听器各触发三次(执行前、成功或失败、完成)。所以一个节点的 `update` trace 里同名监听器 span 通常有 3 个。
|
|
126
|
+
- 默认的 9 个监听器:`ANALYSIS_CONF_SYNCHRONIZED`、`COMPUTE_TABLE_FIELD_RENAME`、`COMPUTE_RED_MARK`、`CUSTOM_TABLE_STATUS_EVENT`(或 `TASK_STATUS_EVENT`)、`CORP_SETTING`、`UPDATE_WEB_SOCKET_SEND`、`WORK_FLOW`、`UPDATE_METRIC`、`ANALYSIS_CONFIG_ROUNDTRIP_CHECK`。副本、迁移等场景用不同的组合,所以不是每条链都有全部监听器。
|
|
127
|
+
- span 名只带监听器名,不带是“开始/执行前/成功/失败/完成”哪个阶段,要靠时间顺序和父 span 区分。
|
|
128
|
+
- 分支:
|
|
129
|
+
- 某个监听器抛异常:记 ERROR 日志,继续下一个监听器,节点主结果不变。
|
|
130
|
+
- `onComplete` 只表示这个节点的回调走完,不是整条链完成。
|
|
131
|
+
- 不能说明:监听器自己的异步工作、应用日志都不在这个 span 里;`WORK_FLOW` 监听器只在满足条件(基础表更新、符合条件的工作流)时才会真正启动工作流,不能因为有 `trigger_listener_WORK_FLOW` 就认为启动了工作流。
|
|
132
|
+
|
|
133
|
+
## child-release
|
|
134
|
+
|
|
135
|
+
节点执行完,把它的下游子节点放出来:删除父节点明细,判断每个子节点能不能执行,保存子节点明细并发布。
|
|
136
|
+
|
|
137
|
+
- 计数单位:`execution-detail`
|
|
138
|
+
- span:`dispatch_callback_children`、`evaluator_child`
|
|
139
|
+
- 属性:无
|
|
140
|
+
- 日志 signature:`dispatch callback children, nodeTaskId {}, executeId {}, chainId {}, children size {},`
|
|
141
|
+
- 其他日志:`exist circle, parent {}, cyclicIds {}`(WARN)、`evaluator error, nodeTaskId {}`(ERROR)、`evaluator error`(ERROR)
|
|
142
|
+
- 什么时候出现:
|
|
143
|
+
- `dispatch_callback_children` 在 `update` trace 里;其中判断子节点是否可执行的步骤是 `evaluator_child`;没有子节点的只删除明细,不做判断,所以 `evaluator_child` 比 `dispatch_callback_children` 少。
|
|
144
|
+
- 日志 `children size` 是这次保存的子节点明细数;它只有数量,没有子节点 ID,也没有发布确认。
|
|
145
|
+
- 子节点的状态:自己的所有祖先都完成了才会保存,并直接就绪;祖先还有没完成的就不保存,等祖先完成时再放。如果允许合并,且还有别的链里的祖先在等,就保存成“等待”(INIT),之后由其他链释放或启动巡检放行(见 [init-recovery](events-execution.md#init-recovery))。
|
|
146
|
+
- 配置里出现父子循环依赖(子节点是自己或父节点)时,打 WARN 并排除这些节点。
|
|
147
|
+
- 分支:
|
|
148
|
+
- 没有子节点:只删除父节点明细,不打 `dispatch callback children` 日志。
|
|
149
|
+
- 子节点事务失败:父节点明细保留,没有更强的自动恢复保证。
|
|
150
|
+
- 判断子节点时出错:记 ERROR 后异常上抛。
|
|
151
|
+
- 不能说明:子节点明细是逐步生成的,不是完整的逻辑依赖图,也不是历史尝试;没有子节点和事务/发布失败要分别解读。
|
|
152
|
+
|
|
153
|
+
## listener-derived-chain
|
|
154
|
+
|
|
155
|
+
监听器处理时主动再提交一批更新,生成新的更新链。目前确认的是企业设置监听器触发的“权限变更”链。
|
|
156
|
+
|
|
157
|
+
- 计数单位:`update-chain`
|
|
158
|
+
- span:无
|
|
159
|
+
- 属性:`authChangeDagId`、`authChangeRootCount`
|
|
160
|
+
- 日志 signature:`update corp success , update {}`
|
|
161
|
+
- 什么时候出现:监听器调用调度入口提交权限变更的更新并拿到新链 ID 之后,把新链 ID 和根数量写到源节点所在的 `update` span 上,并打日志。
|
|
162
|
+
- 分支:派生提交失败,监听器记自己的失败日志,源节点的主结果仍是成功,不自动回滚。
|
|
163
|
+
- 不能说明:派生链的上下文里不保存源链 ID,没有“源链—监听器—派生链”的持久关联,只有这条进程内的调用能证明关系;这只覆盖企业设置监听器,不代表所有监听器。
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# 一次更新怎么走完
|
|
2
|
+
|
|
3
|
+
把分析表更新从“业务模块提交”到“下游全部跑完”的过程串成一条线,标出每一步在 SigNoZ 里留下的 span 和日志。各事件的细节在[受理与入队](events-intake.md)、[消费、重排队与合并](events-execution.md)、[load、引擎与结果](events-outcome.md);事件之间怎么关联见[关联边与性能片段](correlations.md)。
|
|
4
|
+
|
|
5
|
+
## 目录
|
|
6
|
+
|
|
7
|
+
- [先记住的几个概念](#先记住的几个概念)
|
|
8
|
+
- [过程总览](#过程总览)
|
|
9
|
+
- [一次执行的 span 结构](#一次执行的-span-结构)
|
|
10
|
+
|
|
11
|
+
## 先记住的几个概念
|
|
12
|
+
|
|
13
|
+
- **链**:一次受理的更新请求生成一条链,链 ID 就是 `dagId`。链里有若干张表(节点)。
|
|
14
|
+
- **明细**:一个节点在一条链里的待执行记录,写在库里,执行完就删除。明细 ID 就是日志里的 `executeId`(队列消息里叫 `id`、死信日志里叫 `msgId`)。
|
|
15
|
+
- **节点表 ID**:就是日志里的 `nodeTaskId`,和 `update` span 上的 `tableId`、加载日志里的 `table:` 是同一个值。
|
|
16
|
+
- **根节点与子节点**:请求里没有祖先在候选里的表是根,先执行;它们执行完再放出直接下游,一层层往下。
|
|
17
|
+
- **更新场景**:`updateScene`,也叫更新“tag”,见[更新场景表](../concepts.md#更新场景updatescene)。
|
|
18
|
+
|
|
19
|
+
## 过程总览
|
|
20
|
+
|
|
21
|
+
| 步骤 | 发生什么 | SigNoZ 里的信号 | 事件 |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| 1 受理 | 业务模块提交候选表,调度生成链、过滤候选、选根、查下游 | `dispatch_submit`(属性 `dagId`、`totalSize`、`updateScene`),其下有 `dispatch_gen_roots`、`dispatch_get_descendants`;日志 `dispatch receive request` / `submit root task success` | [intent-accepted](events-intake.md#intent-accepted)、[effective-root-selection](events-intake.md#effective-root-selection)、[logical-dependency-expansion](events-intake.md#logical-dependency-expansion) |
|
|
24
|
+
| 2 落库与监听器启动 | 根节点明细写库;各监听器收到“开始” | `dispatch_submit` 下的 `trigger_listener_<名称>` | [execution-frontier-persisted](events-intake.md#execution-frontier-persisted)、[listener-invocation](events-outcome.md#listener-invocation) |
|
|
25
|
+
| 3 发布消息 | 明细提交后,把消息发到主队列 | 日志 `send nodeTaskId ... executeId ...` | [after-commit-delivery](events-intake.md#after-commit-delivery) |
|
|
26
|
+
| 4 消费 | 主队列投递一次,就是一次尝试 | 发布所在 trace 里的 `node-task-queue receive`,另开一条 trace,根 span 是 `update`;日志 `handle nodeTaskId ...` | [attempt-consumed](events-execution.md#attempt-consumed) |
|
|
27
|
+
| 4a 限流 | 租户并发超限,消息转到慢队列,额度够了再回主队列 | 日志 `Tenant limit exceeded`;`slow-node-task-queue receive` | [capacity-deferred](events-execution.md#capacity-deferred) |
|
|
28
|
+
| 4b 拿锁失败 | 同一节点正被别人处理,等锁超时后重新排队 | 日志 `resend execute info` | [lock-requeued](events-execution.md#lock-requeued) |
|
|
29
|
+
| 5 合并 | 把同一节点的多条明细合成一次执行 | 日志 `merge isolationMode ...`;多链合并时 `update` 上有 `merge_count` | [merge-decision](events-execution.md#merge-decision) |
|
|
30
|
+
| 6 执行节点 | 语法检查、决定是否加载、写入引擎 | `dispatch_node_task_exec`,里面有 `grammarCheck`、`DataFlowExecutor` / `execute`;日志 `table load start` / `table load success` | [load-decision](events-outcome.md#load-decision)、[load-operation](events-outcome.md#load-operation)、[engine-handoff](events-outcome.md#engine-handoff) |
|
|
31
|
+
| 7 节点结果 | 得出成功或失败,写 `update` 上的结果属性 | `update` 的 `updateType`、`loadData`、`rowCount`、`dispatchConsumed`、`businessConsumed`;日志 `finish to exec task` / `task exec error` | [primary-node-result](events-outcome.md#primary-node-result) |
|
|
32
|
+
| 8 监听器 | 执行前、成功/失败、完成三次回调 | `dispatch_node_task_exec` 下每个监听器 3 个 `trigger_listener_<名称>` | [listener-invocation](events-outcome.md#listener-invocation) |
|
|
33
|
+
| 9 释放子节点 | 删除本节点明细,判断并保存可执行的子节点,再发布 | `dispatch_callback_children`、`evaluator_child`;日志 `dispatch callback children ... children size` | [child-release](events-outcome.md#child-release) |
|
|
34
|
+
| 回到 3 | 子节点的消息再走 3 至 9,直到没有下游 | 每个子节点各有一条 `update` trace,`linked` 指向放出它的上一个节点所在的 trace | — |
|
|
35
|
+
|
|
36
|
+
没有走到执行的投递(限流转发、拿锁失败、判定已执行、被合并掉)也会各有一个 `update` span,但没有 `updateType`、`rowCount` 这些结果属性。
|
|
37
|
+
|
|
38
|
+
## 一次执行的 span 结构
|
|
39
|
+
|
|
40
|
+
一次真实的节点执行(`update` trace,已脱敏简化):
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
update 根 span,Consumer;linked = 放出它的上游所在 trace
|
|
44
|
+
├─ dispatch_node_task_exec 节点真正执行的区间
|
|
45
|
+
│ ├─ trigger_listener_<名称> × 9 执行前(每个监听器 1 个)
|
|
46
|
+
│ ├─ grammarCheck 语法检查
|
|
47
|
+
│ ├─ DataFlowExecutor 引擎写入(有物理写入时)
|
|
48
|
+
│ │ └─ execute
|
|
49
|
+
│ ├─ trigger_listener_<名称> × 9 成功或失败
|
|
50
|
+
│ └─ trigger_listener_<名称> × 9 完成
|
|
51
|
+
└─ dispatch_callback_children 释放子节点
|
|
52
|
+
└─ evaluator_child 判断子节点可否执行(有子节点时)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
要点:
|
|
56
|
+
|
|
57
|
+
- `dispatch_node_task_exec` 是 `update` 的子 span,监听器、语法检查和引擎写入都挂在它下面;`dispatch_callback_children` 挂在 `update` 下,不在 `dispatch_node_task_exec` 里面。
|
|
58
|
+
- 加载日志(`table load start` / `table load success`)带 `span_id`,等于 `dispatch_node_task_exec` 的 span ID,可以直接对回这个区间。
|