github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/retry/errors.go (about)

     1  // Copyright 2019 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package retry
    15  
    16  import (
    17  	"database/sql/driver"
    18  
    19  	gmysql "github.com/go-mysql-org/go-mysql/mysql"
    20  	dmysql "github.com/go-sql-driver/mysql"
    21  	"github.com/pingcap/errors"
    22  	tmysql "github.com/pingcap/tidb/pkg/parser/mysql"
    23  	"github.com/pingcap/tiflow/dm/pkg/terror"
    24  )
    25  
    26  // some error reference: https://docs.pingcap.com/tidb/stable/tidb-limitations#limitations-on-a-single-table
    27  var (
    28  	// UnsupportedDDLMsgs list the error messages of some unsupported DDL in TiDB.
    29  	UnsupportedDDLMsgs = []string{
    30  		"can't drop column with index",
    31  		"with tidb_enable_change_multi_schema is disable", // https://github.com/pingcap/tidb/pull/29526
    32  		"unsupported add column",
    33  		"unsupported modify column",
    34  		"unsupported modify charset",
    35  		"unsupported modify collate",
    36  		"unsupported drop integer primary key",
    37  		"Unsupported collation",
    38  		"Invalid default value for",
    39  		"Unsupported drop primary key",
    40  		"Error 1059", // Identifier name '%s' is too long
    41  		"Error 1117", // Too many columns
    42  		"Error 1069", // Too many keys specified
    43  	}
    44  
    45  	// UnsupportedDMLMsgs list the error messages of some un-recoverable DML, which is used in task auto recovery.
    46  	UnsupportedDMLMsgs = []string{
    47  		"Error 1062", // Duplicate entry
    48  		"Error 1406", // Data too long for column
    49  		"Error 1366", // Incorrect %s value: '%s' for column '%s' at row %d
    50  		"Error 8025", // entry too large
    51  	}
    52  
    53  	// ReplicationErrMsgs list the error message of un-recoverable replication error.
    54  	ReplicationErrMsgs = []string{
    55  		"Could not find first log file name in binary log index file",
    56  		"The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires",
    57  	}
    58  
    59  	// ParseRelayLogErrMsgs list the error messages of some un-recoverable relay log parsing error, which is used in task auto recovery.
    60  	ParseRelayLogErrMsgs = []string{
    61  		"binlog checksum mismatch, data may be corrupted",
    62  		"get event err EOF",
    63  	}
    64  
    65  	// UnresumableErrCodes is a set of unresumeable err codes.
    66  	UnresumableErrCodes = map[int32]struct{}{
    67  		int32(terror.ErrSyncUnitDDLWrongSequence.Code()):    {},
    68  		int32(terror.ErrDumpUnitGlobalLock.Code()):          {},
    69  		int32(terror.ErrDumpUnitRuntime.Code()):             {},
    70  		int32(terror.ErrSyncerUnitDMLColumnNotMatch.Code()): {},
    71  		int32(terror.ErrSyncerCancelledDDL.Code()):          {},
    72  		int32(terror.ErrLoadLightningRuntime.Code()):        {},
    73  		int32(terror.ErrLoadLightningHasDup.Code()):         {},
    74  		int32(terror.ErrLoadLightningChecksum.Code()):       {},
    75  	}
    76  
    77  	// UnresumableRelayErrCodes is a set of unresumeable relay unit err codes.
    78  	UnresumableRelayErrCodes = map[int32]struct{}{
    79  		int32(terror.ErrRelayUUIDSuffixNotValid.Code()):     {},
    80  		int32(terror.ErrRelayUUIDSuffixLessThanPrev.Code()): {},
    81  		int32(terror.ErrRelayBinlogNameNotValid.Code()):     {},
    82  		int32(terror.ErrRelayNoCurrentUUID.Code()):          {},
    83  		int32(terror.ErrRelayLogDirpathEmpty.Code()):        {},
    84  	}
    85  )
    86  
    87  // IsConnectionError tells whether this error should reconnect to Database.
    88  // Return true also means caller can retry sql safely.
    89  func IsConnectionError(err error) bool {
    90  	err = errors.Cause(err)
    91  	switch err {
    92  	case driver.ErrBadConn, tmysql.ErrBadConn, gmysql.ErrBadConn:
    93  		return true
    94  	}
    95  	return false
    96  }
    97  
    98  // IsUnretryableConnectionError checks whether it's an unretryable connection error or not.
    99  func IsUnretryableConnectionError(err error) bool {
   100  	// Can't ensure whether the last write has reached the downstream or not.
   101  	// If the last write isn't idempotent, retry it may cause problems.
   102  	return errors.Cause(err) == dmysql.ErrInvalidConn
   103  }