taurusdb-core 0.1.0
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/README.md +21 -0
- package/dist/auth/secret-resolver.d.ts +16 -0
- package/dist/auth/secret-resolver.js +64 -0
- package/dist/auth/sql-profile-loader/env-source.d.ts +3 -0
- package/dist/auth/sql-profile-loader/env-source.js +94 -0
- package/dist/auth/sql-profile-loader/file-source.d.ts +6 -0
- package/dist/auth/sql-profile-loader/file-source.js +40 -0
- package/dist/auth/sql-profile-loader/loader.d.ts +16 -0
- package/dist/auth/sql-profile-loader/loader.js +81 -0
- package/dist/auth/sql-profile-loader/parsing.d.ts +14 -0
- package/dist/auth/sql-profile-loader/parsing.js +216 -0
- package/dist/auth/sql-profile-loader/runtime-override.d.ts +14 -0
- package/dist/auth/sql-profile-loader/runtime-override.js +52 -0
- package/dist/auth/sql-profile-loader/types.d.ts +64 -0
- package/dist/auth/sql-profile-loader/types.js +1 -0
- package/dist/auth/sql-profile-loader.d.ts +4 -0
- package/dist/auth/sql-profile-loader.js +3 -0
- package/dist/capability/feature-matrix.d.ts +5 -0
- package/dist/capability/feature-matrix.js +237 -0
- package/dist/capability/probe.d.ts +19 -0
- package/dist/capability/probe.js +139 -0
- package/dist/capability/types.d.ts +49 -0
- package/dist/capability/types.js +16 -0
- package/dist/capability/version.d.ts +3 -0
- package/dist/capability/version.js +47 -0
- package/dist/cloud/auth.d.ts +26 -0
- package/dist/cloud/auth.js +198 -0
- package/dist/cloud/instances.d.ts +46 -0
- package/dist/cloud/instances.js +224 -0
- package/dist/config/env.d.ts +1 -0
- package/dist/config/env.js +194 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.js +21 -0
- package/dist/config/redaction.d.ts +2 -0
- package/dist/config/redaction.js +19 -0
- package/dist/config/schema.d.ts +417 -0
- package/dist/config/schema.js +100 -0
- package/dist/context/datasource-resolver.d.ts +19 -0
- package/dist/context/datasource-resolver.js +71 -0
- package/dist/context/session-context.d.ts +26 -0
- package/dist/context/session-context.js +1 -0
- package/dist/diagnostics/metrics-source.d.ts +65 -0
- package/dist/diagnostics/metrics-source.js +280 -0
- package/dist/diagnostics/slow-sql-source/das-source.d.ts +43 -0
- package/dist/diagnostics/slow-sql-source/das-source.js +170 -0
- package/dist/diagnostics/slow-sql-source/factory.d.ts +5 -0
- package/dist/diagnostics/slow-sql-source/factory.js +87 -0
- package/dist/diagnostics/slow-sql-source/parsers.d.ts +7 -0
- package/dist/diagnostics/slow-sql-source/parsers.js +125 -0
- package/dist/diagnostics/slow-sql-source/taurus-api-source.d.ts +42 -0
- package/dist/diagnostics/slow-sql-source/taurus-api-source.js +149 -0
- package/dist/diagnostics/slow-sql-source/types.d.ts +40 -0
- package/dist/diagnostics/slow-sql-source/types.js +1 -0
- package/dist/diagnostics/slow-sql-source/utils.d.ts +20 -0
- package/dist/diagnostics/slow-sql-source/utils.js +170 -0
- package/dist/diagnostics/slow-sql-source.d.ts +4 -0
- package/dist/diagnostics/slow-sql-source.js +3 -0
- package/dist/diagnostics/types.d.ts +189 -0
- package/dist/diagnostics/types.js +39 -0
- package/dist/engine/data-access/locks.d.ts +8 -0
- package/dist/engine/data-access/locks.js +146 -0
- package/dist/engine/data-access/processlist.d.ts +4 -0
- package/dist/engine/data-access/processlist.js +56 -0
- package/dist/engine/data-access/statements.d.ts +10 -0
- package/dist/engine/data-access/statements.js +203 -0
- package/dist/engine/data-access/storage.d.ts +6 -0
- package/dist/engine/data-access/storage.js +96 -0
- package/dist/engine/data-access.d.ts +4 -0
- package/dist/engine/data-access.js +4 -0
- package/dist/engine/diagnostics.d.ts +7 -0
- package/dist/engine/diagnostics.js +7 -0
- package/dist/engine/helper-modules/diagnostics.d.ts +57 -0
- package/dist/engine/helper-modules/diagnostics.js +322 -0
- package/dist/engine/helper-modules/parsers.d.ts +13 -0
- package/dist/engine/helper-modules/parsers.js +283 -0
- package/dist/engine/helper-modules/sql.d.ts +12 -0
- package/dist/engine/helper-modules/sql.js +119 -0
- package/dist/engine/helper-modules/types.d.ts +103 -0
- package/dist/engine/helper-modules/types.js +1 -0
- package/dist/engine/helpers.d.ts +4 -0
- package/dist/engine/helpers.js +4 -0
- package/dist/engine/runtime.d.ts +20 -0
- package/dist/engine/runtime.js +385 -0
- package/dist/engine/types.d.ts +125 -0
- package/dist/engine/types.js +1 -0
- package/dist/engine/workflows/connection-spike.d.ts +4 -0
- package/dist/engine/workflows/connection-spike.js +316 -0
- package/dist/engine/workflows/db-hotspot.d.ts +4 -0
- package/dist/engine/workflows/db-hotspot.js +182 -0
- package/dist/engine/workflows/lock-contention-helpers/entities.d.ts +9 -0
- package/dist/engine/workflows/lock-contention-helpers/entities.js +58 -0
- package/dist/engine/workflows/lock-contention-helpers/no-match.d.ts +3 -0
- package/dist/engine/workflows/lock-contention-helpers/no-match.js +65 -0
- package/dist/engine/workflows/lock-contention-helpers/report.d.ts +21 -0
- package/dist/engine/workflows/lock-contention-helpers/report.js +104 -0
- package/dist/engine/workflows/lock-contention-helpers/root-cause.d.ts +4 -0
- package/dist/engine/workflows/lock-contention-helpers/root-cause.js +79 -0
- package/dist/engine/workflows/lock-contention-helpers/signals.d.ts +22 -0
- package/dist/engine/workflows/lock-contention-helpers/signals.js +34 -0
- package/dist/engine/workflows/lock-contention-helpers.d.ts +5 -0
- package/dist/engine/workflows/lock-contention-helpers.js +5 -0
- package/dist/engine/workflows/lock-contention.d.ts +4 -0
- package/dist/engine/workflows/lock-contention.js +67 -0
- package/dist/engine/workflows/service-latency.d.ts +4 -0
- package/dist/engine/workflows/service-latency.js +262 -0
- package/dist/engine/workflows/slow-query-helpers.d.ts +41 -0
- package/dist/engine/workflows/slow-query-helpers.js +253 -0
- package/dist/engine/workflows/slow-query.d.ts +4 -0
- package/dist/engine/workflows/slow-query.js +156 -0
- package/dist/engine/workflows/storage-pressure-helpers.d.ts +12 -0
- package/dist/engine/workflows/storage-pressure-helpers.js +281 -0
- package/dist/engine/workflows/storage-pressure.d.ts +4 -0
- package/dist/engine/workflows/storage-pressure.js +27 -0
- package/dist/engine/workflows/top-slow-sql.d.ts +4 -0
- package/dist/engine/workflows/top-slow-sql.js +222 -0
- package/dist/engine.d.ts +77 -0
- package/dist/engine.js +240 -0
- package/dist/executor/adapters/mysql.d.ts +2 -0
- package/dist/executor/adapters/mysql.js +114 -0
- package/dist/executor/connection-pool.d.ts +105 -0
- package/dist/executor/connection-pool.js +236 -0
- package/dist/executor/explain.d.ts +5 -0
- package/dist/executor/explain.js +119 -0
- package/dist/executor/query-tracker.d.ts +45 -0
- package/dist/executor/query-tracker.js +83 -0
- package/dist/executor/result-normalizer.d.ts +6 -0
- package/dist/executor/result-normalizer.js +47 -0
- package/dist/executor/sql-executor.d.ts +32 -0
- package/dist/executor/sql-executor.js +250 -0
- package/dist/executor/types.d.ts +70 -0
- package/dist/executor/types.js +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +21 -0
- package/dist/safety/confirmation-store.d.ts +44 -0
- package/dist/safety/confirmation-store.js +130 -0
- package/dist/safety/guardrail.d.ts +39 -0
- package/dist/safety/guardrail.js +99 -0
- package/dist/safety/parser/adapter.d.ts +10 -0
- package/dist/safety/parser/adapter.js +72 -0
- package/dist/safety/parser/ast-utils.d.ts +10 -0
- package/dist/safety/parser/ast-utils.js +167 -0
- package/dist/safety/parser/features.d.ts +12 -0
- package/dist/safety/parser/features.js +113 -0
- package/dist/safety/parser/index.d.ts +2 -0
- package/dist/safety/parser/index.js +1 -0
- package/dist/safety/parser/types.d.ts +76 -0
- package/dist/safety/parser/types.js +1 -0
- package/dist/safety/redaction.d.ts +34 -0
- package/dist/safety/redaction.js +186 -0
- package/dist/safety/sql-classifier.d.ts +19 -0
- package/dist/safety/sql-classifier.js +43 -0
- package/dist/safety/sql-validator.d.ts +19 -0
- package/dist/safety/sql-validator.js +143 -0
- package/dist/schema/adapters/mysql.d.ts +16 -0
- package/dist/schema/adapters/mysql.js +287 -0
- package/dist/schema/introspector.d.ts +70 -0
- package/dist/schema/introspector.js +40 -0
- package/dist/taurus/flashback.d.ts +36 -0
- package/dist/taurus/flashback.js +149 -0
- package/dist/taurus/recycle-bin.d.ts +14 -0
- package/dist/taurus/recycle-bin.js +61 -0
- package/dist/utils/formatter.d.ts +70 -0
- package/dist/utils/formatter.js +60 -0
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.js +247 -0
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.js +11 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.js +39 -0
- package/package.json +46 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { normalizeSql, sqlHash } from "../../utils/hash.js";
|
|
2
|
+
import { buildDbHotspotNextToolInput, buildFindTopSlowSqlNextToolInput, buildSlowQueryNextToolInput, clampInteger, dedupeNextToolInputs, metricSummaryText, metricsSourceLimitation, pickMetric, roundMetric, withDatasourceSummary, } from "../helpers.js";
|
|
3
|
+
export function buildStoragePressureDiagnosis(input) {
|
|
4
|
+
const { diagnosisInput, ctx, digestRows, tableRows, metrics, metricsSource } = input;
|
|
5
|
+
const maxCandidates = clampInteger(diagnosisInput.maxCandidates, 5, 1, 10);
|
|
6
|
+
const storageUsedMetric = pickMetric(metrics, "storage_used_size");
|
|
7
|
+
const writeDelayMetric = pickMetric(metrics, "storage_write_delay");
|
|
8
|
+
const readDelayMetric = pickMetric(metrics, "storage_read_delay");
|
|
9
|
+
const writeIopsMetric = pickMetric(metrics, "write_iops");
|
|
10
|
+
const readIopsMetric = pickMetric(metrics, "read_iops");
|
|
11
|
+
const writeThroughputMetric = pickMetric(metrics, "write_throughput");
|
|
12
|
+
const readThroughputMetric = pickMetric(metrics, "read_throughput");
|
|
13
|
+
const tempTablesMetric = pickMetric(metrics, "temp_tables_per_min");
|
|
14
|
+
const metricEvidence = metrics.map((metric) => ({
|
|
15
|
+
source: "ces_metrics",
|
|
16
|
+
title: `CES ${metric.alias}`,
|
|
17
|
+
summary: metricSummaryText(metric),
|
|
18
|
+
}));
|
|
19
|
+
const recommendedNextTools = new Set();
|
|
20
|
+
const nextToolInputs = [];
|
|
21
|
+
const focusedTableName = diagnosisInput.table?.includes(".")
|
|
22
|
+
? diagnosisInput.table.split(".").slice(1).join(".")
|
|
23
|
+
: diagnosisInput.table;
|
|
24
|
+
const relevantDigests = digestRows.filter((row) => {
|
|
25
|
+
if (!focusedTableName) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
const target = focusedTableName.toUpperCase();
|
|
29
|
+
return (row.digestText?.toUpperCase().includes(target) ||
|
|
30
|
+
row.querySampleText?.toUpperCase().includes(target));
|
|
31
|
+
});
|
|
32
|
+
const tmpDiskDigests = relevantDigests.filter((row) => (row.avgTmpDiskTables ?? 0) > 0);
|
|
33
|
+
const tmpTableDigests = relevantDigests.filter((row) => (row.avgTmpTables ?? 0) > 0);
|
|
34
|
+
const scanDigests = relevantDigests.filter((row) => (row.noIndexUsedCount ?? 0) > 0 ||
|
|
35
|
+
(row.selectScanCount ?? 0) > 0 ||
|
|
36
|
+
(row.avgRowsExamined ?? 0) >= 10_000);
|
|
37
|
+
const sortDigests = relevantDigests.filter((row) => (row.avgSortRows ?? 0) >= 1_000);
|
|
38
|
+
const largeTables = tableRows.filter((row) => (row.totalMb ?? 0) >= 1024 ||
|
|
39
|
+
(row.rowCountEstimate ?? 0) >= 1_000_000 ||
|
|
40
|
+
(row.dataFreeMb ?? 0) >= 1024);
|
|
41
|
+
const rootCauseCandidates = [];
|
|
42
|
+
if (tmpDiskDigests.length > 0) {
|
|
43
|
+
const lead = tmpDiskDigests[0];
|
|
44
|
+
rootCauseCandidates.push({
|
|
45
|
+
code: "storage_pressure_tmp_disk_spill",
|
|
46
|
+
title: "SQL workload is spilling temporary tables to disk",
|
|
47
|
+
confidence: (lead.avgTmpDiskTables ?? 0) >= 1 ? "high" : "medium",
|
|
48
|
+
rationale: `Digest summaries show temporary disk table usage${lead.digestText ? ` for ${lead.digestText}` : ""}${lead.avgTmpDiskTables !== undefined ? `; avg_tmp_disk_tables=${lead.avgTmpDiskTables}` : ""}.`,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (scanDigests.length > 0) {
|
|
52
|
+
const lead = scanDigests[0];
|
|
53
|
+
rootCauseCandidates.push({
|
|
54
|
+
code: "storage_pressure_scan_heavy_sql",
|
|
55
|
+
title: "Scan-heavy SQL is driving storage pressure",
|
|
56
|
+
confidence: (lead.noIndexUsedCount ?? 0) > 0 ||
|
|
57
|
+
(lead.avgRowsExamined ?? 0) >= 100_000
|
|
58
|
+
? "high"
|
|
59
|
+
: "medium",
|
|
60
|
+
rationale: `Digest summaries show scan-heavy execution${lead.digestText ? ` for ${lead.digestText}` : ""}${lead.avgRowsExamined !== undefined ? `; avg_rows_examined=${lead.avgRowsExamined}` : ""}${lead.noIndexUsedCount !== undefined ? `, no_index_used_count=${lead.noIndexUsedCount}` : ""}${lead.selectScanCount !== undefined ? `, select_scan_count=${lead.selectScanCount}` : ""}.`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
if (sortDigests.length > 0 || tmpTableDigests.length > 0) {
|
|
64
|
+
const lead = sortDigests[0] ?? tmpTableDigests[0];
|
|
65
|
+
rootCauseCandidates.push({
|
|
66
|
+
code: "storage_pressure_sort_or_tmp_table_workload",
|
|
67
|
+
title: "Sort or temporary-table workload is increasing storage work",
|
|
68
|
+
confidence: (lead.avgSortRows ?? 0) >= 10_000 || (lead.avgTmpTables ?? 0) >= 1
|
|
69
|
+
? "medium"
|
|
70
|
+
: "low",
|
|
71
|
+
rationale: `Digest summaries show sort or temporary-table work${lead.digestText ? ` for ${lead.digestText}` : ""}${lead.avgSortRows !== undefined ? `; avg_sort_rows=${lead.avgSortRows}` : ""}${lead.avgTmpTables !== undefined ? `, avg_tmp_tables=${lead.avgTmpTables}` : ""}.`,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (largeTables.length > 0) {
|
|
75
|
+
const lead = largeTables[0];
|
|
76
|
+
const qualifiedTable = [lead.schemaName, lead.tableName]
|
|
77
|
+
.filter(Boolean)
|
|
78
|
+
.join(".");
|
|
79
|
+
rootCauseCandidates.push({
|
|
80
|
+
code: "storage_pressure_large_or_fragmented_table",
|
|
81
|
+
title: "Large or fragmented table may amplify storage work",
|
|
82
|
+
confidence: "medium",
|
|
83
|
+
rationale: `${qualifiedTable || "A table"} is among the largest local tables${lead.totalMb !== undefined ? `; total_mb=${lead.totalMb}` : ""}${lead.rowCountEstimate !== undefined ? `, row_count_estimate=${lead.rowCountEstimate}` : ""}${lead.dataFreeMb !== undefined ? `, data_free_mb=${lead.dataFreeMb}` : ""}.`,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if ((writeDelayMetric?.max ?? 0) >= 50 || (readDelayMetric?.max ?? 0) >= 50) {
|
|
87
|
+
rootCauseCandidates.push({
|
|
88
|
+
code: "storage_pressure_ces_io_latency",
|
|
89
|
+
title: "Cloud Eye shows elevated storage read/write latency",
|
|
90
|
+
confidence: (writeDelayMetric?.max ?? 0) >= 100 ||
|
|
91
|
+
(readDelayMetric?.max ?? 0) >= 100
|
|
92
|
+
? "high"
|
|
93
|
+
: "medium",
|
|
94
|
+
rationale: `CES storage latency crossed the current thresholds${writeDelayMetric?.max !== undefined ? `; max_write_delay=${roundMetric(writeDelayMetric.max)}` : ""}${readDelayMetric?.max !== undefined ? `, max_read_delay=${roundMetric(readDelayMetric.max)}` : ""}.`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
if ((writeIopsMetric?.max ?? 0) >= 1000 ||
|
|
98
|
+
(readIopsMetric?.max ?? 0) >= 1000 ||
|
|
99
|
+
(writeThroughputMetric?.max ?? 0) >= 50 * 1024 * 1024 ||
|
|
100
|
+
(readThroughputMetric?.max ?? 0) >= 50 * 1024 * 1024) {
|
|
101
|
+
rootCauseCandidates.push({
|
|
102
|
+
code: "storage_pressure_ces_io_throughput",
|
|
103
|
+
title: "Cloud Eye shows elevated IOPS or throughput",
|
|
104
|
+
confidence: "medium",
|
|
105
|
+
rationale: `CES I/O workload metrics are elevated${writeIopsMetric?.max !== undefined ? `; max_write_iops=${roundMetric(writeIopsMetric.max)}` : ""}${readIopsMetric?.max !== undefined ? `, max_read_iops=${roundMetric(readIopsMetric.max)}` : ""}${writeThroughputMetric?.max !== undefined ? `, max_write_throughput=${roundMetric(writeThroughputMetric.max)}` : ""}${readThroughputMetric?.max !== undefined ? `, max_read_throughput=${roundMetric(readThroughputMetric.max)}` : ""}.`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (tempTablesMetric &&
|
|
109
|
+
(tempTablesMetric.max ?? 0) > 0 &&
|
|
110
|
+
tmpDiskDigests.length > 0) {
|
|
111
|
+
rootCauseCandidates.push({
|
|
112
|
+
code: "storage_pressure_tmp_table_metric_confirmed",
|
|
113
|
+
title: "Temporary table workload is visible in SQL and CES metrics",
|
|
114
|
+
confidence: "medium",
|
|
115
|
+
rationale: `Statement digests show temporary disk usage and CES temp-table metrics were non-zero; ${metricSummaryText(tempTablesMetric)}.`,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
if (rootCauseCandidates.length === 0) {
|
|
119
|
+
rootCauseCandidates.push({
|
|
120
|
+
code: "storage_pressure_snapshot_collected",
|
|
121
|
+
title: "Storage evidence was collected but no dominant pressure signal stood out",
|
|
122
|
+
confidence: "low",
|
|
123
|
+
rationale: "Local table size and statement digest summaries were collected, but temporary disk spill, scan pressure, and large-table thresholds were not crossed.",
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const leadDigest = relevantDigests[0];
|
|
127
|
+
const suspiciousSqls = relevantDigests
|
|
128
|
+
.filter((row) => (row.avgTmpDiskTables ?? 0) > 0 ||
|
|
129
|
+
(row.avgTmpTables ?? 0) > 0 ||
|
|
130
|
+
(row.avgSortRows ?? 0) >= 1_000 ||
|
|
131
|
+
(row.noIndexUsedCount ?? 0) > 0 ||
|
|
132
|
+
(row.selectScanCount ?? 0) > 0 ||
|
|
133
|
+
(row.avgRowsExamined ?? 0) >= 10_000)
|
|
134
|
+
.slice(0, maxCandidates)
|
|
135
|
+
.map((row) => ({
|
|
136
|
+
sqlHash: row.querySampleText
|
|
137
|
+
? sqlHash(normalizeSql(row.querySampleText))
|
|
138
|
+
: undefined,
|
|
139
|
+
digestText: row.digestText,
|
|
140
|
+
reason: `Statement digest shows storage-relevant work${row.avgTmpDiskTables !== undefined ? `; avg_tmp_disk_tables=${row.avgTmpDiskTables}` : ""}${row.avgTmpTables !== undefined ? `, avg_tmp_tables=${row.avgTmpTables}` : ""}${row.avgSortRows !== undefined ? `, avg_sort_rows=${row.avgSortRows}` : ""}${row.avgRowsExamined !== undefined ? `, avg_rows_examined=${row.avgRowsExamined}` : ""}.`,
|
|
141
|
+
}));
|
|
142
|
+
const suspiciousTables = tableRows.slice(0, maxCandidates).map((row) => {
|
|
143
|
+
const qualifiedTable = [row.schemaName, row.tableName]
|
|
144
|
+
.filter(Boolean)
|
|
145
|
+
.join(".");
|
|
146
|
+
return {
|
|
147
|
+
table: qualifiedTable || row.tableName || diagnosisInput.table || "unknown",
|
|
148
|
+
reason: diagnosisInput.table
|
|
149
|
+
? "Provided as the storage-pressure focus and matched against local table-size metadata."
|
|
150
|
+
: `Top local table by storage footprint${row.totalMb !== undefined ? `; total_mb=${row.totalMb}` : ""}${row.rowCountEstimate !== undefined ? `, row_count_estimate=${row.rowCountEstimate}` : ""}.`,
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
const keyFindings = [
|
|
154
|
+
`Scope requested: ${diagnosisInput.scope ?? "instance"}.`,
|
|
155
|
+
diagnosisInput.table
|
|
156
|
+
? `Table focus provided: ${diagnosisInput.table}.`
|
|
157
|
+
: "No table focus was provided.",
|
|
158
|
+
relevantDigests.length > 0
|
|
159
|
+
? `Collected ${relevantDigests.length} statement digest rows for storage-pressure correlation.`
|
|
160
|
+
: "No statement digest rows were available for storage-pressure correlation.",
|
|
161
|
+
tableRows.length > 0
|
|
162
|
+
? `Collected ${tableRows.length} table-size rows from information_schema.TABLES.`
|
|
163
|
+
: "No table-size rows were available from information_schema.TABLES.",
|
|
164
|
+
];
|
|
165
|
+
if (tmpDiskDigests.length > 0) {
|
|
166
|
+
keyFindings.push(`${tmpDiskDigests.length} digest rows show temporary disk table usage.`);
|
|
167
|
+
}
|
|
168
|
+
if (scanDigests.length > 0) {
|
|
169
|
+
keyFindings.push(`${scanDigests.length} digest rows show scan-heavy execution.`);
|
|
170
|
+
}
|
|
171
|
+
if (leadDigest?.digestText) {
|
|
172
|
+
keyFindings.push(`Lead storage-relevant digest: ${leadDigest.digestText}.`);
|
|
173
|
+
}
|
|
174
|
+
if (storageUsedMetric) {
|
|
175
|
+
keyFindings.push(`CES storage used size: ${metricSummaryText(storageUsedMetric)}.`);
|
|
176
|
+
}
|
|
177
|
+
if (writeDelayMetric) {
|
|
178
|
+
keyFindings.push(`CES storage write delay: ${metricSummaryText(writeDelayMetric)}.`);
|
|
179
|
+
}
|
|
180
|
+
if (readDelayMetric) {
|
|
181
|
+
keyFindings.push(`CES storage read delay: ${metricSummaryText(readDelayMetric)}.`);
|
|
182
|
+
}
|
|
183
|
+
if (writeIopsMetric || readIopsMetric) {
|
|
184
|
+
keyFindings.push(`CES IOPS: write=${writeIopsMetric ? metricSummaryText(writeIopsMetric) : "n/a"}; read=${readIopsMetric ? metricSummaryText(readIopsMetric) : "n/a"}.`);
|
|
185
|
+
}
|
|
186
|
+
const leadSlowQueryInput = buildSlowQueryNextToolInput({
|
|
187
|
+
sqlHash: leadDigest?.querySampleText
|
|
188
|
+
? sqlHash(normalizeSql(leadDigest.querySampleText))
|
|
189
|
+
: undefined,
|
|
190
|
+
digestText: leadDigest?.digestText,
|
|
191
|
+
sampleSql: leadDigest?.querySampleText,
|
|
192
|
+
}, diagnosisInput, "Inspect the lead storage-relevant digest with plan and runtime counters before tuning only table footprint or instance-level storage settings.");
|
|
193
|
+
if (leadSlowQueryInput) {
|
|
194
|
+
recommendedNextTools.add("diagnose_slow_query");
|
|
195
|
+
nextToolInputs.push(leadSlowQueryInput);
|
|
196
|
+
}
|
|
197
|
+
if (relevantDigests.length > 1 ||
|
|
198
|
+
(writeDelayMetric?.max ?? 0) >= 50 ||
|
|
199
|
+
(readDelayMetric?.max ?? 0) >= 50 ||
|
|
200
|
+
(writeIopsMetric?.max ?? 0) >= 1000 ||
|
|
201
|
+
(readIopsMetric?.max ?? 0) >= 1000 ||
|
|
202
|
+
(writeThroughputMetric?.max ?? 0) >= 50 * 1024 * 1024 ||
|
|
203
|
+
(readThroughputMetric?.max ?? 0) >= 50 * 1024 * 1024) {
|
|
204
|
+
recommendedNextTools.add("find_top_slow_sql");
|
|
205
|
+
nextToolInputs.push(buildFindTopSlowSqlNextToolInput({ sortBy: "total_latency", topN: 5 }, diagnosisInput, "Rank the broader slow-SQL set to confirm whether the lead digest is representative of overall storage pressure."));
|
|
206
|
+
}
|
|
207
|
+
if (diagnosisInput.scope === "table" ||
|
|
208
|
+
diagnosisInput.table ||
|
|
209
|
+
largeTables.length > 0) {
|
|
210
|
+
recommendedNextTools.add("diagnose_db_hotspot");
|
|
211
|
+
nextToolInputs.push(buildDbHotspotNextToolInput({ scope: "table" }, diagnosisInput, "Correlate the suspected table footprint with current table-level hotspots before changing only storage capacity or purge policy."));
|
|
212
|
+
}
|
|
213
|
+
const recommendedActions = [
|
|
214
|
+
"Use diagnose_slow_query on the lead storage-relevant SQL digest to inspect plan shape and runtime counters.",
|
|
215
|
+
"Review predicates, indexes, ORDER BY, and GROUP BY clauses for digests with scan, filesort, or temporary-table signals.",
|
|
216
|
+
];
|
|
217
|
+
if (tmpDiskDigests.length > 0) {
|
|
218
|
+
recommendedActions.push("Reduce temporary disk tables by supporting grouping/sorting with indexes or reducing intermediate row width.");
|
|
219
|
+
}
|
|
220
|
+
if (largeTables.length > 0) {
|
|
221
|
+
recommendedActions.push("Review the largest table footprints and purge/archive strategy before tuning only individual SQL statements.");
|
|
222
|
+
}
|
|
223
|
+
if ((writeDelayMetric?.max ?? 0) >= 50 || (readDelayMetric?.max ?? 0) >= 50) {
|
|
224
|
+
recommendedActions.push("Correlate SQL spill/scan candidates with CES storage read/write latency before changing only query plans.");
|
|
225
|
+
}
|
|
226
|
+
const severity = (writeDelayMetric?.max ?? 0) >= 100 ||
|
|
227
|
+
(readDelayMetric?.max ?? 0) >= 100 ||
|
|
228
|
+
tmpDiskDigests.length > 0 ||
|
|
229
|
+
scanDigests.some((row) => (row.avgRowsExamined ?? 0) >= 100_000)
|
|
230
|
+
? "warning"
|
|
231
|
+
: rootCauseCandidates[0]?.code === "storage_pressure_snapshot_collected"
|
|
232
|
+
? "info"
|
|
233
|
+
: "warning";
|
|
234
|
+
return {
|
|
235
|
+
tool: "diagnose_storage_pressure",
|
|
236
|
+
status: relevantDigests.length > 0 || tableRows.length > 0 || metrics.length > 0
|
|
237
|
+
? "ok"
|
|
238
|
+
: "inconclusive",
|
|
239
|
+
severity,
|
|
240
|
+
summary: withDatasourceSummary(rootCauseCandidates[0]?.code === "storage_pressure_snapshot_collected"
|
|
241
|
+
? "Storage-pressure diagnosis collected local evidence without isolating a dominant pressure signal"
|
|
242
|
+
: "Storage-pressure diagnosis collected local SQL and table metadata evidence", ctx.datasource),
|
|
243
|
+
diagnosisWindow: {
|
|
244
|
+
from: diagnosisInput.timeRange?.from,
|
|
245
|
+
to: diagnosisInput.timeRange?.to,
|
|
246
|
+
relative: diagnosisInput.timeRange?.relative,
|
|
247
|
+
},
|
|
248
|
+
rootCauseCandidates: rootCauseCandidates.slice(0, maxCandidates),
|
|
249
|
+
keyFindings,
|
|
250
|
+
suspiciousEntities: suspiciousSqls.length > 0 || suspiciousTables.length > 0
|
|
251
|
+
? {
|
|
252
|
+
sqls: suspiciousSqls.length > 0 ? suspiciousSqls : undefined,
|
|
253
|
+
tables: suspiciousTables.length > 0 ? suspiciousTables : undefined,
|
|
254
|
+
}
|
|
255
|
+
: undefined,
|
|
256
|
+
evidence: [
|
|
257
|
+
{
|
|
258
|
+
source: "statement_digest",
|
|
259
|
+
title: "Statement digest storage counters",
|
|
260
|
+
summary: relevantDigests.length > 0
|
|
261
|
+
? `Collected ${relevantDigests.length} digest rows; tmp_disk=${tmpDiskDigests.length}, scan_heavy=${scanDigests.length}, sort_or_tmp=${Math.max(sortDigests.length, tmpTableDigests.length)}.`
|
|
262
|
+
: "No matching rows were returned from performance_schema.events_statements_summary_by_digest.",
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
source: "table_storage",
|
|
266
|
+
title: "Table storage footprint",
|
|
267
|
+
summary: tableRows.length > 0
|
|
268
|
+
? `Collected ${tableRows.length} rows from information_schema.TABLES; largest=${[tableRows[0]?.schemaName, tableRows[0]?.tableName].filter(Boolean).join(".") || "n/a"}${tableRows[0]?.totalMb !== undefined ? ` (${tableRows[0].totalMb} MB)` : ""}.`
|
|
269
|
+
: "No matching table-size rows were returned from information_schema.TABLES.",
|
|
270
|
+
},
|
|
271
|
+
...metricEvidence,
|
|
272
|
+
],
|
|
273
|
+
recommendedActions: [...new Set(recommendedActions)],
|
|
274
|
+
recommendedNextTools: [...recommendedNextTools],
|
|
275
|
+
nextToolInputs: dedupeNextToolInputs(nextToolInputs).slice(0, 5),
|
|
276
|
+
limitations: [
|
|
277
|
+
...metricsSourceLimitation(metricsSource),
|
|
278
|
+
"Statement digest counters are cumulative within performance_schema retention and are not yet filtered by the requested time_range.",
|
|
279
|
+
],
|
|
280
|
+
};
|
|
281
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SessionContext } from "../../context/session-context.js";
|
|
2
|
+
import type { DiagnoseStoragePressureInput, DiagnosticResult } from "../../diagnostics/types.js";
|
|
3
|
+
import type { TaurusDBEngine } from "../../engine.js";
|
|
4
|
+
export declare function diagnoseStoragePressure(engine: TaurusDBEngine, input: DiagnoseStoragePressureInput, ctx: SessionContext): Promise<DiagnosticResult>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { queryMetricsSafely, } from "../helpers.js";
|
|
2
|
+
import { buildStoragePressureDiagnosis } from "./storage-pressure-helpers.js";
|
|
3
|
+
const STORAGE_PRESSURE_METRICS = [
|
|
4
|
+
"storage_used_size",
|
|
5
|
+
"storage_write_delay",
|
|
6
|
+
"storage_read_delay",
|
|
7
|
+
"write_iops",
|
|
8
|
+
"read_iops",
|
|
9
|
+
"write_throughput",
|
|
10
|
+
"read_throughput",
|
|
11
|
+
"temp_tables_per_min",
|
|
12
|
+
];
|
|
13
|
+
export async function diagnoseStoragePressure(engine, input, ctx) {
|
|
14
|
+
const [digestRows, tableRows, metrics] = await Promise.all([
|
|
15
|
+
engine.findStorageStatementDigests(input, ctx).catch(() => []),
|
|
16
|
+
engine.findTableStorageStats(input, ctx).catch(() => []),
|
|
17
|
+
queryMetricsSafely(engine.metricsSource, STORAGE_PRESSURE_METRICS, input, ctx),
|
|
18
|
+
]);
|
|
19
|
+
return buildStoragePressureDiagnosis({
|
|
20
|
+
diagnosisInput: input,
|
|
21
|
+
ctx,
|
|
22
|
+
digestRows,
|
|
23
|
+
tableRows,
|
|
24
|
+
metrics,
|
|
25
|
+
metricsSource: engine.metricsSource,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SessionContext } from "../../context/session-context.js";
|
|
2
|
+
import { type FindTopSlowSqlInput, type FindTopSlowSqlResult } from "../../diagnostics/types.js";
|
|
3
|
+
import type { TaurusDBEngine } from "../../engine.js";
|
|
4
|
+
export declare function findTopSlowSql(engine: TaurusDBEngine, input: FindTopSlowSqlInput, ctx: SessionContext): Promise<FindTopSlowSqlResult>;
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { normalizeSql, sqlHash } from "../../utils/hash.js";
|
|
2
|
+
import { clampInteger, withDatasourceSummary, } from "../helpers.js";
|
|
3
|
+
export async function findTopSlowSql(engine, input, ctx) {
|
|
4
|
+
try {
|
|
5
|
+
const [digestRows, externalTopSqls] = await Promise.all([
|
|
6
|
+
engine.findTopStatementDigests(input, ctx).catch(() => []),
|
|
7
|
+
engine.slowSqlSource?.findTop
|
|
8
|
+
? engine.slowSqlSource.findTop(input, ctx).catch(() => [])
|
|
9
|
+
: Promise.resolve([]),
|
|
10
|
+
]);
|
|
11
|
+
if (digestRows.length === 0 && externalTopSqls.length === 0) {
|
|
12
|
+
const performanceSchemaEnabled = await engine.isPerformanceSchemaEnabled(ctx);
|
|
13
|
+
return {
|
|
14
|
+
tool: "find_top_slow_sql",
|
|
15
|
+
status: "inconclusive",
|
|
16
|
+
summary: withDatasourceSummary(performanceSchemaEnabled === false
|
|
17
|
+
? "Top slow SQL discovery could not collect local digest evidence because performance_schema is disabled"
|
|
18
|
+
: "No statement digest ranking evidence was available for top slow SQL discovery", ctx.datasource),
|
|
19
|
+
diagnosisWindow: {
|
|
20
|
+
from: input.timeRange?.from,
|
|
21
|
+
to: input.timeRange?.to,
|
|
22
|
+
relative: input.timeRange?.relative,
|
|
23
|
+
},
|
|
24
|
+
topSqls: [],
|
|
25
|
+
evidence: [
|
|
26
|
+
{
|
|
27
|
+
source: "statement_digest",
|
|
28
|
+
title: "Statement digest ranking",
|
|
29
|
+
summary: performanceSchemaEnabled === false
|
|
30
|
+
? "performance_schema is disabled on the selected datasource. performance_schema.events_statements_summary_by_digest is therefore unavailable for local slow-SQL digest discovery."
|
|
31
|
+
: "No matching rows were returned from performance_schema.events_statements_summary_by_digest, and no external Taurus slow-SQL ranking was available.",
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
limitations: [
|
|
35
|
+
performanceSchemaEnabled === false
|
|
36
|
+
? "performance_schema is currently disabled. Enable it and repopulate statement activity if you want local digest-based slow SQL discovery."
|
|
37
|
+
: engine.slowSqlSource?.findTop
|
|
38
|
+
? "Neither performance_schema digest ranking nor the configured external Taurus slow-SQL ranking returned usable rows."
|
|
39
|
+
: "This discovery currently depends on performance_schema digest summaries being enabled and populated.",
|
|
40
|
+
"The selected time_range is not yet enforced against cumulative digest counters; current ranking reflects retained digest summaries.",
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const digestTopSqls = digestRows.map((row) => {
|
|
45
|
+
const evidenceSources = ["statement_digest"];
|
|
46
|
+
const recommendationParts = [];
|
|
47
|
+
if (row.querySampleText || row.digestText) {
|
|
48
|
+
recommendationParts.push("Run diagnose_slow_query with sql or digest_text to analyze the dominant bottleneck.");
|
|
49
|
+
}
|
|
50
|
+
if ((row.avgLockTimeMs ?? 0) >= 10) {
|
|
51
|
+
recommendationParts.push("Correlate with diagnose_lock_contention if lock time remains elevated.");
|
|
52
|
+
}
|
|
53
|
+
if ((row.execCount ?? 0) >= 20 && (row.avgLatencyMs ?? 0) < 50) {
|
|
54
|
+
recommendationParts.push("Review high-frequency workload shape before focusing only on single-query latency.");
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
sqlHash: row.querySampleText
|
|
58
|
+
? sqlHash(normalizeSql(row.querySampleText))
|
|
59
|
+
: undefined,
|
|
60
|
+
digestText: row.digestText,
|
|
61
|
+
sampleSql: row.querySampleText,
|
|
62
|
+
avgLatencyMs: row.avgLatencyMs,
|
|
63
|
+
totalLatencyMs: row.totalLatencyMs,
|
|
64
|
+
execCount: row.execCount,
|
|
65
|
+
avgLockTimeMs: row.avgLockTimeMs,
|
|
66
|
+
avgRowsExamined: row.avgRowsExamined,
|
|
67
|
+
evidenceSources,
|
|
68
|
+
recommendation: recommendationParts.length > 0
|
|
69
|
+
? recommendationParts.join(" ")
|
|
70
|
+
: "Review this digest with diagnose_slow_query if it aligns with the reported symptom window.",
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
const externalMappedSqls = externalTopSqls.map((sample) => {
|
|
74
|
+
const recommendationParts = [
|
|
75
|
+
"Run diagnose_slow_query with sql or digest_text to analyze the dominant bottleneck.",
|
|
76
|
+
];
|
|
77
|
+
if ((sample.avgLockTimeMs ?? 0) >= 10) {
|
|
78
|
+
recommendationParts.push("Correlate with diagnose_lock_contention if lock time remains elevated.");
|
|
79
|
+
}
|
|
80
|
+
if ((sample.execCount ?? 0) >= 20 && (sample.avgLatencyMs ?? 0) < 50) {
|
|
81
|
+
recommendationParts.push("Review high-frequency workload shape before focusing only on single-query latency.");
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
sqlHash: sample.sqlHash,
|
|
85
|
+
digestText: sample.digestText,
|
|
86
|
+
sampleSql: sample.sql,
|
|
87
|
+
avgLatencyMs: sample.avgLatencyMs,
|
|
88
|
+
totalLatencyMs: sample.avgLatencyMs !== undefined
|
|
89
|
+
? sample.avgLatencyMs * Math.max(sample.execCount ?? 1, 1)
|
|
90
|
+
: undefined,
|
|
91
|
+
execCount: sample.execCount,
|
|
92
|
+
avgLockTimeMs: sample.avgLockTimeMs,
|
|
93
|
+
avgRowsExamined: sample.avgRowsExamined,
|
|
94
|
+
evidenceSources: [sample.source],
|
|
95
|
+
recommendation: recommendationParts.join(" "),
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
const mergedTopSqls = [...digestTopSqls];
|
|
99
|
+
for (const externalSql of externalMappedSqls) {
|
|
100
|
+
const existingIndex = mergedTopSqls.findIndex((item) => (externalSql.sqlHash && item.sqlHash === externalSql.sqlHash) ||
|
|
101
|
+
(externalSql.digestText &&
|
|
102
|
+
item.digestText === externalSql.digestText) ||
|
|
103
|
+
(externalSql.sampleSql && item.sampleSql === externalSql.sampleSql));
|
|
104
|
+
if (existingIndex >= 0) {
|
|
105
|
+
const existing = mergedTopSqls[existingIndex];
|
|
106
|
+
mergedTopSqls[existingIndex] = {
|
|
107
|
+
...existing,
|
|
108
|
+
sampleSql: existing.sampleSql ?? externalSql.sampleSql,
|
|
109
|
+
avgLatencyMs: existing.avgLatencyMs ?? externalSql.avgLatencyMs,
|
|
110
|
+
totalLatencyMs: existing.totalLatencyMs ?? externalSql.totalLatencyMs,
|
|
111
|
+
execCount: existing.execCount ?? externalSql.execCount,
|
|
112
|
+
avgLockTimeMs: existing.avgLockTimeMs ?? externalSql.avgLockTimeMs,
|
|
113
|
+
avgRowsExamined: existing.avgRowsExamined ?? externalSql.avgRowsExamined,
|
|
114
|
+
evidenceSources: [
|
|
115
|
+
...new Set([
|
|
116
|
+
...existing.evidenceSources,
|
|
117
|
+
...externalSql.evidenceSources,
|
|
118
|
+
]),
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
mergedTopSqls.push(externalSql);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const topSqls = mergedTopSqls
|
|
127
|
+
.sort((left, right) => {
|
|
128
|
+
const leftAvgLatency = left.avgLatencyMs ?? 0;
|
|
129
|
+
const rightAvgLatency = right.avgLatencyMs ?? 0;
|
|
130
|
+
const leftTotalLatency = left.totalLatencyMs ?? 0;
|
|
131
|
+
const rightTotalLatency = right.totalLatencyMs ?? 0;
|
|
132
|
+
const leftExecCount = left.execCount ?? 0;
|
|
133
|
+
const rightExecCount = right.execCount ?? 0;
|
|
134
|
+
const leftLockTime = left.avgLockTimeMs ?? 0;
|
|
135
|
+
const rightLockTime = right.avgLockTimeMs ?? 0;
|
|
136
|
+
switch (input.sortBy) {
|
|
137
|
+
case "avg_latency":
|
|
138
|
+
return (rightAvgLatency - leftAvgLatency ||
|
|
139
|
+
rightTotalLatency - leftTotalLatency);
|
|
140
|
+
case "exec_count":
|
|
141
|
+
return (rightExecCount - leftExecCount ||
|
|
142
|
+
rightTotalLatency - leftTotalLatency);
|
|
143
|
+
case "lock_time":
|
|
144
|
+
return (rightLockTime - leftLockTime ||
|
|
145
|
+
rightTotalLatency - leftTotalLatency);
|
|
146
|
+
default:
|
|
147
|
+
return (rightTotalLatency - leftTotalLatency ||
|
|
148
|
+
rightAvgLatency - leftAvgLatency);
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
.slice(0, clampInteger(input.topN, 5, 1, 20));
|
|
152
|
+
return {
|
|
153
|
+
tool: "find_top_slow_sql",
|
|
154
|
+
status: "ok",
|
|
155
|
+
summary: withDatasourceSummary(`Top slow SQL discovery collected ${topSqls.length} suspect statements`, ctx.datasource),
|
|
156
|
+
diagnosisWindow: {
|
|
157
|
+
from: input.timeRange?.from,
|
|
158
|
+
to: input.timeRange?.to,
|
|
159
|
+
relative: input.timeRange?.relative,
|
|
160
|
+
},
|
|
161
|
+
topSqls,
|
|
162
|
+
evidence: [
|
|
163
|
+
...(digestRows.length > 0
|
|
164
|
+
? [
|
|
165
|
+
{
|
|
166
|
+
source: "statement_digest",
|
|
167
|
+
title: "Statement digest ranking",
|
|
168
|
+
summary: `Collected ${digestRows.length} ranked rows from performance_schema.events_statements_summary_by_digest ordered by ${input.sortBy ?? "total_latency"}.`,
|
|
169
|
+
},
|
|
170
|
+
]
|
|
171
|
+
: []),
|
|
172
|
+
...(externalTopSqls.length > 0
|
|
173
|
+
? [
|
|
174
|
+
{
|
|
175
|
+
source: externalTopSqls[0].source,
|
|
176
|
+
title: "External Taurus slow SQL ranking",
|
|
177
|
+
summary: `Collected ${externalTopSqls.length} ranked rows from the configured Taurus slow-SQL source ordered by ${input.sortBy ?? "total_latency"}.`,
|
|
178
|
+
rawRef: externalTopSqls[0].rawRef,
|
|
179
|
+
},
|
|
180
|
+
]
|
|
181
|
+
: []),
|
|
182
|
+
],
|
|
183
|
+
limitations: [
|
|
184
|
+
...(digestRows.length > 0
|
|
185
|
+
? [
|
|
186
|
+
"The selected time_range is not yet enforced against cumulative digest counters; current ranking reflects retained digest summaries.",
|
|
187
|
+
]
|
|
188
|
+
: []),
|
|
189
|
+
...(externalTopSqls.length > 0
|
|
190
|
+
? [
|
|
191
|
+
"External Taurus slow-SQL ranking depends on the configured API retention window and may not cover every statement in the requested time range.",
|
|
192
|
+
]
|
|
193
|
+
: []),
|
|
194
|
+
],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
return {
|
|
199
|
+
tool: "find_top_slow_sql",
|
|
200
|
+
status: "inconclusive",
|
|
201
|
+
summary: withDatasourceSummary("Top slow SQL discovery could not collect digest ranking evidence", ctx.datasource),
|
|
202
|
+
diagnosisWindow: {
|
|
203
|
+
from: input.timeRange?.from,
|
|
204
|
+
to: input.timeRange?.to,
|
|
205
|
+
relative: input.timeRange?.relative,
|
|
206
|
+
},
|
|
207
|
+
topSqls: [],
|
|
208
|
+
evidence: [
|
|
209
|
+
{
|
|
210
|
+
source: "statement_digest",
|
|
211
|
+
title: "Statement digest ranking unavailable",
|
|
212
|
+
summary: error instanceof Error
|
|
213
|
+
? error.message
|
|
214
|
+
: "Digest ranking query failed unexpectedly.",
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
limitations: [
|
|
218
|
+
"This discovery currently depends on performance_schema digest summaries being accessible from the selected datasource.",
|
|
219
|
+
],
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
}
|
package/dist/engine.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type ProfileLoader } from "./auth/sql-profile-loader.js";
|
|
2
|
+
import { type SecretResolver } from "./auth/secret-resolver.js";
|
|
3
|
+
import { type CapabilityProbe } from "./capability/probe.js";
|
|
4
|
+
import type { CapabilitySnapshot, FeatureMatrix, KernelInfo } from "./capability/types.js";
|
|
5
|
+
import { type Config } from "./config/index.js";
|
|
6
|
+
import type { DatasourceResolveInput, DatasourceResolver, SessionContext } from "./context/session-context.js";
|
|
7
|
+
import { type ConnectionPool } from "./executor/connection-pool.js";
|
|
8
|
+
import { type CancelResult, type ExplainResult, type MutationOptions, type MutationResult, type QueryResult, type QueryStatus, type ReadonlyOptions, type SqlExecutor } from "./executor/sql-executor.js";
|
|
9
|
+
import { type ConfirmationStore, type ConfirmationToken, type ConfirmationValidationResult } from "./safety/confirmation-store.js";
|
|
10
|
+
import { type Guardrail, type GuardrailDecision, type InspectInput } from "./safety/guardrail.js";
|
|
11
|
+
import { type DatabaseInfo, type SchemaIntrospector, type TableInfo, type TableSchema } from "./schema/introspector.js";
|
|
12
|
+
import { type FlashbackInput } from "./taurus/flashback.js";
|
|
13
|
+
import { type RestoreRecycleBinTableInput } from "./taurus/recycle-bin.js";
|
|
14
|
+
import { type DbHotspotResult, type DiagnoseDbHotspotInput, type DiagnoseServiceLatencyInput, type FindTopSlowSqlInput, type FindTopSlowSqlResult, type DiagnoseConnectionSpikeInput, type DiagnoseLockContentionInput, type DiagnoseSlowQueryInput, type DiagnoseStoragePressureInput, type DiagnosticResult, type ServiceLatencyResult } from "./diagnostics/types.js";
|
|
15
|
+
import { type SlowSqlSource } from "./diagnostics/slow-sql-source.js";
|
|
16
|
+
import { type MetricsSource } from "./diagnostics/metrics-source.js";
|
|
17
|
+
import type { ConfirmationOutcome, DataSourceInfo, EnhancedExplainResult, IssueConfirmationInput, ShowLockWaitsInput, ShowProcesslistInput, TaurusDBEngineCreateOptions, TaurusDBEngineDeps } from "./engine/types.js";
|
|
18
|
+
import { type DeadlockSummary, type MetadataLockRow, type StatementDigestRow, type StatementWaitEventRow, type TableStorageRow } from "./engine/helpers.js";
|
|
19
|
+
export type { ConfirmationOutcome, DataSourceInfo, EnhancedExplainResult, IssueConfirmationInput, ShowLockWaitsInput, ShowProcesslistInput, TaurusDBEngineCreateOptions, TaurusDBEngineDeps, } from "./engine/types.js";
|
|
20
|
+
export declare class TaurusDBEngine {
|
|
21
|
+
readonly config: Config;
|
|
22
|
+
readonly profileLoader: ProfileLoader;
|
|
23
|
+
readonly secretResolver: SecretResolver;
|
|
24
|
+
readonly datasourceResolver: DatasourceResolver;
|
|
25
|
+
readonly connectionPool: ConnectionPool;
|
|
26
|
+
readonly schemaIntrospector: SchemaIntrospector;
|
|
27
|
+
readonly guardrail: Guardrail;
|
|
28
|
+
readonly executor: SqlExecutor;
|
|
29
|
+
readonly confirmationStore: ConfirmationStore;
|
|
30
|
+
readonly capabilityProbe: CapabilityProbe;
|
|
31
|
+
readonly slowSqlSource?: SlowSqlSource;
|
|
32
|
+
readonly metricsSource?: MetricsSource;
|
|
33
|
+
constructor(deps: TaurusDBEngineDeps);
|
|
34
|
+
static create(options?: TaurusDBEngineCreateOptions): Promise<TaurusDBEngine>;
|
|
35
|
+
listDataSources(): Promise<DataSourceInfo[]>;
|
|
36
|
+
getDefaultDataSource(): Promise<string | undefined>;
|
|
37
|
+
resolveContext(input: DatasourceResolveInput, taskId: string): Promise<SessionContext>;
|
|
38
|
+
listDatabases(ctx: SessionContext): Promise<DatabaseInfo[]>;
|
|
39
|
+
listTables(ctx: SessionContext, database: string): Promise<TableInfo[]>;
|
|
40
|
+
describeTable(ctx: SessionContext, database: string, table: string): Promise<TableSchema>;
|
|
41
|
+
inspectSql(input: InspectInput): Promise<GuardrailDecision>;
|
|
42
|
+
probeCapabilities(ctx: SessionContext): Promise<CapabilitySnapshot>;
|
|
43
|
+
getKernelInfo(ctx: SessionContext): Promise<KernelInfo>;
|
|
44
|
+
listFeatures(ctx: SessionContext): Promise<FeatureMatrix>;
|
|
45
|
+
showProcesslist(input: ShowProcesslistInput, ctx: SessionContext): Promise<QueryResult>;
|
|
46
|
+
showLockWaits(input: ShowLockWaitsInput, ctx: SessionContext): Promise<QueryResult>;
|
|
47
|
+
findMetadataLockWaits(input: DiagnoseLockContentionInput, ctx: SessionContext): Promise<MetadataLockRow[]>;
|
|
48
|
+
findLatestDeadlock(ctx: SessionContext): Promise<DeadlockSummary | undefined>;
|
|
49
|
+
findStatementDigestSample(digestText: string, ctx: SessionContext): Promise<StatementDigestRow | undefined>;
|
|
50
|
+
findStatementDigestSampleForSql(sql: string, ctx: SessionContext): Promise<StatementDigestRow | undefined>;
|
|
51
|
+
findStatementDigestCandidatesForSqlHints(sqlText: string, ctx: SessionContext): Promise<StatementDigestRow[]>;
|
|
52
|
+
findTopStatementDigests(input: FindTopSlowSqlInput, ctx: SessionContext): Promise<StatementDigestRow[]>;
|
|
53
|
+
isPerformanceSchemaEnabled(ctx: SessionContext): Promise<boolean | undefined>;
|
|
54
|
+
findStorageStatementDigests(input: DiagnoseStoragePressureInput, ctx: SessionContext): Promise<StatementDigestRow[]>;
|
|
55
|
+
findStatementWaitEvents(digestText: string, ctx: SessionContext): Promise<StatementWaitEventRow[]>;
|
|
56
|
+
findTableStorageStats(input: DiagnoseStoragePressureInput, ctx: SessionContext): Promise<TableStorageRow[]>;
|
|
57
|
+
diagnoseSlowQuery(input: DiagnoseSlowQueryInput, ctx: SessionContext): Promise<DiagnosticResult>;
|
|
58
|
+
diagnoseServiceLatency(input: DiagnoseServiceLatencyInput, ctx: SessionContext): Promise<ServiceLatencyResult>;
|
|
59
|
+
diagnoseDbHotspot(input: DiagnoseDbHotspotInput, ctx: SessionContext): Promise<DbHotspotResult>;
|
|
60
|
+
findTopSlowSql(input: FindTopSlowSqlInput, ctx: SessionContext): Promise<FindTopSlowSqlResult>;
|
|
61
|
+
diagnoseConnectionSpike(input: DiagnoseConnectionSpikeInput, ctx: SessionContext): Promise<DiagnosticResult>;
|
|
62
|
+
diagnoseLockContention(input: DiagnoseLockContentionInput, ctx: SessionContext): Promise<DiagnosticResult>;
|
|
63
|
+
diagnoseStoragePressure(input: DiagnoseStoragePressureInput, ctx: SessionContext): Promise<DiagnosticResult>;
|
|
64
|
+
explain(sql: string, ctx: SessionContext): Promise<ExplainResult>;
|
|
65
|
+
explainEnhanced(sql: string, ctx: SessionContext): Promise<EnhancedExplainResult>;
|
|
66
|
+
executeReadonly(sql: string, ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
67
|
+
executeMutation(sql: string, ctx: SessionContext, opts?: MutationOptions): Promise<MutationResult>;
|
|
68
|
+
flashbackQuery(input: FlashbackInput, ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
69
|
+
listRecycleBin(ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
70
|
+
restoreRecycleBinTable(input: RestoreRecycleBinTableInput, ctx: SessionContext, opts?: MutationOptions): Promise<MutationResult>;
|
|
71
|
+
getQueryStatus(queryId: string): Promise<QueryStatus>;
|
|
72
|
+
cancelQuery(queryId: string): Promise<CancelResult>;
|
|
73
|
+
issueConfirmation(input: IssueConfirmationInput): Promise<ConfirmationToken>;
|
|
74
|
+
validateConfirmation(token: string, sql: string, ctx: SessionContext): Promise<ConfirmationValidationResult>;
|
|
75
|
+
handleConfirmation(decision: GuardrailDecision, ctx: SessionContext): Promise<ConfirmationOutcome>;
|
|
76
|
+
close(): Promise<void>;
|
|
77
|
+
}
|