You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
1.6 KiB
Go
81 lines
1.6 KiB
Go
2 years ago
|
package mysql
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// For binlog filename + position based replication
|
||
|
type Position struct {
|
||
|
Name string
|
||
|
Pos uint32
|
||
|
}
|
||
|
|
||
|
func (p Position) Compare(o Position) int {
|
||
|
// First compare binlog name
|
||
|
nameCmp := CompareBinlogFileName(p.Name, o.Name)
|
||
|
if nameCmp != 0 {
|
||
|
return nameCmp
|
||
|
}
|
||
|
// Same binlog file, compare position
|
||
|
if p.Pos > o.Pos {
|
||
|
return 1
|
||
|
} else if p.Pos < o.Pos {
|
||
|
return -1
|
||
|
} else {
|
||
|
return 0
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (p Position) String() string {
|
||
|
return fmt.Sprintf("(%s, %d)", p.Name, p.Pos)
|
||
|
}
|
||
|
|
||
|
func CompareBinlogFileName(a, b string) int {
|
||
|
// sometimes it's convenient to construct a `Position` literal with no `Name`
|
||
|
if a == "" && b == "" {
|
||
|
return 0
|
||
|
} else if a == "" {
|
||
|
return -1
|
||
|
} else if b == "" {
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
splitBinlogName := func(n string) (string, int) {
|
||
|
// mysqld appends a numeric extension to the binary log base name to generate binary log file names
|
||
|
// ...
|
||
|
// If you supply an extension in the log name (for example, --log-bin=base_name.extension),
|
||
|
// the extension is silently removed and ignored.
|
||
|
// ref: https://dev.mysql.com/doc/refman/8.0/en/binary-log.html
|
||
|
i := strings.LastIndexByte(n, '.')
|
||
|
if i == -1 {
|
||
|
// try keeping backward compatibility
|
||
|
return n, 0
|
||
|
}
|
||
|
|
||
|
seq, err := strconv.Atoi(n[i+1:])
|
||
|
if err != nil {
|
||
|
panic(fmt.Sprintf("binlog file %s doesn't contain numeric extension", err))
|
||
|
}
|
||
|
return n[:i], seq
|
||
|
}
|
||
|
|
||
|
aBase, aSeq := splitBinlogName(a)
|
||
|
bBase, bSeq := splitBinlogName(b)
|
||
|
|
||
|
if aBase > bBase {
|
||
|
return 1
|
||
|
} else if aBase < bBase {
|
||
|
return -1
|
||
|
}
|
||
|
|
||
|
if aSeq > bSeq {
|
||
|
return 1
|
||
|
} else if aSeq < bSeq {
|
||
|
return -1
|
||
|
} else {
|
||
|
return 0
|
||
|
}
|
||
|
}
|