关于 profiling-transaction-fingerprints
面向 CockroachDB 数据库工程师的技能,通过 SQL 分析历史事务统计,定位重试、争用和提交延迟问题。无需访问 DB Console,并可进一步关联事务中的语句指纹。
主要功能
- 01分析历史事务重试与提交延迟
- 02按应用识别事务重试模式
- 03检查事务中的语句组成
- 04关联事务与语句指纹
- 05评估网络、内存和磁盘用量
适用场景
- 01调查事务重试风暴
- 02分析高提交延迟事务
- 03定位导致重试的具体语句
- 04制作应用级事务健康概览
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cockroachlabs/ cockroachdb-skills --skill profiling-transaction-fingerprints安装后在 Claude Code 中输入/profiling-transaction-fingerprints确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/json-field-reference.mdmetrics-and-units.mdsql-query-variations.md详细介绍
事务指纹分析
使用聚合 SQL 统计信息分析历史事务性能模式,以识别高重试事务、争用模式和提交延迟问题。通过 crdb_internal.transaction_statistics 按时间窗口分析重试行为、提交延迟和语句组成——完全使用 SQL,无需访问 DB Console。
与 profiling-statement-fingerprints 互为补充: 此技能分析事务级模式(具有重试行为的一组语句);如需进行语句级优化,请参阅 profiling-statement-fingerprints。
与 triaging-live-sql-activity 互为补充: 此技能分析历史事务模式;如需立即排查当前活动的事务,请参阅 triaging-live-sql-activity。
何时使用此技能
- 识别重试次数较多的事务
- 分析事务指纹的提交延迟趋势
- 查找事务边界处争用严重的事务
- 了解问题事务的语句组成
- 调查事务重试风暴或中止模式
- 无需访问 DB Console,仅使用 SQL 分析历史事务
如需立即响应事件: 使用 triaging-live-sql-activity 排查当前活动的事务,并取消失控的工作。 如需进行语句级优化: 使用 profiling-statement-fingerprints 分析单条查询模式。
前提条件
- 连接到 CockroachDB 集群的 SQL 连接
- 需要
VIEWACTIVITY或VIEWACTIVITYREDACTED集群权限,才能查看整个集群- 权限要求与 profiling-statement-fingerprints 相同
- 了解事务性能相关概念
- 已启用事务统计信息收集(默认):
sql.stats.automatic_collection.enabled = true
检查事务统计信息收集状态:
SHOW CLUSTER SETTING sql.stats.automatic_collection.enabled;
-- Should return: true
有关 RBAC 设置,请参阅 triaging-live-sql-activity 权限参考(所需权限相同)。
核心概念
事务指纹与实时事务
事务指纹: 将带参数化常量的语句分组后得到的规范化事务模式。
主要区别:
- 时间范围: 历史小时级时间桶与实时当前状态
- 粒度: 聚合的重试/提交统计信息与单个事务实例
- 关系: 事务 = 一组语句指纹
时间序列分桶
aggregated_ts: UTC 小时级时间桶(例如,2026-02-21 14:00:00 = 14:00 至 14:59 执行的数据)
数据保留: 受行数限制,而非时间限制。sql.stats.persisted_rows.max(默认值为 1,000,000)限制持久化的语句和事务行数;达到上限后,较旧的时间桶会被压缩。实际的墙钟时间窗口取决于工作负载的多样性。
最佳实践: 始终按时间窗口进行筛选:WHERE aggregated_ts > now() - INTERVAL '24 hours'
聚合指标与采样指标
| 指标类别 | JSON 路径 | 范围 | 用途 |
|---|---|---|---|
| 聚合指标 | statistics.statistics.* | 所有执行 | 重试、提交延迟、执行次数 |
| 采样指标 | statistics.execution_statistics.* | 由 sql.txn_stats.sample_rate 控制的概率采样(默认值为 0.01) | 争用、网络、内存/磁盘 |
重要提示: 采样指标包含显示样本量的 cnt 字段。务必检查:
WHERE (statistics->'execution_statistics'->>'cnt') IS NOT NULL
JSON 字段提取
CockroachDB 将事务元数据和统计信息存储为 JSONB。使用以下运算符:
运算符:
->:提取 JSON 对象/值(返回 JSON)->>:提取为文本(返回文本)::TYPE:转换为指定类型encode(fingerprint_id, 'hex'):将二进制指纹转换为十六进制字符串
事务专用示例:
encode(fingerprint_id, 'hex') AS txn_fingerprint_id -- Hex encoding
(statistics->'statistics'->>'maxRetries')::INT -- Max retry count
(statistics->'statistics'->'retryLat'->>'mean')::FLOAT8 -- Retry latency (seconds)
(statistics->'statistics'->'commitLat'->>'mean')::FLOAT8 -- Commit latency (seconds)
(statistics->'statistics'->'svcLat'->>'mean')::FLOAT8 -- Service latency (seconds)
metadata->'stmtFingerprintIDs' AS stmt_fingerprint_ids_json -- Statement composition
单位:
- 延迟字段:秒(FLOAT8)
- CPU/争用:纳秒(除以 1e9 转换为秒)
- 内存/磁盘:字节(可除以 1048576 转换为 MB)
完整架构请参阅 JSON 字段参考。
语句组成
metadata.stmtFingerprintIDs: 将事务映射到其组成语句的 JSONB 数组
用例: 了解高重试事务由哪些语句组成
交叉引用工作流: 按指纹 ID 联接 transaction_statistics 与 statement_statistics
示例模式:
-- Extract statement fingerprint IDs from transaction
metadata -> 'stmtFingerprintIDs' AS stmt_ids
-- Use with jsonb_array_elements_text to expand and join
jsonb_array_elements_text(metadata->'stmtFingerprintIDs') AS stmt_fingerprint_id
核心诊断查询
查询 1:按重试次数和争用情况排列的顶级事务
-- Identify transactions with high retry counts and contention
SELECT
encode(fingerprint_id, 'hex') AS txn_fingerprint_id,
metadata->>'db' AS database,
metadata->>'app' AS application,
(statistics->'statistics'->>'cnt')::INT AS execution_count,
(statistics->'statistics'->>'maxRetries')::INT AS max_retries,
(statistics->'statistics'->'retryLat'->>'mean')::FLOAT8 AS mean_retry_lat_seconds,
(statistics->'execution_statistics'->'contentionTime'->>'mean')::FLOAT8 / 1e9 AS mean_contention_seconds,
aggregated_ts
FROM crdb_internal.transaction_statistics
WHERE aggregated_ts > now() - INTERVAL '24 hours'
AND (statistics->'statistics'->>'maxRetries')::INT > 0
ORDER BY (statistics->'statistics'->>'maxRetries')::INT DESC
LIMIT 20;
关键列: max_retries 显示最大重试次数;mean_retry_lat_seconds 显示重试耗时;mean_contention_seconds 显示锁等待时间。
解读: max_retries 较高(>10)表示存在事务冲突;结合争用情况,找出锁热点。
查询 2:语句组成分析
-- Extract statement fingerprints for high-retry transactions
SELECT
encode(t.fingerprint_id, 'hex') AS txn_fingerprint_id,
t.metadata->>'app' AS application,
(t.statistics->'statistics'->>'maxRetries')::INT AS max_retries,
jsonb_array_length(t.metadata->'stmtFingerprintIDs') AS num_statements,
t.metadata->'stmtFingerprintIDs' AS stmt_fingerprint_ids,
t.aggregated_ts
FROM crdb_internal.transaction_statistics t
WHERE t.aggregated_ts > now() - INTERVAL '24 hours'
AND (t.statistics->'statistics'->>'maxRetries')::INT > 10
AND t.metadata->'stmtFingerprintIDs' IS NOT NULL
ORDER BY max_retries DESC
LIMIT 20;
关键列: num_statements 显示事务复杂度;stmt_fingerprint_ids 包含用于与 statement_statistics 交叉引用的语句 ID。
用例: 了解哪些语句组合会导致重试;使用查询 7 深入查看具体语句。
查询 3:提交延迟较高的事务
-- Find transactions with slow commit latency
SELECT
encode(fingerprint_id, 'hex') AS txn_fingerprint_id,
metadata->>'db' AS database,
metadata->>'app' AS application,
(statistics->'statistics'->>'cnt')::INT AS execution_count,
(statistics->'statistics'->'commitLat'->>'mean')::FLOAT8 AS mean_commit_lat_seconds,
(statistics->'statistics'->'svcLat'->>'mean')::FLOAT8 AS mean_service_lat_seconds,
ROUND(
((statistics->'statistics'->'commitLat'->>'mean')::FLOAT8 /
NULLIF((statistics->'statistics'->'svcLat'->>'mean')::FLOAT8, 0)) * 100, 2
) AS commit_pct_of_service_lat,
aggregated_ts
FROM crdb_internal.transaction_statistics
WHERE aggregated_ts > now() - INTERVAL '24 hours'
AND (statistics->'statistics'->'commitLat'->>'mean')::FLOAT8 > 0.1 -- > 100ms commit latency
ORDER BY (statistics->'statistics'->'commitLat'->>'mean')::FLOAT8 DESC
LIMIT 20;
关键列: mean_commit_lat_seconds 显示 2PC 提交时间;commit_pct_of_service_lat 显示提交开销占总延迟的百分比。
解读: 提交占比较高(>20%)表明存在分布式事务开销、复制延迟或跨区域写入。
查询 4:按应用统计重试率
-- Analyze retry patterns by application
SELECT
metadata->>'app' AS application,
metadata->>'db' AS database,
COUNT(*) AS transaction_fingerprint_count,
SUM((statistics->'statistics'->>'cnt')::INT) AS total_executions,
AVG((statistics->'statistics'->>'maxRetries')::INT) AS avg_max_retries,
MAX((statistics->'statistics'->>'maxRetries')::INT) AS overall_max_retries,
AVG((statistics->'statistics'->'retryLat'->>'mean')::FLOAT8) AS avg_retry_lat_seconds
FROM crdb_internal.transaction_statistics
WHERE aggregated_ts > now() - INTERVAL '24 hours'
AND (statistics->'statistics'->>'maxRetries')::INT > 0
GROUP BY metadata->>'app', metadata->>'db'
ORDER BY avg_max_retries DESC
LIMIT 20;
用例: 评估应用级运行状况;找出事务模式问题最多的应用。
自定义: 将时间窗口调整为 7 天以查看趋势;按特定数据库筛选。
查询 5:事务资源消耗
-- Find transactions with high resource usage
SELECT
encode(fingerprint_id, 'hex') AS txn_fingerprint_id,
metadata->>'app' AS application,
(statistics->'statistics'->>'cnt')::INT AS execution_count,
(statistics->'execution_statistics'->'networkBytes'->>'mean')::FLOAT8 / 1048576 AS mean_network_mb,
(statistics->'execution_statistics'->'maxMemUsage'->>'mean')::FLOAT8 / 1048576 AS mean_mem_mb,
(statistics->'execution_statistics'->'maxDiskUsage'->>'mean')::FLOAT8 / 1048576 AS mean_disk_mb,
ROUND(
((statistics->'execution_statistics'->'networkBytes'->>'mean')::FLOAT8 / 1048576) *
(statistics->'statistics'->>'cnt')::INT, 2
) AS estimated_total_network_mb,
aggregated_ts
FROM crdb_internal.transaction_statistics
WHERE aggregated_ts > now() - INTERVAL '24 hours'
AND (statistics->'execution_statistics'->>'cnt') IS NOT NULL
AND (statistics->'execution_statistics'->'networkBytes'->>'mean')::FLOAT8 > 0
ORDER BY estimated_total_network_mb DESC
LIMIT 20;
关键列: mean_network_mb 显示分布式事务开销;mean_disk_mb > 0 表示发生了内存溢写。
解读: 网络字节数较高表示存在跨区域事务或分布不佳;磁盘使用量表示内存压力。
查询 6:重试延迟分解
-- Understand retry latency as percentage of service latency
SELECT
encode(fingerprint_id, 'hex') AS txn_fingerprint_id,
metadata->>'app' AS application,
(statistics->'statistics'->>'cnt')::INT AS execution_count,
(statistics->'statistics'->>'maxRetries')::INT AS max_retries,
(statistics->'statistics'->'retryLat'->>'mean')::FLOAT8 AS mean_retry_lat_seconds,
(statistics->'statistics'->'svcLat'->>'mean')::FLOAT8 AS mean_service_lat_seconds,
ROUND(
((statistics->'statistics'->'retryLat'->>'mean')::FLOAT8 /
NULLIF((statistics->'statistics'->'svcLat'->>'mean')::FLOAT8, 0)) * 100, 2
) AS retry_pct_of_service_lat,
aggregated_ts
FROM crdb_internal.transaction_statistics
WHERE aggregated_ts > now() - INTERVAL '24 hours'
AND (statistics->'statistics'->>'maxRetries')::INT > 0
AND (statistics->'statistics'->'retryLat'->>'mean')::FLOAT8 > 0
ORDER BY retry_pct_of_service_lat DESC
LIMIT 20;
解读: 重试占比较高(>30%)意味着大部分延迟都耗在因争用导致的重试上;请优化事务边界或架构。
查询 7:交叉引用事务与语句
-- Join transaction statistics with statement statistics to see constituent statements
SELECT
encode(t.fingerprint_id, 'hex') AS txn_fingerprint_id,
t.metadata->>'app' AS txn_application,
(t.statistics->'statistics'->>'maxRetries')::INT AS txn_max_retries,
stmt_fp_id AS stmt_fingerprint_id,
s.metadata->>'query' AS statement_query,
(s.statistics->'statistics'->'runLat'->>'mean')::FLOAT8 AS stmt_mean_run_lat_seconds,
t.aggregated_ts
FROM crdb_internal.transaction_statistics t
CROSS JOIN LATERAL jsonb_array_elements_text(t.metadata->'stmtFingerprintIDs') AS stmt_fp_id
LEFT JOIN crdb_internal.statement_statistics s
ON s.fingerprint_id = decode(stmt_fp_id, 'hex')
AND s.aggregated_ts = t.aggregated_ts
WHERE t.aggregated_ts > now() - INTERVAL '24 hours'
AND (t.statistics->'statistics'->>'maxRetries')::INT > 10
AND t.metadata->'stmtFingerprintIDs' IS NOT NULL
ORDER BY txn_max_retries DESC, stmt_mean_run_lat_seconds DESC
LIMIT 50;
用例: 从高重试事务深入查看具体问题语句;找出事务中导致重试的语句。
注意: 使用 decode(stmt_fp_id, 'hex') 将十六进制字符串转换回二进制,以便与 statement_statistics 联接。
常见工作流
工作流 1:调查重试风暴
- 找出高重试事务: 运行查询 1,重点查看
max_retries > 20 - 按应用分析重试模式: 运行查询 4,找出有问题的应用
- 检查语句组成: 运行查询 7,查看高重试事务中包含哪些语句
- 交叉查看实时活动: 如果问题仍在持续,使用 triaging-live-sql-activity 检查当前事务状态
- 修复: 调整事务边界、批处理操作,并优化步骤 3 中发现的语句
工作流 2:提交延迟分析
- **查找缓慢的提交事务:**运行查询 3,重点关注
commit_pct_of_service_lat > 20% - **检查是否与争用相关:**针对相同的事务指纹运行查询 1,查看争用是否与之相关
- **分析时间模式:**按
aggregated_ts对查询 3 分组,以识别高峰时段 - **调查资源:**运行查询 5,检查网络开销是否与提交延迟相关
- **采取补救措施:**考虑批量处理操作、对表进行分区,或调查复制配置
工作流 3:深入分析语句组成
- **识别有问题的事务:**运行查询 1 或查询 3,查找重试次数多或提交缓慢的事务
- **提取语句 ID:**运行查询 2,查看目标事务的
stmtFingerprintIDs - **与 statement_statistics 联接:**运行查询 7,查看完整的语句详情
- **优化瓶颈语句:**使用 profiling-statement-fingerprints 技能分析并优化已识别的语句
- **验证重试次数是否减少:**优化后重新运行查询 1,确认重试次数有所改善
工作流 4:应用健康状况评分卡
- **按应用生成重试指标:**运行查询 4,获取应用级别的重试统计信息
- **关联提交延迟:**修改查询 3,按应用分组
- **资源归因:**按应用对查询 5 分组,查看资源影响
- **趋势分析:**使用 7 天时间窗口运行查询,并比较各小时数据桶
- **联系应用团队:**提供重试次数多或延迟高的具体事务指纹,以便调查
安全注意事项
只读操作:
所有查询都是针对 crdb_internal.transaction_statistics 执行的 SELECT 语句,该表已获准用于生产环境,可安全用于诊断。
性能影响:
| 注意事项 | 影响 | 缓解措施 |
|---|---|---|
| 大型表 | 事务多样性高会导致行数很多 | 始终使用 WHERE aggregated_ts > now() - INTERVAL '24 hours' 和 LIMIT |
| JSON 解析 | 提取 JSONB 会产生 CPU 开销 | 避免紧密循环;使用特定时间窗口 |
| 时间窗口过宽 | 7 天的查询会返回更多行 | 默认使用 24 小时;仅在需要时扩大范围 |
| 采样指标 | 处理 NULL 会产生开销 | 使用防御性条件 WHERE (statistics->'execution_statistics'->>'cnt') IS NOT NULL |
**隐私:**在多租户环境中,使用 VIEWACTIVITYREDACTED 对查询常量进行脱敏(与语句分析相同)。
**默认时间窗口:**24 小时的窗口兼顾近期数据与易于管理的结果集。
故障排查
| 问题 | 原因 | 修复方法 |
|---|---|---|
| 结果为空 | 时间窗口内没有数据,或已禁用统计信息收集 | 检查 sql.stats.automatic_collection.enabled = true |
column does not exist | JSON 字段拼写错误或版本不匹配 | 验证字段名称;检查 CockroachDB 版本 |
| 采样指标为 NULL | 未在该数据桶中采样此指标 | 添加筛选条件:WHERE (statistics->'execution_statistics'->>'cnt') IS NOT NULL |
fingerprint_id 不是十六进制 | 默认二进制格式 | 使用 encode(fingerprint_id, 'hex') 提高可读性 |
| 语句联接失败 | aggregated_ts 或指纹格式不匹配 | 确保使用相同的时间桶,并通过 decode() 进行正确的类型转换 |
| 查询非常慢 | 表很大,且没有时间筛选条件 | 始终添加时间窗口和 LIMIT |
stmtFingerprintIDs 为空 | 单语句事务或版本较旧 | 对于简单事务,这是正常现象 |
关键注意事项
- 时间窗口: 默认使用 24h;分析趋势时扩展至 7d
- 采样指标: 并非会捕获所有执行;请检查样本量(
cnt) - JSON 字段安全: 使用防御性 NULL 检查;处理类型转换错误
- 隐私: 在生产环境中使用 VIEWACTIVITYREDACTED
- 性能: 始终包含时间筛选条件和 LIMIT 子句
- 与语句分析互补: 配合使用以实现完整覆盖(事务 + 语句)
- 与实时问题排查互补: 历史模式与实时数据互补(两者都要使用)
- 数据保留: 受行数上限
sql.stats.persisted_rows.max(默认值为 1,000,000)限制,而非 TTL;实际时间窗口因工作负载多样性而异 - 重试语义:
maxRetries是时间段内所有执行中的最大值,而非平均值 - 指纹编码: 使用
encode(fingerprint_id, 'hex')获取便于阅读的 ID
参考资料
技能参考:
- JSON 字段架构和提取
- 指标目录和单位
- SQL 查询变体
- RBAC 和权限(与 triaging-live-sql-activity 共用)
CockroachDB 官方文档:
相关技能:
- profiling-statement-fingerprints - 用于语句级优化
- triaging-live-sql-activity - 用于对活动事务进行即时问题排查