Skip to content

Commit 78309d8

Browse files
committed
isession: add a helper for mutating the session
This adds a MutateSession method that allows modifying the session without going through the SQL layer. It is possible to modify the session using `SET ...` statements, but LDR must mutate the session before every statement and modifying the session consumes ~10% of all CPU cycles in a cluster that is using the crud writer to replicate data. An alternative to adding MutateSession is we could optimize the Set statement. The main reasons its inefficient for LDR are: 1. It only supports strings, so we can set the hlc origin timestamp without roundtripping through a string. 2. The optimizer does not support generic query plans for prepared statements that include a set statement. Release note: none Epic: CRDB-48647
1 parent c83ee6b commit 78309d8

File tree

6 files changed

+70
-0
lines changed

6 files changed

+70
-0
lines changed

pkg/sql/internal_session.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ func (c *ConnectionStateMachine) Push(ctx context.Context, cmd Command) error {
113113
return c.buffer.Push(ctx, cmd)
114114
}
115115

116+
// SessionDataMutatorIterator returns the session data mutator iterator for this connection.
117+
func (c *ConnectionStateMachine) SessionDataMutatorIterator() *sessionmutator.SessionDataMutatorIterator {
118+
return c.config.sdMutIterator
119+
}
120+
116121
// NewInternalSession constructs an internal session instance.
117122
func (s *Server) NewInternalSession(
118123
ctx context.Context,

pkg/sql/isession/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ go_library(
2020
"//pkg/sql/pgwire/pgwirebase",
2121
"//pkg/sql/sem/tree",
2222
"//pkg/sql/sessiondatapb",
23+
"//pkg/sql/sessionmutator",
2324
"//pkg/sql/types",
2425
"//pkg/util/retry",
2526
"@com_github_cockroachdb_crlib//crtime",
@@ -45,6 +46,7 @@ go_test(
4546
"//pkg/sql/isql",
4647
"//pkg/sql/parser",
4748
"//pkg/sql/sem/tree",
49+
"//pkg/sql/sessionmutator",
4850
"//pkg/sql/types",
4951
"//pkg/testutils/serverutils",
5052
"//pkg/testutils/sqlutils",

pkg/sql/isession/internal_session.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/cockroachdb/cockroach/pkg/sql/isql"
1515
"github.com/cockroachdb/cockroach/pkg/sql/parser/statements"
1616
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
17+
"github.com/cockroachdb/cockroach/pkg/sql/sessionmutator"
1718
"github.com/cockroachdb/cockroach/pkg/sql/types"
1819
"github.com/cockroachdb/cockroach/pkg/util/retry"
1920
"github.com/cockroachdb/crlib/crtime"
@@ -325,6 +326,20 @@ func (i *InternalSession) readResults(ctx context.Context) ([]tree.Datums, int,
325326
return rows, rowCount, resultErr
326327
}
327328

329+
func (i *InternalSession) ModifySession(
330+
ctx context.Context, mutate func(mutator sessionmutator.SessionDataMutator),
331+
) error {
332+
if i.poison != nil {
333+
return i.poison
334+
}
335+
336+
sdMutIterator := i.csm.SessionDataMutatorIterator()
337+
return sdMutIterator.ApplyOnTopMutator(func(m sessionmutator.SessionDataMutator) error {
338+
mutate(m)
339+
return nil
340+
})
341+
}
342+
328343
func (i *InternalSession) Close(ctx context.Context) {
329344
i.csm.Close(ctx)
330345
}

pkg/sql/isession/internal_session_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/cockroachdb/cockroach/pkg/sql/isql"
1717
"github.com/cockroachdb/cockroach/pkg/sql/parser"
1818
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
19+
"github.com/cockroachdb/cockroach/pkg/sql/sessionmutator"
1920
"github.com/cockroachdb/cockroach/pkg/sql/types"
2021
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
2122
"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
@@ -612,3 +613,35 @@ func TestSavepoint(t *testing.T) {
612613
{tree.NewDInt(tree.DInt(1)), tree.NewDInt(tree.DInt(10))},
613614
}, rows)
614615
}
616+
617+
func TestModifySession(t *testing.T) {
618+
defer leaktest.AfterTest(t)()
619+
defer log.Scope(t).Close(t)
620+
621+
ctx := context.Background()
622+
s := serverutils.StartServerOnly(t, base.TestServerArgs{})
623+
defer s.Stopper().Stop(ctx)
624+
625+
db := s.InternalDB().(descs.DB)
626+
session, err := db.Session(ctx, "test-session")
627+
require.NoError(t, err)
628+
defer session.Close(ctx)
629+
630+
// Modify the application name using ModifySession.
631+
err = session.ModifySession(ctx, func(m sessionmutator.SessionDataMutator) {
632+
m.SetApplicationName("my_test_app")
633+
})
634+
require.NoError(t, err)
635+
636+
// Verify the change by querying the session variable.
637+
stmt, err := parser.ParseOne("SHOW application_name")
638+
require.NoError(t, err)
639+
640+
prepared, err := session.Prepare(ctx, "show_app", stmt, nil)
641+
require.NoError(t, err)
642+
643+
rows, err := session.QueryPrepared(ctx, prepared, nil)
644+
require.NoError(t, err)
645+
require.Len(t, rows, 1)
646+
require.Equal(t, "my_test_app", string(tree.MustBeDString(rows[0][0])))
647+
}

pkg/sql/isql/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ go_library(
1818
"//pkg/sql/parser/statements",
1919
"//pkg/sql/sem/tree",
2020
"//pkg/sql/sessiondata",
21+
"//pkg/sql/sessionmutator",
2122
"//pkg/sql/types",
2223
"//pkg/util/admission/admissionpb",
2324
"@com_github_cockroachdb_redact//:redact",

pkg/sql/isql/isql_session.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/cockroachdb/cockroach/pkg/sql/parser/statements"
1212
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
13+
"github.com/cockroachdb/cockroach/pkg/sql/sessionmutator"
1314
"github.com/cockroachdb/cockroach/pkg/sql/types"
1415
)
1516

@@ -80,6 +81,19 @@ type Session interface {
8081
// }
8182
Savepoint(ctx context.Context, do func(context.Context) error) error
8283

84+
// ModifySession executes a function that mutates the session using the
85+
// sessionmutator.SessionDataMutator argument.
86+
//
87+
// Example:
88+
// err := session.ModifySession(ctx, func(mutator sessionmutator.SessionDataMutator) {
89+
// mutator.SetApplicationName("my_app")
90+
// mutator.SetDatabase("my_database")
91+
// })
92+
// if err != nil {
93+
// return err
94+
// }
95+
ModifySession(ctx context.Context, mutate func(mutator sessionmutator.SessionDataMutator)) error
96+
8397
// Close closes the session and cleans up internal resources.
8498
Close(ctx context.Context)
8599
}

0 commit comments

Comments
 (0)