diff --git a/pkg/apiserver/slowquery/model.go b/pkg/apiserver/slowquery/model.go index d85d0116b3..fb508b2af9 100644 --- a/pkg/apiserver/slowquery/model.go +++ b/pkg/apiserver/slowquery/model.go @@ -57,8 +57,9 @@ type Model struct { PlanFromBinding int `gorm:"column:Plan_from_binding" json:"plan_from_binding"` // Connection - User string `gorm:"column:User" json:"user"` - Host string `gorm:"column:Host" json:"host"` + User string `gorm:"column:User" json:"user"` + Host string `gorm:"column:Host" json:"host"` + SessionConnectAttrs *string `gorm:"column:Session_connect_attrs" json:"session_connect_attrs"` // Time ProcessTime float64 `gorm:"column:Process_time" json:"process_time"` diff --git a/tests/fixtures/CLUSTER_SLOW_QUERY.yml b/tests/fixtures/CLUSTER_SLOW_QUERY.yml index 29594a8847..499447acc3 100644 --- a/tests/fixtures/CLUSTER_SLOW_QUERY.yml +++ b/tests/fixtures/CLUSTER_SLOW_QUERY.yml @@ -5,6 +5,7 @@ User: "1" Host: "1" Conn_ID: 1 + Session_connect_attrs: '{"_client_name":"Go-MySQL-Driver","_os":"linux","app_name":"test_app"}' Exec_retry_count: 1 Exec_retry_time: 1 Query_time: 0.462883101 @@ -78,6 +79,7 @@ User: root Host: 127.0.0.1 Conn_ID: 7 + Session_connect_attrs: '{"_client_name":"Go-MySQL-Driver","_os":"linux","app_name":"test_app"}' Exec_retry_count: 0 Exec_retry_time: 0 Query_time: 6.3039e-05 diff --git a/tests/integration/slowquery/mock_db_test.go b/tests/integration/slowquery/mock_db_test.go index 57aa287ee8..ba1a7dcd0f 100644 --- a/tests/integration/slowquery/mock_db_test.go +++ b/tests/integration/slowquery/mock_db_test.go @@ -114,6 +114,8 @@ func (s *testMockDBSuite) TestGetListAllFieldsRequest() { s.Require().NotEmpty(d.Digest) s.Require().NotEmpty(d.GetCommitTSTime) s.Require().NotEmpty(d.Host) + s.Require().NotNil(d.SessionConnectAttrs) + s.Require().JSONEq(`{"_client_name":"Go-MySQL-Driver","_os":"linux","app_name":"test_app"}`, *d.SessionConnectAttrs) s.Require().NotEmpty(d.IndexNames) s.Require().NotEmpty(d.Instance) s.Require().NotEmpty(d.IsInternal) @@ -142,6 +144,12 @@ func (s *testMockDBSuite) TestGetListAllFieldsRequest() { s.Require().NotEmpty(d.WriteSize) } +func (s *testMockDBSuite) TestGetAvailableFields() { + cls, err := slowquery.GetAvailableFields(s.sysSchema, s.mockDBSession()) + s.Require().NoError(err) + s.Require().Contains(cls, "session_connect_attrs") +} + func (s *testMockDBSuite) TestGetListTimeRangeRequest() { // 1639928730 - 2021-12-19T23:45:30+08:00 // 1639928987 - 2021-12-19T23:49:48+08:00 @@ -282,4 +290,6 @@ func (s *testMockDBSuite) TestGetDetailRequest() { s.Require().Equal(ds2.Timestamp, 1639928987.802016) s.Require().Equal(ds2.Digest, "2375da6810d9c5a0d1c84875b1376bfd469ad952c1884f5dc1d6f36fc953b5df") s.Require().Equal(ds2.ConnectionID, "7") + s.Require().NotNil(ds2.SessionConnectAttrs) + s.Require().JSONEq(`{"_client_name":"Go-MySQL-Driver","_os":"linux","app_name":"test_app"}`, *ds2.SessionConnectAttrs) } diff --git a/tests/schema/test.CLUSTER_SLOW_QUERY-schema.sql b/tests/schema/test.CLUSTER_SLOW_QUERY-schema.sql index a7f712195b..9e96fdc29c 100644 --- a/tests/schema/test.CLUSTER_SLOW_QUERY-schema.sql +++ b/tests/schema/test.CLUSTER_SLOW_QUERY-schema.sql @@ -1,3 +1,3 @@ /*!40101 SET NAMES binary*/; /*T![placement] SET PLACEMENT_CHECKS = 0*/; -CREATE TABLE `CLUSTER_SLOW_QUERY` (`INSTANCE` varchar(64) DEFAULT NULL, `Time` timestamp(6) NOT NULL, `Txn_start_ts` bigint(20) unsigned DEFAULT NULL, `User` varchar(64) DEFAULT NULL, `Host` varchar(64) DEFAULT NULL, `Conn_ID` bigint(20) unsigned DEFAULT NULL, `Session_alias` varchar(64) DEFAULT NULL, `Exec_retry_count` bigint(20) unsigned DEFAULT NULL, `Exec_retry_time` double DEFAULT NULL, `Query_time` double DEFAULT NULL, `Parse_time` double DEFAULT NULL, `Compile_time` double DEFAULT NULL, `Rewrite_time` double DEFAULT NULL, `Preproc_subqueries` bigint(20) unsigned DEFAULT NULL, `Preproc_subqueries_time` double DEFAULT NULL, `Optimize_time` double DEFAULT NULL, `Wait_TS` double DEFAULT NULL, `Prewrite_time` double DEFAULT NULL, `Wait_prewrite_binlog_time` double DEFAULT NULL, `Commit_time` double DEFAULT NULL, `Get_commit_ts_time` double DEFAULT NULL, `Commit_backoff_time` double DEFAULT NULL, `Backoff_types` varchar(64) DEFAULT NULL, `Resolve_lock_time` double DEFAULT NULL, `Local_latch_wait_time` double DEFAULT NULL, `Write_keys` bigint(22) DEFAULT NULL, `Write_size` bigint(22) DEFAULT NULL, `Prewrite_region` bigint(22) DEFAULT NULL, `Txn_retry` bigint(22) DEFAULT NULL, `Cop_time` double DEFAULT NULL, `Process_time` double DEFAULT NULL, `Wait_time` double DEFAULT NULL, `Backoff_time` double DEFAULT NULL, `LockKeys_time` double DEFAULT NULL, `Request_count` bigint(20) unsigned DEFAULT NULL, `Total_keys` bigint(20) unsigned DEFAULT NULL, `Process_keys` bigint(20) unsigned DEFAULT NULL, `Rocksdb_delete_skipped_count` bigint(20) unsigned DEFAULT NULL, `Rocksdb_key_skipped_count` bigint(20) unsigned DEFAULT NULL, `Rocksdb_block_cache_hit_count` bigint(20) unsigned DEFAULT NULL, `Rocksdb_block_read_count` bigint(20) unsigned DEFAULT NULL, `Rocksdb_block_read_byte` bigint(20) unsigned DEFAULT NULL, `DB` varchar(64) DEFAULT NULL, `Index_names` varchar(100) DEFAULT NULL, `Is_internal` tinyint(1) DEFAULT NULL, `Digest` varchar(64) DEFAULT NULL, `Stats` varchar(512) DEFAULT NULL, `Cop_proc_avg` double DEFAULT NULL, `Cop_proc_p90` double DEFAULT NULL, `Cop_proc_max` double DEFAULT NULL, `Cop_proc_addr` varchar(64) DEFAULT NULL, `Cop_wait_avg` double DEFAULT NULL, `Cop_wait_p90` double DEFAULT NULL, `Cop_wait_max` double DEFAULT NULL, `Cop_wait_addr` varchar(64) DEFAULT NULL, `Mem_max` bigint(20) DEFAULT NULL, `Mem_arbitration` double DEFAULT NULL, `Disk_max` bigint(20) DEFAULT NULL, `KV_total` double DEFAULT NULL, `PD_total` double DEFAULT NULL, `Backoff_total` double DEFAULT NULL, `Write_sql_response_total` double DEFAULT NULL, `Result_rows` bigint(22) DEFAULT NULL, `Warnings` longtext DEFAULT NULL, `Backoff_Detail` varchar(4096) DEFAULT NULL, `Prepared` tinyint(1) DEFAULT NULL, `Succ` tinyint(1) DEFAULT NULL, `IsExplicitTxn` tinyint(1) DEFAULT NULL, `IsWriteCacheTable` tinyint(1) DEFAULT NULL, `Plan_from_cache` tinyint(1) DEFAULT NULL, `Plan_from_binding` tinyint(1) DEFAULT NULL, `Has_more_results` tinyint(1) DEFAULT NULL, `Resource_group` varchar(64) DEFAULT NULL, `Request_unit_read` double DEFAULT NULL, `Request_unit_write` double DEFAULT NULL, `Time_queued_by_rc` double DEFAULT NULL, `Unpacked_bytes_sent_tikv_total` bigint DEFAULT NULL, `Unpacked_bytes_received_tikv_total` bigint DEFAULT NULL, `Unpacked_bytes_sent_tikv_cross_zone` bigint DEFAULT NULL, `Unpacked_bytes_received_tikv_cross_zone` bigint DEFAULT NULL, `Unpacked_bytes_sent_tiflash_total` bigint DEFAULT NULL, `Unpacked_bytes_received_tiflash_total` bigint DEFAULT NULL, `Unpacked_bytes_sent_tiflash_cross_zone` bigint DEFAULT NULL, `Unpacked_bytes_received_tiflash_cross_zone` bigint DEFAULT NULL, `Plan` longtext DEFAULT NULL, `Plan_digest` varchar(128) DEFAULT NULL, `Binary_plan` longtext DEFAULT NULL, `Prev_stmt` longtext DEFAULT NULL, `Query` longtext DEFAULT NULL, PRIMARY KEY (`Time`) /*T![clustered_index] CLUSTERED */ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; \ No newline at end of file +CREATE TABLE `CLUSTER_SLOW_QUERY` (`INSTANCE` varchar(64) DEFAULT NULL, `Time` timestamp(6) NOT NULL, `Txn_start_ts` bigint(20) unsigned DEFAULT NULL, `User` varchar(64) DEFAULT NULL, `Host` varchar(64) DEFAULT NULL, `Conn_ID` bigint(20) unsigned DEFAULT NULL, `Session_alias` varchar(64) DEFAULT NULL, `Session_connect_attrs` json DEFAULT NULL, `Exec_retry_count` bigint(20) unsigned DEFAULT NULL, `Exec_retry_time` double DEFAULT NULL, `Query_time` double DEFAULT NULL, `Parse_time` double DEFAULT NULL, `Compile_time` double DEFAULT NULL, `Rewrite_time` double DEFAULT NULL, `Preproc_subqueries` bigint(20) unsigned DEFAULT NULL, `Preproc_subqueries_time` double DEFAULT NULL, `Optimize_time` double DEFAULT NULL, `Wait_TS` double DEFAULT NULL, `Prewrite_time` double DEFAULT NULL, `Wait_prewrite_binlog_time` double DEFAULT NULL, `Commit_time` double DEFAULT NULL, `Get_commit_ts_time` double DEFAULT NULL, `Commit_backoff_time` double DEFAULT NULL, `Backoff_types` varchar(64) DEFAULT NULL, `Resolve_lock_time` double DEFAULT NULL, `Local_latch_wait_time` double DEFAULT NULL, `Write_keys` bigint(22) DEFAULT NULL, `Write_size` bigint(22) DEFAULT NULL, `Prewrite_region` bigint(22) DEFAULT NULL, `Txn_retry` bigint(22) DEFAULT NULL, `Cop_time` double DEFAULT NULL, `Process_time` double DEFAULT NULL, `Wait_time` double DEFAULT NULL, `Backoff_time` double DEFAULT NULL, `LockKeys_time` double DEFAULT NULL, `Request_count` bigint(20) unsigned DEFAULT NULL, `Total_keys` bigint(20) unsigned DEFAULT NULL, `Process_keys` bigint(20) unsigned DEFAULT NULL, `Rocksdb_delete_skipped_count` bigint(20) unsigned DEFAULT NULL, `Rocksdb_key_skipped_count` bigint(20) unsigned DEFAULT NULL, `Rocksdb_block_cache_hit_count` bigint(20) unsigned DEFAULT NULL, `Rocksdb_block_read_count` bigint(20) unsigned DEFAULT NULL, `Rocksdb_block_read_byte` bigint(20) unsigned DEFAULT NULL, `DB` varchar(64) DEFAULT NULL, `Index_names` varchar(100) DEFAULT NULL, `Is_internal` tinyint(1) DEFAULT NULL, `Digest` varchar(64) DEFAULT NULL, `Stats` varchar(512) DEFAULT NULL, `Cop_proc_avg` double DEFAULT NULL, `Cop_proc_p90` double DEFAULT NULL, `Cop_proc_max` double DEFAULT NULL, `Cop_proc_addr` varchar(64) DEFAULT NULL, `Cop_wait_avg` double DEFAULT NULL, `Cop_wait_p90` double DEFAULT NULL, `Cop_wait_max` double DEFAULT NULL, `Cop_wait_addr` varchar(64) DEFAULT NULL, `Mem_max` bigint(20) DEFAULT NULL, `Mem_arbitration` double DEFAULT NULL, `Disk_max` bigint(20) DEFAULT NULL, `KV_total` double DEFAULT NULL, `PD_total` double DEFAULT NULL, `Backoff_total` double DEFAULT NULL, `Write_sql_response_total` double DEFAULT NULL, `Result_rows` bigint(22) DEFAULT NULL, `Warnings` longtext DEFAULT NULL, `Backoff_Detail` varchar(4096) DEFAULT NULL, `Prepared` tinyint(1) DEFAULT NULL, `Succ` tinyint(1) DEFAULT NULL, `IsExplicitTxn` tinyint(1) DEFAULT NULL, `IsWriteCacheTable` tinyint(1) DEFAULT NULL, `Plan_from_cache` tinyint(1) DEFAULT NULL, `Plan_from_binding` tinyint(1) DEFAULT NULL, `Has_more_results` tinyint(1) DEFAULT NULL, `Resource_group` varchar(64) DEFAULT NULL, `Request_unit_read` double DEFAULT NULL, `Request_unit_write` double DEFAULT NULL, `Time_queued_by_rc` double DEFAULT NULL, `Unpacked_bytes_sent_tikv_total` bigint DEFAULT NULL, `Unpacked_bytes_received_tikv_total` bigint DEFAULT NULL, `Unpacked_bytes_sent_tikv_cross_zone` bigint DEFAULT NULL, `Unpacked_bytes_received_tikv_cross_zone` bigint DEFAULT NULL, `Unpacked_bytes_sent_tiflash_total` bigint DEFAULT NULL, `Unpacked_bytes_received_tiflash_total` bigint DEFAULT NULL, `Unpacked_bytes_sent_tiflash_cross_zone` bigint DEFAULT NULL, `Unpacked_bytes_received_tiflash_cross_zone` bigint DEFAULT NULL, `Plan` longtext DEFAULT NULL, `Plan_digest` varchar(128) DEFAULT NULL, `Binary_plan` longtext DEFAULT NULL, `Prev_stmt` longtext DEFAULT NULL, `Query` longtext DEFAULT NULL, PRIMARY KEY (`Time`) /*T![clustered_index] CLUSTERED */ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; diff --git a/ui/packages/tidb-dashboard-lib/src/apps/SlowQuery/pages/Detail/DetailTabs.tsx b/ui/packages/tidb-dashboard-lib/src/apps/SlowQuery/pages/Detail/DetailTabs.tsx index 1dc66fc4c3..606ec402d1 100644 --- a/ui/packages/tidb-dashboard-lib/src/apps/SlowQuery/pages/Detail/DetailTabs.tsx +++ b/ui/packages/tidb-dashboard-lib/src/apps/SlowQuery/pages/Detail/DetailTabs.tsx @@ -13,6 +13,25 @@ import { tabTxnItems } from './DetailTabTxn' import { useSchemaColumns } from '../../utils/useSchemaColumns' import { SlowQueryContext } from '../../context' +type SlowqueryModelWithSessionConnectAttrs = SlowqueryModel & { + session_connect_attrs?: string | null +} + +function getSessionConnectAttrsRaw(data: SlowqueryModel) { + return (data as SlowqueryModelWithSessionConnectAttrs).session_connect_attrs +} + +function parseSessionConnectAttrs(raw?: string | null) { + if (!raw || raw === 'null') { + return null + } + try { + return JSON.parse(raw) + } catch { + return raw + } +} + export default function DetailTabs({ data }: { data: SlowqueryModel }) { const ctx = useContext(SlowQueryContext) @@ -92,7 +111,38 @@ export default function DetailTabs({ data }: { data: SlowqueryModel }) { } } ] - if (data.warnings) { + const hasSessionConnectAttrs = schemaColumns.includes( + 'session_connect_attrs' + ) + const sessionConnectAttrsRaw = hasSessionConnectAttrs + ? getSessionConnectAttrsRaw(data) + : null + const sessionConnectAttrs = parseSessionConnectAttrs(sessionConnectAttrsRaw) + if (hasSessionConnectAttrs) { + tbs.push({ + key: 'session_attrs', + title: t('slow_query.detail.tabs.session_attrs'), + content: () => { + if ( + sessionConnectAttrs == null || + typeof sessionConnectAttrs === 'string' + ) { + return
{sessionConnectAttrsRaw ?? 'null'}
+ }
+ return (
+