@@ -2,6 +2,8 @@ package mysql
2
2
3
3
import (
4
4
"fmt"
5
+ "strconv"
6
+ "strings"
5
7
)
6
8
7
9
// For binlog filename + position based replication
@@ -12,22 +14,67 @@ type Position struct {
12
14
13
15
func (p Position ) Compare (o Position ) int {
14
16
// First compare binlog name
15
- if p .Name > o .Name {
17
+ nameCmp := CompareBinlogFileName (p .Name , o .Name )
18
+ if nameCmp != 0 {
19
+ return nameCmp
20
+ }
21
+ // Same binlog file, compare position
22
+ if p .Pos > o .Pos {
16
23
return 1
17
- } else if p .Name < o .Name {
24
+ } else if p .Pos < o .Pos {
18
25
return - 1
19
26
} else {
20
- // Same binlog file, compare position
21
- if p .Pos > o .Pos {
22
- return 1
23
- } else if p .Pos < o .Pos {
24
- return - 1
25
- } else {
26
- return 0
27
- }
27
+ return 0
28
28
}
29
29
}
30
30
31
31
func (p Position ) String () string {
32
32
return fmt .Sprintf ("(%s, %d)" , p .Name , p .Pos )
33
33
}
34
+
35
+ func CompareBinlogFileName (a , b string ) int {
36
+ // sometimes it's convenient to construct a `Position` literal with no `Name`
37
+ if a == "" && b == "" {
38
+ return 0
39
+ } else if a == "" {
40
+ return - 1
41
+ } else if b == "" {
42
+ return 1
43
+ }
44
+
45
+ splitBinlogName := func (n string ) (string , int ) {
46
+ // mysqld appends a numeric extension to the binary log base name to generate binary log file names
47
+ // ...
48
+ // If you supply an extension in the log name (for example, --log-bin=base_name.extension),
49
+ // the extension is silently removed and ignored.
50
+ // ref: https://dev.mysql.com/doc/refman/8.0/en/binary-log.html
51
+ i := strings .LastIndexByte (n , '.' )
52
+ if i == - 1 {
53
+ // try keeping backward compatibility
54
+ return n , 0
55
+ }
56
+
57
+ seq , err := strconv .Atoi (n [i + 1 :])
58
+ if err != nil {
59
+ panic (fmt .Sprintf ("binlog file %s doesn't contain numeric extension" , err ))
60
+ }
61
+ return n [:i ], seq
62
+ }
63
+
64
+ aBase , aSeq := splitBinlogName (a )
65
+ bBase , bSeq := splitBinlogName (b )
66
+
67
+ if aBase > bBase {
68
+ return 1
69
+ } else if aBase < bBase {
70
+ return - 1
71
+ }
72
+
73
+ if aSeq > bSeq {
74
+ return 1
75
+ } else if aSeq < bSeq {
76
+ return - 1
77
+ } else {
78
+ return 0
79
+ }
80
+ }
0 commit comments