-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ddl: support alter algorithm INPLACE/INSTANT (#8811)
- Loading branch information
Showing
7 changed files
with
293 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Copyright 2018 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package ddl | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/pingcap/parser/ast" | ||
) | ||
|
||
// AlterAlgorithm is used to store supported alter algorithm. | ||
// For now, TiDB only support AlterAlgorithmInplace and AlterAlgorithmInstant. | ||
// The most alter operations are using instant algorithm, and only the add index is using inplace(not really inplace, | ||
// because we never block the DML but costs some time to backfill the index data) | ||
// See https://dev.mysql.com/doc/refman/8.0/en/alter-table.html#alter-table-performance. | ||
type AlterAlgorithm struct { | ||
supported []ast.AlterAlgorithm | ||
// If the alter algorithm is not given, the defAlgorithm will be used. | ||
defAlgorithm ast.AlterAlgorithm | ||
} | ||
|
||
var ( | ||
instantAlgorithm = &AlterAlgorithm{ | ||
supported: []ast.AlterAlgorithm{ast.AlterAlgorithmInstant}, | ||
defAlgorithm: ast.AlterAlgorithmInstant, | ||
} | ||
|
||
inplaceAlgorithm = &AlterAlgorithm{ | ||
supported: []ast.AlterAlgorithm{ast.AlterAlgorithmInplace}, | ||
defAlgorithm: ast.AlterAlgorithmInplace, | ||
} | ||
|
||
defaultAlgorithm = ast.AlterAlgorithmInstant | ||
) | ||
|
||
func getProperAlgorithm(specify ast.AlterAlgorithm, algorithm *AlterAlgorithm) (ast.AlterAlgorithm, error) { | ||
if specify == ast.AlterAlgorithmDefault { | ||
return algorithm.defAlgorithm, nil | ||
} | ||
|
||
for _, a := range algorithm.supported { | ||
if specify == a { | ||
return specify, nil | ||
} | ||
} | ||
|
||
return algorithm.defAlgorithm, ErrAlterOperationNotSupported.GenWithStackByArgs(fmt.Sprintf("ALGORITHM=%s", specify), fmt.Sprintf("Cannot alter table by %s", specify), fmt.Sprintf("ALGORITHM=%s", algorithm.defAlgorithm)) | ||
} | ||
|
||
// ResolveAlterAlgorithm resolves the algorithm of the alterSpec. | ||
// If specify algorithm is not supported by the alter action, errAlterOperationNotSupported will be returned. | ||
// If specify is the ast.AlterAlgorithmDefault, then the default algorithm of the alter action will be returned. | ||
func ResolveAlterAlgorithm(alterSpec *ast.AlterTableSpec, specify ast.AlterAlgorithm) (ast.AlterAlgorithm, error) { | ||
switch alterSpec.Tp { | ||
// For now, TiDB only support inplace algorithm and instant algorithm. | ||
case ast.AlterTableAddConstraint: | ||
return getProperAlgorithm(specify, inplaceAlgorithm) | ||
default: | ||
return getProperAlgorithm(specify, instantAlgorithm) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// Copyright 2018 PingCAP, Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package ddl_test | ||
|
||
import ( | ||
. "github.com/pingcap/check" | ||
"github.com/pingcap/parser/ast" | ||
"github.com/pingcap/tidb/ddl" | ||
) | ||
|
||
var _ = Suite(&testDDLAlgorithmSuite{}) | ||
|
||
var ( | ||
allAlgorithm = []ast.AlterAlgorithm{ast.AlterAlgorithmCopy, | ||
ast.AlterAlgorithmInplace, ast.AlterAlgorithmInstant} | ||
) | ||
|
||
type testDDLAlgorithmSuite struct{} | ||
|
||
type testCase struct { | ||
alterSpec ast.AlterTableSpec | ||
supportedAlgorithm []ast.AlterAlgorithm | ||
defAlgorithm ast.AlterAlgorithm | ||
} | ||
|
||
func (s *testDDLAlgorithmSuite) TestFindAlterAlgorithm(c *C) { | ||
instantAlgorithm := []ast.AlterAlgorithm{ast.AlterAlgorithmInstant} | ||
inplaceAlgorithm := []ast.AlterAlgorithm{ast.AlterAlgorithmInplace} | ||
|
||
testCases := []testCase{ | ||
{ast.AlterTableSpec{Tp: ast.AlterTableAddConstraint}, inplaceAlgorithm, ast.AlterAlgorithmInplace}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableAddColumns}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableDropColumn}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableDropPrimaryKey}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableDropIndex}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableDropForeignKey}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableRenameTable}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableRenameIndex}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
|
||
// Alter table options. | ||
{ast.AlterTableSpec{Tp: ast.AlterTableOption, Options: []*ast.TableOption{{Tp: ast.TableOptionShardRowID}}}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableOption, Options: []*ast.TableOption{{Tp: ast.TableOptionAutoIncrement}}}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableOption, Options: []*ast.TableOption{{Tp: ast.TableOptionComment}}}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableOption, Options: []*ast.TableOption{{Tp: ast.TableOptionCharset}}}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableOption, Options: []*ast.TableOption{{Tp: ast.TableOptionCollate}}}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
|
||
// TODO: after we support migrate the data of partitions, change below cases. | ||
{ast.AlterTableSpec{Tp: ast.AlterTableCoalescePartitions}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableAddPartitions}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableDropPartition}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableTruncatePartition}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
|
||
// TODO: after we support lock a table, change the below case. | ||
{ast.AlterTableSpec{Tp: ast.AlterTableLock}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
// TODO: after we support changing the column type, below cases need to change. | ||
{ast.AlterTableSpec{Tp: ast.AlterTableModifyColumn}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableChangeColumn}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
{ast.AlterTableSpec{Tp: ast.AlterTableAlterColumn}, instantAlgorithm, ast.AlterAlgorithmInstant}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
runAlterAlgorithmTestCases(c, &tc) | ||
} | ||
} | ||
|
||
func runAlterAlgorithmTestCases(c *C, tc *testCase) { | ||
algorithm, err := ddl.ResolveAlterAlgorithm(&tc.alterSpec, ast.AlterAlgorithmDefault) | ||
c.Assert(err, IsNil) | ||
c.Assert(algorithm, Equals, tc.defAlgorithm) | ||
|
||
unsupported := make([]ast.AlterAlgorithm, 0, len(allAlgorithm)) | ||
Loop: | ||
for _, alm := range allAlgorithm { | ||
for _, almSupport := range tc.supportedAlgorithm { | ||
if alm == almSupport { | ||
continue Loop | ||
} | ||
} | ||
|
||
unsupported = append(unsupported, alm) | ||
} | ||
|
||
// Test supported. | ||
for _, alm := range tc.supportedAlgorithm { | ||
algorithm, err = ddl.ResolveAlterAlgorithm(&tc.alterSpec, alm) | ||
c.Assert(err, IsNil) | ||
c.Assert(algorithm, Equals, alm) | ||
} | ||
|
||
// Test unsupported. | ||
for _, alm := range unsupported { | ||
algorithm, err = ddl.ResolveAlterAlgorithm(&tc.alterSpec, alm) | ||
c.Assert(err, NotNil, Commentf("Tp:%v, alm:%s", tc.alterSpec.Tp, alm)) | ||
c.Assert(ddl.ErrAlterOperationNotSupported.Equal(err), IsTrue) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters