position.go 1.6 KB

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