diff --git a/go/base/context.go b/go/base/context.go index 41aa915..5ef5e6e 100644 --- a/go/base/context.go +++ b/go/base/context.go @@ -112,6 +112,7 @@ type MigrationContext struct { Hostname string AssumeMasterHostname string + TimeZone string TableEngine string RowsEstimate int64 RowsDeltaEstimate int64 diff --git a/go/cmd/gh-ost/main.go b/go/cmd/gh-ost/main.go index 9231269..0ca18fa 100644 --- a/go/cmd/gh-ost/main.go +++ b/go/cmd/gh-ost/main.go @@ -48,6 +48,7 @@ func main() { flag.IntVar(&migrationContext.InspectorConnectionConfig.Key.Port, "port", 3306, "MySQL port (preferably a replica, not the master)") flag.StringVar(&migrationContext.CliUser, "user", "", "MySQL user") flag.StringVar(&migrationContext.CliPassword, "password", "", "MySQL password") + flag.StringVar(&migrationContext.TimeZone, "time-zone", "+00:00", "assume timezone. Default: UTC. Set empty for system time zone") flag.StringVar(&migrationContext.ConfigFile, "conf", "", "Config file") flag.StringVar(&migrationContext.DatabaseName, "database", "", "database name (mandatory)") diff --git a/go/logic/applier.go b/go/logic/applier.go index cabd66a..8976bf2 100644 --- a/go/logic/applier.go +++ b/go/logic/applier.go @@ -420,10 +420,11 @@ func (this *Applier) ApplyIterationInsertQuery() (chunkSize int64, rowsAffected if err != nil { return nil, err } - if _, err := tx.Exec(`SET - SESSION time_zone = '+00:00', + sessionQuery := fmt.Sprintf(`SET + SESSION time_zone = '%s', sql_mode = CONCAT(@@session.sql_mode, ',STRICT_ALL_TABLES') - `); err != nil { + `, this.migrationContext.TimeZone) + if _, err := tx.Exec(sessionQuery); err != nil { return nil, err } result, err := tx.Exec(query, explodedArgs...) @@ -892,10 +893,11 @@ func (this *Applier) ApplyDMLEventQuery(dmlEvent *binlog.BinlogDMLEvent) error { if err != nil { return err } - if _, err := tx.Exec(`SET - SESSION time_zone = '+00:00', + sessionQuery := fmt.Sprintf(`SET + SESSION time_zone = '%s', sql_mode = CONCAT(@@session.sql_mode, ',STRICT_ALL_TABLES') - `); err != nil { + `, this.migrationContext.TimeZone) + if _, err := tx.Exec(sessionQuery); err != nil { return err } if _, err := tx.Exec(query, args...); err != nil { diff --git a/vendor/github.com/siddontang/go-mysql/replication/row_event.go b/vendor/github.com/siddontang/go-mysql/replication/row_event.go index 7a2b7a4..4ed093e 100644 --- a/vendor/github.com/siddontang/go-mysql/replication/row_event.go +++ b/vendor/github.com/siddontang/go-mysql/replication/row_event.go @@ -591,7 +591,7 @@ func decodeBit(data []byte, nbits int, length int) (value int64, err error) { return } -func decodeTimestamp2(data []byte, dec uint16) (string, int, error) { +func decodeTimestamp2(data []byte, dec uint16) (interface{}, int, error) { //get timestamp binary length n := int(4 + (dec+1)/2) sec := int64(binary.BigEndian.Uint32(data[0:4])) @@ -609,13 +609,15 @@ func decodeTimestamp2(data []byte, dec uint16) (string, int, error) { return "0000-00-00 00:00:00", n, nil } - t := time.Unix(sec, usec*1000).UTC() // .UTC() converted by shlomi-noach - return t.Format(TimeFormat), n, nil + // t := time.Unix(sec, usec*1000).UTC() // .UTC() converted by shlomi-noach + // return t.Format(TimeFormat), n, nil + t := time.Unix(sec, usec*1000).UTC() + return t, n, nil } const DATETIMEF_INT_OFS int64 = 0x8000000000 -func decodeDatetime2(data []byte, dec uint16) (string, int, error) { +func decodeDatetime2(data []byte, dec uint16) (interface{}, int, error) { //get datetime binary length n := int(5 + (dec+1)/2) @@ -658,7 +660,8 @@ func decodeDatetime2(data []byte, dec uint16) (string, int, error) { hour := int((hms >> 12)) t := time.Date(year, time.Month(month), day, hour, minute, second, 0, time.UTC) // added by Shlomi Noach - return t.Format(TimeFormat), n, nil // added by Shlomi Noach + //return t.Format(TimeFormat), n, nil // added by Shlomi Noach + return t, n, nil // added by Shlomi Noach // return fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second), n, nil // commented by Shlomi Noach. Yes I know about `git blame` }