Files
tidb/telemetry/data_feature_usage_test.go
2023-01-29 19:39:54 +08:00

780 lines
32 KiB
Go

// Copyright 2021 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package telemetry_test
import (
"encoding/json"
"fmt"
"strings"
"testing"
"time"
_ "github.com/pingcap/tidb/autoid_service"
"github.com/pingcap/tidb/config"
"github.com/pingcap/tidb/ddl"
"github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/telemetry"
"github.com/pingcap/tidb/testkit"
"github.com/stretchr/testify/require"
)
func TestTxnUsageInfo(t *testing.T) {
store := testkit.CreateMockStore(t)
t.Run("Used", func(t *testing.T) {
tk := testkit.NewTestKit(t, store)
tk.MustExec(fmt.Sprintf("set global %s = 0", variable.TiDBEnableAsyncCommit))
tk.MustExec(fmt.Sprintf("set global %s = 0", variable.TiDBEnable1PC))
txnUsage := telemetry.GetTxnUsageInfo(tk.Session())
require.False(t, txnUsage.AsyncCommitUsed)
require.False(t, txnUsage.OnePCUsed)
tk.MustExec(fmt.Sprintf("set global %s = 1", variable.TiDBEnableAsyncCommit))
tk.MustExec(fmt.Sprintf("set global %s = 1", variable.TiDBEnable1PC))
txnUsage = telemetry.GetTxnUsageInfo(tk.Session())
require.True(t, txnUsage.AsyncCommitUsed)
require.True(t, txnUsage.OnePCUsed)
tk.MustExec(fmt.Sprintf("set global %s = 0", variable.TiDBEnableMutationChecker))
tk.MustExec(fmt.Sprintf("set global %s = off", variable.TiDBTxnAssertionLevel))
txnUsage = telemetry.GetTxnUsageInfo(tk.Session())
require.False(t, txnUsage.MutationCheckerUsed)
require.Equal(t, "OFF", txnUsage.AssertionLevel)
tk.MustExec(fmt.Sprintf("set global %s = 1", variable.TiDBEnableMutationChecker))
tk.MustExec(fmt.Sprintf("set global %s = strict", variable.TiDBTxnAssertionLevel))
txnUsage = telemetry.GetTxnUsageInfo(tk.Session())
require.True(t, txnUsage.MutationCheckerUsed)
require.Equal(t, "STRICT", txnUsage.AssertionLevel)
tk.MustExec(fmt.Sprintf("set global %s = fast", variable.TiDBTxnAssertionLevel))
txnUsage = telemetry.GetTxnUsageInfo(tk.Session())
require.Equal(t, "FAST", txnUsage.AssertionLevel)
tk.MustExec(fmt.Sprintf("set global %s = 1", variable.TiDBRCReadCheckTS))
txnUsage = telemetry.GetTxnUsageInfo(tk.Session())
require.True(t, txnUsage.RcCheckTS)
tk.MustExec(fmt.Sprintf("set global %s = 1", variable.TiDBRCWriteCheckTs))
txnUsage = telemetry.GetTxnUsageInfo(tk.Session())
require.True(t, txnUsage.RCWriteCheckTS)
})
t.Run("Count", func(t *testing.T) {
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists txn_usage_info")
tk.MustExec("create table txn_usage_info (a int)")
tk.MustExec(fmt.Sprintf("set %s = 1", variable.TiDBEnableAsyncCommit))
tk.MustExec(fmt.Sprintf("set %s = 1", variable.TiDBEnable1PC))
tk.MustExec("insert into txn_usage_info values (1)")
tk.MustExec(fmt.Sprintf("set %s = 0", variable.TiDBEnable1PC))
tk.MustExec("insert into txn_usage_info values (2)")
tk.MustExec(fmt.Sprintf("set %s = 0", variable.TiDBEnableAsyncCommit))
tk.MustExec("insert into txn_usage_info values (3)")
txnUsage := telemetry.GetTxnUsageInfo(tk.Session())
require.True(t, txnUsage.AsyncCommitUsed)
require.True(t, txnUsage.OnePCUsed)
require.Greater(t, txnUsage.TxnCommitCounter.AsyncCommit, int64(0))
require.Greater(t, txnUsage.TxnCommitCounter.OnePC, int64(0))
require.Greater(t, txnUsage.TxnCommitCounter.TwoPC, int64(0))
})
}
func TestTemporaryTable(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.False(t, usage.TemporaryTable)
tk.MustExec("create global temporary table t (id int) on commit delete rows")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.True(t, usage.TemporaryTable)
}
func TestCachedTable(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.False(t, usage.CachedTable)
tk.MustExec("drop table if exists tele_cache_t")
tk.MustExec("create table tele_cache_t (id int)")
tk.MustExec("alter table tele_cache_t cache")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.True(t, usage.CachedTable)
tk.MustExec("alter table tele_cache_t nocache")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.False(t, usage.CachedTable)
}
func TestAutoIDNoCache(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.False(t, usage.CachedTable)
tk.MustExec("drop table if exists tele_autoid")
tk.MustExec("create table tele_autoid (id int) auto_id_cache 1")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.True(t, usage.AutoIDNoCache)
tk.MustExec("drop table tele_autoid")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.False(t, usage.AutoIDNoCache)
}
func TestAccountLock(t *testing.T) {
store := testkit.CreateMockStore(t)
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.AccountLock.LockUser)
require.Equal(t, int64(0), usage.AccountLock.UnlockUser)
require.Equal(t, int64(0), usage.AccountLock.CreateOrAlterUser)
tk.MustExec("drop user if exists testUser")
tk.MustExec("create user testUser account lock")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(1), usage.AccountLock.LockUser)
require.Equal(t, int64(0), usage.AccountLock.UnlockUser)
require.Equal(t, int64(1), usage.AccountLock.CreateOrAlterUser)
tk.MustExec("alter user testUser account unlock")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(1), usage.AccountLock.LockUser)
require.Equal(t, int64(1), usage.AccountLock.UnlockUser)
require.Equal(t, int64(2), usage.AccountLock.CreateOrAlterUser)
}
func TestMultiSchemaChange(t *testing.T) {
store := testkit.CreateMockStore(t)
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 TestTablePartition(t *testing.T) {
store := testkit.CreateMockStore(t)
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.TablePartition.TablePartitionCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionListCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionMaxPartitionsCnt)
tk.MustExec("drop table if exists pt")
tk.MustExec("create table pt (a int,b int) partition by hash(a) partitions 4")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(1), usage.TablePartition.TablePartitionCnt)
require.Equal(t, int64(1), usage.TablePartition.TablePartitionHashCnt)
require.Equal(t, int64(4), usage.TablePartition.TablePartitionMaxPartitionsCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionListCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionRangeCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionRangeColumnsCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionRangeColumnsGt1Cnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionRangeColumnsGt2Cnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionRangeColumnsGt3Cnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionListColumnsCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionCreateIntervalPartitionsCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionAddIntervalPartitionsCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionDropIntervalPartitionsCnt)
telemetry.PostReportTelemetryDataForTest()
tk.MustExec("drop table if exists pt1")
tk.MustExec("create table pt1 (a int,b int) partition by range(a) (" +
"partition p0 values less than (3)," +
"partition p1 values less than (6), " +
"partition p2 values less than (9)," +
"partition p3 values less than (12)," +
"partition p4 values less than (15))")
tk.MustExec("alter table pt1 first partition less than (9)")
tk.MustExec("alter table pt1 last partition less than (21)")
tk.MustExec("drop table if exists pt1")
tk.MustExec("create table pt1 (d datetime primary key, v varchar(255)) partition by range columns(d)" +
" interval (1 day) first partition less than ('2022-01-01') last partition less than ('2022-02-22')")
tk.MustExec("create table pt2 (d datetime, v varchar(255)) partition by range columns(d,v)" +
" (partition p0 values less than ('2022-01-01', ''), partition p1 values less than ('2023-01-01','ZZZ'))")
tk.MustExec("create table pt3 (d datetime, v varchar(255), i int) partition by range columns(d,v,i)" +
" (partition p0 values less than ('2022-01-01', '', 0), partition p1 values less than ('2023-01-01','ZZZ', 1))")
tk.MustExec("create table pt4 (d datetime, v varchar(255), s bigint unsigned, u tinyint) partition by range columns(d,v,s,u)" +
" (partition p0 values less than ('2022-01-01', '', 1, -3), partition p1 values less than ('2023-01-01','ZZZ', 1, 3))")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(5), usage.TablePartition.TablePartitionCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionHashCnt)
require.Equal(t, int64(11), usage.TablePartition.TablePartitionMaxPartitionsCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionListCnt)
require.Equal(t, int64(1), usage.TablePartition.TablePartitionRangeCnt)
require.Equal(t, int64(4), usage.TablePartition.TablePartitionRangeColumnsCnt)
require.Equal(t, int64(3), usage.TablePartition.TablePartitionRangeColumnsGt1Cnt)
require.Equal(t, int64(2), usage.TablePartition.TablePartitionRangeColumnsGt2Cnt)
require.Equal(t, int64(1), usage.TablePartition.TablePartitionRangeColumnsGt3Cnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionListColumnsCnt)
require.Equal(t, int64(1), usage.TablePartition.TablePartitionCreateIntervalPartitionsCnt)
require.Equal(t, int64(1), usage.TablePartition.TablePartitionAddIntervalPartitionsCnt)
require.Equal(t, int64(1), usage.TablePartition.TablePartitionDropIntervalPartitionsCnt)
tk.MustExec("drop table if exists pt2")
tk.MustExec("create table pt2 (a int,b int) partition by range(a) (" +
"partition p0 values less than (10)," +
"partition p1 values less than (20))")
tk.MustExec("drop table if exists nt")
tk.MustExec("create table nt (a int,b int)")
require.Equal(t, int64(0), usage.ExchangePartition.ExchangePartitionCnt)
tk.MustExec(`alter table pt2 exchange partition p1 with table nt`)
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(1), usage.ExchangePartition.ExchangePartitionCnt)
require.Equal(t, int64(0), usage.TablePartition.TablePartitionComactCnt)
tk.MustExec(`alter table pt2 compact partition p0 tiflash replica;`)
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(1), usage.TablePartition.TablePartitionComactCnt)
}
func TestPlacementPolicies(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, uint64(0), usage.PlacementPolicyUsage.NumPlacementPolicies)
require.Equal(t, uint64(0), usage.PlacementPolicyUsage.NumDBWithPolicies)
require.Equal(t, uint64(0), usage.PlacementPolicyUsage.NumTableWithPolicies)
require.Equal(t, uint64(0), usage.PlacementPolicyUsage.NumPartitionWithExplicitPolicies)
tk.MustExec("create placement policy p1 followers=4;")
tk.MustExec(`create placement policy p2 primary_region="cn-east-1" regions="cn-east-1,cn-east"`)
tk.MustExec(`create placement policy p3 followers=3`)
tk.MustExec("alter database test placement policy=p1;")
tk.MustExec("create table t1(a int);")
tk.MustExec("create table t2(a int) placement policy=p2;")
tk.MustExec("create table t3(id int) PARTITION BY RANGE (id) (" +
"PARTITION p0 VALUES LESS THAN (100) placement policy p3," +
"PARTITION p1 VALUES LESS THAN (1000))")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, uint64(3), usage.PlacementPolicyUsage.NumPlacementPolicies)
require.Equal(t, uint64(1), usage.PlacementPolicyUsage.NumDBWithPolicies)
require.Equal(t, uint64(3), usage.PlacementPolicyUsage.NumTableWithPolicies)
require.Equal(t, uint64(1), usage.PlacementPolicyUsage.NumPartitionWithExplicitPolicies)
tk.MustExec("drop table t2;")
tk.MustExec("drop placement policy p2;")
tk.MustExec("alter table t3 placement policy=default")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, uint64(2), usage.PlacementPolicyUsage.NumPlacementPolicies)
require.Equal(t, uint64(1), usage.PlacementPolicyUsage.NumDBWithPolicies)
require.Equal(t, uint64(1), usage.PlacementPolicyUsage.NumTableWithPolicies)
require.Equal(t, uint64(1), usage.PlacementPolicyUsage.NumPartitionWithExplicitPolicies)
}
func TestResourceGroups(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, uint64(0), usage.ResourceControlUsage.NumResourceGroups)
require.Equal(t, false, usage.ResourceControlUsage.Enabled)
tk.MustExec("set global tidb_enable_resource_control = 'ON'")
tk.MustExec("create resource group x rru_per_sec=100 wru_per_sec=200")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, true, usage.ResourceControlUsage.Enabled)
require.Equal(t, uint64(1), usage.ResourceControlUsage.NumResourceGroups)
tk.MustExec("create resource group y rru_per_sec=100 wru_per_sec=200")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, uint64(2), usage.ResourceControlUsage.NumResourceGroups)
tk.MustExec("alter resource group y rru_per_sec=100 wru_per_sec=300")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, uint64(2), usage.ResourceControlUsage.NumResourceGroups)
tk.MustExec("drop resource group y")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, uint64(1), usage.ResourceControlUsage.NumResourceGroups)
tk.MustExec("set global tidb_enable_resource_control = 'OFF'")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, uint64(1), usage.ResourceControlUsage.NumResourceGroups)
require.Equal(t, false, usage.ResourceControlUsage.Enabled)
}
func TestAutoCapture(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.False(t, usage.AutoCapture)
tk.MustExec("SET GLOBAL tidb_capture_plan_baselines = on")
defer func() {
tk.MustExec("SET GLOBAL tidb_capture_plan_baselines = off")
}()
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.True(t, usage.AutoCapture)
}
func TestClusterIndexUsageInfo(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table t1(a int key clustered);")
tk.MustExec("create table t2(a int);")
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.NotNil(t, usage.ClusterIndex)
require.Equal(t, uint64(1), usage.NewClusterIndex.NumClusteredTables)
require.Equal(t, uint64(2), usage.NewClusterIndex.NumTotalTables)
}
func TestNonTransactionalUsage(t *testing.T) {
store := testkit.CreateMockStore(t)
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.NonTransactionalUsage.DeleteCount)
require.Equal(t, int64(0), usage.NonTransactionalUsage.UpdateCount)
require.Equal(t, int64(0), usage.NonTransactionalUsage.InsertCount)
tk.MustExec("create table t(a int);")
tk.MustExec("batch limit 1 delete from t")
tk.MustExec("batch limit 1 update t set a = 1")
tk.MustExec("batch limit 1 insert into t select * from t")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(1), usage.NonTransactionalUsage.DeleteCount)
require.Equal(t, int64(1), usage.NonTransactionalUsage.UpdateCount)
require.Equal(t, int64(1), usage.NonTransactionalUsage.InsertCount)
}
func TestGlobalKillUsageInfo(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.True(t, usage.GlobalKill)
originCfg := config.GetGlobalConfig()
newCfg := *originCfg
newCfg.EnableGlobalKill = false
config.StoreGlobalConfig(&newCfg)
defer func() {
config.StoreGlobalConfig(originCfg)
}()
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.False(t, usage.GlobalKill)
}
func TestPagingUsageInfo(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.True(t, usage.EnablePaging == variable.DefTiDBEnablePaging)
tk.Session().GetSessionVars().EnablePaging = false
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.False(t, usage.EnablePaging)
}
func TestCostModelVer2UsageInfo(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, usage.EnableCostModelVer2, variable.DefTiDBCostModelVer == 2)
tk.Session().GetSessionVars().CostModelVersion = 2
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.True(t, usage.EnableCostModelVer2)
}
func TestTxnSavepointUsageInfo(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("savepoint sp1")
tk.MustExec("savepoint sp2")
txnUsage := telemetry.GetTxnUsageInfo(tk.Session())
require.Equal(t, int64(2), txnUsage.SavepointCounter)
tk.MustExec("savepoint sp3")
txnUsage = telemetry.GetTxnUsageInfo(tk.Session())
require.Equal(t, int64(3), txnUsage.SavepointCounter)
telemetry.PostSavepointCount()
tk.MustExec("savepoint sp1")
txnUsage = telemetry.GetTxnUsageInfo(tk.Session())
require.Equal(t, int64(1), txnUsage.SavepointCounter)
}
func TestLazyPessimisticUniqueCheck(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk2 := testkit.NewTestKit(t, store)
tk.MustExec("use test")
usage := telemetry.GetTxnUsageInfo(tk.Session())
require.Equal(t, int64(0), usage.LazyUniqueCheckSetCounter)
tk2.MustExec("set @@tidb_constraint_check_in_place_pessimistic = 0")
tk2.MustExec("set @@tidb_constraint_check_in_place_pessimistic = 0")
usage = telemetry.GetTxnUsageInfo(tk.Session())
require.Equal(t, int64(2), usage.LazyUniqueCheckSetCounter)
}
func TestFlashbackCluster(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk1 := testkit.NewTestKit(t, store)
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.Equal(t, int64(0), usage.DDLUsageCounter.FlashbackClusterUsed)
require.NoError(t, err)
tk.MustExecToErr("flashback cluster to timestamp '2011-12-21 00:00:00'")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.Equal(t, int64(1), usage.DDLUsageCounter.FlashbackClusterUsed)
require.NoError(t, err)
tk1.MustExec("use test")
tk1.MustExec("create table t(a int)")
usage, err = telemetry.GetFeatureUsage(tk1.Session())
require.Equal(t, int64(1), usage.DDLUsageCounter.FlashbackClusterUsed)
require.NoError(t, err)
}
func TestAddIndexAccelerationAndMDL(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.Equal(t, int64(0), usage.DDLUsageCounter.AddIndexIngestUsed)
require.NoError(t, err)
allow := ddl.IsEnableFastReorg()
require.Equal(t, true, allow)
tk.MustExec("set global tidb_enable_metadata_lock = 0")
tk.MustExec("use test")
tk.MustExec("drop table if exists tele_t")
tk.MustExec("create table tele_t(id int, b int)")
tk.MustExec("insert into tele_t values(1,1),(2,2);")
tk.MustExec("alter table tele_t add index idx_org(b)")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(1), usage.DDLUsageCounter.AddIndexIngestUsed)
require.Equal(t, false, usage.DDLUsageCounter.MetadataLockUsed)
tk.MustExec("set @@global.tidb_ddl_enable_fast_reorg = on")
tk.MustExec("set global tidb_enable_metadata_lock = 1")
allow = ddl.IsEnableFastReorg()
require.Equal(t, true, allow)
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(1), usage.DDLUsageCounter.AddIndexIngestUsed)
tk.MustExec("alter table tele_t add index idx_new(b)")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.Equal(t, int64(2), usage.DDLUsageCounter.AddIndexIngestUsed)
require.Equal(t, true, usage.DDLUsageCounter.MetadataLockUsed)
}
func TestGlobalMemoryControl(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.True(t, usage.EnableGlobalMemoryControl == (variable.DefTiDBServerMemoryLimit != "0"))
tk.MustExec("set global tidb_server_memory_limit = 5 << 30")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.True(t, usage.EnableGlobalMemoryControl)
tk.MustExec("set global tidb_server_memory_limit = 0")
usage, err = telemetry.GetFeatureUsage(tk.Session())
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)
}
func TestTTLTelemetry(t *testing.T) {
timeFormat := "2006-01-02 15:04:05"
dateFormat := "2006-01-02"
now := time.Now()
curDate := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
if interval := curDate.Add(time.Hour * 24).Sub(now); interval > 0 && interval < 5*time.Minute {
// make sure testing is not running at the end of one day
time.Sleep(interval)
}
store, do := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@global.tidb_ttl_job_enable=0")
getTTLTable := func(name string) *model.TableInfo {
tbl, err := do.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr(name))
require.NoError(t, err)
require.NotNil(t, tbl.Meta().TTLInfo)
return tbl.Meta()
}
jobIDIdx := 1
insertTTLHistory := func(tblName string, partitionName string, createTime, finishTime, ttlExpire time.Time, scanError string, totalRows, errorRows int64, status string) {
defer func() {
jobIDIdx++
}()
tbl := getTTLTable(tblName)
tblID := tbl.ID
partitionID := tbl.ID
if partitionName != "" {
for _, def := range tbl.Partition.Definitions {
if def.Name.L == strings.ToLower(partitionName) {
partitionID = def.ID
}
}
require.NotEqual(t, tblID, partitionID)
}
summary := make(map[string]interface{})
summary["total_rows"] = totalRows
summary["success_rows"] = totalRows - errorRows
summary["error_rows"] = errorRows
summary["total_scan_task"] = 1
summary["scheduled_scan_task"] = 1
summary["finished_scan_task"] = 1
if scanError != "" {
summary["scan_task_err"] = scanError
}
summaryText, err := json.Marshal(summary)
require.NoError(t, err)
tk.MustExec("insert into "+
"mysql.tidb_ttl_job_history ("+
" job_id, table_id, parent_table_id, table_schema, table_name, partition_name, "+
" create_time, finish_time, ttl_expire, summary_text, "+
" expired_rows, deleted_rows, error_delete_rows, status) "+
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
jobIDIdx, partitionID, tblID, "test", tblName, partitionName,
createTime.Format(timeFormat), finishTime.Format(timeFormat), ttlExpire.Format(timeFormat), summaryText,
totalRows, totalRows-errorRows, errorRows, status,
)
}
oneDayAgoDate := curDate.Add(-24 * time.Hour)
// start today, end today
times11 := []time.Time{curDate.Add(time.Hour), curDate.Add(2 * time.Hour), curDate}
// start yesterday, end today
times21 := []time.Time{curDate.Add(-2 * time.Hour), curDate, curDate.Add(-3 * time.Hour)}
// start yesterday, end yesterday
times31 := []time.Time{oneDayAgoDate, oneDayAgoDate.Add(time.Hour), oneDayAgoDate.Add(-time.Hour)}
times32 := []time.Time{oneDayAgoDate.Add(2 * time.Hour), oneDayAgoDate.Add(3 * time.Hour), oneDayAgoDate.Add(time.Hour)}
times33 := []time.Time{oneDayAgoDate.Add(4 * time.Hour), oneDayAgoDate.Add(5 * time.Hour), oneDayAgoDate.Add(3 * time.Hour)}
// start 2 days ago, end yesterday
times41 := []time.Time{oneDayAgoDate.Add(-2 * time.Hour), oneDayAgoDate.Add(time.Hour), oneDayAgoDate.Add(-3 * time.Hour)}
// start two days ago, end two days ago
times51 := []time.Time{oneDayAgoDate.Add(-5 * time.Hour), oneDayAgoDate.Add(-4 * time.Hour), oneDayAgoDate.Add(-6 * time.Hour)}
tk.MustExec("create table t1 (t timestamp) TTL=`t` + interval 1 hour")
insertTTLHistory("t1", "", times11[0], times11[1], times11[2], "", 100000000, 0, "finished")
insertTTLHistory("t1", "", times21[0], times21[1], times21[2], "", 100000000, 0, "finished")
insertTTLHistory("t1", "", times31[0], times31[1], times31[2], "err1", 112600, 110000, "finished")
insertTTLHistory("t1", "", times32[0], times32[1], times32[2], "", 2600, 0, "timeout")
insertTTLHistory("t1", "", times33[0], times33[1], times33[2], "", 2600, 0, "finished")
insertTTLHistory("t1", "", times41[0], times41[1], times41[2], "", 2600, 0, "finished")
insertTTLHistory("t1", "", times51[0], times51[1], times51[2], "", 100000000, 1, "finished")
usage, err := telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
checkTableHistWithDeleteRows := func(vals ...int64) {
require.Equal(t, 5, len(vals))
require.Equal(t, 5, len(usage.TTLUsage.TableHistWithDeleteRows))
require.Equal(t, int64(10*1000), *usage.TTLUsage.TableHistWithDeleteRows[0].LessThan)
require.Equal(t, vals[0], usage.TTLUsage.TableHistWithDeleteRows[0].Count)
require.Equal(t, int64(100*1000), *usage.TTLUsage.TableHistWithDeleteRows[1].LessThan)
require.Equal(t, vals[1], usage.TTLUsage.TableHistWithDeleteRows[1].Count)
require.Equal(t, int64(1000*1000), *usage.TTLUsage.TableHistWithDeleteRows[2].LessThan)
require.Equal(t, vals[2], usage.TTLUsage.TableHistWithDeleteRows[2].Count)
require.Equal(t, int64(10*1000*1000), *usage.TTLUsage.TableHistWithDeleteRows[3].LessThan)
require.Equal(t, vals[3], usage.TTLUsage.TableHistWithDeleteRows[3].Count)
require.True(t, usage.TTLUsage.TableHistWithDeleteRows[4].LessThanMax)
require.Nil(t, usage.TTLUsage.TableHistWithDeleteRows[4].LessThan)
require.Equal(t, vals[4], usage.TTLUsage.TableHistWithDeleteRows[4].Count)
}
checkTableHistWithDelay := func(vals ...int64) {
require.Equal(t, 5, len(vals))
require.Equal(t, 5, len(usage.TTLUsage.TableHistWithDelayTime))
require.Equal(t, int64(1), *usage.TTLUsage.TableHistWithDelayTime[0].LessThan)
require.Equal(t, vals[0], usage.TTLUsage.TableHistWithDelayTime[0].Count)
require.Equal(t, int64(6), *usage.TTLUsage.TableHistWithDelayTime[1].LessThan)
require.Equal(t, vals[1], usage.TTLUsage.TableHistWithDelayTime[1].Count)
require.Equal(t, int64(24), *usage.TTLUsage.TableHistWithDelayTime[2].LessThan)
require.Equal(t, vals[2], usage.TTLUsage.TableHistWithDelayTime[2].Count)
require.Equal(t, int64(72), *usage.TTLUsage.TableHistWithDelayTime[3].LessThan)
require.Equal(t, vals[3], usage.TTLUsage.TableHistWithDelayTime[3].Count)
require.True(t, usage.TTLUsage.TableHistWithDelayTime[4].LessThanMax)
require.Nil(t, usage.TTLUsage.TableHistWithDelayTime[4].LessThan)
require.Equal(t, vals[4], usage.TTLUsage.TableHistWithDelayTime[4].Count)
}
require.False(t, usage.TTLUsage.TTLJobEnabled)
require.Equal(t, int64(1), usage.TTLUsage.TTLTables)
require.Equal(t, int64(1), usage.TTLUsage.TTLJobEnabledTables)
require.Equal(t, oneDayAgoDate.Format(dateFormat), usage.TTLUsage.TTLHistDate)
checkTableHistWithDeleteRows(0, 1, 0, 0, 0)
checkTableHistWithDelay(0, 0, 1, 0, 0)
tk.MustExec("create table t2 (t timestamp) TTL=`t` + interval 20 hour")
tk.MustExec("set @@global.tidb_ttl_job_enable=1")
insertTTLHistory("t2", "", times31[0], times31[1], times31[2], "", 9999, 0, "finished")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.True(t, usage.TTLUsage.TTLJobEnabled)
require.Equal(t, int64(2), usage.TTLUsage.TTLTables)
require.Equal(t, int64(2), usage.TTLUsage.TTLJobEnabledTables)
require.Equal(t, oneDayAgoDate.Format(dateFormat), usage.TTLUsage.TTLHistDate)
checkTableHistWithDeleteRows(1, 1, 0, 0, 0)
checkTableHistWithDelay(0, 1, 1, 0, 0)
tk.MustExec("create table t3 (t timestamp) TTL=`t` + interval 1 hour TTL_ENABLE='OFF'")
usage, err = telemetry.GetFeatureUsage(tk.Session())
require.NoError(t, err)
require.True(t, usage.TTLUsage.TTLJobEnabled)
require.Equal(t, int64(3), usage.TTLUsage.TTLTables)
require.Equal(t, int64(2), usage.TTLUsage.TTLJobEnabledTables)
require.Equal(t, oneDayAgoDate.Format(dateFormat), usage.TTLUsage.TTLHistDate)
checkTableHistWithDeleteRows(1, 1, 0, 0, 0)
checkTableHistWithDelay(0, 1, 1, 0, 1)
}