This repository was archived by the owner on Jul 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 100
Restore: support restore data from cdc log #482
Merged
Merged
Changes from all commits
Commits
Show all changes
68 commits
Select commit
Hold shift + click to select a range
2891caa
add log restore cmd for cdc log
3pointer 0e345e0
tmp
3pointer 37ff834
move encoder from lightning to br
3pointer 0c2de08
add puller
3pointer d420b26
implement write and ingest
3pointer 29cc906
define flags
3pointer b42680d
add log
3pointer f381b95
fix decoder bug
3pointer 6d48220
fix create ddl bug
3pointer 182c0a4
Merge branch 'master' into log_restore
3pointer d5de731
adapt walkDir
3pointer 87bf634
fix can't found schema in domain
3pointer 85e0a1e
fix panic
3pointer 92f3021
fix next panic
3pointer 40239ee
fix write kv bug
3pointer 5d962d3
more log
3pointer 5532779
fix write failed
3pointer d9da188
fix rowID
3pointer beae903
upate datum
3pointer c96bc69
fix lost data
3pointer f047506
fix size
3pointer 0f823c8
format
3pointer 1c7268b
fix check
3pointer d6bdbcb
fix check
3pointer 2205982
fix Hound
3pointer 7e74044
fix lint
3pointer d040b90
Merge branch 'master' into log_restore
3pointer d0ba5da
add decoder test
3pointer a06b788
fix lint
3pointer 06ca099
make some settings to a config
3pointer d5593c2
address comment
3pointer 92aaad4
Update pkg/restore/cdclog/decoder.go
3pointer a57beb5
address comments
3pointer 25fb5e5
fix build
3pointer 4024d21
reload table info in tableBuffer after ddl executed
3pointer 1adeb58
address comments
3pointer 6f68643
remove useless create ddl logic
3pointer 1309566
reset kv encoder
3pointer eeb4c55
recreate kv encoder
3pointer 6afe56e
add primary table id to do database level ddl
3pointer 9ad5bd9
add allocator to adapt specific table
3pointer 5616667
fix check
3pointer 1828d68
Merge branch 'master' into log_restore
3pointer bc872b7
adapt file sink
3pointer a991db1
log restore: add delete flag deleted kv pair
3pointer 8cb0d48
Merge branch 'master' into log_restore
3pointer 652efc1
update kvproto to lastst
3pointer fffcd5f
address comment
3pointer 1933674
address comment
3pointer 8a05521
add comment for ddl file name
3pointer 432ded5
fix build
3pointer bf17a1f
address some comments
3pointer 1b6de45
reuse br importClient
3pointer 32801d9
fix check
3pointer 84d0d56
try fix parseQuoteName
3pointer a5ccc79
use regexp to parse quote name
3pointer 8123cf4
remove Rows interface
3pointer 674d144
Merge branch 'master' into log_restore
3pointer fa60275
fill the docs
3pointer 1aed603
address comment
3pointer d832f29
hidden log command
3pointer cbd2480
update code folder
3pointer eed7d1c
Merge remote-tracking branch 'origin/master' into log_restore
3pointer 6f0487d
mv common code to kv pkg
3pointer e3a69c1
Merge branch 'master' into log_restore
3pointer f73ef64
adapt master code
3pointer 8454191
address comment
3pointer 3378ccf
address comment
3pointer 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 hidden or 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 hidden or 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
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or 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 |
|---|---|---|
| @@ -0,0 +1,213 @@ | ||
| // Copyright 2020 PingCAP, Inc. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| package cdclog | ||
|
|
||
| import ( | ||
| "time" | ||
|
|
||
| "github.com/pingcap/errors" | ||
| "github.com/pingcap/log" | ||
| "github.com/pingcap/tidb/meta/autoid" | ||
| "github.com/pingcap/tidb/table" | ||
| "github.com/pingcap/tidb/types" | ||
| "go.uber.org/zap" | ||
|
|
||
| "github.com/pingcap/br/pkg/kv" | ||
| ) | ||
|
|
||
| // TableBuffer represents the kv buffer of this table. | ||
| // we restore one tableBuffer in one goroutine. | ||
| // this is the concurrent unit of log restore. | ||
| type TableBuffer struct { | ||
| KvPairs []kv.Row | ||
| count int | ||
| size int64 | ||
|
|
||
| KvEncoder kv.Encoder | ||
| tableInfo table.Table | ||
| allocator autoid.Allocators | ||
|
|
||
| flushKVSize int64 | ||
| flushKVPairs int | ||
|
|
||
| colNames []string | ||
| colPerm []int | ||
| } | ||
|
|
||
| func newKVEncoder(allocators autoid.Allocators, tbl table.Table) (kv.Encoder, error) { | ||
| encTable, err := table.TableFromMeta(allocators, tbl.Meta()) | ||
| if err != nil { | ||
| return nil, errors.Trace(err) | ||
| } | ||
| return kv.NewTableKVEncoder(encTable, &kv.SessionOptions{ | ||
| Timestamp: time.Now().Unix(), | ||
| // TODO get the version from TiDB cluster | ||
| // currently TiDB only support v1 and v2, and since 4.0 | ||
| // the default RowFormatVersion is 2, so I think | ||
| // we can implement the row version retrieve from cluster in the future | ||
| // when TiDB decide to support v3 RowFormatVersion. | ||
| RowFormatVersion: "2", | ||
| }), nil | ||
| } | ||
|
|
||
| // NewTableBuffer creates TableBuffer. | ||
| func NewTableBuffer(tbl table.Table, allocators autoid.Allocators, flushKVPairs int, flushKVSize int64) *TableBuffer { | ||
| tb := &TableBuffer{ | ||
| KvPairs: make([]kv.Row, 0, flushKVPairs), | ||
| flushKVPairs: flushKVPairs, | ||
| flushKVSize: flushKVSize, | ||
| } | ||
| if tbl != nil { | ||
| tb.ReloadMeta(tbl, allocators) | ||
| } | ||
| return tb | ||
| } | ||
|
|
||
| // TableInfo returns the table info of this buffer. | ||
| func (t *TableBuffer) TableInfo() table.Table { | ||
| return t.tableInfo | ||
| } | ||
|
|
||
| // TableID returns the table id of this buffer. | ||
| func (t *TableBuffer) TableID() int64 { | ||
| if t.tableInfo != nil { | ||
| return t.tableInfo.Meta().ID | ||
| } | ||
| return 0 | ||
| } | ||
|
|
||
| // ReloadMeta reload columns after | ||
| // 1. table buffer created. | ||
| // 2. every ddl executed. | ||
| func (t *TableBuffer) ReloadMeta(tbl table.Table, allocator autoid.Allocators) { | ||
| columns := tbl.Meta().Cols() | ||
| colNames := make([]string, 0, len(columns)) | ||
| colPerm := make([]int, 0, len(columns)+1) | ||
|
|
||
| for i, col := range columns { | ||
| colNames = append(colNames, col.Name.String()) | ||
| colPerm = append(colPerm, i) | ||
| } | ||
| if kv.TableHasAutoRowID(tbl.Meta()) { | ||
| colPerm = append(colPerm, -1) | ||
| } | ||
| if t.allocator == nil { | ||
| t.allocator = allocator | ||
| } | ||
| t.tableInfo = tbl | ||
| t.colNames = colNames | ||
| t.colPerm = colPerm | ||
| // reset kv encoder after meta changed | ||
| t.KvEncoder = nil | ||
| } | ||
|
|
||
| func (t *TableBuffer) translateToDatum(row map[string]Column) ([]types.Datum, error) { | ||
| cols := make([]types.Datum, 0, len(row)) | ||
| for _, col := range t.colNames { | ||
| val, err := row[col].ToDatum() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| log.Debug("translate to datum", zap.String("col", col), zap.Stringer("val", val)) | ||
| cols = append(cols, val) | ||
| } | ||
| return cols, nil | ||
| } | ||
|
|
||
| func (t *TableBuffer) appendRow( | ||
| row map[string]Column, | ||
| item *SortItem, | ||
| encodeFn func(row []types.Datum, | ||
| rowID int64, | ||
| columnPermutation []int) (kv.Row, int, error), | ||
| ) error { | ||
| cols, err := t.translateToDatum(row) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| pair, size, err := encodeFn(cols, item.RowID, t.colPerm) | ||
| if err != nil { | ||
| return errors.Trace(err) | ||
| } | ||
| t.KvPairs = append(t.KvPairs, pair) | ||
| t.size += int64(size) | ||
| t.count++ | ||
| return nil | ||
| } | ||
|
|
||
| // Append appends the item to this buffer. | ||
| func (t *TableBuffer) Append(item *SortItem) error { | ||
| var err error | ||
| log.Debug("Append item to buffer", | ||
| zap.Stringer("table", t.tableInfo.Meta().Name), | ||
| zap.Any("item", item), | ||
| ) | ||
| row := item.Data.(*MessageRow) | ||
|
|
||
| if t.KvEncoder == nil { | ||
| // lazy create kv encoder | ||
| log.Debug("create kv encoder lazily", | ||
| zap.Any("alloc", t.allocator), zap.Any("tbl", t.tableInfo)) | ||
| t.KvEncoder, err = newKVEncoder(t.allocator, t.tableInfo) | ||
| if err != nil { | ||
| return errors.Trace(err) | ||
| } | ||
| } | ||
|
|
||
| if row.PreColumns != nil { | ||
| // remove old keys | ||
| log.Debug("process update event", zap.Any("row", row)) | ||
| err := t.appendRow(row.PreColumns, item, t.KvEncoder.RemoveRecord) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| } | ||
| if row.Update != nil { | ||
| // Add new columns | ||
| if row.PreColumns == nil { | ||
| log.Debug("process insert event", zap.Any("row", row)) | ||
| } | ||
| err := t.appendRow(row.Update, item, t.KvEncoder.AddRecord) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| } | ||
| if row.Delete != nil { | ||
| // Remove current columns | ||
| log.Debug("process delete event", zap.Any("row", row)) | ||
| err := t.appendRow(row.Delete, item, t.KvEncoder.RemoveRecord) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| // ShouldApply tells whether we should flush memory kv buffer to storage. | ||
| func (t *TableBuffer) ShouldApply() bool { | ||
| // flush when reached flush kv len or flush size | ||
| return t.size >= t.flushKVSize || t.count >= t.flushKVPairs | ||
| } | ||
|
|
||
| // IsEmpty tells buffer is empty. | ||
| func (t *TableBuffer) IsEmpty() bool { | ||
| return t.size == 0 | ||
| } | ||
|
|
||
| // Clear reset the buffer. | ||
| func (t *TableBuffer) Clear() { | ||
| t.KvPairs = t.KvPairs[:0] | ||
| t.count = 0 | ||
| t.size = 0 | ||
| } |
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.
Uh oh!
There was an error while loading. Please reload this page.