From e98e9594bce66288e7c0021aeefc3d4e8d44157b Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Wed, 30 Nov 2022 12:23:59 +0800 Subject: [PATCH] *: add telemetry support for IndexMerge (#39469) close pingcap/tidb#39475 --- executor/adapter.go | 1 + executor/builder.go | 3 +++ metrics/telemetry.go | 26 +++++++++++++++++++++++++ session/session.go | 6 ++++++ telemetry/data_feature_usage.go | 14 ++++++++++++++ telemetry/data_feature_usage_test.go | 29 ++++++++++++++++++++++++++++ 6 files changed, 79 insertions(+) diff --git a/executor/adapter.go b/executor/adapter.go index aaa7aa8c4b8c9..a7942f2638a02 100644 --- a/executor/adapter.go +++ b/executor/adapter.go @@ -198,6 +198,7 @@ type TelemetryInfo struct { UseFlashbackToCluster bool PartitionTelemetry *PartitionTelemetryInfo AccountLockTelemetry *AccountLockTelemetryInfo + UseIndexMerge bool } // PartitionTelemetryInfo records table partition telemetry information during execution. diff --git a/executor/builder.go b/executor/builder.go index 8391964095877..e3c4e5533b68f 100644 --- a/executor/builder.go +++ b/executor/builder.go @@ -3977,6 +3977,9 @@ func buildNoRangeIndexMergeReader(b *executorBuilder, v *plannercore.PhysicalInd } func (b *executorBuilder) buildIndexMergeReader(v *plannercore.PhysicalIndexMergeReader) Executor { + if b.Ti != nil { + b.Ti.UseIndexMerge = true + } ts := v.TablePlans[0].(*plannercore.PhysicalTableScan) if err := b.validCanReadTemporaryOrCacheTable(ts.Table); err != nil { b.err = err diff --git a/metrics/telemetry.go b/metrics/telemetry.go index 7460ca5ceb04c..591823f9952d9 100644 --- a/metrics/telemetry.go +++ b/metrics/telemetry.go @@ -155,6 +155,13 @@ var ( Name: "flashback_cluster_usage", Help: "Counter of usage of flashback cluster", }) + TelemetryIndexMergeUsage = prometheus.NewCounter( + prometheus.CounterOpts{ + Namespace: "tidb", + Subsystem: "telemetry", + Name: "index_merge_usage", + Help: "Counter of usage of index merge", + }) TelemetryCompactPartitionCnt = prometheus.NewCounter( prometheus.CounterOpts{ Namespace: "tidb", @@ -396,3 +403,22 @@ func GetDDLUsageCounter() DDLUsageCounter { FlashbackClusterUsed: readCounter(TelemetryFlashbackClusterCnt), } } + +// IndexMergeUsageCounter records the usages of IndexMerge feature. +type IndexMergeUsageCounter struct { + IndexMergeUsed int64 `json:"index_merge_used"` +} + +// Sub returns the difference of two counters. +func (i IndexMergeUsageCounter) Sub(rhs IndexMergeUsageCounter) IndexMergeUsageCounter { + return IndexMergeUsageCounter{ + IndexMergeUsed: i.IndexMergeUsed - rhs.IndexMergeUsed, + } +} + +// GetIndexMergeCounter gets the IndexMerge usage counter. +func GetIndexMergeCounter() IndexMergeUsageCounter { + return IndexMergeUsageCounter{ + IndexMergeUsed: readCounter(TelemetryIndexMergeUsage), + } +} diff --git a/session/session.go b/session/session.go index 437c663999b83..9104c4186bf74 100644 --- a/session/session.go +++ b/session/session.go @@ -150,6 +150,8 @@ var ( telemetryLockUserUsage = metrics.TelemetryAccountLockCnt.WithLabelValues("lockUser") telemetryUnlockUserUsage = metrics.TelemetryAccountLockCnt.WithLabelValues("unlockUser") telemetryCreateOrAlterUserUsage = metrics.TelemetryAccountLockCnt.WithLabelValues("createOrAlterUser") + + telemetryIndexMerge = metrics.TelemetryIndexMergeUsage ) // Session context, it is consistent with the lifecycle of a client connection. @@ -3588,6 +3590,10 @@ func (s *session) updateTelemetryMetric(es *executor.ExecStmt) { telemetryCTEUsageNotCTE.Inc() } + if ti.UseIndexMerge { + telemetryIndexMerge.Inc() + } + if ti.UseMultiSchemaChange { telemetryMultiSchemaChangeUsage.Inc() } diff --git a/telemetry/data_feature_usage.go b/telemetry/data_feature_usage.go index 3766945536d9c..6dec8edcb023a 100644 --- a/telemetry/data_feature_usage.go +++ b/telemetry/data_feature_usage.go @@ -58,6 +58,7 @@ type featureUsage struct { DDLUsageCounter *m.DDLUsageCounter `json:"DDLUsageCounter"` EnableGlobalMemoryControl bool `json:"enableGlobalMemoryControl"` AutoIDNoCache bool `json:"autoIDNoCache"` + IndexMergeUsageCounter *m.IndexMergeUsageCounter `json:"indexMergeUsageCounter"` } type placementPolicyUsage struct { @@ -108,6 +109,8 @@ func getFeatureUsage(ctx context.Context, sctx sessionctx.Context) (*featureUsag usage.EnableGlobalMemoryControl = getGlobalMemoryControl() + usage.IndexMergeUsageCounter = getIndexMergeUsageInfo() + return &usage, nil } @@ -244,6 +247,7 @@ var initialTablePartitionCounter m.TablePartitionUsageCounter var initialSavepointStmtCounter int64 var initialLazyPessimisticUniqueCheckSetCount int64 var initialDDLUsageCounter m.DDLUsageCounter +var initialIndexMergeCounter m.IndexMergeUsageCounter // getTxnUsageInfo gets the usage info of transaction related features. It's exported for tests. func getTxnUsageInfo(ctx sessionctx.Context) *TxnUsage { @@ -402,3 +406,13 @@ func getDDLUsageInfo(ctx sessionctx.Context) *m.DDLUsageCounter { func getGlobalMemoryControl() bool { return memory.ServerMemoryLimit.Load() > 0 } + +func postReportIndexMergeUsage() { + initialIndexMergeCounter = m.GetIndexMergeCounter() +} + +func getIndexMergeUsageInfo() *m.IndexMergeUsageCounter { + curr := m.GetIndexMergeCounter() + diff := curr.Sub(initialIndexMergeCounter) + return &diff +} diff --git a/telemetry/data_feature_usage_test.go b/telemetry/data_feature_usage_test.go index ebe93d6dbaa52..369073009c0a4 100644 --- a/telemetry/data_feature_usage_test.go +++ b/telemetry/data_feature_usage_test.go @@ -554,3 +554,32 @@ func TestGlobalMemoryControl(t *testing.T) { require.NoError(t, err) require.False(t, usage.EnableGlobalMemoryControl) } + +func TestIndexMergeUsage(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("create table t1(c1 int, c2 int, index idx1(c1), index idx2(c2))") + res := tk.MustQuery("explain select /*+ use_index_merge(t1, idx1, idx2) */ * from t1 where c1 = 1 and c2 = 1").Rows() + require.Contains(t, res[0][0], "IndexMerge") + + usage, err := telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, usage.IndexMergeUsageCounter.IndexMergeUsed, int64(0)) + + tk.MustExec("select /*+ use_index_merge(t1, idx1, idx2) */ * from t1 where c1 = 1 and c2 = 1") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, int64(1), usage.IndexMergeUsageCounter.IndexMergeUsed) + + tk.MustExec("select /*+ use_index_merge(t1, idx1, idx2) */ * from t1 where c1 = 1 or c2 = 1") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, int64(2), usage.IndexMergeUsageCounter.IndexMergeUsed) + + tk.MustExec("select /*+ no_index_merge() */ * from t1 where c1 = 1 or c2 = 1") + usage, err = telemetry.GetFeatureUsage(tk.Session()) + require.NoError(t, err) + require.Equal(t, int64(2), usage.IndexMergeUsageCounter.IndexMergeUsed) +}