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

ddl: implement ALTER DATABASE to alter charset/collation #10393

Merged
merged 7 commits into from
May 15, 2019

Conversation

bb7133
Copy link
Member

@bb7133 bb7133 commented May 8, 2019

What problem does this PR solve?

Add support for ALTER DATABASE syntax

Related issue: #4641
Related parser PR: pingcap/parser#318

What is changed and how it works?

A new DDL job is added to change charset/collate for a database.

Check List

Tests

  • Integration test

Code changes

  • Has exported function/method change

Side effects

  • Increased code complexity

Related changes

  • Need to cherry-pick to the release branch
  • Need to update the documentation
  • Need to be included in the release note

@bb7133 bb7133 added type/enhancement The issue or PR belongs to an enhancement. component/DDL-need-LGT3 labels May 8, 2019
@bb7133
Copy link
Member Author

bb7133 commented May 8, 2019

PTAL @crazycs520 @lonng @winkyao

@zhouqiang-cl
Copy link
Contributor

/run-all-tests

@codecov
Copy link

codecov bot commented May 9, 2019

Codecov Report

Merging #10393 into master will decrease coverage by 0.0281%.
The diff coverage is 71.4285%.

@@               Coverage Diff                @@
##             master     #10393        +/-   ##
================================================
- Coverage   77.3263%   77.2982%   -0.0281%     
================================================
  Files           412        412                
  Lines         86629      86720        +91     
================================================
+ Hits          66987      67033        +46     
- Misses        14498      14528        +30     
- Partials       5144       5159        +15

@zhouqiang-cl
Copy link
Contributor

/rebuild

go.sum1 Outdated Show resolved Hide resolved
Copy link
Contributor

@crazycs520 crazycs520 left a comment

Choose a reason for hiding this comment

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

LGTM

@crazycs520
Copy link
Contributor

@bb7133 I got some problem, but maybe we can fix this in other PR:
In this PR

mysql root@localhost:(none)> create database test charset utf8;
Query OK, 0 rows affected
Time: 0.005s
mysql root@localhost:(none)> alter database test charset="utf8"
(1105, u'unsupported modify collate from  to utf8_bin')
mysql root@localhost:(none)> drop database if exists test
Query OK, 0 rows affected
Time: 0.010s
mysql root@localhost:(none)> create database test charset UTF8MB4;
Query OK, 0 rows affected
Time: 0.005s
mysql root@localhost:(none)> alter database test charset="utf8mb4"
(1105, u'unsupported modify collate from  to utf8mb4_bin')
mysql root@localhost:(none)>

There is some bug in create a schema.

@bb7133
Copy link
Member Author

bb7133 commented May 11, 2019

There are some bugs in creating a schema.

func modifiableCharsetAndCollation(toCharset, toCollate, origCharset, origCollate string) error {

Isn't this an expected behavior? For now, we only support changing charset from utf8 to utf8mb4

@bb7133
Copy link
Member Author

bb7133 commented May 11, 2019

@jackysp @crazycs520 addressed, PTAL, thank you!

Copy link
Contributor

@winkyao winkyao left a comment

Choose a reason for hiding this comment

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

rest LGTM

ddl/schema.go Outdated

dbInfo, err := checkSchemaExistAndCancelNotExistJob(t, job)
if err != nil {
if infoschema.ErrDatabaseDropExists.Equal(err) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This error is weird, I think to call checkSchemaExistAndCancelNotExistJob is not appropriate. Maybe you should call t.GetDatabase(job.SchemaID) directly.

Copy link
Member Author

Choose a reason for hiding this comment

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

addressed

Copy link
Member

@jackysp jackysp left a comment

Choose a reason for hiding this comment

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

LGTM

if !ok {
return ErrDatabaseNotExists.GenWithStackByArgs(di.Name.O)
}
if oldInfo.Charset == di.Charset && oldInfo.Collate == di.Collate {
Copy link
Contributor

Choose a reason for hiding this comment

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

If this happens, it is already processed when the DDL job is processed. Doesn't this happen here?

Copy link
Member Author

Choose a reason for hiding this comment

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

I suppose another DDL job may have changed the charset already, is it possible?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think so. If another DDL job changed, this DDL job needn't to be handled.

return errors.Trace(err)
}
if di == nil {
// When we apply an old schema diff, the database may has been dropped already
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto. Maybe we can update this comment.

}
return ver, errors.Trace(err)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can check "if dbInfo.Charset == toCharset && dbInfo.Charset == toCollate {return nil}" here。

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, then

ddl/ddl_api.go Outdated
return errors.Trace(err)
}

// Do DDL job
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Do DDL job
// Do the DDL job.

ddl/ddl_api.go Outdated
return nil
}

// check current TiDB limitations
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// check current TiDB limitations
// Check the current TiDB limitations.

ddl/ddl_api.go Outdated
@@ -90,6 +90,63 @@ func (d *ddl) CreateSchema(ctx sessionctx.Context, schema model.CIStr, charsetIn
err = d.callHookOnChanged(err)
return errors.Trace(err)
}
func (d *ddl) AlterSchema(ctx sessionctx.Context, stmt *ast.AlterDatabaseStmt) (err error) {
// Resolve target charset and collation from options
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add the . at the end of a line. And please update other comments in this PR.

@bb7133
Copy link
Member Author

bb7133 commented May 14, 2019

PTAL @winkyao @zimulala , thanks

}

dbInfo, err := t.GetDatabase(job.SchemaID)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Here we need to add job.State = model.JobStateCancelled to make sure the job will be done.

Copy link
Contributor

Choose a reason for hiding this comment

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

yes, if we don't cancel the job here, the job will never be finished.

@winkyao winkyao added the priority/release-blocker This issue blocks a release. Please solve it ASAP. label May 15, 2019
ddl/schema.go Outdated
}

if dbInfo.Charset == toCharset && dbInfo.Collate == toCollate {
job.FinishDBJob(model.JobStateDone, model.StatePublic, ver, dbInfo)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think replace this line with job.State = model.JobStateCancelled is better.
We don't do this schema change, becase other job is done.

Copy link
Member Author

Choose a reason for hiding this comment

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

But this will cause an error message, right?

Copy link
Contributor

@zimulala zimulala May 15, 2019

Choose a reason for hiding this comment

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

No. Here we return error is nil.

Copy link
Member Author

Choose a reason for hiding this comment

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

addressed, thanks @zimulala

Copy link
Contributor

@zimulala zimulala left a comment

Choose a reason for hiding this comment

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

LGTM

@zimulala
Copy link
Contributor

/run-all-tests

Copy link
Contributor

@winkyao winkyao left a comment

Choose a reason for hiding this comment

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

LGTM

@bb7133
Copy link
Member Author

bb7133 commented May 15, 2019

/run-all-tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority/release-blocker This issue blocks a release. Please solve it ASAP. sig/sql-infra SIG: SQL Infra type/enhancement The issue or PR belongs to an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants