-
Notifications
You must be signed in to change notification settings - Fork 76
Composite key pagination support for ghostferry #420
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
base: main
Are you sure you want to change the base?
Conversation
| } | ||
|
|
||
| func (t *TableSchema) paginationKeyColumn(cascadingPaginationColumnConfig *CascadingPaginationColumnConfig) (*schema.TableColumn, int, error) { | ||
| func (t *TableSchema) getPaginationKeyColumns(cascadingPaginationColumnConfig *CascadingPaginationColumnConfig) ([]*schema.TableColumn, []int, error) { |
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.
Not sure if that's the right place, though all composite columns should be checked for *_bin collation (#422 does this for non-integer PKs in the parent PR)
| "table": c.Table.String(), | ||
| "tag": "cursor", | ||
| }) | ||
| c.paginationKeyColumn = c.Table.GetPaginationColumn() |
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.
Let's check if this field can be removed 👀
| return t.PaginationKeyColumns | ||
| } | ||
|
|
||
| // Deprecated: Use GetPaginationKeyIndexes |
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 remove the fns that got marked as deprecated?
| } | ||
| } else if cascadingPaginationColumnConfig != nil { | ||
| // Fallback | ||
| if fallbackColumnName, ok := cascadingPaginationColumnConfig.FallbackPaginationColumnName(); ok { |
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.
I think in case fallback columns are specified that are not the primary key, ghostferry must fail unless there exists a unique index that spans them (in the right order)
Summary
This PR adds support for tables with composite primary keys (multi-column PKs) in Ghostferry's data migration process. Previously, Ghostferry only supported tables with single-column numeric primary keys. This PR is developed on top of another PR - Pagination beyond uint64
This is a large PR so please let me know if I should break it down to smaller ones.
Key Changes
Core Pagination Key Types (
pagination_key.go)CompositeKeytype: A slice ofPaginationKeyobjects for multi-column keysMinPaginationKey/MaxPaginationKeyfunctions that handle both single and composite keysTable Schema Detection (
table_schema_cache.go)GetPaginationColumns()returns all PK columns (replaces single-columnGetPaginationColumn())Cursor & Data Iteration (
cursor.go,data_iterator.go)(col1, col2) > (?, ?)ORDER BY col1, col2State Management (
state_tracker.go)CompositeKey.NumericPosition()uses first column as heuristic).Verifiers (
iterative_verifier.go,inline_verifier.go,compression_verifier.go)WHERE (k1, k2) IN ((?, ?), ...)Sorter (
data_iterator_sorter.go)MaxPaginationKeySorterhandles mixed key types without panickingTest
✅
dev testpass (unit tests and integration tests)✅ New integration tests are added for composite key support (with 2 columns, 3 columns).
Backward Compatibility