Skip to content

Commit d3920de

Browse files
sql: Queries under the InternalAppNamePrefix attribute to internal metrics.
Previously, there did not exist a way for external connections to have their SQL metrics (ex/ `sql.insert.count`) be counted as internal queries (ex/ `sql.insert.count.internal`). This is specifically problematic for cli utilities like `cockroach debug zip` which issue SQL queries that often take much longer than queries in a user's workload. As a result, users see a spike in their p99.99 or p99.9 SQL service latencies causing unnecessary concern. This commit utilizes the existing constant InternalAppNamePrefix. Specifically, it modifies the connExecutor to set the metrics struct to the server's internal or user facing metrics according to the app name. This commit also modifies the debug zip to use the InternalAppNamePrefix. Fixes: #143224 Release note (ops change): debug zip queries are attributed towards internal sql metrics. As a result user's won't see the debug zip impact on the SQL charts in DB console.
1 parent 93754a1 commit d3920de

File tree

5 files changed

+107
-5
lines changed

5 files changed

+107
-5
lines changed

pkg/cli/sql_client.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,14 @@ func makeSQLClientForBaseURL(
136136
// If there is no user in the URL already, fill in the default user.
137137
sqlCtx.User = username.RootUser
138138

139-
// If there is no application name already, use the provided one.
140-
sqlCtx.ApplicationName = catconstants.ReportableAppNamePrefix + appName
139+
// Some cli utilities (ex/ debug zip) use an InternalAppNamePrefix so that
140+
// they do not affect user facing SQL metrics (and as a result the SQL charts
141+
// in the DB Console).
142+
if strings.HasPrefix(appName, catconstants.InternalAppNamePrefix) {
143+
sqlCtx.ApplicationName = appName
144+
} else {
145+
sqlCtx.ApplicationName = catconstants.ReportableAppNamePrefix + appName
146+
}
141147

142148
// How we're going to authenticate.
143149
usePw, _, _ := baseURL.GetAuthnPassword()

pkg/cli/zip.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ func runDebugZip(cmd *cobra.Command, args []string) (retErr error) {
291291

292292
zr.sqlOutputFilenameExtension = computeSQLOutputFilenameExtension(sqlExecCtx.TableDisplayFormat)
293293

294-
sqlConn, err := makeTenantSQLClient(ctx, "cockroach zip", useSystemDb, tenant.TenantName)
294+
sqlConn, err := makeTenantSQLClient(ctx, catconstants.InternalAppNamePrefix+" cockroach zip", useSystemDb, tenant.TenantName)
295295
// The zip output is sent directly into a text file, so the results should
296296
// be scanned into strings.
297297
_ = sqlConn.SetAlwaysInferResultTypes(false)

pkg/sql/conn_executor.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,14 +879,22 @@ func (s *Server) SetupConn(
879879
return ConnectionHandler{}, err
880880
}
881881

882+
// Usage of the InternalAppNamePrefix is usually done using an InternalExecutor which already is set up
883+
// to use the InternalMetrics. However, some external connections use the prefix as well, for example
884+
// the debug zip cli tool.
885+
metrics := &s.Metrics
886+
if strings.HasPrefix(sd.ApplicationName, catconstants.InternalAppNamePrefix) {
887+
metrics = &s.InternalMetrics
888+
}
889+
882890
ex := s.newConnExecutor(
883891
ctx,
884892
executorTypeExec,
885893
sdMutIterator,
886894
stmtBuf,
887895
clientComm,
888896
memMetrics,
889-
&s.Metrics,
897+
metrics,
890898
s.localSqlStats.GetApplicationStats(sd.ApplicationName),
891899
sessionID,
892900
false, /* underOuterTxn */
@@ -1227,6 +1235,11 @@ func (s *Server) newConnExecutor(
12271235
ex.dataMutatorIterator.onApplicationNameChange = func(newName string) {
12281236
ex.applicationName.Store(newName)
12291237
ex.applicationStats = ex.server.localSqlStats.GetApplicationStats(newName)
1238+
if strings.HasPrefix(newName, catconstants.InternalAppNamePrefix) {
1239+
ex.metrics = &ex.server.InternalMetrics
1240+
} else {
1241+
ex.metrics = &ex.server.Metrics
1242+
}
12301243
}
12311244

12321245
ex.extraTxnState.underOuterTxn = underOuterTxn

pkg/sql/conn_executor_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"github.com/cockroachdb/cockroach/pkg/sql/parser"
3838
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
3939
"github.com/cockroachdb/cockroach/pkg/sql/rowexec"
40+
"github.com/cockroachdb/cockroach/pkg/sql/sem/catconstants"
4041
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
4142
"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
4243
"github.com/cockroachdb/cockroach/pkg/sql/sqlliveness"
@@ -2420,3 +2421,85 @@ SELECT id
24202421
).Scan(&id)
24212422
return id
24222423
}
2424+
2425+
func TestInternalAppNamePrefix(t *testing.T) {
2426+
defer leaktest.AfterTest(t)()
2427+
defer log.Scope(t).Close(t)
2428+
2429+
ctx := context.Background()
2430+
params := base.TestServerArgs{}
2431+
params.Insecure = true
2432+
s, sqlDB, _ := serverutils.StartServer(t, params)
2433+
defer s.Stopper().Stop(ctx)
2434+
2435+
// Create a test table.
2436+
_, err := sqlDB.Exec("CREATE TABLE test (k INT PRIMARY KEY, v INT)")
2437+
require.NoError(t, err)
2438+
2439+
t.Run("app name set at conn init", func(t *testing.T) {
2440+
// Create a connection.
2441+
connURL := url.URL{
2442+
Scheme: "postgres",
2443+
User: url.User(username.RootUser),
2444+
Host: s.AdvSQLAddr(),
2445+
}
2446+
q := connURL.Query()
2447+
q.Add("sslmode", "disable")
2448+
q.Add("application_name", catconstants.InternalAppNamePrefix+"mytest")
2449+
connURL.RawQuery = q.Encode()
2450+
db, err := gosql.Open("postgres", connURL.String())
2451+
require.NoError(t, err)
2452+
defer db.Close()
2453+
runner := sqlutils.MakeSQLRunner(db)
2454+
2455+
// Get initial metric values
2456+
sqlServer := s.SQLServer().(*sql.Server)
2457+
initialInternalMetrics := sqlServer.InternalMetrics.ExecutedStatementCounters.InsertCount.Count()
2458+
initialUserMetrics := sqlServer.Metrics.ExecutedStatementCounters.InsertCount.Count()
2459+
runner.Exec(t, "INSERT into test values (1, 1)")
2460+
// Confirm only internal metrics increased.
2461+
finalInternalMetrics := sqlServer.InternalMetrics.ExecutedStatementCounters.InsertCount.Count()
2462+
finalUserMetrics := sqlServer.Metrics.ExecutedStatementCounters.InsertCount.Count()
2463+
require.Equal(t, initialUserMetrics, finalUserMetrics)
2464+
require.Equal(t, initialInternalMetrics+1, finalInternalMetrics)
2465+
})
2466+
2467+
t.Run("app name set in session", func(t *testing.T) {
2468+
// Create a connection.
2469+
connURL := url.URL{
2470+
Scheme: "postgres",
2471+
User: url.User(username.RootUser),
2472+
Host: s.AdvSQLAddr(),
2473+
RawQuery: "sslmode=disable",
2474+
}
2475+
db, err := gosql.Open("postgres", connURL.String())
2476+
require.NoError(t, err)
2477+
defer db.Close()
2478+
runner := sqlutils.MakeSQLRunner(db)
2479+
2480+
// Get initial metric values
2481+
sqlServer := s.SQLServer().(*sql.Server)
2482+
initialInternalMetrics := sqlServer.InternalMetrics.ExecutedStatementCounters.InsertCount.Count()
2483+
initialUserMetrics := sqlServer.Metrics.ExecutedStatementCounters.InsertCount.Count()
2484+
2485+
// Set app name to attribute query towards internal metrics.
2486+
runner.Exec(t, fmt.Sprintf("set application_name='%v'", catconstants.InternalAppNamePrefix+"mytest"))
2487+
runner.Exec(t, "INSERT into test values (2, 1)")
2488+
2489+
// Confirm only internal metrics increased.
2490+
finalInternalMetrics := sqlServer.InternalMetrics.ExecutedStatementCounters.InsertCount.Count()
2491+
finalUserMetrics := sqlServer.Metrics.ExecutedStatementCounters.InsertCount.Count()
2492+
require.Equal(t, initialUserMetrics, finalUserMetrics)
2493+
require.Equal(t, initialInternalMetrics+1, finalInternalMetrics)
2494+
2495+
// Reset app name.
2496+
runner.Exec(t, "set application_name='mytest'")
2497+
runner.Exec(t, "INSERT into test values (3, 1)")
2498+
2499+
// Confirm only user metrics increased.
2500+
finalInternalMetrics = sqlServer.InternalMetrics.ExecutedStatementCounters.InsertCount.Count()
2501+
finalUserMetrics = sqlServer.Metrics.ExecutedStatementCounters.InsertCount.Count()
2502+
require.Equal(t, initialUserMetrics+1, finalUserMetrics)
2503+
require.Equal(t, initialInternalMetrics+1, finalInternalMetrics)
2504+
})
2505+
}

pkg/sql/sem/catconstants/constants.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const InternalAppNamePrefix = ReportableAppNamePrefix + "internal"
2020

2121
// AttributedToUserInternalAppNamePrefix indicates that the application name
2222
// identifies an internally-executed query that should be attributed to the
23-
// user.
23+
// user. Specifically, this means having the queries show up in SQL activity pages.
2424
const AttributedToUserInternalAppNamePrefix = ReportableAppNamePrefix + "public-internal"
2525

2626
// DelegatedAppNamePrefix is added to a regular client application

0 commit comments

Comments
 (0)