Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: add telemetry support for multi-schema change #35977

Merged
merged 3 commits into from
Jul 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions executor/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,9 @@ func (a *recordSet) OnFetchReturned() {

// TelemetryInfo records some telemetry information during execution.
type TelemetryInfo struct {
UseNonRecursive bool
UseRecursive bool
UseNonRecursive bool
UseRecursive bool
UseMultiSchemaChange bool
}

// ExecStmt implements the sqlexec.Statement interface, it builds a planner.Plan to an sqlexec.Statement.
Expand Down
6 changes: 6 additions & 0 deletions executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,12 @@ func (b *executorBuilder) buildRevoke(revoke *ast.RevokeStmt) Executor {
}

func (b *executorBuilder) buildDDL(v *plannercore.DDL) Executor {
switch v.Statement.(type) {
case *ast.AlterTableStmt:
if len(v.Statement.(*ast.AlterTableStmt).Specs) > 1 && b.Ti != nil {
b.Ti.UseMultiSchemaChange = true
}
}
e := &DDLExec{
baseExecutor: newBaseExecutor(b.ctx, v.Schema(), v.ID()),
stmt: v.Statement,
Expand Down
26 changes: 26 additions & 0 deletions metrics/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ var (
Name: "non_recursive_cte_usage",
Help: "Counter of usage of CTE",
}, []string{LblCTEType})
TelemetryMultiSchemaChangeCnt = prometheus.NewCounter(
prometheus.CounterOpts{
Namespace: "tidb",
Subsystem: "telemetry",
Name: "multi_schema_change_usage",
Help: "Counter of usage of multi-schema change",
})
)

// readCounter reads the value of a prometheus.Counter.
Expand Down Expand Up @@ -68,6 +75,25 @@ func GetCTECounter() CTEUsageCounter {
}
}

// MultiSchemaChangeUsageCounter records the usages of multi-schema change.
type MultiSchemaChangeUsageCounter struct {
MultiSchemaChangeUsed int64 `json:"multi_schema_change_used"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a struct named "counter"? Is there any plan to add more counters in this struct?

      "multiSchemaChange": {
        "multi_schema_change_used": 0
      },

Is this necessary?

}

// Sub returns the difference of two counters.
func (c MultiSchemaChangeUsageCounter) Sub(rhs MultiSchemaChangeUsageCounter) MultiSchemaChangeUsageCounter {
return MultiSchemaChangeUsageCounter{
MultiSchemaChangeUsed: c.MultiSchemaChangeUsed - rhs.MultiSchemaChangeUsed,
}
}

// GetMultiSchemaCounter gets the TxnCommitCounter.
func GetMultiSchemaCounter() MultiSchemaChangeUsageCounter {
return MultiSchemaChangeUsageCounter{
MultiSchemaChangeUsed: readCounter(TelemetryMultiSchemaChangeCnt),
}
}

// NonTransactionalStmtCounter records the usages of non-transactional statements.
type NonTransactionalStmtCounter struct {
DeleteCount int64 `json:"delete"`
Expand Down
7 changes: 6 additions & 1 deletion session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ var (
sessionExecuteParseDurationInternal = metrics.SessionExecuteParseDuration.WithLabelValues(metrics.LblInternal)
sessionExecuteParseDurationGeneral = metrics.SessionExecuteParseDuration.WithLabelValues(metrics.LblGeneral)

telemetryCTEUsage = metrics.TelemetrySQLCTECnt
telemetryCTEUsage = metrics.TelemetrySQLCTECnt
telemetryMultiSchemaChangeUsage = metrics.TelemetryMultiSchemaChangeCnt
)

// Session context, it is consistent with the lifecycle of a client connection.
Expand Down Expand Up @@ -3421,6 +3422,10 @@ func (s *session) updateTelemetryMetric(es *executor.ExecStmt) {
} else {
telemetryCTEUsage.WithLabelValues("notCTE").Inc()
}

if ti.UseMultiSchemaChange {
telemetryMultiSchemaChangeUsage.Inc()
}
}

// GetBuiltinFunctionUsage returns the replica of counting of builtin function usage
Expand Down
1 change: 1 addition & 0 deletions telemetry/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func generateTelemetryData(sctx sessionctx.Context, trackingID string) telemetry
func postReportTelemetryData() {
postReportTxnUsage()
postReportCTEUsage()
postReportMultiSchemaChangeUsage()
postReportSlowQueryStats()
postReportNonTransactionalCounter()
}
33 changes: 23 additions & 10 deletions telemetry/data_feature_usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ type featureUsage struct {
Txn *TxnUsage `json:"txn"`
// cluster index usage information
// key is the first 6 characters of sha2(TABLE_NAME, 256)
ClusterIndex *ClusterIndexUsage `json:"clusterIndex"`
NewClusterIndex *NewClusterIndexUsage `json:"newClusterIndex"`
TemporaryTable bool `json:"temporaryTable"`
CTE *m.CTEUsageCounter `json:"cte"`
CachedTable bool `json:"cachedTable"`
AutoCapture bool `json:"autoCapture"`
PlacementPolicyUsage *placementPolicyUsage `json:"placementPolicy"`
NonTransactionalUsage *m.NonTransactionalStmtCounter `json:"nonTransactional"`
GlobalKill bool `json:"globalKill"`
ClusterIndex *ClusterIndexUsage `json:"clusterIndex"`
NewClusterIndex *NewClusterIndexUsage `json:"newClusterIndex"`
TemporaryTable bool `json:"temporaryTable"`
CTE *m.CTEUsageCounter `json:"cte"`
CachedTable bool `json:"cachedTable"`
AutoCapture bool `json:"autoCapture"`
PlacementPolicyUsage *placementPolicyUsage `json:"placementPolicy"`
NonTransactionalUsage *m.NonTransactionalStmtCounter `json:"nonTransactional"`
GlobalKill bool `json:"globalKill"`
MultiSchemaChange *m.MultiSchemaChangeUsageCounter `json:"multiSchemaChange"`
}

type placementPolicyUsage struct {
Expand All @@ -70,6 +71,8 @@ func getFeatureUsage(ctx context.Context, sctx sessionctx.Context) (*featureUsag

usage.CTE = getCTEUsageInfo()

usage.MultiSchemaChange = getMultiSchemaChangeUsageInfo()

usage.AutoCapture = getAutoCaptureUsageInfo(sctx)

collectFeatureUsageFromInfoschema(sctx, &usage)
Expand Down Expand Up @@ -201,6 +204,7 @@ type TxnUsage struct {
var initialTxnCommitCounter metrics.TxnCommitCounter
var initialCTECounter m.CTEUsageCounter
var initialNonTransactionalCounter m.NonTransactionalStmtCounter
var initialMultiSchemaChangeCounter m.MultiSchemaChangeUsageCounter

// getTxnUsageInfo gets the usage info of transaction related features. It's exported for tests.
func getTxnUsageInfo(ctx sessionctx.Context) *TxnUsage {
Expand Down Expand Up @@ -233,7 +237,6 @@ func postReportTxnUsage() {
initialTxnCommitCounter = metrics.GetTxnCommitCounter()
}

// ResetCTEUsage resets CTE usages.
func postReportCTEUsage() {
initialCTECounter = m.GetCTECounter()
}
Expand All @@ -245,6 +248,16 @@ func getCTEUsageInfo() *m.CTEUsageCounter {
return &diff
}

func postReportMultiSchemaChangeUsage() {
initialMultiSchemaChangeCounter = m.GetMultiSchemaCounter()
}

func getMultiSchemaChangeUsageInfo() *m.MultiSchemaChangeUsageCounter {
curr := m.GetMultiSchemaCounter()
diff := curr.Sub(initialMultiSchemaChangeCounter)
return &diff
}

// getAutoCaptureUsageInfo gets the 'Auto Capture' usage
func getAutoCaptureUsageInfo(ctx sessionctx.Context) bool {
if val, err := variable.GetGlobalSystemVar(ctx.GetSessionVars(), variable.TiDBCapturePlanBaseline); err == nil {
Expand Down
34 changes: 34 additions & 0 deletions telemetry/data_feature_usage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,40 @@ func TestCachedTable(t *testing.T) {
require.False(t, usage.CachedTable)
}

func TestMultiSchemaChange(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()

tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")

usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(0), usage.MultiSchemaChange.MultiSchemaChangeUsed)

tk.MustExec("drop table if exists tele_multi_t")
tk.MustExec("create table tele_multi_t(id int)")
tk.MustExec("alter table tele_multi_t add column b int")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(0), usage.MultiSchemaChange.MultiSchemaChangeUsed)

tk.MustExec("alter table tele_multi_t add column c int, drop column b")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(1), usage.MultiSchemaChange.MultiSchemaChangeUsed)

tk.MustExec("alter table tele_multi_t add column b int, drop column c")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(2), usage.MultiSchemaChange.MultiSchemaChangeUsed)

tk.MustExec("alter table tele_multi_t drop column b")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(2), usage.MultiSchemaChange.MultiSchemaChangeUsed)
}

func TestPlacementPolicies(t *testing.T) {
store, clean := testkit.CreateMockStore(t)
defer clean()
Expand Down