From 8a59d7e8239dce9f654406c17f9edcfdcc02afa1 Mon Sep 17 00:00:00 2001 From: Shlomi Noach Date: Wed, 8 Nov 2017 11:11:17 +0200 Subject: [PATCH] failing on PK value change --- go/logic/applier.go | 22 +++++++++++++ localtests/test.sh | 5 +++ localtests/update-pk-column/create.sql | 44 -------------------------- 3 files changed, 27 insertions(+), 44 deletions(-) delete mode 100644 localtests/update-pk-column/create.sql diff --git a/go/logic/applier.go b/go/logic/applier.go index 2607f30..a1175b1 100644 --- a/go/logic/applier.go +++ b/go/logic/applier.go @@ -899,6 +899,25 @@ func (this *Applier) ShowStatusVariable(variableName string) (result int64, err return result, nil } +func (this *Applier) validateUpdateDoesNotModifyMigrationUniqueKeyColumns(dmlEvent *binlog.BinlogDMLEvent) error { + // log.Debugf("............ UPDATE") + // log.Debugf("............ UPDATE: %+v", this.migrationContext.UniqueKey.Columns.String()) + // log.Debugf("............ UPDATE: %+v", dmlEvent.WhereColumnValues.String()) + // log.Debugf("............ UPDATE: %+v", dmlEvent.NewColumnValues.String()) + for _, column := range this.migrationContext.UniqueKey.Columns.Columns() { + tableOrdinal := this.migrationContext.OriginalTableColumns.Ordinals[column.Name] + whereColumnValue := dmlEvent.WhereColumnValues.AbstractValues()[tableOrdinal] + newColumnValue := dmlEvent.NewColumnValues.AbstractValues()[tableOrdinal] + // log.Debugf("............ UPDATE: old value= %+v", whereColumnValue) + // log.Debugf("............ UPDATE: new value= %+v", newColumnValue) + // log.Debugf("............ UPDATE: equals? %+v", newColumnValue == whereColumnValue) + if newColumnValue != whereColumnValue { + return log.Errorf("gh-ost detected an UPDATE to a unique key column this migration is iterating on. Such update is not supported. Column is %s", column.Name) + } + } + return nil +} + // buildDMLEventQuery creates a query to operate on the ghost table, based on an intercepted binlog // event entry on the original table. func (this *Applier) buildDMLEventQuery(dmlEvent *binlog.BinlogDMLEvent) (query string, args []interface{}, rowsDelta int64, err error) { @@ -915,6 +934,9 @@ func (this *Applier) buildDMLEventQuery(dmlEvent *binlog.BinlogDMLEvent) (query } case binlog.UpdateDML: { + if err := this.validateUpdateDoesNotModifyMigrationUniqueKeyColumns(dmlEvent); err != nil { + return query, args, rowsDelta, err + } query, sharedArgs, uniqueKeyArgs, err := sql.BuildDMLUpdateQuery(dmlEvent.DatabaseName, this.migrationContext.GetGhostTableName(), this.migrationContext.OriginalTableColumns, this.migrationContext.SharedColumns, this.migrationContext.MappedSharedColumns, &this.migrationContext.UniqueKey.Columns, dmlEvent.NewColumnValues.AbstractValues(), dmlEvent.WhereColumnValues.AbstractValues()) args = append(args, sharedArgs...) args = append(args, uniqueKeyArgs...) diff --git a/localtests/test.sh b/localtests/test.sh index b901ce3..477ecbb 100755 --- a/localtests/test.sh +++ b/localtests/test.sh @@ -170,7 +170,12 @@ test_single() { build_binary() { echo "Building" + rm -f $ghost_binary go build -o $ghost_binary go/cmd/gh-ost/main.go + if [ $? -ne 0 ] ; then + echo "Build failure" + exit 1 + fi } test_all() { diff --git a/localtests/update-pk-column/create.sql b/localtests/update-pk-column/create.sql deleted file mode 100644 index 3de5098..0000000 --- a/localtests/update-pk-column/create.sql +++ /dev/null @@ -1,44 +0,0 @@ -drop table if exists gh_ost_test; -create table gh_ost_test ( - id int auto_increment, - i int not null, - primary key(id) -) auto_increment=1; - -insert into gh_ost_test values (null, 101); -insert into gh_ost_test values (null, 102); -insert into gh_ost_test values (null, 103); -insert into gh_ost_test values (null, 104); -insert into gh_ost_test values (null, 105); -insert into gh_ost_test values (null, 106); -insert into gh_ost_test values (null, 107); -insert into gh_ost_test values (null, 108); -insert into gh_ost_test values (null, 109); -insert into gh_ost_test values (null, 110); -insert into gh_ost_test values (null, 111); -insert into gh_ost_test values (null, 112); -insert into gh_ost_test values (null, 113); -insert into gh_ost_test values (null, 114); -insert into gh_ost_test values (null, 115); -insert into gh_ost_test values (null, 116); -insert into gh_ost_test values (null, 117); -insert into gh_ost_test values (null, 118); -insert into gh_ost_test values (null, 119); -insert into gh_ost_test values (null, 120); -insert into gh_ost_test values (null, 121); -insert into gh_ost_test values (null, 122); -insert into gh_ost_test values (null, 123); -insert into gh_ost_test values (null, 124); - -drop event if exists gh_ost_test; -delimiter ;; -create event gh_ost_test - on schedule every 1 second - starts current_timestamp + interval 3 second - ends current_timestamp + interval 60 second - on completion not preserve - enable - do -begin - update gh_ost_test set id=-2 where id=21; -end ;;