From a9d69c4d3f8866f2c88a9d20926395303410dfbb Mon Sep 17 00:00:00 2001 From: fengwei <283987694@qq.com> Date: Mon, 11 Nov 2019 12:33:50 +0800 Subject: [PATCH] fix bug : concurrency error is modified by other goroutines https://github.com/github/orchestrator/issues/1000 --- go/inst/instance_dao.go | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/go/inst/instance_dao.go b/go/inst/instance_dao.go index afc35451f..ff05314f2 100644 --- a/go/inst/instance_dao.go +++ b/go/inst/instance_dao.go @@ -294,6 +294,7 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool, isMaxScale := false isMaxScale110 := false slaveStatusFound := false + errorChan := make(chan error, 32) var resolveErr error if !instanceKey.IsValid() { @@ -361,7 +362,7 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool, defer waitGroup.Done() var dummy string // show global status works just as well with 5.6 & 5.7 (5.7 moves variables to performance_schema) - err = db.QueryRow("show global status like 'Uptime'").Scan(&dummy, &instance.Uptime) + err := db.QueryRow("show global status like 'Uptime'").Scan(&dummy, &instance.Uptime) if err != nil { logReadTopologyInstanceError(instanceKey, "show global status like 'Uptime'", err) @@ -373,6 +374,7 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool, // so as to completely fail reading a 5.7 instance. // This is supposed to be fixed in 5.7.9 } + errorChan <- err }() } @@ -402,12 +404,13 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool, waitGroup.Add(1) go func() { defer waitGroup.Done() - err = sqlutils.QueryRowsMap(db, "show master status", func(m sqlutils.RowMap) error { + err := sqlutils.QueryRowsMap(db, "show master status", func(m sqlutils.RowMap) error { var err error instance.SelfBinlogCoordinates.LogFile = m.GetString("File") instance.SelfBinlogCoordinates.LogPos = m.GetInt64("Position") return err }) + errorChan <- err }() } @@ -415,7 +418,7 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool, waitGroup.Add(1) go func() { defer waitGroup.Done() - err = sqlutils.QueryRowsMap(db, "show global status like 'rpl_semi_sync_%_status'", func(m sqlutils.RowMap) error { + err := sqlutils.QueryRowsMap(db, "show global status like 'rpl_semi_sync_%_status'", func(m sqlutils.RowMap) error { if m.GetString("Variable_name") == "Rpl_semi_sync_master_status" { instance.SemiSyncMasterEnabled = (m.GetString("Value") == "ON") } else if m.GetString("Variable_name") == "Rpl_semi_sync_slave_status" { @@ -423,6 +426,7 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool, } return nil }) + errorChan <- err }() } if (instance.IsOracleMySQL() || instance.IsPercona()) && !instance.IsSmallerMajorVersionByString("5.6") { @@ -806,6 +810,19 @@ func ReadTopologyInstanceBufferable(instanceKey *InstanceKey, bufferWrites bool, Cleanup: waitGroup.Wait() + close(errorChan) + err = func() error { + if err != nil { + return err + } + + for err := range errorChan { + if err != nil { + return err + } + } + return nil + }() if instanceFound { if instance.IsCoMaster {