From aa31d921d1454ced057089c8645a9c9b6d1a77a6 Mon Sep 17 00:00:00 2001 From: Michael Erickson Date: Thu, 23 Feb 2023 12:05:32 -0800 Subject: [PATCH] sql: add metrics for prepared statement memory usage Add node-level metrics for memory used by prepared statements across all sessions. Assists: #72581 Epic: None Release note (ui change): Add the following new metrics to track memory usage of prepared statements in sessions: - sql.mem.internal.session.prepared.current - sql.mem.internal.session.prepared.max-avg - sql.mem.internal.session.prepared.max-count - sql.mem.internal.session.prepared.max-max - sql.mem.internal.session.prepared.max-p50 - sql.mem.internal.session.prepared.max-p75 - sql.mem.internal.session.prepared.max-p90 - sql.mem.internal.session.prepared.max-p99 - sql.mem.internal.session.prepared.max-p99.9 - sql.mem.internal.session.prepared.max-p99.99 - sql.mem.internal.session.prepared.max-p99.999 - sql.mem.sql.session.prepared.current - sql.mem.sql.session.prepared.max-avg - sql.mem.sql.session.prepared.max-count - sql.mem.sql.session.prepared.max-max - sql.mem.sql.session.prepared.max-p50 - sql.mem.sql.session.prepared.max-p75 - sql.mem.sql.session.prepared.max-p90 - sql.mem.sql.session.prepared.max-p99 - sql.mem.sql.session.prepared.max-p99.9 - sql.mem.sql.session.prepared.max-p99.99 - sql.mem.sql.session.prepared.max-p99.999 --- pkg/sql/conn_executor.go | 14 +++++++++ pkg/sql/conn_executor_prepare.go | 2 +- pkg/sql/mem_metrics.go | 49 +++++++++++++++++--------------- pkg/ts/catalog/chart_catalog.go | 16 +++++++++++ 4 files changed, 57 insertions(+), 24 deletions(-) diff --git a/pkg/sql/conn_executor.go b/pkg/sql/conn_executor.go index fb7340f6f4d2..d1ee58b9c162 100644 --- a/pkg/sql/conn_executor.go +++ b/pkg/sql/conn_executor.go @@ -958,6 +958,13 @@ func (s *Server) newConnExecutor( memMetrics.SessionMaxBytesHist, -1 /* increment */, noteworthyMemoryUsageBytes, s.cfg.Settings, ) + sessionPreparedMon := mon.NewMonitor( + "session prepared statements", + mon.MemoryResource, + memMetrics.SessionPreparedCurBytesCount, + memMetrics.SessionPreparedMaxBytesHist, + -1 /* increment */, noteworthyMemoryUsageBytes, s.cfg.Settings, + ) // The txn monitor is started in txnState.resetForNewSQLTxn(). txnMon := mon.NewMonitor( "txn", @@ -975,6 +982,7 @@ func (s *Server) newConnExecutor( clientComm: clientComm, mon: sessionRootMon, sessionMon: sessionMon, + sessionPreparedMon: sessionPreparedMon, sessionDataStack: sdMutIterator.sds, dataMutatorIterator: sdMutIterator, state: txnState{ @@ -1205,10 +1213,12 @@ func (ex *connExecutor) close(ctx context.Context, closeType closeType) { if closeType != panicClose { ex.state.mon.Stop(ctx) + ex.sessionPreparedMon.Stop(ctx) ex.sessionMon.Stop(ctx) ex.mon.Stop(ctx) } else { ex.state.mon.EmergencyStop(ctx) + ex.sessionPreparedMon.EmergencyStop(ctx) ex.sessionMon.EmergencyStop(ctx) ex.mon.EmergencyStop(ctx) } @@ -1254,6 +1264,9 @@ type connExecutor struct { // statistics for result sets (which escape transactions). mon *mon.BytesMonitor sessionMon *mon.BytesMonitor + + // sessionPreparedMon tracks memory usage by prepared statements. + sessionPreparedMon *mon.BytesMonitor // memMetrics contains the metrics that statements executed on this connection // will contribute to. memMetrics MemoryMetrics @@ -1812,6 +1825,7 @@ func (ex *connExecutor) activate( // single threaded, and the point of buffering is just to avoid contention. ex.mon.Start(ctx, parentMon, reserved) ex.sessionMon.StartNoReserved(ctx, ex.mon) + ex.sessionPreparedMon.StartNoReserved(ctx, ex.sessionMon) // Enable the trace if configured. if traceSessionEventLogEnabled.Get(&ex.server.cfg.Settings.SV) { diff --git a/pkg/sql/conn_executor_prepare.go b/pkg/sql/conn_executor_prepare.go index b025d723622c..cb3603adec46 100644 --- a/pkg/sql/conn_executor_prepare.go +++ b/pkg/sql/conn_executor_prepare.go @@ -157,7 +157,7 @@ func (ex *connExecutor) prepare( ) (_ *PreparedStatement, retErr error) { prepared := &PreparedStatement{ - memAcc: ex.sessionMon.MakeBoundAccount(), + memAcc: ex.sessionPreparedMon.MakeBoundAccount(), refCount: 1, createdAt: timeutil.Now(), diff --git a/pkg/sql/mem_metrics.go b/pkg/sql/mem_metrics.go index 248aff4ddc88..995a95d1226d 100644 --- a/pkg/sql/mem_metrics.go +++ b/pkg/sql/mem_metrics.go @@ -34,6 +34,10 @@ type MemoryMetrics struct { TxnCurBytesCount *metric.Gauge SessionMaxBytesHist metric.IHistogram SessionCurBytesCount *metric.Gauge + + // For prepared statements. + SessionPreparedMaxBytesHist metric.IHistogram + SessionPreparedCurBytesCount *metric.Gauge } // MetricStruct implements the metrics.Struct interface. @@ -66,6 +70,18 @@ func makeMemMetricMetadata(name, help string) metric.Metadata { } } +func makeMemMetricHistogram( + metadata metric.Metadata, histogramWindow time.Duration, +) metric.IHistogram { + return metric.NewHistogram(metric.HistogramOptions{ + Metadata: metadata, + Duration: histogramWindow, + MaxVal: log10int64times1000, + SigFigs: 3, + Buckets: metric.MemoryUsage64MBBuckets, + }) +} + // MakeBaseMemMetrics instantiates the metric objects for an SQL endpoint, but // only includes the root metrics: .max and .current, without txn and session. func MakeBaseMemMetrics(endpoint string, histogramWindow time.Duration) BaseMemoryMetrics { @@ -73,13 +89,7 @@ func MakeBaseMemMetrics(endpoint string, histogramWindow time.Duration) BaseMemo MetaMemMaxBytes := makeMemMetricMetadata(prefix+".max", "Memory usage per sql statement for "+endpoint) MetaMemCurBytes := makeMemMetricMetadata(prefix+".current", "Current sql statement memory usage for "+endpoint) return BaseMemoryMetrics{ - MaxBytesHist: metric.NewHistogram(metric.HistogramOptions{ - Metadata: MetaMemMaxBytes, - Duration: histogramWindow, - MaxVal: log10int64times1000, - SigFigs: 3, - Buckets: metric.MemoryUsage64MBBuckets, - }), + MaxBytesHist: makeMemMetricHistogram(MetaMemMaxBytes, histogramWindow), CurBytesCount: metric.NewGauge(MetaMemCurBytes), } } @@ -92,22 +102,15 @@ func MakeMemMetrics(endpoint string, histogramWindow time.Duration) MemoryMetric MetaMemTxnCurBytes := makeMemMetricMetadata(prefix+".txn.current", "Current sql transaction memory usage for "+endpoint) MetaMemMaxSessionBytes := makeMemMetricMetadata(prefix+".session.max", "Memory usage per sql session for "+endpoint) MetaMemSessionCurBytes := makeMemMetricMetadata(prefix+".session.current", "Current sql session memory usage for "+endpoint) + MetaMemMaxSessionPreparedBytes := makeMemMetricMetadata(prefix+".session.prepared.max", "Memory usage by prepared statements per sql session for "+endpoint) + MetaMemSessionPreparedCurBytes := makeMemMetricMetadata(prefix+".session.prepared.current", "Current sql session memory usage by prepared statements for "+endpoint) return MemoryMetrics{ - BaseMemoryMetrics: base, - TxnMaxBytesHist: metric.NewHistogram(metric.HistogramOptions{ - Metadata: MetaMemMaxTxnBytes, - Duration: histogramWindow, - MaxVal: log10int64times1000, - SigFigs: 3, - Buckets: metric.MemoryUsage64MBBuckets}), - TxnCurBytesCount: metric.NewGauge(MetaMemTxnCurBytes), - SessionMaxBytesHist: metric.NewHistogram(metric.HistogramOptions{ - Metadata: MetaMemMaxSessionBytes, - Duration: histogramWindow, - MaxVal: log10int64times1000, - SigFigs: 3, - Buckets: metric.MemoryUsage64MBBuckets}), - SessionCurBytesCount: metric.NewGauge(MetaMemSessionCurBytes), + BaseMemoryMetrics: base, + TxnMaxBytesHist: makeMemMetricHistogram(MetaMemMaxTxnBytes, histogramWindow), + TxnCurBytesCount: metric.NewGauge(MetaMemTxnCurBytes), + SessionMaxBytesHist: makeMemMetricHistogram(MetaMemMaxSessionBytes, histogramWindow), + SessionCurBytesCount: metric.NewGauge(MetaMemSessionCurBytes), + SessionPreparedMaxBytesHist: makeMemMetricHistogram(MetaMemMaxSessionPreparedBytes, histogramWindow), + SessionPreparedCurBytesCount: metric.NewGauge(MetaMemSessionPreparedCurBytes), } - } diff --git a/pkg/ts/catalog/chart_catalog.go b/pkg/ts/catalog/chart_catalog.go index 10533e44beb8..1df78835de24 100644 --- a/pkg/ts/catalog/chart_catalog.go +++ b/pkg/ts/catalog/chart_catalog.go @@ -2542,6 +2542,14 @@ var charts = []sectionDescription{ Title: "Session Current", Metrics: []string{"sql.mem.internal.session.current"}, }, + { + Title: "Prepared Statements All", + Metrics: []string{"sql.mem.internal.session.prepared.max"}, + }, + { + Title: "Prepared Statements Current", + Metrics: []string{"sql.mem.internal.session.prepared.current"}, + }, { Title: "Txn All", Metrics: []string{"sql.mem.internal.txn.max"}, @@ -2563,6 +2571,14 @@ var charts = []sectionDescription{ Title: "Max", Metrics: []string{"sql.mem.sql.session.max"}, }, + { + Title: "Prepared Statements Current", + Metrics: []string{"sql.mem.sql.session.prepared.current"}, + }, + { + Title: "Prepared Statements Max", + Metrics: []string{"sql.mem.sql.session.prepared.max"}, + }, }, }, {