Skip to content
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

Restrict live migration to single table-list and added guardrails for that around table-list flags #2354

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
245034c
Initial changes for hanlding the table names for supporting ddl chang…
priyanshi-yb Feb 20, 2025
28736f3
in case includetable list is not used then use stored list as include…
priyanshi-yb Feb 20, 2025
0fe89a2
changed logic of getting getting registered list to first return obje…
priyanshi-yb Feb 20, 2025
81ebdc7
minor fix
priyanshi-yb Feb 20, 2025
e07e69f
add leaf partititons in include list for guardrails
priyanshi-yb Feb 21, 2025
ce05787
handle the case where only subset of leaf partitions are passed in fl…
priyanshi-yb Feb 24, 2025
f275d35
fix the export data from target case after testing
priyanshi-yb Feb 24, 2025
f09e16f
minor cleanup
priyanshi-yb Feb 24, 2025
65fd658
Report the new leaf tables added upfront on re-run in the command output
priyanshi-yb Feb 25, 2025
c760d92
minor cleanup
priyanshi-yb Feb 25, 2025
f8869de
Minor fix to handle upgrade and resumption in export data, hanlde the…
priyanshi-yb Feb 26, 2025
5da3738
restructured the code in smaller re-usable functions for table-list area
priyanshi-yb Feb 26, 2025
2d132cb
minor change
priyanshi-yb Feb 27, 2025
fa0370d
minor misss for first run in export data from target
priyanshi-yb Feb 27, 2025
90e2dd7
added unit tests for fetchTablesNamesFromSourceAndFilterTableList
priyanshi-yb Feb 27, 2025
36e02eb
fix git tag
priyanshi-yb Feb 27, 2025
d042d3d
clean db after each test
priyanshi-yb Feb 27, 2025
bdd9b39
test for the subsequent run basic
priyanshi-yb Feb 27, 2025
e64f29f
more tests on Subsequent run with basic start-clean true/false cases,…
priyanshi-yb Feb 27, 2025
b842a60
Restructured the code a bit to be able to add more tests for guardrai…
priyanshi-yb Feb 28, 2025
25d97fc
Added Unknown table case as well, by changing the utils.ErrExit funct…
priyanshi-yb Feb 28, 2025
0cd8597
Merge branch 'main' into priyanshi/name-reg-table-name
priyanshi-yb Feb 28, 2025
ccc7316
minor change
priyanshi-yb Feb 28, 2025
e4f8a89
minor change
priyanshi-yb Mar 1, 2025
b034db2
fixed the 'GetRegisteredTableList' function to return only table name…
priyanshi-yb Mar 3, 2025
51db76b
minor miss
priyanshi-yb Mar 3, 2025
a61d355
some review comments
priyanshi-yb Mar 3, 2025
0325e8b
minor comment
priyanshi-yb Mar 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions yb-voyager/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,9 @@ func storeTableListInMSR(tableList []sqlname.NameTuple) error {
}))
err := metaDB.UpdateMigrationStatusRecord(func(record *metadb.MigrationStatusRecord) {
record.TableListExportedFromSource = minQuotedTableList
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: minQuotedTableList -> minQuotedTableListWithRoots

record.SourceExportedTableListWithLeafPartitions = lo.Map(tableList, func(t sqlname.NameTuple, _ int) string {
return t.ForOutput()
})
})
if err != nil {
return fmt.Errorf("update migration status record: %v", err)
Expand Down
407 changes: 359 additions & 48 deletions yb-voyager/cmd/exportData.go

Large diffs are not rendered by default.

661 changes: 661 additions & 0 deletions yb-voyager/cmd/exportData_test.go

Large diffs are not rendered by default.

27 changes: 15 additions & 12 deletions yb-voyager/src/metadb/migrationStatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,21 @@ import (
)

type MigrationStatusRecord struct {
MigrationUUID string `json:"MigrationUUID"`
VoyagerVersion string `json:"VoyagerVersion"`
ExportType string `json:"ExportType"`
ArchivingEnabled bool `json:"ArchivingEnabled"`
FallForwardEnabled bool `json:"FallForwardEnabled"`
FallbackEnabled bool `json:"FallbackEnabled"`
UseYBgRPCConnector bool `json:"UseYBgRPCConnector"`
TargetDBConf *tgtdb.TargetConf `json:"TargetDBConf"`
SourceReplicaDBConf *tgtdb.TargetConf `json:"SourceReplicaDBConf"`
SourceDBAsTargetConf *tgtdb.TargetConf `json:"SourceDBAsTargetConf"`
TableListExportedFromSource []string `json:"TableListExportedFromSource"`
SourceDBConf *srcdb.Source `json:"SourceDBConf"`
MigrationUUID string `json:"MigrationUUID"`
VoyagerVersion string `json:"VoyagerVersion"`
ExportType string `json:"ExportType"`
ArchivingEnabled bool `json:"ArchivingEnabled"`
FallForwardEnabled bool `json:"FallForwardEnabled"`
FallbackEnabled bool `json:"FallbackEnabled"`
UseYBgRPCConnector bool `json:"UseYBgRPCConnector"`
TargetDBConf *tgtdb.TargetConf `json:"TargetDBConf"`
SourceReplicaDBConf *tgtdb.TargetConf `json:"SourceReplicaDBConf"`
SourceDBAsTargetConf *tgtdb.TargetConf `json:"SourceDBAsTargetConf"`
TableListExportedFromSource []string `json:"TableListExportedFromSource"`
SourceExportedTableListWithLeafPartitions []string `json:"SourceExportedTableListWithLeafPartitions"` // will be same as `TableListExportedFromSource` for Oracle and MySQL but will have leaf partitions in case of PG
TargetExportedTableListWithLeafPartitions []string `json:"TargetExportedTableListWithLeafPartitions"` // will be the table list for export data from target with leaf partitions

SourceDBConf *srcdb.Source `json:"SourceDBConf"`

CutoverToTargetRequested bool `json:"CutoverToTargetRequested"`
CutoverProcessedBySourceExporter bool `json:"CutoverProcessedBySourceExporter"`
Expand Down
43 changes: 43 additions & 0 deletions yb-voyager/src/namereg/namereg.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package namereg
import (
"errors"
"fmt"
"slices"
"strings"

"github.com/samber/lo"
Expand Down Expand Up @@ -68,6 +69,9 @@ type NameRegistry struct {
// Source replica has same table name list as original source.

params NameRegistryParams

SourceDBSequenceNames map[string][]string
YBSequenceNames map[string][]string
}

func InitNameRegistry(params NameRegistryParams) error {
Expand Down Expand Up @@ -148,6 +152,7 @@ func (reg *NameRegistry) registerSourceNames() (bool, error) {
reg.SourceDBType = reg.params.SourceDBType
reg.initSourceDBSchemaNames()
m := make(map[string][]string)
m1 := make(map[string][]string)
for _, schemaName := range reg.SourceDBSchemaNames {
tableNames, err := reg.params.SDB.GetAllTableNamesRaw(schemaName)
if err != nil {
Expand All @@ -159,11 +164,46 @@ func (reg *NameRegistry) registerSourceNames() (bool, error) {
return false, fmt.Errorf("get all sequence names: %w", err)
}
m[schemaName] = append(m[schemaName], seqNames...)
m1[schemaName] = append(m1[schemaName], seqNames...)
}
reg.SourceDBTableNames = m
reg.SourceDBSequenceNames = m1
return true, nil
}

func (reg *NameRegistry) GetRegisteredTableList() ([]*sqlname.ObjectName, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a comment here on why we implemented this (partitions)

var res []*sqlname.ObjectName
var m map[string][]string // Complete list of tables and sequences
var sequencesMap map[string][]string // only sequence list
var dbType string
var defaultSchemaName string
switch reg.params.Role {
case SOURCE_DB_EXPORTER_ROLE, SOURCE_DB_IMPORTER_ROLE, SOURCE_REPLICA_DB_IMPORTER_ROLE:
m = reg.SourceDBTableNames
sequencesMap = reg.SourceDBSequenceNames
dbType = reg.SourceDBType
defaultSchemaName = reg.DefaultSourceDBSchemaName
if reg.params.Role == SOURCE_REPLICA_DB_IMPORTER_ROLE {
defaultSchemaName = reg.DefaultSourceReplicaDBSchemaName
}
case TARGET_DB_EXPORTER_FB_ROLE, TARGET_DB_EXPORTER_FF_ROLE, TARGET_DB_IMPORTER_ROLE:
m = reg.YBTableNames
sequencesMap = reg.YBSequenceNames
dbType = constants.YUGABYTEDB
defaultSchemaName = reg.DefaultYBSchemaName
}
for s, tables := range m {
for _, t := range tables {
if slices.Contains(sequencesMap[s], t) {
//If its a sequence continue and not append in the registerd list
continue
}
res = append(res, sqlname.NewObjectName(dbType, defaultSchemaName, s, t))
}
}
return res, nil
}

func (reg *NameRegistry) initSourceDBSchemaNames() {
// source.Schema contains only one schema name for MySQL and Oracle; whereas
// it contains a pipe separated list for postgres.
Expand Down Expand Up @@ -191,6 +231,7 @@ func (reg *NameRegistry) registerYBNames() (bool, error) {
yb := reg.params.YBDB

m := make(map[string][]string)
m1 := make(map[string][]string)
reg.DefaultYBSchemaName = reg.params.TargetDBSchema
if reg.SourceDBTableNames != nil && reg.SourceDBType == constants.POSTGRESQL {
reg.DefaultYBSchemaName = reg.DefaultSourceDBSchemaName
Expand All @@ -212,8 +253,10 @@ func (reg *NameRegistry) registerYBNames() (bool, error) {
return false, fmt.Errorf("get all sequence names: %w", err)
}
m[schemaName] = append(m[schemaName], seqNames...)
m1[schemaName] = append(m1[schemaName], seqNames...)
}
reg.YBTableNames = m
reg.YBSequenceNames = m1
return true, nil
}

Expand Down
6 changes: 5 additions & 1 deletion yb-voyager/src/namereg/namereg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,8 @@ func TestNameRegistryStructs(t *testing.T) {
YBTableNames map[string][]string
DefaultSourceReplicaDBSchemaName string
params NameRegistryParams
SourceDBSequenceNames map[string][]string
YBSequenceNames map[string][]string
}{},
},
}
Expand Down Expand Up @@ -692,7 +694,9 @@ func TestNameRegistryJson(t *testing.T) {
` "lower_caps"`,
" ]",
" },",
` "DefaultSourceReplicaDBSchemaName": "SAKILA_FF"`,
` "DefaultSourceReplicaDBSchemaName": "SAKILA_FF",`,
` "SourceDBSequenceNames": null,`,
` "YBSequenceNames": null`,
"}",
}, "\n")

Expand Down
2 changes: 1 addition & 1 deletion yb-voyager/src/utils/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (

var ErrExitErr error

func ErrExit(formatString string, args ...interface{}) {
var ErrExit = func(formatString string, args ...interface{}) {
ErrExitErr = fmt.Errorf(formatString, args...)
formatString = strings.Replace(formatString, "%w", "%s", -1)
fmt.Fprintf(os.Stderr, formatString+"\n", args...)
Expand Down
9 changes: 9 additions & 0 deletions yb-voyager/src/utils/sqlname/nametuple.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"strings"

"github.com/samber/lo"

"github.com/yugabyte/yb-voyager/yb-voyager/src/constants"
)

Expand Down Expand Up @@ -60,6 +61,14 @@ func NewObjectName(dbType, defaultSchemaName, schemaName, tableName string) *Obj
return result
}

func NewObjectNameWithQualifiedName(dbType, defaultSchemaName, objName string) *ObjectName {
parts := strings.Split(objName, ".")
if len(parts) != 2 {
panic(fmt.Sprintf("invalid qualified name: %s", objName))
}
return NewObjectName(dbType, defaultSchemaName, parts[0], unquote(parts[1], dbType))
}

func (nv *ObjectName) String() string {
return nv.MinQualified.MinQuoted
}
Expand Down
Loading