From 1ed1b0d156b4af2832db2b086c864ef0b83754e6 Mon Sep 17 00:00:00 2001 From: Shlomi Noach Date: Fri, 22 Apr 2016 13:41:20 -0700 Subject: [PATCH] - `quick-and-bumpy-swap-tables` uses quicker swap tables, at the expense of a period where the table does not exist (non atomic renames) - refactored lock-and-swap code, in preparation for atomic swap --- go/base/context.go | 6 ++++++ go/logic/applier.go | 24 ++++++++++++++++++++++-- go/logic/migrator.go | 4 ++-- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/go/base/context.go b/go/base/context.go index 3a060fa..33e52f2 100644 --- a/go/base/context.go +++ b/go/base/context.go @@ -123,6 +123,12 @@ func (this *MigrationContext) GetChangelogTableName() string { return fmt.Sprintf("_%s_OSC", this.OriginalTableName) } +// GetVoluntaryLockName returns a name of a voluntary lock to be used throughout +// the swap-tables process. +func (this *MigrationContext) GetVoluntaryLockName() string { + return fmt.Sprintf("%s.%s.lock", this.DatabaseName, this.OriginalTableName) +} + // RequiresBinlogFormatChange is `true` when the original binlog format isn't `ROW` func (this *MigrationContext) RequiresBinlogFormatChange() bool { return this.OriginalBinlogFormat != "ROW" diff --git a/go/logic/applier.go b/go/logic/applier.go index c7ff916..314d683 100644 --- a/go/logic/applier.go +++ b/go/logic/applier.go @@ -427,8 +427,8 @@ func (this *Applier) UnlockTables() error { return nil } -// LockTables -func (this *Applier) SwapTables() error { +// SwapTablesQuickAndBumpy +func (this *Applier) SwapTablesQuickAndBumpy() error { // query := fmt.Sprintf(`rename /* gh-osc */ table %s.%s to %s.%s, %s.%s to %s.%s`, // sql.EscapeName(this.migrationContext.DatabaseName), // sql.EscapeName(this.migrationContext.OriginalTableName), @@ -468,6 +468,26 @@ func (this *Applier) SwapTables() error { return nil } +// SwapTablesQuickAndBumpy +func (this *Applier) SwapTablesAtomic() error { + query := fmt.Sprintf(`rename /* gh-osc */ table %s.%s to %s.%s, %s.%s to %s.%s`, + sql.EscapeName(this.migrationContext.DatabaseName), + sql.EscapeName(this.migrationContext.OriginalTableName), + sql.EscapeName(this.migrationContext.DatabaseName), + sql.EscapeName(this.migrationContext.GetOldTableName()), + sql.EscapeName(this.migrationContext.DatabaseName), + sql.EscapeName(this.migrationContext.GetGhostTableName()), + sql.EscapeName(this.migrationContext.DatabaseName), + sql.EscapeName(this.migrationContext.OriginalTableName), + ) + log.Infof("Renaming tables") + if _, err := sqlutils.ExecNoPrepare(this.singletonDB, query); err != nil { + return err + } + log.Infof("Tables renamed") + return nil +} + // StopSlaveIOThread is applicable with --test-on-replica; it stops the IO thread func (this *Applier) StopSlaveIOThread() error { query := `stop /* gh-osc */ slave io_thread` diff --git a/go/logic/migrator.go b/go/logic/migrator.go index 2d328cb..df6eaba 100644 --- a/go/logic/migrator.go +++ b/go/logic/migrator.go @@ -322,7 +322,7 @@ func (this *Migrator) stopWritesAndCompleteMigrationOnMasterQuickAndBumpy() (err <-this.allEventsUpToLockProcessed log.Debugf("Done waiting for events up to lock") - if err := this.retryOperation(this.applier.SwapTables); err != nil { + if err := this.retryOperation(this.applier.SwapTablesQuickAndBumpy); err != nil { return err } if err := this.retryOperation(this.applier.UnlockTables); err != nil { @@ -353,7 +353,7 @@ func (this *Migrator) stopWritesAndCompleteMigrationOnMasterViaLock() (err error <-this.allEventsUpToLockProcessed log.Debugf("Done waiting for events up to lock") - if err := this.retryOperation(this.applier.SwapTables); err != nil { + if err := this.retryOperation(this.applier.SwapTablesAtomic); err != nil { return err } if err := this.retryOperation(this.applier.UnlockTables); err != nil {