-
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
Conversation
[REVIEW NOTIFICATION] This pull request has been approved by:
To complete the pull request process, please ask the reviewers in the list to review by filling The full list of commands accepted by this bot can be found here. Reviewer can indicate their review by submitting an approval review. |
@lichunzhu PTAL |
/run-all-tests |
drainer/translator/mysql.go
Outdated
@@ -31,6 +31,8 @@ import ( | |||
|
|||
const implicitColID = -1 | |||
|
|||
var destDBType = "tidb" |
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.
Can we use an iota for this variable? I'm affray that string type is not accurate and may affect the efficiency.
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.
var destDBType = "tidb" | |
type destDBType int | |
var ( | |
mysql = iota | |
oracle | |
) |
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.
OK,good idea
drainer/translator/mysql.go
Outdated
data = types.NewDatum(fmt.Sprintf("%v", data.GetValue())) | ||
case mysql.TypeDuration: | ||
//only for oracle db | ||
if destDBType == "oracle" { |
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.
ditto
drainer/translator/mysql.go
Outdated
case mysql.TypeDuration: | ||
//only for oracle db | ||
if destDBType == "oracle" { | ||
return data, errors.New("unsupport column type[time]") |
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.
return data, errors.New("unsupport column type[time]") | |
return data, errors.New("unsupport column type[time]") |
drainer/translator/mysql.go
Outdated
//only for oracle db | ||
if destDBType == "oracle" { | ||
stype := types.TypeToStr(ft.Tp, ft.Charset) | ||
if stype == "blob" || stype == "tinyblob" || stype == "mediumblob" || stype == "longblob" { |
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.
Can we just use IsTypeBlob
in parser here?
pkg/loader/model.go
Outdated
if dml.DestDBType == "oracle" { | ||
colName = escapeName(name) | ||
} else { | ||
colName = quoteName(name) | ||
} | ||
value := dml.Values[name] | ||
if value == nil { | ||
fmt.Fprintf(builder, "%s = NULL", escapeName(name)) | ||
if dml.DestDBType == "oracle" { | ||
fmt.Fprintf(builder, "%s = :%d", colName, oracleHolderPos) | ||
oracleHolderPos++ | ||
} else { | ||
fmt.Fprintf(builder, "%s = %s", escapeName(name), genOracleValue(dml.UpColumnsInfoMap[name], value)) | ||
fmt.Fprintf(builder, "%s = ?", colName) | ||
} |
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.
Can we directly write here? colName
seems useless here but will take another copy time.
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.
Yes
pkg/loader/model.go
Outdated
@@ -37,6 +35,11 @@ const ( | |||
DeleteDMLType DMLType = 3 | |||
) | |||
|
|||
const ( | |||
MysqlDB = iota |
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.
Ok
/run-all-tests |
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.
rest LGTM
drainer/sync/mysql.go
Outdated
opts = append(opts, loader.DestinationDBType(destDBType), loader.WorkerCount(worker), loader.BatchSize(batchSize), | ||
loader.SaveAppliedTS(destDBType == "tidb" || destDBType == "oracle"), loader.SetloopBackSyncInfo(info)) | ||
opts = append(opts, loader.DestinationDBType(destDBTypeInt), loader.WorkerCount(worker), loader.BatchSize(batchSize), | ||
loader.SaveAppliedTS(destDBTypeInt == loader.MysqlDB || destDBTypeInt == loader.OracleDB), loader.SetloopBackSyncInfo(info)) |
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, then destDBTypeInt == loader.MysqlDB || destDBTypeInt == loader.OracleDB
is always true
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.
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
is mysql
we shouldn't save applied ts while for tidb
we should save.
drainer/translator/mysql.go
Outdated
@@ -31,6 +31,8 @@ import ( | |||
|
|||
const implicitColID = -1 | |||
|
|||
var destDBType = loader.MysqlDB |
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.
why need a global variable here?
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.
some method use this variable to check downstream DB, i don't like to pass it from one method to another
pkg/loader/model.go
Outdated
const ( | ||
DBTypeUnknown = iota | ||
MysqlDB | ||
OracleDB | ||
) |
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.
const ( | |
DBTypeUnknown = iota | |
MysqlDB | |
OracleDB | |
) | |
type DBType int | |
const ( | |
DBTypeUnknown DBType = iota | |
MysqlDB | |
OracleDB | |
) |
Always use DBType
instead of int
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.
LGTM
/run-all-tests |
drainer/sync/mysql.go
Outdated
opts = append(opts, loader.DestinationDBType(destDBType), loader.WorkerCount(worker), loader.BatchSize(batchSize), | ||
loader.SaveAppliedTS(destDBType == "tidb" || destDBType == "oracle"), loader.SetloopBackSyncInfo(info)) | ||
opts = append(opts, loader.DestinationDBType(destDBTypeInt), loader.WorkerCount(worker), loader.BatchSize(batchSize), | ||
loader.SaveAppliedTS(destDBTypeInt == loader.MysqlDB || destDBTypeInt == loader.OracleDB), loader.SetloopBackSyncInfo(info)) |
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
is mysql
we shouldn't save applied ts while for tidb
we should save.
drainer/translator/mysql.go
Outdated
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 comment
The reason will be displayed to describe this comment to others. Learn more.
return data, errors.New("unsupported column type[time]") | |
return types.Datum{}, errors.New("unsupported column type[time]") |
drainer/translator/mysql.go
Outdated
|
||
func isBlob(ft types.FieldType) bool { | ||
stype := types.TypeToStr(ft.Tp, ft.Charset) | ||
if stype == "blob" || stype == "tinyblob" || stype == "mediumblob" || stype == "longblob" { |
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.
if stype == "blob" || stype == "tinyblob" || stype == "mediumblob" || stype == "longblob" { | |
switch stype: | |
case "blob", "tinyblob", "mediumblob", "longblob": | |
return true |
drainer/translator/pb.go
Outdated
@@ -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 comment
The reason will be displayed to describe this comment to others. Learn more.
move this to L34~35
pkg/loader/model.go
Outdated
fmt.Fprintf(builder, "%s = ?", quoteName(name)) | ||
if dml.DestDBType == OracleDB { | ||
fmt.Fprintf(builder, "%s = :%d", escapeName(name), oracleHolderPos) | ||
oracleHolderPos++ |
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.
To me oracleHolderPos = i + 1
? Can we directly use i + 1 for this?
for i, name := range dml.columnNames() {
pkg/loader/model.go
Outdated
wnames, wargs := dml.whereSlice() | ||
for i := 0; i < len(wnames); i++ { | ||
for i, pOracleHolderPos := 0, oracleHolderPos; i < len(wnames); i++ { |
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.
ditto, is pOracleHolderPos
always equal to i+1
?
sql = builder.String() | ||
return | ||
} | ||
|
||
func (dml *DML) buildWhere(builder *strings.Builder) (args []interface{}) { | ||
func (dml *DML) buildWhere(builder *strings.Builder, oracleHolderPos int) (args []interface{}) { |
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.
However, I'm a bit afraid this combination will make drainer has a lower effiency. We will do a lot of extra if check
however half of them are useless because we won't change destDBType when we runs drainer.
refer: https://zhuanlan.zhihu.com/p/143275246 提前进行分支预测
pkg/loader/model.go
Outdated
@@ -343,14 +323,16 @@ func (dml *DML) oracleDeleteNewValueSQL() (sql string) { | |||
} | |||
} | |||
|
|||
for i := 0; i < len(colNames); i++ { | |||
for i, oracleHolderPos := 0, 1; i < len(colNames); i++ { |
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.
ditto
/run-all-tests |
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.
LGTM
/merge |
This pull request has been accepted and is ready to merge. Commit hash: 4e59a23
|
What problem does this PR solve?
Issue Number: ref #1157
What is changed and how it works?
Using prepare statement method ,when access to oracle
Check List
Tests
Code changes
Side effects
Related changes
tidb-ansible
repositoryRelease note