- 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
This commit is contained in:
Shlomi Noach 2016-04-22 13:41:20 -07:00
parent 54c6d059b5
commit 1ed1b0d156
3 changed files with 30 additions and 4 deletions

View File

@ -123,6 +123,12 @@ func (this *MigrationContext) GetChangelogTableName() string {
return fmt.Sprintf("_%s_OSC", this.OriginalTableName) 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` // RequiresBinlogFormatChange is `true` when the original binlog format isn't `ROW`
func (this *MigrationContext) RequiresBinlogFormatChange() bool { func (this *MigrationContext) RequiresBinlogFormatChange() bool {
return this.OriginalBinlogFormat != "ROW" return this.OriginalBinlogFormat != "ROW"

View File

@ -427,8 +427,8 @@ func (this *Applier) UnlockTables() error {
return nil return nil
} }
// LockTables // SwapTablesQuickAndBumpy
func (this *Applier) SwapTables() error { func (this *Applier) SwapTablesQuickAndBumpy() error {
// query := fmt.Sprintf(`rename /* gh-osc */ table %s.%s to %s.%s, %s.%s to %s.%s`, // 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.DatabaseName),
// sql.EscapeName(this.migrationContext.OriginalTableName), // sql.EscapeName(this.migrationContext.OriginalTableName),
@ -468,6 +468,26 @@ func (this *Applier) SwapTables() error {
return nil 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 // StopSlaveIOThread is applicable with --test-on-replica; it stops the IO thread
func (this *Applier) StopSlaveIOThread() error { func (this *Applier) StopSlaveIOThread() error {
query := `stop /* gh-osc */ slave io_thread` query := `stop /* gh-osc */ slave io_thread`

View File

@ -322,7 +322,7 @@ func (this *Migrator) stopWritesAndCompleteMigrationOnMasterQuickAndBumpy() (err
<-this.allEventsUpToLockProcessed <-this.allEventsUpToLockProcessed
log.Debugf("Done waiting for events up to lock") 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 return err
} }
if err := this.retryOperation(this.applier.UnlockTables); err != nil { if err := this.retryOperation(this.applier.UnlockTables); err != nil {
@ -353,7 +353,7 @@ func (this *Migrator) stopWritesAndCompleteMigrationOnMasterViaLock() (err error
<-this.allEventsUpToLockProcessed <-this.allEventsUpToLockProcessed
log.Debugf("Done waiting for events up to lock") 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 return err
} }
if err := this.retryOperation(this.applier.UnlockTables); err != nil { if err := this.retryOperation(this.applier.UnlockTables); err != nil {