Skip to content

Commit

Permalink
cherry pick pingcap#24513 to release-5.0
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
ClSlaid authored and ti-srebot committed Jun 9, 2021
1 parent dc40a09 commit 1a50d44
Show file tree
Hide file tree
Showing 9 changed files with 725 additions and 11 deletions.
1 change: 1 addition & 0 deletions executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1533,6 +1533,7 @@ func (b *executorBuilder) buildMemTable(v *plannercore.PhysicalMemTable) Executo
strings.ToLower(infoschema.TableTiKVStoreStatus),
strings.ToLower(infoschema.TableStatementsSummary),
strings.ToLower(infoschema.TableStatementsSummaryHistory),
strings.ToLower(infoschema.TableStatementsSummaryEvicted),
strings.ToLower(infoschema.ClusterTableStatementsSummary),
strings.ToLower(infoschema.ClusterTableStatementsSummaryHistory),
strings.ToLower(infoschema.TablePlacementPolicy),
Expand Down
60 changes: 60 additions & 0 deletions executor/infoschema_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ func (e *memtableRetriever) retrieve(ctx context.Context, sctx sessionctx.Contex
infoschema.ClusterTableStatementsSummary,
infoschema.ClusterTableStatementsSummaryHistory:
err = e.setDataForStatementsSummary(sctx, e.table.Name.O)
case infoschema.TableStatementsSummaryEvicted:
e.setDataForStatementsSummaryEvicted(sctx)
case infoschema.TablePlacementPolicy:
err = e.setDataForPlacementPolicy(sctx)
case infoschema.TableClientErrorsSummaryGlobal,
Expand Down Expand Up @@ -1966,6 +1968,64 @@ func (e *memtableRetriever) setDataForClientErrorsSummary(ctx sessionctx.Context
return nil
}

<<<<<<< HEAD
=======
func (e *memtableRetriever) setDataForTiDBTrx(ctx sessionctx.Context) {
sm := ctx.GetSessionManager()
if sm == nil {
return
}

loginUser := ctx.GetSessionVars().User
hasProcessPriv := hasPriv(ctx, mysql.ProcessPriv)
infoList := sm.ShowTxnList()
for _, info := range infoList {
// If you have the PROCESS privilege, you can see all running transactions.
// Otherwise, you can see only your own transactions.
if !hasProcessPriv && loginUser != nil && info.Username != loginUser.Username {
continue
}
e.rows = append(e.rows, info.ToDatum())
}
}

func (e *memtableRetriever) setDataForClusterTiDBTrx(ctx sessionctx.Context) error {
e.setDataForTiDBTrx(ctx)
rows, err := infoschema.AppendHostInfoToRows(ctx, e.rows)
if err != nil {
return err
}
e.rows = rows
return nil
}

func (e *memtableRetriever) setDataForDeadlock(ctx sessionctx.Context) error {
if !hasPriv(ctx, mysql.ProcessPriv) {
return plannercore.ErrSpecificAccessDenied.GenWithStackByArgs("PROCESS")
}

e.rows = deadlockhistory.GlobalDeadlockHistory.GetAllDatum()
return nil
}

func (e *memtableRetriever) setDataForClusterDeadlock(ctx sessionctx.Context) error {
err := e.setDataForDeadlock(ctx)
if err != nil {
return err
}
rows, err := infoschema.AppendHostInfoToRows(ctx, e.rows)
if err != nil {
return err
}
e.rows = rows
return nil
}

func (e *memtableRetriever) setDataForStatementsSummaryEvicted(ctx sessionctx.Context) {
e.rows = stmtsummary.StmtSummaryByDigestMap.ToEvictedCountDatum()
}

>>>>>>> 0367c5469... inforschema, executor, util/kvcache, util/statement_summary : Add STATEMENTS_SUMMARY_EVICTED into information_schema (#24513)
type hugeMemTableRetriever struct {
dummyCloser
table *model.TableInfo
Expand Down
54 changes: 54 additions & 0 deletions infoschema/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ const (
TableStatementsSummary = "STATEMENTS_SUMMARY"
// TableStatementsSummaryHistory is the string constant of statements summary history table.
TableStatementsSummaryHistory = "STATEMENTS_SUMMARY_HISTORY"
// TableStatementsSummaryEvicted is the string constant of statements summary evicted table.
TableStatementsSummaryEvicted = "STATEMENTS_SUMMARY_EVICTED"
// TableStorageStats is a table that contains all tables disk usage
TableStorageStats = "TABLE_STORAGE_STATS"
// TableTiFlashTables is the string constant of tiflash tables table.
Expand Down Expand Up @@ -233,6 +235,15 @@ var tableIDMap = map[string]int64{
TableClientErrorsSummaryGlobal: autoid.InformationSchemaDBID + 67,
TableClientErrorsSummaryByUser: autoid.InformationSchemaDBID + 68,
TableClientErrorsSummaryByHost: autoid.InformationSchemaDBID + 69,
<<<<<<< HEAD
=======
TableTiDBTrx: autoid.InformationSchemaDBID + 70,
ClusterTableTiDBTrx: autoid.InformationSchemaDBID + 71,
TableDeadlocks: autoid.InformationSchemaDBID + 72,
ClusterTableDeadlocks: autoid.InformationSchemaDBID + 73,
TableDataLockWaits: autoid.InformationSchemaDBID + 74,
TableStatementsSummaryEvicted: autoid.InformationSchemaDBID + 75,
>>>>>>> 0367c5469... inforschema, executor, util/kvcache, util/statement_summary : Add STATEMENTS_SUMMARY_EVICTED into information_schema (#24513)
}

type columnInfo struct {
Expand Down Expand Up @@ -1331,6 +1342,48 @@ var tableClientErrorsSummaryByHostCols = []columnInfo{
{name: "LAST_SEEN", tp: mysql.TypeTimestamp, size: 26},
}

<<<<<<< HEAD
=======
var tableTiDBTrxCols = []columnInfo{
{name: "ID", tp: mysql.TypeLonglong, size: 21, flag: mysql.PriKeyFlag | mysql.NotNullFlag | mysql.UnsignedFlag},
{name: "START_TIME", tp: mysql.TypeTimestamp, decimal: 6, size: 26, comment: "Start time of the transaction"},
{name: "CURRENT_SQL_DIGEST", tp: mysql.TypeVarchar, size: 64, comment: "Digest of the sql the transaction are currently running"},
{name: "STATE", tp: mysql.TypeEnum, enumElems: txninfo.TxnRunningStateStrs, comment: "Current running state of the transaction"},
{name: "WAITING_START_TIME", tp: mysql.TypeTimestamp, decimal: 6, size: 26, comment: "Current lock waiting's start time"},
{name: "LEN", tp: mysql.TypeLonglong, size: 64, comment: "How many entries are in MemDB"},
{name: "SIZE", tp: mysql.TypeLonglong, size: 64, comment: "MemDB used memory"},
{name: "SESSION_ID", tp: mysql.TypeLonglong, size: 21, flag: mysql.UnsignedFlag, comment: "Which session this transaction belongs to"},
{name: "USER", tp: mysql.TypeVarchar, size: 16, comment: "The user who open this session"},
{name: "DB", tp: mysql.TypeVarchar, size: 64, comment: "The schema this transaction works on"},
{name: "ALL_SQL_DIGESTS", tp: mysql.TypeBlob, size: types.UnspecifiedLength, comment: "A list of the digests of SQL statements that the transaction has executed"},
}

var tableDeadlocksCols = []columnInfo{
{name: "DEADLOCK_ID", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag, comment: "The ID to distinguish different deadlock events"},
{name: "OCCUR_TIME", tp: mysql.TypeTimestamp, decimal: 6, size: 26, comment: "The physical time when the deadlock occurs"},
{name: "RETRYABLE", tp: mysql.TypeTiny, size: 1, flag: mysql.NotNullFlag, comment: "Whether the deadlock is retryable. Retryable deadlocks are usually not reported to the client"},
{name: "TRY_LOCK_TRX_ID", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag | mysql.UnsignedFlag, comment: "The transaction ID (start ts) of the transaction that's trying to acquire the lock"},
{name: "CURRENT_SQL_DIGEST", tp: mysql.TypeVarchar, size: 64, comment: "The digest of the SQL that's being blocked"},
{name: "KEY", tp: mysql.TypeBlob, size: types.UnspecifiedLength, comment: "The key on which a transaction is waiting for another"},
{name: "TRX_HOLDING_LOCK", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag | mysql.UnsignedFlag, comment: "The transaction ID (start ts) of the transaction that's currently holding the lock"},
// TODO: Implement the ALL_SQL_DIGESTS column
// {name: "ALL_SQL_DIGESTS", tp: mysql.TypeBlob, size: types.UnspecifiedLength, comment: "A list of the digests of SQL statements that the transaction has executed"},
}

var tableDataLockWaitsCols = []columnInfo{
{name: "KEY", tp: mysql.TypeVarchar, size: 64, flag: mysql.NotNullFlag, comment: "The key that's being waiting on"},
{name: "TRX_ID", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag | mysql.UnsignedFlag, comment: "Current transaction that's waiting for the lock"},
{name: "CURRENT_HOLDING_TRX_ID", tp: mysql.TypeLonglong, size: 21, flag: mysql.NotNullFlag | mysql.UnsignedFlag, comment: "The transaction that's holding the lock and blocks the current transaction"},
{name: "SQL_DIGEST", tp: mysql.TypeVarchar, size: 64, comment: "Digest of the SQL that's trying to acquire the lock"},
}

var tableStatementsSummaryEvictedCols = []columnInfo{
{name: "BEGIN_TIME", tp: mysql.TypeTimestamp, size: 26},
{name: "END_TIME", tp: mysql.TypeTimestamp, size: 26},
{name: "EVICTED_COUNT", tp: mysql.TypeLonglong, size: 64, flag: mysql.NotNullFlag},
}

>>>>>>> 0367c5469... inforschema, executor, util/kvcache, util/statement_summary : Add STATEMENTS_SUMMARY_EVICTED into information_schema (#24513)
// GetShardingInfo returns a nil or description string for the sharding information of given TableInfo.
// The returned description string may be:
// - "NOT_SHARDED": for tables that SHARD_ROW_ID_BITS is not specified.
Expand Down Expand Up @@ -1693,6 +1746,7 @@ var tableNameToColumns = map[string][]columnInfo{
TableSequences: tableSequencesCols,
TableStatementsSummary: tableStatementsSummaryCols,
TableStatementsSummaryHistory: tableStatementsSummaryCols,
TableStatementsSummaryEvicted: tableStatementsSummaryEvictedCols,
TableStorageStats: tableStorageStatsCols,
TableTiFlashTables: tableTableTiFlashTablesCols,
TableTiFlashSegments: tableTableTiFlashSegmentsCols,
Expand Down
27 changes: 27 additions & 0 deletions infoschema/tables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,33 @@ func (s *testTableSuite) TestStmtSummarySensitiveQuery(c *C) {
))
}

func (s *testTableSuite) TestSimpleStmtSummaryEvictedCount(c *C) {
now := time.Now().Unix()
interval := int64(1800)
beginTimeForCurInterval := now - now%interval
tk := s.newTestKitWithPlanCache(c)
tk.MustExec(fmt.Sprintf("set global tidb_stmt_summary_refresh_interval = %v", interval))
tk.MustExec("set global tidb_enable_stmt_summary = 0")
tk.MustExec("set global tidb_enable_stmt_summary = 1")
// first sql
tk.MustExec("set global tidb_stmt_summary_max_stmt_count = 1")
// second sql
tk.MustQuery("show databases;")
// query `evicted table` is also a SQL, passing it leads to the eviction of the previous SQLs.
tk.MustQuery("select * from `information_schema`.`STATEMENTS_SUMMARY_EVICTED`;").
Check(testkit.Rows(
fmt.Sprintf("%s %s %v",
time.Unix(beginTimeForCurInterval, 0).Format("2006-01-02 15:04:05"),
time.Unix(beginTimeForCurInterval+interval, 0).Format("2006-01-02 15:04:05"),
int64(2)),
))
// TODO: Add more tests.

// clean up side effects
tk.MustExec("set global tidb_stmt_summary_max_stmt_count = 100")
tk.MustExec("set global tidb_stmt_summary_refresh_interval = 1800")
}

func (s *testTableSuite) TestPerformanceSchemaforPlanCache(c *C) {
orgEnable := plannercore.PreparedPlanCacheEnabled()
defer func() {
Expand Down
3 changes: 3 additions & 0 deletions util/kvcache/simple_lru.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ func (l *SimpleLRUCache) Put(key Key, value Value) {
if l.size > l.capacity {
lru := l.cache.Back()
l.cache.Remove(lru)
if l.onEvict != nil {
l.onEvict(lru.Value.(*cacheEntry).key, lru.Value.(*cacheEntry).value)
}
delete(l.elements, string(lru.Value.(*cacheEntry).key.Hash()))
l.size--
}
Expand Down
46 changes: 37 additions & 9 deletions util/kvcache/simple_lru_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,29 +58,57 @@ func (s *testLRUCacheSuite) TestPut(c *C) {
maxMem, err := memory.MemTotal()
c.Assert(err, IsNil)

lru := NewSimpleLRUCache(3, 0, maxMem)
c.Assert(lru.capacity, Equals, uint(3))
lruMaxMem := NewSimpleLRUCache(3, 0, maxMem)
lruZeroQuota := NewSimpleLRUCache(3, 0, 0)
c.Assert(lruMaxMem.capacity, Equals, uint(3))
c.Assert(lruZeroQuota.capacity, Equals, uint(3))

keys := make([]*mockCacheKey, 5)
vals := make([]int64, 5)

<<<<<<< HEAD

=======
maxMemDroppedKv := make(map[Key]Value)
zeroQuotaDroppedKv := make(map[Key]Value)

// test onEvict function
lruMaxMem.SetOnEvict(func(key Key, value Value) {
maxMemDroppedKv[key] = value
})
// test onEvict function on 0 value of quota
lruZeroQuota.SetOnEvict(func(key Key, value Value) {
zeroQuotaDroppedKv[key] = value
})
>>>>>>> 0367c5469... inforschema, executor, util/kvcache, util/statement_summary : Add STATEMENTS_SUMMARY_EVICTED into information_schema (#24513)
for i := 0; i < 5; i++ {
keys[i] = newMockHashKey(int64(i))
vals[i] = int64(i)
lru.Put(keys[i], vals[i])
lruMaxMem.Put(keys[i], vals[i])
lruZeroQuota.Put(keys[i], vals[i])
}
c.Assert(lru.size, Equals, lru.capacity)
c.Assert(lru.size, Equals, uint(3))
c.Assert(lruMaxMem.size, Equals, lruMaxMem.capacity)
c.Assert(lruZeroQuota.size, Equals, lruZeroQuota.capacity)
c.Assert(lruMaxMem.size, Equals, uint(3))
c.Assert(lruZeroQuota.size, Equals, lruMaxMem.size)

// test for non-existent elements
<<<<<<< HEAD
=======
c.Assert(len(maxMemDroppedKv), Equals, 2)
>>>>>>> 0367c5469... inforschema, executor, util/kvcache, util/statement_summary : Add STATEMENTS_SUMMARY_EVICTED into information_schema (#24513)
for i := 0; i < 2; i++ {
element, exists := lru.elements[string(keys[i].Hash())]
element, exists := lruMaxMem.elements[string(keys[i].Hash())]
c.Assert(exists, IsFalse)
c.Assert(element, IsNil)
<<<<<<< HEAD
=======
c.Assert(maxMemDroppedKv[keys[i]], Equals, vals[i])
c.Assert(zeroQuotaDroppedKv[keys[i]], Equals, vals[i])
>>>>>>> 0367c5469... inforschema, executor, util/kvcache, util/statement_summary : Add STATEMENTS_SUMMARY_EVICTED into information_schema (#24513)
}

// test for existent elements
root := lru.cache.Front()
root := lruMaxMem.cache.Front()
c.Assert(root, NotNil)
for i := 4; i >= 2; i-- {
entry, ok := root.Value.(*cacheEntry)
Expand All @@ -92,7 +120,7 @@ func (s *testLRUCacheSuite) TestPut(c *C) {
c.Assert(key, NotNil)
c.Assert(key, Equals, keys[i])

element, exists := lru.elements[string(keys[i].Hash())]
element, exists := lruMaxMem.elements[string(keys[i].Hash())]
c.Assert(exists, IsTrue)
c.Assert(element, NotNil)
c.Assert(element, Equals, root)
Expand Down
Loading

0 comments on commit 1a50d44

Please sign in to comment.