-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[fix-issue-2676] repair a snapshot-split bug: #2968
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,8 +17,14 @@ | |
|
||
package org.apache.flink.cdc.connectors.mysql.source.utils; | ||
|
||
import io.debezium.jdbc.JdbcConnection; | ||
import io.debezium.relational.TableId; | ||
import org.apache.commons.lang3.StringUtils; | ||
|
||
import java.math.BigDecimal; | ||
import java.math.BigInteger; | ||
import java.sql.SQLException; | ||
import java.util.Objects; | ||
|
||
/** Utilities for operation on {@link Object}. */ | ||
public class ObjectUtils { | ||
|
@@ -89,6 +95,48 @@ public static int compare(Object obj1, Object obj2) { | |
} | ||
} | ||
|
||
/** | ||
* Compares two comparable objects. When the compared objects are not instance of {@link | ||
* Comparable} or instace of String, we will compare them in db, ignore the charset of table | ||
* effects the table-split result exmaple: primaryKey: | ||
* ['0000','1111','2222','3333','4444','aaaa','bbbb','cccc','ZZZZ'] collate: utf8mb4_general_ci | ||
* when chunkSize = 3 we want : split1: ['0000','1111'] split2: ['3333','4444'] split3: | ||
* ['aaaa','bbbb'] split3: ['cccc','ZZZZ'] but if we use a table with | ||
* COLLATE='utf8mb4_general_ci' and compare them with {@link ObjectUtils#compare(Object, | ||
* Object)}, we whill get: split1: ['0000','1111'] split2: ['3333','4444'] split3: | ||
* ['aaaa','bbbb','cccc','ZZZZ'....] the split3 whill contains all of the remain rows | ||
* | ||
* @return The value {@code 0} if {@code num1} is equal to the {@code num2}; a value less than | ||
* {@code 0} if the {@code num1} is numerically less than the {@code num2}; and a value | ||
* greater than {@code 0} if the {@code num1} is numerically greater than the {@code num2}. | ||
* @throws ClassCastException if the compared objects are not instance of {@link Comparable} or | ||
* not <i>mutually comparable</i> (for example, strings and integers). | ||
*/ | ||
@SuppressWarnings("unchecked") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason for this suppress? |
||
public static int dbCompare( | ||
Object obj1, | ||
Object obj2, | ||
JdbcConnection jdbcConnection, | ||
TableId tableId, | ||
String splitColumn) | ||
throws SQLException { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this function throw an |
||
if (Objects.equals(obj1, obj2)) { | ||
return 0; | ||
} | ||
if (obj1 instanceof String && obj2 instanceof String) { | ||
// if instance of String, we will compare them in db, to ignore effects of the charset | ||
// and collation of the column | ||
String columnCollation = | ||
StatementUtils.queryColumnCollation(jdbcConnection, tableId, splitColumn); | ||
Comment on lines
+129
to
+130
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIUC There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, you are right. during the chunk splitting process, db queries have been changed from once to three times. But at this stage, I cannot fully cover different MySQL versions as well as various database character sets and collations. So I temporarily chose a relatively simple approach to solve it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, this solution looks reasonable. |
||
if (!StringUtils.isEmpty(columnCollation)) { | ||
return StatementUtils.compareValueByQuery( | ||
obj1, obj2, jdbcConnection, columnCollation); | ||
} | ||
// cannot get column collation, use default compare | ||
} | ||
return compare(obj1, obj2); | ||
} | ||
|
||
/** | ||
* Compares two Double numeric object. | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.