Skip to content

Commit

Permalink
ddl: support the rolling upgrade. (pingcap#6301)
Browse files Browse the repository at this point in the history
  • Loading branch information
zimulala committed Apr 17, 2018
1 parent 8ec4cf0 commit bbad617
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
7 changes: 7 additions & 0 deletions ddl/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,13 @@ func (d *ddl) doModifyColumn(t *meta.Meta, job *model.Job, newCol *model.ColumnI
return ver, infoschema.ErrColumnNotExists.GenByArgs(oldName, tblInfo.Name)
}

// gofail: var uninitializedOffsetAndState bool
// if uninitializedOffsetAndState {
// if newCol.State != model.StatePublic {
// return ver, errors.New("the column state is wrong")
// }
// }

// We need the latest column's offset and state. This information can be obtained from the store.
newCol.Offset = oldCol.Offset
newCol.State = oldCol.State
Expand Down
11 changes: 10 additions & 1 deletion ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1259,7 +1259,16 @@ func (d *ddl) getModifiableColumnJob(ctx context.Context, ident ast.Ident, origi
}

newCol := table.ToColumn(&model.ColumnInfo{
ID: col.ID,
ID: col.ID,
// We use this PR(https://github.com/pingcap/tidb/pull/6274) as the dividing line to define whether it is a new version or an old version TiDB.
// The old version TiDB initializes the column's offset and state here.
// The new version TiDB doesn't initialize the column's offset and state, and it will do the initialization in run DDL function.
// When we do the rolling upgrade the following may happen:
// a new version TiDB builds the DDL job that doesn't be set the column's offset and state,
// and the old version TiDB is the DDL owner, it doesn't get offset and state from the store. Then it will encounter errors.
// So here we set offset and state to support the rolling upgrade.
Offset: col.Offset,
State: col.State,
OriginDefaultValue: col.OriginDefaultValue,
FieldType: *spec.NewColumn.Tp,
Name: spec.NewColumn.Name.Name,
Expand Down
35 changes: 35 additions & 0 deletions ddl/fail_db_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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 (
gofail "github.com/coreos/gofail/runtime"
. "github.com/pingcap/check"
"golang.org/x/net/context"
)

// TestInitializeOffsetAndState tests the case that the column's offset and state don't be initialized in the file of ddl_api.go when
// doing the operation of 'modify column'.
func (s *testStateChangeSuite) TestInitializeOffsetAndState(c *C) {
_, err := s.se.Execute(context.Background(), "use test_db_state")
c.Assert(err, IsNil)
_, err = s.se.Execute(context.Background(), "create table t(a int, b int, c int)")
c.Assert(err, IsNil)
defer s.se.Execute(context.Background(), "drop table t")

gofail.Enable("github.com/pingcap/tidb/ddl/uninitializedOffsetAndState", `return(true)`)
_, err = s.se.Execute(context.Background(), "ALTER TABLE t MODIFY COLUMN b int FIRST;")
c.Assert(err, IsNil)
gofail.Disable("github.com/pingcap/tidb/ddl/uninitializedOffsetAndState")
}

0 comments on commit bbad617

Please sign in to comment.