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

tabletserver: SBR deprecation #5940

Merged
merged 18 commits into from
Mar 20, 2020

Conversation

sougou
Copy link
Contributor

@sougou sougou commented Mar 20, 2020

Closes #5920

The planbuilder and query_executor were essentially rewritten. I had to make tweaks in a few other places to accommodate changes in behavior.

It was not necessary, and was obfuscating the fact that it's
wrapping TxEngine.

Signed-off-by: Sugu Sougoumarane <[email protected]>
There was an aspiration that applications will use an event token
to validate how fresh a replica read was. The feature was neither
very usable nor used by anyone.

This has now been deleted.

Signed-off-by: Sugu Sougoumarane <[email protected]>
Signed-off-by: Sugu Sougoumarane <[email protected]>
Signed-off-by: Sugu Sougoumarane <[email protected]>
Signed-off-by: Sugu Sougoumarane <[email protected]>
Signed-off-by: Sugu Sougoumarane <[email protected]>
Signed-off-by: Sugu Sougoumarane <[email protected]>
Signed-off-by: Sugu Sougoumarane <[email protected]>
Signed-off-by: Sugu Sougoumarane <[email protected]>
Signed-off-by: Sugu Sougoumarane <[email protected]>
qre := newTestQueryExecutor(ctx, tsv, tcase.input, 0)
_, err := qre.Execute()
wantErr := "caller id: d: row count exceeded 2 (errno 10001) (sqlstate HY000)"
if err == nil || err.Error() != wantErr {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: You could use

require.Error(t, wantErr)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason, assert didn't work. In any case, I had to change the test to use "Contains".
But assert.Contains can't check if an error contains a string, which is unfortunate.

Copy link
Collaborator

@systay systay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -227,65 +227,45 @@ var (
getModeSQL = "select @@global.sql_mode"
getAutocommit = "select @@autocommit"
getAutoIsNull = "select @@sql_auto_is_null"
showBinlog = "show variables like 'binlog_format'"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we not verify bin log format. Now it has to be ROW.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still want to allow some legacy usage. People transitioning should be able to run SBR. RBR becomes a hard requirement only while resharding.

Comment on lines 66 to 84
var planName = [NumPlans]string{
"PASS_SELECT",
"SELECT_LOCK",
"NEXTVAL",
"PASS_DML",
"DML_PK",
"DML_SUBQUERY",
"INSERT_PK",
"INSERT_SUBQUERY",
"UPSERT_PK",
"INSERT_TOPIC",
"INSERT_MESSAGE",
"SET",
"Select",
"SelectLock",
"Nextval",
"SelectImpossible",
"Insert",
"InsertTopic",
"InsertMessage",
"Update",
"UpdateLimit",
"Delete",
"DeleteLimit",
"DDL",
"SELECT_STREAM",
"OTHER_READ",
"OTHER_ADMIN",
"MESSAGE_STREAM",
"SELECT_IMPOSSIBLE",
"Set",
"OtherRead",
"OtherAdmin",
"SelectStream",
"MessageStream",
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this should not be renamed as this impacts the query stats naming. All metrics will get disjoint.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good time to rename everything uniformly because this has been announced as one of the breaking changes. People anyway have to deal with all the other new values already.

Comment on lines 68 to +69
flag.BoolVar(&Config.PassthroughDMLs, "queryserver-config-passthrough-dmls", DefaultQsConfig.PassthroughDMLs, "query server pass through all dml statements without rewriting")
flag.BoolVar(&Config.AllowUnsafeDMLs, "queryserver-config-allowunsafe-dmls", DefaultQsConfig.AllowUnsafeDMLs, "query server allow unsafe dml statements")
flag.BoolVar(&deprecateAllowUnsafeDMLs, "queryserver-config-allowunsafe-dmls", false, "deprecated")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the difference between pass through and unsafe dmls?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsafe DMLs are those that were considered unsafe for SBR, like "insert on duplicate key", etc.

@@ -881,7 +835,7 @@ func (tsv *TabletServer) CreateTransaction(ctx context.Context, target *querypb.
return tsv.execRequest(
ctx, tsv.QueryTimeout.Get(),
"CreateTransaction", "create_transaction", nil,
target, nil, true /* isBegin */, true, /* allowOnShutdown */
target, nil, true, /* allowOnShutdown */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for CreateTransaction method: should this be false?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It either doesn't matter, or it's extremely important that it be true. Changing to false is likely risky without knowing why.

Comment on lines +352 to 358
// This used to be ResultExtras.
reserved 5;

repeated Field fields = 1;
uint64 rows_affected = 2;
uint64 insert_id = 3;
repeated Row rows = 4;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this works, I believe ordering is not important.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to follow the rules. Then we don't have to worry about corner cases.

Comment on lines +128 to +129
if err := qre.verifyRowCount(int64(len(qr.Rows)), maxrows); err != nil {
return nil, err
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test exists for DML Limit. Not able to find a test for select limit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I must have accidentally deleted an existing test.

Comment on lines 102 to 108
case planbuilder.PlanSelectImpossible:
if qre.plan.Fields != nil {
return &sqltypes.Result{
Fields: qre.plan.Fields,
RowsAffected: 0,
InsertID: 0,
Rows: nil,
Extras: nil,
Fields: qre.plan.Fields,
}, nil
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case planbuilder.PlanSelect, planbuilder.PlanSelectImpossible also exists below. Why "planbuilder.PlanSelectImpossible" is present in two switch statement?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the fields did not get cached, then we have to send the query to mysql. Added a comment.

go/vt/vttablet/tabletserver/query_executor.go Show resolved Hide resolved
Comment on lines +550 to 551
if qre.tsv.qe.enableConsolidator || (qre.tsv.qe.enableConsolidatorReplicas && qre.tabletType != topodatapb.TabletType_MASTER) {
q, original := qre.tsv.qe.consolidator.Create(string(sqlWithoutComments))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consolidator is default to true and hence test does not go in else part. Can a test be added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test requires creating a delay in query execution, which the test framework can't emulate. So, it's covered in the go/vt/vttablet/endtoend/misc_test.go.

Comment on lines 172 to 173
case *sqlparser.DDL:
plan, err = analyzeDDL(stmt, tables), nil
plan = &Plan{PlanID: PlanDDL}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not contain the DDL Query. Could you explain the reason for not adding the query?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because the plan can only store ParsedQuery, but the parsed version of a DDL is incomplete. So, we use the original query at the time of execution. We could add a special-case field for DDLs, but it didn't feel worth it. I've added a comment.

Signed-off-by: Sugu Sougoumarane <[email protected]>
Copy link
Member

@harshit-gangal harshit-gangal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

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.

RFC: RBR vttablet -> Breaking changes
3 participants