GG-596: Implement checks for ggcheckmigrate - #25
Conversation
dkovalev1
left a comment
There was a problem hiding this comment.
The patch is solid and comprehensive. Special thanks for embedding SQL using separated file. However, some questions arose.
| return false, returnError | ||
| } | ||
|
|
||
| hasCheckFindings, returnError := checkMultiColumnListPartitions(sourceConnection) |
There was a problem hiding this comment.
This is repetitive code, have you considered to make an array of check* functions and call them in a loop?
| LibraryName string `db:"library_name"` | ||
| } | ||
|
|
||
| func runMigrationChecks(sourceConnection *dbconn.DBConn, targetConnection *dbconn.DBConn) (hasFindings bool, returnError error) { |
There was a problem hiding this comment.
Could it be more informative to return a number of successful checks and a number of unsuccessful checks instead of a single bool?
| func DoCheckMigrate() { | ||
| if sourceConnectionPool == nil { | ||
| gplog.SetErrorCode(5) | ||
| panic(fmt.Errorf("The source connection is not initialized")) |
There was a problem hiding this comment.
The Go convention is: "Error strings should not be capitalized (unless beginning with proper nouns or acronyms) or end with punctuation, since they are usually printed following other context. "
See https://go.dev/wiki/CodeReviewComments#error-strings
| @@ -0,0 +1,67 @@ | |||
| SET LOCAL track_counts TO off; | |||
| CREATE SCHEMA __ggcheckmigrate_tmp; | |||
There was a problem hiding this comment.
Is the schema expected to be left after the run? Is the second run allowed? What if someone runs 2 instances in parallel?
| } | ||
|
|
||
| var output strings.Builder | ||
| output.WriteString("Your cluster contains partitioned tables with child partitions, which do not have the parent table's settings defined.\nIn version 7, they will be inherited from the parent table instead of being taken by default.\nYou can recreate following tables with defined setting.\nList of partitioned tables, partitions, and settings with the specified problem:\n") |
There was a problem hiding this comment.
why not use multiline string here?
| SELECT datname::text AS database_name | ||
| FROM pg_catalog.pg_database | ||
| WHERE datallowconn | ||
| AND NOT datistemplate |
There was a problem hiding this comment.
Template database can still be modified by the user and can be worst migrating and checking.
| JOIN unnest(parent_relation.reloptions) po ON true | ||
| LEFT JOIN unnest(child_relation.reloptions) co ON split_part(po, '=', 1) = split_part(co, '=', 1) | ||
| WHERE co IS NULL | ||
| ORDER BY p.schemaname, p.tablename, p.partitionschemaname, p.partitiontablename, po; |
There was a problem hiding this comment.
The query in spec is simpler, with no child_relation and no WHERE co IS NULL
| FROM pg_catalog.pg_class c | ||
| JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace | ||
| WHERE c.relkind IN ('v', 'm') | ||
| AND c.oid >= 16384 |
There was a problem hiding this comment.
Why this checks restrict selection by user objects while neighbor removed_operator_views.sql does not?
| JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace | ||
| JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid AND a.attnum = ANY(p.paratts) | ||
| JOIN pg_catalog.pg_type t ON t.oid = a.atttypid | ||
| JOIN pg_catalog.pg_class child_relation ON child_relation.oid = partition_rule.parchildrelid |
There was a problem hiding this comment.
what is child_relation join for?
There was a problem hiding this comment.
A language created explicitly (CREATE LANGUAGE mypy HANDLER plpython_call_handler) has no template row and is invisible to the check. Resolving through the handler is robust: pg_language.lanplcallfoid → pg_proc.probin = '$libdir/plpython2'.
|
Can we be sure that this is a complete set of potential problems in the migration? |
|
Are the tests against live 6.x schema considered? |
|
Shall we add a single summary line (databases checked / skipped / total findings)? Right now a large run's outcome has to be reconstructed from scattered stderr blocks plus the exit code. |
I think Also, i think I guess this is also relevant to other options as they all use |
Implement checks for ggcheckmigrate
Implement GG6-to-GG7 migration validation in
ggcheckmigrate.The utility now:
--source-database.The implemented checks cover:
EXECUTE ONfunctions.The PR has been tested against live GG6 6.31.0 and GG7 7.5.0 clusters.