-
Notifications
You must be signed in to change notification settings - Fork 131
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
drainer:sync lob data to oracle #1158
Merged
Merged
Changes from 4 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
d656aab
support lob
cartersz 6481ff7
fix comment
cartersz cf892d9
add comment for MysqlDB/OracleDB
cartersz 34bb725
fix comment 2
cartersz 205bf01
fix comment 3
cartersz 61479ca
fix comment on DBType
cartersz 4e59a23
fix comment 4
cartersz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -31,7 +31,7 @@ import ( | |||||||||
|
||||||||||
const implicitColID = -1 | ||||||||||
|
||||||||||
func genDBInsert(schema string, ptable, table *model.TableInfo, row []byte) (names []string, args []interface{}, err error) { | ||||||||||
func genDBInsert(schema string, ptable, table *model.TableInfo, row []byte, destDBType int) (names []string, args []interface{}, err error) { | ||||||||||
columns := writableColumns(table) | ||||||||||
|
||||||||||
columnValues, err := insertRowToDatums(table, row) | ||||||||||
|
@@ -46,7 +46,7 @@ func genDBInsert(schema string, ptable, table *model.TableInfo, row []byte) (nam | |||||||||
val = getDefaultOrZeroValue(ptable, col) | ||||||||||
} | ||||||||||
|
||||||||||
value, err := formatData(val, col.FieldType) | ||||||||||
value, err := formatData(val, col.FieldType, destDBType) | ||||||||||
if err != nil { | ||||||||||
return nil, nil, errors.Trace(err) | ||||||||||
} | ||||||||||
|
@@ -58,7 +58,7 @@ func genDBInsert(schema string, ptable, table *model.TableInfo, row []byte) (nam | |||||||||
return names, args, nil | ||||||||||
} | ||||||||||
|
||||||||||
func genDBUpdate(schema string, ptable, table *model.TableInfo, row []byte, canAppendDefaultValue bool) (names []string, values []interface{}, oldValues []interface{}, err error) { | ||||||||||
func genDBUpdate(schema string, ptable, table *model.TableInfo, row []byte, canAppendDefaultValue bool, destDBType int) (names []string, values []interface{}, oldValues []interface{}, err error) { | ||||||||||
columns := writableColumns(table) | ||||||||||
updtDecoder := newUpdateDecoder(ptable, table, canAppendDefaultValue) | ||||||||||
|
||||||||||
|
@@ -69,12 +69,12 @@ func genDBUpdate(schema string, ptable, table *model.TableInfo, row []byte, canA | |||||||||
return nil, nil, nil, errors.Annotatef(err, "table `%s`.`%s`", schema, table.Name) | ||||||||||
} | ||||||||||
|
||||||||||
_, oldValues, err = generateColumnAndValue(columns, oldColumnValues) | ||||||||||
_, oldValues, err = generateColumnAndValue(columns, oldColumnValues, destDBType) | ||||||||||
if err != nil { | ||||||||||
return nil, nil, nil, errors.Trace(err) | ||||||||||
} | ||||||||||
|
||||||||||
updateColumns, values, err = generateColumnAndValue(columns, newColumnValues) | ||||||||||
updateColumns, values, err = generateColumnAndValue(columns, newColumnValues, destDBType) | ||||||||||
if err != nil { | ||||||||||
return nil, nil, nil, errors.Trace(err) | ||||||||||
} | ||||||||||
|
@@ -84,7 +84,7 @@ func genDBUpdate(schema string, ptable, table *model.TableInfo, row []byte, canA | |||||||||
return | ||||||||||
} | ||||||||||
|
||||||||||
func genDBDelete(schema string, table *model.TableInfo, row []byte) (names []string, values []interface{}, err error) { | ||||||||||
func genDBDelete(schema string, table *model.TableInfo, row []byte, destDBType int) (names []string, values []interface{}, err error) { | ||||||||||
columns := table.Columns | ||||||||||
colsTypeMap := util.ToColumnTypeMap(columns) | ||||||||||
|
||||||||||
|
@@ -93,7 +93,7 @@ func genDBDelete(schema string, table *model.TableInfo, row []byte) (names []str | |||||||||
return nil, nil, errors.Trace(err) | ||||||||||
} | ||||||||||
|
||||||||||
columns, values, err = generateColumnAndValue(columns, columnValues) | ||||||||||
columns, values, err = generateColumnAndValue(columns, columnValues, destDBType) | ||||||||||
if err != nil { | ||||||||||
return nil, nil, errors.Trace(err) | ||||||||||
} | ||||||||||
|
@@ -144,33 +144,35 @@ func TiBinlogToTxn(infoGetter TableInfoGetter, schema string, table string, tiBi | |||||||||
|
||||||||||
switch mutType { | ||||||||||
case tipb.MutationType_Insert: | ||||||||||
names, args, err := genDBInsert(schema, pinfo, info, row) | ||||||||||
names, args, err := genDBInsert(schema, pinfo, info, row, loader.MysqlDB) | ||||||||||
if err != nil { | ||||||||||
return nil, errors.Annotate(err, "gen insert fail") | ||||||||||
} | ||||||||||
|
||||||||||
dml := &loader.DML{ | ||||||||||
Tp: loader.InsertDMLType, | ||||||||||
Database: schema, | ||||||||||
Table: table, | ||||||||||
Values: make(map[string]interface{}), | ||||||||||
Tp: loader.InsertDMLType, | ||||||||||
Database: schema, | ||||||||||
Table: table, | ||||||||||
Values: make(map[string]interface{}), | ||||||||||
DestDBType: loader.MysqlDB, | ||||||||||
} | ||||||||||
txn.DMLs = append(txn.DMLs, dml) | ||||||||||
for i, name := range names { | ||||||||||
dml.Values[name] = args[i] | ||||||||||
} | ||||||||||
case tipb.MutationType_Update: | ||||||||||
names, args, oldArgs, err := genDBUpdate(schema, pinfo, info, row, canAppendDefaultValue) | ||||||||||
names, args, oldArgs, err := genDBUpdate(schema, pinfo, info, row, canAppendDefaultValue, loader.MysqlDB) | ||||||||||
if err != nil { | ||||||||||
return nil, errors.Annotate(err, "gen update fail") | ||||||||||
} | ||||||||||
|
||||||||||
dml := &loader.DML{ | ||||||||||
Tp: loader.UpdateDMLType, | ||||||||||
Database: schema, | ||||||||||
Table: table, | ||||||||||
Values: make(map[string]interface{}), | ||||||||||
OldValues: make(map[string]interface{}), | ||||||||||
Tp: loader.UpdateDMLType, | ||||||||||
Database: schema, | ||||||||||
Table: table, | ||||||||||
Values: make(map[string]interface{}), | ||||||||||
OldValues: make(map[string]interface{}), | ||||||||||
DestDBType: loader.MysqlDB, | ||||||||||
} | ||||||||||
txn.DMLs = append(txn.DMLs, dml) | ||||||||||
for i, name := range names { | ||||||||||
|
@@ -179,16 +181,17 @@ func TiBinlogToTxn(infoGetter TableInfoGetter, schema string, table string, tiBi | |||||||||
} | ||||||||||
|
||||||||||
case tipb.MutationType_DeleteRow: | ||||||||||
names, args, err := genDBDelete(schema, info, row) | ||||||||||
names, args, err := genDBDelete(schema, info, row, loader.MysqlDB) | ||||||||||
if err != nil { | ||||||||||
return nil, errors.Annotate(err, "gen delete fail") | ||||||||||
} | ||||||||||
|
||||||||||
dml := &loader.DML{ | ||||||||||
Tp: loader.DeleteDMLType, | ||||||||||
Database: schema, | ||||||||||
Table: table, | ||||||||||
Values: make(map[string]interface{}), | ||||||||||
Tp: loader.DeleteDMLType, | ||||||||||
Database: schema, | ||||||||||
Table: table, | ||||||||||
Values: make(map[string]interface{}), | ||||||||||
DestDBType: loader.MysqlDB, | ||||||||||
} | ||||||||||
txn.DMLs = append(txn.DMLs, dml) | ||||||||||
for i, name := range names { | ||||||||||
|
@@ -225,15 +228,15 @@ func genColumnNameList(columns []*model.ColumnInfo) (names []string) { | |||||||||
return | ||||||||||
} | ||||||||||
|
||||||||||
func generateColumnAndValue(columns []*model.ColumnInfo, columnValues map[int64]types.Datum) ([]*model.ColumnInfo, []interface{}, error) { | ||||||||||
func generateColumnAndValue(columns []*model.ColumnInfo, columnValues map[int64]types.Datum, destDBType int) ([]*model.ColumnInfo, []interface{}, error) { | ||||||||||
var newColumn []*model.ColumnInfo | ||||||||||
var newColumnsValues []interface{} | ||||||||||
|
||||||||||
for _, col := range columns { | ||||||||||
val, ok := columnValues[col.ID] | ||||||||||
if ok { | ||||||||||
newColumn = append(newColumn, col) | ||||||||||
value, err := formatData(val, col.FieldType) | ||||||||||
value, err := formatData(val, col.FieldType, destDBType) | ||||||||||
if err != nil { | ||||||||||
return nil, nil, errors.Trace(err) | ||||||||||
} | ||||||||||
|
@@ -245,13 +248,19 @@ func generateColumnAndValue(columns []*model.ColumnInfo, columnValues map[int64] | |||||||||
return newColumn, newColumnsValues, nil | ||||||||||
} | ||||||||||
|
||||||||||
func formatData(data types.Datum, ft types.FieldType) (types.Datum, error) { | ||||||||||
func formatData(data types.Datum, ft types.FieldType, destDBType int) (types.Datum, error) { | ||||||||||
if data.GetValue() == nil { | ||||||||||
return data, nil | ||||||||||
} | ||||||||||
|
||||||||||
switch ft.Tp { | ||||||||||
case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeNewDate, mysql.TypeTimestamp, mysql.TypeDuration, mysql.TypeNewDecimal, mysql.TypeJSON: | ||||||||||
case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeNewDate, mysql.TypeTimestamp, mysql.TypeNewDecimal, mysql.TypeJSON: | ||||||||||
data = types.NewDatum(fmt.Sprintf("%v", data.GetValue())) | ||||||||||
case mysql.TypeDuration: | ||||||||||
//only for oracle db | ||||||||||
if destDBType == loader.OracleDB { | ||||||||||
return data, errors.New("unsupported column type[time]") | ||||||||||
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.
Suggested change
|
||||||||||
} | ||||||||||
data = types.NewDatum(fmt.Sprintf("%v", data.GetValue())) | ||||||||||
case mysql.TypeEnum: | ||||||||||
data = types.NewDatum(data.GetMysqlEnum().Value) | ||||||||||
|
@@ -264,7 +273,20 @@ func formatData(data types.Datum, ft types.FieldType) (types.Datum, error) { | |||||||||
return types.Datum{}, err | ||||||||||
} | ||||||||||
data = types.NewUintDatum(val) | ||||||||||
case mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob, mysql.TypeBlob: | ||||||||||
//only for oracle db | ||||||||||
if destDBType == loader.OracleDB && isBlob(ft) { | ||||||||||
data = types.NewBytesDatum(data.GetBytes()) | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
return data, nil | ||||||||||
} | ||||||||||
|
||||||||||
func isBlob(ft types.FieldType) bool { | ||||||||||
stype := types.TypeToStr(ft.Tp, ft.Charset) | ||||||||||
if stype == "blob" || stype == "tinyblob" || stype == "mediumblob" || stype == "longblob" { | ||||||||||
glorv marked this conversation as resolved.
Show resolved
Hide resolved
glorv marked this conversation as resolved.
Show resolved
Hide resolved
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.
Suggested change
|
||||||||||
return true | ||||||||||
} | ||||||||||
return false | ||||||||||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,8 @@ import ( | |
"strings" | ||
"time" | ||
|
||
"github.com/pingcap/tidb-binlog/pkg/loader" | ||
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. move this to L34~35 |
||
|
||
//nolint | ||
"github.com/golang/protobuf/proto" | ||
"github.com/pingcap/errors" | ||
|
@@ -137,7 +139,7 @@ func genInsert(schema string, ptable, table *model.TableInfo, row []byte) (event | |
val = getDefaultOrZeroValue(ptable, col) | ||
} | ||
|
||
value, err := formatData(val, col.FieldType) | ||
value, err := formatData(val, col.FieldType, loader.DBTypeUnknown) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
} | ||
|
@@ -173,11 +175,11 @@ func genUpdate(schema string, ptable, table *model.TableInfo, row []byte, canApp | |
for _, col := range columns { | ||
val, ok := newColumnValues[col.ID] | ||
if ok { | ||
oldValue, err := formatData(oldColumnValues[col.ID], col.FieldType) | ||
oldValue, err := formatData(oldColumnValues[col.ID], col.FieldType, loader.DBTypeUnknown) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
} | ||
newValue, err := formatData(val, col.FieldType) | ||
newValue, err := formatData(val, col.FieldType, loader.DBTypeUnknown) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
} | ||
|
@@ -217,7 +219,7 @@ func genDelete(schema string, table *model.TableInfo, row []byte) (event *pb.Eve | |
for _, col := range columns { | ||
val, ok := columnValues[col.ID] | ||
if ok { | ||
value, err := formatData(val, col.FieldType) | ||
value, err := formatData(val, col.FieldType, loader.DBTypeUnknown) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
From L60-63, the
destDBTypeInt
is either MysqlDB or OracleDB, thendestDBTypeInt == loader.MysqlDB || destDBTypeInt == loader.OracleDB
is always trueThere 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.
when downstream is mysql or oracle DB, we need to save appliedTS, if it is not , we do not need to save appliedTS.
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.
The logic has been changed. When
destDBType
ismysql
we shouldn't save applied ts while fortidb
we should save.