-
Notifications
You must be signed in to change notification settings - Fork 198
Expand file tree
/
Copy pathmysql.go
More file actions
122 lines (98 loc) · 3.34 KB
/
Copy pathmysql.go
File metadata and controls
122 lines (98 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package exceptions
import (
"context"
"crypto/tls"
"errors"
"fmt"
"regexp"
"strings"
"github.com/go-mysql-org/go-mysql/mysql"
)
// InvalidSequenceRe go-mysql-org returns "invalid sequence X != Y" when the TCP packet sequence
// is out of sync — always transient, safe to retry.
var InvalidSequenceRe = regexp.MustCompile(`invalid sequence \d+ != \d+`)
type MySQLIncompatibleColumnTypeError struct {
TableName string
ColumnName string
dataType string
qkind string
columnType byte
}
func NewMySQLIncompatibleColumnTypeError(
tableName string, columnName string, columnType byte, dataType string, qkind string,
) *MySQLIncompatibleColumnTypeError {
return &MySQLIncompatibleColumnTypeError{
TableName: tableName,
ColumnName: columnName,
dataType: dataType,
qkind: qkind,
columnType: columnType,
}
}
func (e *MySQLIncompatibleColumnTypeError) Error() string {
return fmt.Sprintf("Incompatible type for column %s in table %s, expect qkind %s but data is %s (mysql type %d)",
e.ColumnName, e.TableName, e.qkind, e.dataType, e.columnType)
}
type MySQLUnsupportedBinlogRowMetadataError struct {
SchemaName string
TableName string
}
func NewMySQLUnsupportedBinlogRowMetadataError(schema string, table string) *MySQLUnsupportedBinlogRowMetadataError {
return &MySQLUnsupportedBinlogRowMetadataError{SchemaName: schema, TableName: table}
}
func (e *MySQLUnsupportedBinlogRowMetadataError) Error() string {
return fmt.Sprintf("Detected binlog_row_metadata change from FULL to MINIMAL while processing %s.%s",
e.SchemaName, e.TableName)
}
type MySQLUnsupportedDDLError struct {
TableName string
}
func NewMySQLUnsupportedDDLError(tableName string) *MySQLUnsupportedDDLError {
return &MySQLUnsupportedDDLError{TableName: tableName}
}
func (e *MySQLUnsupportedDDLError) Error() string {
return fmt.Sprintf(
"Detected position-shifting DDL on table %s but binlog_row_metadata is not supported by this MySQL version.", e.TableName)
}
// MySQLGeometryParseError wraps go-geos WKB parse failures so they can be
// classified as MySQL-source errors without string-matching at the alerting layer.
// The underlying message comes from go-geos C code and is not unique to MySQL on its own.
type MySQLGeometryParseError struct {
error
}
func NewMySQLGeometryParseError(err error) *MySQLGeometryParseError {
return &MySQLGeometryParseError{err}
}
func (e *MySQLGeometryParseError) Error() string {
return "failed to parse MySQL geometry WKB: " + e.error.Error()
}
func (e *MySQLGeometryParseError) Unwrap() error {
return e.error
}
type MySQLStreamingError struct {
error
Retryable bool
}
func NewMySQLStreamingError(err error) *MySQLStreamingError {
if errors.Is(err, context.DeadlineExceeded) {
return &MySQLStreamingError{err, true}
}
if recordHeaderError, ok := errors.AsType[tls.RecordHeaderError](err); ok {
if recordHeaderError.Msg == "first record does not look like a TLS handshake" {
return &MySQLStreamingError{err, true}
}
}
if strings.Contains(err.Error(), mysql.ErrBadConn.Error()) {
return &MySQLStreamingError{err, true}
}
if InvalidSequenceRe.MatchString(err.Error()) {
return &MySQLStreamingError{err, true}
}
return &MySQLStreamingError{err, false}
}
func (e *MySQLStreamingError) Error() string {
return "MySQL streaming error: " + e.error.Error()
}
func (e *MySQLStreamingError) Unwrap() error {
return e.error
}