encoding range values as base64

This commit is contained in:
Shlomi Noach 2016-12-20 15:48:42 +02:00
parent 66894d3a52
commit 75b6f9edf2
4 changed files with 49 additions and 3 deletions

View File

@ -175,6 +175,7 @@ type MigrationContext struct {
Iteration int64
MigrationIterationRangeMinValues *sql.ColumnValues
MigrationIterationRangeMaxValues *sql.ColumnValues
EncodedRangeValues map[string]string
}
type ContextConfig struct {
@ -211,6 +212,7 @@ func newMigrationContext() *MigrationContext {
configMutex: &sync.Mutex{},
pointOfInterestTimeMutex: &sync.Mutex{},
ColumnRenameMap: make(map[string]string),
EncodedRangeValues: make(map[string]string),
}
}
@ -227,12 +229,25 @@ func (this *MigrationContext) ToJSON() (string, error) {
// DumpJSON exports this config to JSON string and writes it to file
func (this *MigrationContext) DumpJSON() (fileName string, err error) {
if this.MigrationRangeMinValues != nil {
this.EncodedRangeValues["MigrationRangeMinValues"], _ = this.MigrationRangeMinValues.ToBase64()
}
if this.MigrationRangeMaxValues != nil {
this.EncodedRangeValues["MigrationRangeMaxValues"], _ = this.MigrationRangeMaxValues.ToBase64()
}
if this.MigrationIterationRangeMinValues != nil {
this.EncodedRangeValues["MigrationIterationRangeMinValues"], _ = this.MigrationIterationRangeMinValues.ToBase64()
}
if this.MigrationIterationRangeMaxValues != nil {
this.EncodedRangeValues["MigrationIterationRangeMaxValues"], _ = this.MigrationIterationRangeMaxValues.ToBase64()
}
jsonBytes, err := json.Marshal(this)
if err != nil {
return fileName, err
}
fileName = fmt.Sprintf("%s/gh-ost.%s.%d.context.json", "/tmp", this.OriginalTableName, this.ElapsedTime())
err = ioutil.WriteFile(fileName, jsonBytes, 0644)
return fileName, err
}

View File

@ -124,7 +124,7 @@ func (this *Inspector) inspectOriginalAndGhostTables() (err error) {
return fmt.Errorf("No shared unique key can be found after ALTER! Bailing out")
}
this.migrationContext.UniqueKey = sharedUniqueKeys[0]
log.Infof("Chosen shared unique key is %s", this.migrationContext.UniqueKey.Name)
log.Infof("Chosen shared unique key is %+v", this.migrationContext.UniqueKey)
if this.migrationContext.UniqueKey.HasNullable {
if this.migrationContext.NullableUniqueKeyAllowed {
log.Warningf("Chosen key (%s) has nullable columns. You have supplied with --allow-nullable-unique-key and so this migration proceeds. As long as there aren't NULL values in this key's column, migration should be fine. NULL values will corrupt migration's data", this.migrationContext.UniqueKey)

View File

@ -31,6 +31,8 @@ const (
AllEventsUpToLockProcessed = "AllEventsUpToLockProcessed"
)
const contextDumpInterval time.Duration = 1 * time.Second
func ReadChangelogState(s string) ChangelogState {
return ChangelogState(strings.Split(s, ":")[0])
}
@ -124,7 +126,7 @@ func (this *Migrator) initiateHooksExecutor() (err error) {
// initiateContextDump
func (this *Migrator) initiateContextDump() (err error) {
go func() {
contextDumpTick := time.Tick(1 * time.Minute)
contextDumpTick := time.Tick(contextDumpInterval)
for range contextDumpTick {
if dumpFile, err := this.migrationContext.DumpJSON(); err == nil {
this.contextDumpFiles = append(this.contextDumpFiles, dumpFile)

View File

@ -6,6 +6,9 @@
package sql
import (
"bytes"
"encoding/base64"
"encoding/gob"
"encoding/json"
"fmt"
"reflect"
@ -216,7 +219,7 @@ func (this *UniqueKey) String() string {
if this.IsAutoIncrement {
description = fmt.Sprintf("%s (auto_increment)", description)
}
return fmt.Sprintf("%s: %s; has nullable: %+v", description, this.Columns.Names(), this.HasNullable)
return fmt.Sprintf("%s: %s; has nullable: %+v", description, this.Columns.String(), this.HasNullable)
}
type ColumnValues struct {
@ -248,6 +251,32 @@ func ToColumnValues(abstractValues []interface{}) *ColumnValues {
return result
}
func NewColumnValuesFromBase64(b64 string) (columnValues *ColumnValues, err error) {
var abstractValues []interface{}
b, err := base64.StdEncoding.DecodeString(b64)
if err != nil {
return nil, err
}
buff := bytes.Buffer{}
buff.Write(b)
decoder := gob.NewDecoder(&buff)
err = decoder.Decode(&abstractValues)
if err != nil {
return nil, err
}
return ToColumnValues(abstractValues), nil
}
func (this *ColumnValues) ToBase64() (b64 string, err error) {
buff := bytes.Buffer{}
encoder := gob.NewEncoder(&buff)
if err = encoder.Encode(this.abstractValues); err != nil {
return b64, err
}
return base64.StdEncoding.EncodeToString(buff.Bytes()), nil
}
// MarshalJSON will marshal this object as JSON
func (this *ColumnValues) MarshalJSON() ([]byte, error) {
return json.Marshal(this.abstractValues)