@@ -47,13 +47,15 @@ type BinlogSyncer struct {
4747
4848 DBPool map [string ]* sql.DB
4949 WriteChs []chan * WriteEvent
50- CountCh chan * Status
50+ CountCh chan * Result
5151
5252 mutex * sync.Mutex
5353 wg * sync.WaitGroup
5454 shellLog * log.Logger
5555 fileLog * log.Logger
5656
57+ stat * Status
58+
5759 stop bool
5860}
5961
@@ -63,44 +65,47 @@ type BinlogPosition struct {
6365 NextGTID string `yaml:"GTID"`
6466}
6567
66- type OutMessage struct {
67- Synced int64 `yaml:"Synced"`
68- Faild int64 `yaml:"Faild"`
68+ type Status struct {
69+ Finished int64 `yaml:"Finished"`
70+ Failed int64 `yaml:"Failed"`
71+ Errors map [string ]int `yaml:"Errors"`
6972 RowsPerSec float64 `yaml:"RowsPerSec"`
70- Position BinlogPosition `yaml:"Position"`
71- Error map [string ]int `yaml:"Error"`
7273}
7374
74- type Status struct {
75+ type Result struct {
7576 err error
7677 goroutineIndex int
7778
79+ gtid string
80+
7881 position BinlogPosition
7982}
8083
81- func NewBinlogSyncer (conf Config ) * BinlogSyncer {
84+ func NewBinlogSyncer (conf * Config ) * BinlogSyncer {
8285 fileLog := log .New (logFile , "" , log .Ldate | log .Ltime | log .Lshortfile )
8386 fileLog .SetPrefix ("[" + conf .SourceConn .Addr + "] " )
8487
8588 bs := & BinlogSyncer {
86- Config : conf ,
89+ Config : * conf ,
8790
8891 DBPool : make (map [string ]* sql.DB ),
8992 WriteChs : make ([]chan * WriteEvent , conf .WorkerCnt ),
90- CountCh : make (chan * Status , channelCapacity * conf .WorkerCnt ),
93+ CountCh : make (chan * Result , channelCapacity * conf .WorkerCnt ),
9194
9295 mutex : & sync.Mutex {},
9396 wg : & sync.WaitGroup {},
9497 shellLog : shellLog ,
9598 fileLog : fileLog ,
96- stop : false ,
99+ stat : & Status {
100+ Errors : make (map [string ]int ),
101+ },
102+ stop : false ,
97103 }
98104
99105 return bs
100106}
101107
102108func (bs * BinlogSyncer ) Sync () {
103- defer mainWG .Done ()
104109
105110 var binlogReader * replication.BinlogStreamer
106111 var err error
@@ -167,14 +172,14 @@ func (bs *BinlogSyncer) writeToDB(chIdx int, inCh chan *WriteEvent) {
167172 if ev .event .Header .EventType == replication .ROTATE_EVENT {
168173 rotateEv , _ := ev .event .Event .(* replication.RotateEvent )
169174
170- stat := & Status {
175+ rst := & Result {
171176 goroutineIndex : chIdx ,
172177 position : BinlogPosition {
173178 BinlogPos : int64 (rotateEv .Position ),
174179 BinlogFile : string (rotateEv .NextLogName ),
175180 },
176181 }
177- bs .CountCh <- stat
182+ bs .CountCh <- rst
178183 continue
179184 }
180185
@@ -224,7 +229,7 @@ func (bs *BinlogSyncer) writeToDB(chIdx int, inCh chan *WriteEvent) {
224229 }
225230 }
226231
227- stat := & Status {
232+ rst := & Result {
228233 err : err ,
229234 goroutineIndex : chIdx ,
230235 position : BinlogPosition {
@@ -235,7 +240,7 @@ func (bs *BinlogSyncer) writeToDB(chIdx int, inCh chan *WriteEvent) {
235240 }
236241
237242 bs .fileLog .Printf ("routin index: %d, event position: %d\n " , chIdx , ev .event .Header .LogPos )
238- bs .CountCh <- stat
243+ bs .CountCh <- rst
239244 }
240245}
241246
@@ -295,45 +300,36 @@ func (bs *BinlogSyncer) readBinlog(binlogReader *replication.BinlogStreamer) {
295300}
296301
297302func (bs * BinlogSyncer ) collector () {
298- var rowCnt int64
299- var errCnt int64
300- var errTypes = make (map [string ]int )
301303
302304 var start = time .Now ()
305+ var tickCnt = int64 (0 )
303306
304- for outStat := range bs .CountCh {
305- if outStat .err != nil {
306- errCnt += 1
307- errTypes [outStat .err .Error ()] += 1
308- }
309-
310- rowCnt += 1
311-
312- if rowCnt % bs .TickCnt == 0 {
313-
314- rowsPerSec := float64 (bs .TickCnt ) / time .Since (start ).Seconds ()
315-
316- om := & OutMessage {
317- Synced : rowCnt ,
318- Faild : errCnt ,
319- RowsPerSec : rowsPerSec ,
320- Position : outStat .position ,
321- Error : errTypes ,
322- }
307+ ticker := time .NewTicker (time .Duration (time .Minute * 1 ))
308+ defer ticker .Stop ()
323309
324- outMessage , err := marshalYAML (om )
325- if err != nil {
326- bs .fileLog .Printf ("[%s] dump out message to YAML failed: %v\n " , bs .SourceConn .Addr , outMessage )
327- }
310+ go func () {
311+ for _ = range ticker .C {
312+ bs .stat .RowsPerSec = float64 (tickCnt ) / time .Since (start ).Seconds ()
313+ tickCnt = 0
314+ start = time .Now ()
315+ }
316+ }()
328317
329- outMessage = " ====== [" + bs .SourceConn .Addr + "] status ======\n " + outMessage
330- bs .shellLog .Printf (outMessage )
318+ for rst := range bs .CountCh {
319+ bs .stat .Finished += 1
320+ tickCnt += 1
331321
332- start = time .Now ()
322+ if rst .err != nil {
323+ bs .stat .Errors [rst .err .Error ()] += 1
324+ bs .stat .Failed += 1
333325 }
334326 }
335327}
336328
329+ func (bs * BinlogSyncer ) GetStat () * Status {
330+ return bs .stat
331+ }
332+
337333func (bs * BinlogSyncer ) getWriteConnection (row map [string ]interface {}) (* DBInfo , error ) {
338334 shardValues := make ([]interface {}, len (bs .TableShard ))
339335 for i , k := range bs .TableShard {
0 commit comments