Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor system variables to support account isolation #16551

Merged
merged 13 commits into from
Jun 4, 2024

Conversation

ck89119
Copy link
Contributor

@ck89119 ck89119 commented May 31, 2024

What type of PR is this?

  • API-change
  • BUG
  • Improvement
  • Documentation
  • Feature
  • Test and CI
  • Code Refactoring

Which issue(s) this PR fixes:

issue #16047

What this PR does / why we need it:

  • system variable now is account isolated
  • table mo_mysql_compatibility_mode only saves delta info between account's and cluster's default system variable values
  • always use session variable except show global variables

Copy link

PR-Agent was enabled for this repository. To continue using it, please link your git user with your CodiumAI identity here.

PR Review 🔍

⏱️ Estimated effort to review [1-5]

4, because the PR involves substantial changes across multiple files, including refactoring of system variables handling, authentication processes, and session management. The changes impact core functionalities such as session initialization, variable management, and transaction handling. Additionally, the PR modifies both the frontend and backend components, which requires careful review to ensure consistency and correctness across the system.

🧪 Relevant tests

Yes

⚡ Possible issues

Possible Bug: The removal of GlobalSystemVariables and introduction of GlobalSysVarsMgr could lead to issues if not all instances where global system variables were used have been updated to use the new manager. This includes ensuring that all necessary locks and thread-safety mechanisms are correctly implemented.

Refactoring Impact: The changes in session and variable handling need thorough testing to ensure that existing functionalities related to transaction management, session variables, and system variables are not adversely affected.

Performance Concerns: The new locking mechanisms and changes in the management of system variables could introduce performance bottlenecks, especially in high concurrency environments. It's crucial to benchmark these changes under load to identify any potential degradation in performance.

🔒 Security concerns

No

Copy link

PR-Agent was enabled for this repository. To continue using it, please link your git user with your CodiumAI identity here.

PR Code Suggestions ✨

CategorySuggestion                                                                                                                                    Score
Best practice
Handle errors from getSystemVariables more gracefully by returning the error to the caller

The getSystemVariables function call in genSession should handle errors more gracefully by
returning the error to the caller instead of calling t.Error(err).

pkg/frontend/session_test.go [236-238]

 sv, err := getSystemVariables("test/system_vars_config.toml")
 if err != nil {
-    t.Error(err)
+    return nil, err
 }
 
Suggestion importance[1-10]: 8

Why: This suggestion addresses a best practice by improving error handling in the genSession function. It correctly identifies the specific lines where the error handling can be improved, making the function more robust and maintainable by returning errors instead of directly logging them. This change is crucial for better error propagation and handling in test scenarios.

8
Handle the error returned by uuid.NewV7() in the NewSession function to ensure proper UUID generation

In the NewSession function, handle the error returned by uuid.NewV7() to ensure that the
session UUID is correctly generated.

pkg/frontend/session.go [505]

-ses.uuid, _ = uuid.NewV7()
+if ses.uuid, err = uuid.NewV7(); err != nil {
+    return nil, fmt.Errorf("failed to generate session UUID: %w", err)
+}
 
Suggestion importance[1-10]: 7

Why: Handling errors from uuid.NewV7() is important for ensuring the session UUID is correctly generated, which is crucial for session management and tracking.

7
Add a call to ctrl.Finish() to ensure all mock expectations are met and to avoid memory leaks

The Test_checkTenantExistsOrNot function should include a call to ctrl.Finish() at the end
of the test to ensure that all expectations are met and to avoid potential memory leaks.

pkg/frontend/authenticate_test.go [178-179]

 convey.Convey("check tenant exists or not", t, func() {
     ctrl := gomock.NewController(t)
+    defer ctrl.Finish()
 
Suggestion importance[1-10]: 7

Why: The suggestion correctly identifies a missing defer ctrl.Finish() in the test function, which is important for proper cleanup of resources and ensuring that all expectations on the mock controller are met. This is a good practice in Go testing with mocks.

7
Possible bug
Add a nil check for ses.GetTenantInfo() in InitSystemVariables to avoid potential nil pointer dereference

The InitSystemVariables function should handle the case where ses.GetTenantInfo() returns
nil to avoid potential nil pointer dereference.

pkg/frontend/session.go [234]

-if ses.gSysVars, err = GSysVarsMgr.Get(ses.GetTenantInfo().TenantID, ses, ctx); err != nil {
+tenantInfo := ses.GetTenantInfo()
+if tenantInfo == nil {
+    return errors.New("tenant info is nil")
+}
+if ses.gSysVars, err = GSysVarsMgr.Get(tenantInfo.TenantID, ses, ctx); err != nil {
 
Suggestion importance[1-10]: 8

Why: This suggestion correctly identifies a potential nil pointer dereference, which is a critical issue that could cause runtime panics.

8
Maintainability
Move the genSession function outside of the TestSession_TxnBegin function to avoid redefining it multiple times

The genSession function in TestSession_TxnBegin does not need to be defined inside the
test function. Consider moving it outside to avoid redefining it multiple times if used in
other tests.

pkg/frontend/session_test.go [230-257]

+func genSession(ctrl *gomock.Controller) *Session {
+    ioSes := mock_frontend.NewMockIOSession(ctrl)
+    ioSes.EXPECT().OutBuf().Return(buf.NewByteBuf(1024)).AnyTimes()
+    ioSes.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+    ioSes.EXPECT().RemoteAddress().Return("").AnyTimes()
+    ioSes.EXPECT().Ref().AnyTimes()
+    sv, err := getSystemVariables("test/system_vars_config.toml")
+    if err != nil {
+        t.Error(err)
+    }
+    setGlobalPu(&config.ParameterUnit{
+        SV: sv,
+    })
+    proto := NewMysqlClientProtocol(0, ioSes, 1024, sv)
+    txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
+    txnOperator.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
+    txnOperator.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes()
+    eng := mock_frontend.NewMockEngine(ctrl)
+    eng.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+    getGlobalPu().TxnClient = txnClient
+    getGlobalPu().StorageEngine = eng
+    session := NewSession(ctx, proto, nil)
+    return session
+}
+
 func TestSession_TxnBegin(t *testing.T) {
     ctx := defines.AttachAccountId(context.Background(), sysAccountID)
-    genSession := func(ctrl *gomock.Controller) *Session {
-        ioSes := mock_frontend.NewMockIOSession(ctrl)
-        ioSes.EXPECT().OutBuf().Return(buf.NewByteBuf(1024)).AnyTimes()
-        ioSes.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
-        ioSes.EXPECT().RemoteAddress().Return("").AnyTimes()
-        ioSes.EXPECT().Ref().AnyTimes()
-        sv, err := getSystemVariables("test/system_vars_config.toml")
-        if err != nil {
-            t.Error(err)
-        }
-        setGlobalPu(&config.ParameterUnit{
-            SV: sv,
-        })
-        proto := NewMysqlClientProtocol(0, ioSes, 1024, sv)
-        txnOperator := mock_frontend.NewMockTxnOperator(ctrl)
-        txnOperator.EXPECT().Txn().Return(txn.TxnMeta{}).AnyTimes()
-        txnOperator.EXPECT().Commit(gomock.Any()).Return(nil).AnyTimes()
-        eng := mock_frontend.NewMockEngine(ctrl)
-        eng.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
-        getGlobalPu().TxnClient = txnClient
-        getGlobalPu().StorageEngine = eng
-        session := NewSession(ctx, proto, nil)
-        return session
-    }
 
Suggestion importance[1-10]: 7

Why: The suggestion to move genSession outside of TestSession_TxnBegin is valid for maintainability and reusability. It correctly identifies the function within the new hunk of the PR code, and the improvement would help avoid redundancy if the function is used in multiple tests.

7
Move the genSession function outside of the TestSession_TxnCompilerContext function to avoid redefining it multiple times

The genSession function in TestSession_TxnCompilerContext does not need to be defined
inside the test function. Consider moving it outside to avoid redefining it multiple times
if used in other tests.

pkg/frontend/session_test.go [295-308]

+func genSession(ctrl *gomock.Controller, pu *config.ParameterUnit) *Session {
+    ioses := mock_frontend.NewMockIOSession(ctrl)
+    ioses.EXPECT().OutBuf().Return(buf.NewByteBuf(1024)).AnyTimes()
+    ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+    ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
+    ioses.EXPECT().Ref().AnyTimes()
+    sv, err := getSystemVariables("test/system_vars_config.toml")
+    if err != nil {
+        t.Error(err)
+    }
+    setGlobalPu(&config.ParameterUnit{
+        SV: sv,
+    })
+    proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
+    ctx := defines.AttachAccountId(context.Background(), sysAccountID)
+    session := NewSession(ctx, proto, nil)
+    return session
+}
+
 func TestSession_TxnCompilerContext(t *testing.T) {
-    genSession := func(ctrl *gomock.Controller, pu *config.ParameterUnit) *Session {
-        ioses := mock_frontend.NewMockIOSession(ctrl)
-        ioses.EXPECT().OutBuf().Return(buf.NewByteBuf(1024)).AnyTimes()
-        ioses.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
-        ioses.EXPECT().RemoteAddress().Return("").AnyTimes()
-        ioses.EXPECT().Ref().AnyTimes()
-        sv, err := getSystemVariables("test/system_vars_config.toml")
-        if err != nil {
-            t.Error(err)
-        }
-        setGlobalPu(&config.ParameterUnit{
-            SV: sv,
-        })
-        proto := NewMysqlClientProtocol(0, ioses, 1024, sv)
-        ctx := defines.AttachAccountId(context.Background(), sysAccountID)
-        session := NewSession(ctx, proto, nil)
-        return session
-    }
 
Suggestion importance[1-10]: 7

Why: Similar to the first suggestion, moving genSession outside of TestSession_TxnCompilerContext enhances maintainability. The suggestion correctly targets the function within the new hunk of the PR code, promoting better code organization and reuse.

7
Rename the function to maintain consistency with naming conventions

Consider renaming the function getSqlForGetSysVarWithAccount to
getSqlForGetSystemVariableWithAccount for consistency with the naming convention used in
the rest of the code.

pkg/frontend/authenticate.go [1931-1933]

-func getSqlForGetSysVarWithAccount(accountId uint64, varName string) string {
+func getSqlForGetSystemVariableWithAccount(accountId uint64, varName string) string {
 	return fmt.Sprintf(getSystemVariableWithAccountFormat, accountId, varName)
 }
 
Suggestion importance[1-10]: 7

Why: Renaming getSqlForGetSysVarWithAccount to getSqlForGetSystemVariableWithAccount improves consistency with other function names, enhancing readability and maintainability.

7
Create a helper function to set up the global parameter unit to reduce code duplication

The setGlobalPu function is called multiple times in the tests. Consider creating a helper
function to set up the global parameter unit to reduce code duplication.

pkg/frontend/session_test.go [81-83]

-pu, err := getParameterUnit("test/system_vars_config.toml", eng, txnClient)
+func setupGlobalPu(configPath string, eng Engine, txnClient TxnClient) error {
+    pu, err := getParameterUnit(configPath, eng, txnClient)
+    if err != nil {
+        return err
+    }
+    setGlobalPu(pu)
+    return nil
+}
+
+// Usage in tests
+err := setupGlobalPu("test/system_vars_config.toml", eng, txnClient)
 convey.So(err, convey.ShouldBeNil)
-setGlobalPu(pu)
 
Suggestion importance[1-10]: 6

Why: This suggestion correctly identifies repetitive code related to setting up the global parameter unit across different test functions. Creating a helper function would reduce duplication and improve code clarity, aligning well with the context of the PR changes.

6
Remove commented-out code to keep the codebase clean and maintainable

In the function createSubscriptionDatabase, consider removing the commented-out code to
keep the codebase clean and maintainable.

pkg/frontend/authenticate.go [8018-8056]

 // TODO implement this function (#8946) by other ways
 return nil
-//ctx, span := trace.Debug(ctx, "createSubscriptionDatabase")
-//defer span.End()
-//
-//subscriptions := make([]string, 0)
-////process the syspublications
-//sysPubsVar, err := ses.GetSessionSysVar("syspublications")
-//if err != nil {
-//	return err
-//}
-//
-//if sysPublications, ok := sysPubsVar.(string); ok {
-//	if len(sysPublications) == 0 {
-//		return err
-//	}
-//	subscriptions = strings.Split(sysPublications, ",")
-//}
-//// if no subscriptions, return
-//if len(subscriptions) == 0 {
-//	return err
-//}
-//
-////with new tenant
-//ctx = defines.AttachAccount(ctx, uint32(newTenant.GetTenantID()), uint32(newTenant.GetUserID()), uint32(newTenant.GetDefaultRoleID()))
-//
-//createSubscriptionFormat := `create database %s from sys publication %s;`
-//sqls := make([]string, 0, len(subscriptions))
-//for _, subscription := range subscriptions {
-//	sqls = append(sqls, fmt.Sprintf(createSubscriptionFormat, subscription, subscription))
-//}
-//for _, sql := range sqls {
-//	bh.ClearExecResultSet()
-//	err = bh.Exec(ctx, sql)
-//	if err != nil {
-//		return err
-//	}
-//}
-//return err
 
Suggestion importance[1-10]: 6

Why: Removing extensive commented-out code in createSubscriptionDatabase helps maintain a cleaner and more maintainable codebase, reducing clutter.

6
Readability
Rename the parameter for better clarity and consistency

In the function getSqlForUpdateSysVarValue, consider renaming the parameter varValue to
variableValue for better clarity and consistency with other function parameters.

pkg/frontend/authenticate.go [1940-1942]

-func getSqlForUpdateSysVarValue(varValue string, accountId uint64, varName string) string {
-	return fmt.Sprintf(updateSystemVariableValueFormat, varValue, accountId, varName)
+func getSqlForUpdateSysVarValue(variableValue string, accountId uint64, varName string) string {
+	return fmt.Sprintf(updateSystemVariableValueFormat, variableValue, accountId, varName)
 }
 
Suggestion importance[1-10]: 5

Why: Renaming varValue to variableValue in getSqlForUpdateSysVarValue slightly enhances clarity and consistency with naming conventions, though the impact on overall code quality is moderate.

5
Simplify the function by using a single-line return statement

In the function getSqlForInsertSysVarWithAccount, consider using a single-line return
statement for better readability.

pkg/frontend/authenticate.go [1935-1937]

 func getSqlForInsertSysVarWithAccount(accountId uint64, accountName string, varName string, varValue string) string {
-	return fmt.Sprintf(insertSystemVariableWithAccountFormat, accountId, accountName, varName, varValue, true)
+    return fmt.Sprintf(insertSystemVariableWithAccountFormat, accountId, accountName, varName, varValue, true)
 }
 
Suggestion importance[1-10]: 4

Why: The suggestion to use a single-line return statement in getSqlForInsertSysVarWithAccount is valid for readability, but the impact is minimal as the function is already quite simple.

4

@mergify mergify bot merged commit b4fd0c0 into matrixorigin:main Jun 4, 2024
17 of 18 checks passed
@ck89119 ck89119 deleted the refactor/sys_var branch June 4, 2024 08:26
ck89119 added a commit to ck89119/matrixone that referenced this pull request Jun 4, 2024
…16551)

- system variable now is account isolated
- table `mo_mysql_compatibility_mode` only saves delta info between account's and cluster's default system variable values
- always use session variable except `show global variables`

Approved by: @daviszhen, @aunjgr, @aressu1985
XuPeng-SH pushed a commit to XuPeng-SH/matrixone that referenced this pull request Jun 4, 2024
* GC needs to consume all the mo_snapshot tables (matrixorigin#16539)

Each tenant of the current mo has a mo_snapshot table to store snapshot information. GC needs to consume all mo_snapshot tables.

Approved by: @XuPeng-SH

* append log for upgrade and sqlExecutoer (matrixorigin#16575)

append log for upgrader and sqlExecutor

Approved by: @daviszhen, @badboynt1, @zhangxu19830126, @m-schen

* [enhancement] proxy: filter CNs that are not in working state. (matrixorigin#16558)

1. filter CNs that are not in working state.
2. add some logs for migration

Approved by: @zhangxu19830126

* fix lock service ut (matrixorigin#16517)

fix lock service ut

Approved by: @zhangxu19830126

* Add cost of GC Check (matrixorigin#16470)

To avoid List() operations on oss, tke or s3, you need to add the Cost interface.

Approved by: @reusee, @XuPeng-SH

* optimize explain info for tp/ap query (matrixorigin#16578)

optimize explain info for tp/ap query

Approved by: @daviszhen, @ouyuanning, @aunjgr

* Bvt disable trace (matrixorigin#16581)

aim to exclude the `system,system_metrics` part case.
changes:
1. move `cases/table/system_table_cases` system,system_metrics part into individule case file.

Approved by: @heni02

* remove log print from automaxprocs (matrixorigin#16546)

remove log print from automaxprocs

Approved by: @triump2020, @m-schen, @ouyuanning, @aunjgr, @zhangxu19830126

* rmTag15901 (matrixorigin#16585)

rm 15901

Approved by: @heni02

* remove some MustStrCol&MustBytesCol (matrixorigin#16361)

Remove some unnecessary MustStrCol, MustBytesCol calls.

Approved by: @daviszhen, @reusee, @m-schen, @aunjgr, @XuPeng-SH

* add bvt tag (matrixorigin#16589)

add bvt tag

Approved by: @heni02, @aressu1985

* fix a bug that cause load performance regression issue (matrixorigin#16600)

fix a bug that cause load performance regression issue

Approved by: @m-schen

* add case for restore pub_sub (matrixorigin#16602)

add case for restore pub_sub

Approved by: @heni02

* add shard service kernel (matrixorigin#16565)

Add shardservice kernel.

Approved by: @reusee, @m-schen, @daviszhen, @XuPeng-SH, @volgariver6, @badboynt1, @ouyuanning, @triump2020, @w-zr, @sukki37, @aunjgr, @fengttt

* [BugFix]: Use L2DistanceSq instead of L2Distance during IndexScan (matrixorigin#16366)

During `KNN Select` and `Mapping Entries to Centroids via CROSS_JOIN_L2`, we can make use of L2DistanceSq instead of L2Distance, as it avoids `Sqrt()`. We can see the improvement in QPS for SIFT128 from 90 to 100. However, for GIST960, the QPS did not change much.

L2DistanceSq is suitable only when there is a comparison (ie ORDER BY), and when the absolute value (ie actual L2Distance) is not required.
- In the case of `CROSS JOIN L2` we find the nearest centroid for the Entry using `L2DistanceSq`. `CROSS JOIN L2` is used in both INSERT and CREATE INDEX.
- In the case of `KNN SELECT`, our query has ORDER BY L2_DISTANCE(...), which can make use of `L2DistanceSq` as the L2Distance value is not explicitly required.

**NOTE:** L2DistanceSq is not suitable in Kmenas++ for Centroid Computation, as it will impact the centroids picked.

Approved by: @heni02, @m-schen, @aunjgr, @badboynt1

* add sharding metrics (matrixorigin#16606)

add sharding metrics

Approved by: @aptend

* fix data race (matrixorigin#16608)

fix data race

Approved by: @reusee

* Refactor reshape (matrixorigin#15879)

Reshape objects block by block.

Approved by: @XuPeng-SH

* refactor system variables to support account isolation (matrixorigin#16551)

- system variable now is account isolated
- table `mo_mysql_compatibility_mode` only saves delta info between account's and cluster's default system variable values
- always use session variable except `show global variables`

Approved by: @daviszhen, @aunjgr, @aressu1985

* fix merge

* [cherry-pick-16594] : fix moc3399 (matrixorigin#16611)

When truncate table, if the table does not have any auto-incr col, there is no need to call the Reset interface of increment_service

Approved by: @ouyuanning

* bump go to 1.22.3, fix make compose and optimize ut script (matrixorigin#16604)

1. bump go version from 1.21.5 to 1.22.3
2. fix `make compose` to make it work
3. `make ut` will read `UT_WORKDIR` env variable to store report, it will be `$HOME` if `UT_WORKDIR` is empty

Approved by: @zhangxu19830126, @sukki37

* remove isMerge from build operator (matrixorigin#16622)

remove isMerge from build operator

Approved by: @m-schen

---------

Co-authored-by: GreatRiver <2552853833@qq.com>
Co-authored-by: qingxinhome <70939751+qingxinhome@users.noreply.github.com>
Co-authored-by: LiuBo <g.user.lb@gmail.com>
Co-authored-by: iamlinjunhong <49111204+iamlinjunhong@users.noreply.github.com>
Co-authored-by: nitao <badboynt@126.com>
Co-authored-by: Jackson <xzxiong@yeah.net>
Co-authored-by: Ariznawlll <ariznawl@163.com>
Co-authored-by: Wei Ziran <weiziran125@gmail.com>
Co-authored-by: YANGGMM <www.yangzhao123@gmail.com>
Co-authored-by: fagongzi <zhangxu19830126@gmail.com>
Co-authored-by: Arjun Sunil Kumar <arjunsk@users.noreply.github.com>
Co-authored-by: Kai Cao <ck89119@users.noreply.github.com>
Co-authored-by: Jensen <jensenojs@qq.com>
Co-authored-by: brown <endeavorjia@gmail.com>
@w-zr w-zr mentioned this pull request Jun 5, 2024
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants