Data move of module.dependencies.module.catalog_rds.aws_rds_cluster.this to stackit_mariadb_instance.dependencies_catalog_rds_this
Generated by StackToIT. StackToIT moves no data and opens no connection: this is the preparation, run by a person. The document is written from the steps and the checks of the execution plan (execution-plan.json): each section is one step, in the order of the plan, and every sentence, command and check in it is that step's own, so the document holds nothing the plan does not. A command is a template: a placeholder in angle brackets stands for a name, an endpoint or a credential the plan does not hold, and a password is read from the environment, never pasted. StackToIT runs none of them.
Source: module.dependencies.module.catalog_rds.aws_rds_cluster.this (aws_rds_cluster). Target: stackit_mariadb_instance.dependencies_catalog_rds_this.
Steps
| # | Step | Method | Owner |
|---|---|---|---|
| 1 | Method decision. The methods dump-restore (branch A) and own-tool (branch B) are both defined below and none is chosen here: the decision DEC-GEN-CONVERT-DATA-MOVEMENT of the plan chooses <!-- kind: DECISION --> | every method | not stated |
| 2 | Preflight <!-- kind: TARGET --> | every method | Data Architect |
| 3 | Rehearsal <!-- kind: EXTERNAL --> | every method | Data Architect |
| 4 | Write freeze <!-- kind: EXTERNAL; branch: A --> | dump-restore | Migration Owner |
| 5 | Final sync <!-- kind: TARGET; branch: A --> | dump-restore | Data Architect |
| 6 | Reconcile <!-- kind: TARGET; branch: A --> | dump-restore | Data Architect |
| 7 | Clean-up <!-- kind: TARGET; branch: A --> | dump-restore | Data Architect |
| 8 | Write freeze <!-- kind: EXTERNAL; branch: B --> | own-tool | Migration Owner |
| 9 | Final sync <!-- kind: TARGET; branch: B --> | own-tool | Data Architect |
| 10 | Reconcile <!-- kind: TARGET; branch: B --> | own-tool | Data Architect |
Preflight
Step MAN/data/module.dependencies.module.catalog_rds.aws_rds_cluster.this/preflight (data preflight, phase DATA); owner: Data Architect.
What. Close what the plan lists as UNKNOWN, from the move host, with read-only statements; no password goes on a command line (the client prompts for it). Source (mysql --host=<source-host> --port=<source-port> --user=<source-user> --password): SELECT VERSION();, SELECT table_schema, table_collation, COUNT(*) FROM information_schema.tables GROUP BY 1, 2; and the same over information_schema.columns for the collations the columns use, SELECT routine_schema, routine_type, COUNT(*) FROM information_schema.routines GROUP BY 1, 2; and the triggers, events and views the same way, the DEFINER accounts (SELECT DISTINCT definer FROM information_schema.routines, and for the views and events), SELECT user, host, plugin FROM mysql.user ORDER BY 1, 2; and SHOW GRANTS FOR '<user>'@'<host>'; for each (names and plugins, never the authentication string), SELECT @@GLOBAL.sql_mode, @@GLOBAL.time_zone, @@GLOBAL.gtid_mode;, SHOW DATABASES; and the engines and the tables without a primary key (the queries of the check table-engines-and-keys). Target (after the draft is applied and the instance and its service key exist; mysql --host=<target-host> --port=<target-port> --user=<target-user> --password --database=<target-database>): SELECT VERSION();, SELECT @@GLOBAL.sql_mode, @@GLOBAL.time_zone;, SHOW VARIABLES LIKE 'character_set%';, SHOW VARIABLES LIKE 'collation%';, SHOW COLLATION WHERE Collation LIKE 'utf8mb4%0900%'; and SHOW GRANTS;. Check that the move host is in parameters.sgw_acl of the instance (remove it afterwards), reaches both ends and uses the custom port of the instance's service key.
Why. the checks of the plan that are UNKNOWN are closed by these statements before any data moves
Needs. the checks that are UNKNOWN and what closes each: version-gap (closed by: preflight on the source and the target: SELECT VERSION(); and the application's own test suite against a MariaDB instance of the offered series (the rehearsal)); charset-collation (closed by: preflight on the source: SELECT table_schema, table_collation, COUNT() FROM information_schema.tables GROUP BY 1, 2; SELECT character_set_name, collation_name, COUNT() FROM information_schema.columns GROUP BY 1, 2; on the target: SHOW COLLATION WHERE Collation LIKE 'utf8mb4%0900%'; SHOW VARIABLES LIKE 'character_set%'; SHOW VARIABLES LIKE 'collation%'); stored-programs (closed by: preflight on the source: SELECT routine_schema, routine_type, COUNT() FROM information_schema.routines GROUP BY 1, 2; SELECT trigger_schema, COUNT() FROM information_schema.triggers GROUP BY 1; SELECT event_schema, COUNT() FROM information_schema.events GROUP BY 1; SELECT table_schema, COUNT() FROM information_schema.views GROUP BY 1); definer-accounts (closed by: preflight on the source: SELECT DISTINCT definer FROM information_schema.routines UNION SELECT DISTINCT definer FROM information_schema.views UNION SELECT DISTINCT definer FROM information_schema.events, and the definer of every trigger (SHOW TRIGGERS, or mysql.proc where it is readable); on the target: SHOW GRANTS; for the user of the service key); users-and-grants (closed by: preflight on the source (names and the authentication plugin, never the authentication string): SELECT user, host, plugin FROM mysql.user ORDER BY 1, 2; then SHOW GRANTS FOR '<user>'@'<host>'; for each; on the target: SHOW GRANTS; for the user of the service key); sql-mode (closed by: preflight on both sides: SELECT @@GLOBAL.sql_mode; and, on the source, SELECT DISTINCT sql_mode FROM information_schema.routines (the mode each routine was defined with)); time-zone (closed by: preflight on both sides: SELECT @@GLOBAL.time_zone, @@SESSION.time_zone, @@system_time_zone, NOW(), UTC_TIMESTAMP(); on the target also SELECT CONVERT_TZ('2026-01-01 12:00:00', 'UTC', '<zone>');); binlog-format (closed by: preflight on the source: SHOW VARIABLES LIKE 'log_bin'; SHOW VARIABLES LIKE 'binlog_format'; the owner of the source changes the parameter group, and on Aurora MySQL the cluster parameter group (the parameter is static there, so a reboot)); gtid-in-dump (closed by: preflight on the source: SELECT @@GLOBAL.gtid_mode;); table-engines-and-keys (closed by: preflight on the source: SELECT table_schema, engine, COUNT(*) FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys') GROUP BY 1, 2; and the tables without a primary key: SELECT t.table_schema, t.table_name FROM information_schema.tables t LEFT JOIN information_schema.table_constraints c ON c.table_schema = t.table_schema AND c.table_name = t.table_name AND c.constraint_type = 'PRIMARY KEY' WHERE t.table_type = 'BASE TABLE' AND c.constraint_name IS NULL AND t.table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')); target-databases (closed by: preflight on the source: SHOW DATABASES; the names against the default database of the target instance (the name in the connection string of its service key); the customer decides, for each other database, between declaring it in the custom parameter databases of the instance (Portal) and moving its tables into the default database (an application change)); network-acl (closed by: preflight from the move host: mysql --host=<source-host> --port=<source-port> to the source and mysql --host=<target-host> --port=<target-port> to the target (host and port from the connection string of the service key), and the move host's address in the access list for the time of the move)
Done when. every UNKNOWN check of the plan is HOLDS or FAILS; each collation of the source is known on the target or changed, each DEFINER account exists on the target or is settled, and the databases of the source have a place on the target
Risks.
- the move host in the access list is a hole until it is removed at cleanup
- a password typed on a command line stays in the history of the shell
Rollback. nothing changed on either side: read-only statements and, on the target, an empty instance
Rehearsal
Step MAN/data/module.dependencies.module.catalog_rds.aws_rds_cluster.this/rehearsal (data rehearsal, phase DATA); owner: Data Architect.
What. Rehearse the dump and the load into a scratch instance of the same plan and version as the draft's instance (a second STACKIT MariaDB instance, deleted afterwards: the real instance must stay empty for the final load) from a copy of the source (a restore of a snapshot into a scratch RDS or Aurora database, so that production is not loaded): mysqldump --host=<source-host> --port=<source-port> --user=<source-user> --password --single-transaction --routines --triggers --events --set-gtid-purged=OFF --no-tablespaces --databases <database-1> <database-2> --result-file=<dump-file>.sql, then mysql --host=<target-host> --port=<target-port> --user=<target-user> --password --database=<target-database> < <dump-file>.sql 2> load.log into the scratch instance. Note the elapsed time of the dump, of the load and of the verification, read every line of load.log, run the application's own test suite against the scratch instance, and compare the routines, triggers, events and views that were created with the source's. Delete the scratch instance and the dump afterwards.
Why. the transfer lower bound leaves out the load, the index build and the verification, and the throughput into STACKIT MariaDB is not verified; only a rehearsal measures them and shows which statements the target refuses
Needs. the customer's statements in inputs.yaml: source.dataset.size, source.dataset.bandwidth
Done when. the elapsed times are recorded, every error of the load is settled, the application's tests pass against the scratch instance and the write-freeze window is agreed from them
Risks.
- a scratch instance is billed while it exists
Rollback. delete the scratch instance and the dump file; the draft's instance and the source are untouched
Write freeze (dump-restore)
Step MAN/data/module.dependencies.module.catalog_rds.aws_rds_cluster.this/write-freeze/dump-restore (data write freeze, phase CUTOVER); owner: Migration Owner.
What. List who writes (SELECT user, host, db, command, COUNT(*) FROM information_schema.processlist WHERE db IN ('<database-1>', '<database-2>') GROUP BY 1, 2, 3, 4;) and record the connection settings of every client where they can be restored from. Then stop the writers at the application (services, jobs, migrations, cron, replicas that write). Do not make the source read-only and do not change it. Check: SELECT COUNT(*) FROM information_schema.processlist WHERE db IN ('<database-1>', '<database-2>') AND command <> 'Sleep' AND id <> CONNECTION_ID(); is 0.
Why. the source stays read-write and untouched, so the way back needs nothing on the source; with the writers stopped no ALTER, CREATE, DROP, RENAME or TRUNCATE runs during the dump
Needs. the customer's statements in inputs.yaml: source.dataset.downtime
Done when. no client writes to the source
Method. This step belongs to the method export-and-import-with-the-engine-clients of the decision DEC-GEN-CONVERT-DATA-MOVEMENT: the plan carries it out only when that decision is answered with it; until it is answered, the steps of every open method are listed.
Rollback. start the writers again against the source: nothing was changed
Final sync (dump-restore)
Step MAN/data/module.dependencies.module.catalog_rds.aws_rds_cluster.this/final-sync/dump-restore (data final sync, phase CUTOVER); owner: Data Architect.
What. Dump inside the freeze: mysqldump --host=<source-host> --port=<source-port> --user=<source-user> --password --single-transaction --routines --triggers --events --set-gtid-purged=OFF --no-tablespaces --databases <database-1> <database-2> --result-file=<dump-file>.sql. --set-gtid-purged=OFF leaves the GTID statements out, which MariaDB does not take, and --no-tablespaces leaves out the CREATE TABLESPACE statements, which MariaDB does not support for InnoDB. The target instance must be empty before the load (the STACKIT how-to of the restore says so): load the dump with the mysql client, as the user of the instance's service key, into the empty instance: mysql --host=<target-host> --port=<target-port> --user=<target-user> --password --database=<target-database> < <dump-file>.sql 2> load.log, and read every line of load.log. A DEFINER account that does not exist on the target, a collation the target does not know and a database the target does not have are the errors the checks name: each is settled by a person, never by skipping the object.
Why. the dump is a consistent snapshot of the moment it starts; inside the freeze it is the final state of the source
Needs. the customer's statements in inputs.yaml: source.dataset.downtime
Done when. the load finished, every database of the source is in the instance, and every error in load.log is settled
Risks.
- the freeze lasts as long as the dump and the load
- the connection of a session idle for 60 minutes is dropped by the service
Method. This step belongs to the method export-and-import-with-the-engine-clients of the decision DEC-GEN-CONVERT-DATA-MOVEMENT: the plan carries it out only when that decision is answered with it; until it is answered, the steps of every open method are listed.
Rollback. the source is current to the freeze and untouched: put the writers back on it; before another attempt remove what the load wrote into the instance, or recreate it empty (the instance must be empty for the load)
Reconcile (dump-restore)
Step MAN/data/module.dependencies.module.catalog_rds.aws_rds_cluster.this/reconcile/dump-restore (data reconcile, phase CUTOVER); owner: Data Architect.
What. Both sides, with the writers stopped: per-table counts (SELECT CONCAT('SELECT ''', table_schema, '.', table_name, ''' AS tbl, COUNT(*) FROM ', table_schema, '.', table_name, ';') FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys'); and run what it prints; the table_rows of information_schema are estimates, not counts), for each table that matters an aggregate of its content (SELECT COUNT(*), MIN(<key>), MAX(<key>), SUM(<numeric-column>) FROM <schema>.<table>;; a CHECKSUM TABLE value is compared only where both servers have been shown to agree on a sample in the rehearsal), the number of routines, triggers, events and views on each side (the queries of the preflight) and their definitions (SHOW CREATE <type> <name>;), SELECT @@GLOBAL.sql_mode, @@GLOBAL.time_zone; equal where they are meant to be, a TIMESTAMP column and a DATETIME column of one row read in the same session time zone, and one read query the application itself runs on its most important data, <application-query>: the query and the answer are the customer's, the source does not state them. Record GO or NO-GO.
Why. the move is accepted only when the numbers equal on both sides and the objects behave as on the source; a mismatch is a NO-GO
Done when. counts, content aggregates, the objects and the application query agree: GO
Method. This step belongs to the method export-and-import-with-the-engine-clients of the decision DEC-GEN-CONVERT-DATA-MOVEMENT: the plan carries it out only when that decision is answered with it; until it is answered, the steps of every open method are listed.
Rollback. on NO-GO take the rollback without switching anything: the clients still point at the source, which is current to the freeze
Verification: the checks after the transfer
These are the checks the owner makes with the writers stopped before recording GO; the reconcile step in the execution plan states the same checks, with the same ids. A check with no command says why: the plan states no command it cannot back.
- Count on both sides (
table-counts, command): Print one count statement for every base table of the source and of the target, run what it prints on each side, with the writers stopped (the table_rows of information_schema are estimates, not counts). Expected: the same tables with the same number of rows on both sides.
~~~text SELECT CONCAT('SELECT ''', table_schema, '.', table_name, ''' AS tbl, COUNT(*) FROM ', table_schema, '.', table_name, ';') FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys'); ~~~
- Content on both sides (
content-aggregates, command): For each table that matters, take an aggregate of its content on both sides. Expected: the count, the lowest and highest key and the sum are equal on both sides for every table checked.
~~~text SELECT COUNT(*), MIN(<key>), MAX(<key>), SUM(<numeric-column>) FROM <schema>.<table>; ~~~
- Not provided, so left as a placeholder or for the owner to fill in: the key and the numeric column of each table (<key>, <numeric-column>); the tables that matter.
- Content on both sides (
objects-and-settings, command): Compare the routines, triggers, events and views on both sides (their number and their definitions) and the settings that change how they behave: the SQL mode and the time zone; read a TIMESTAMP column and a DATETIME column of one row in the same session time zone. Expected: the objects and their definitions are the same, and the SQL mode and the time zone are equal where they are meant to be.
~~~text SELECT @@GLOBAL.sql_mode, @@GLOBAL.time_zone; SHOW CREATE <type> <name>; ~~~
- Not provided, so left as a placeholder or for the owner to fill in: the routines, triggers, events and views to compare (<type> <name>).
- Application check (
application-check, manual): Run one read the application itself makes on its most important data against the target database and compare its answer with the answer the application gets from the source; then, from a test copy of the application, make one write against the target database and read it back. Expected: the two answers are equal, the write succeeds and the read returns it. - No command: the read and the write are the application's, and the source states neither the query nor the answer. - Not provided, so left as a placeholder or for the owner to fill in: the read the application makes on its most important data and its expected answer; the write the test copy of the application makes. - Rollback limit (
rollback-limit, manual): Record the point after which a rollback loses data. Until the first of the writes that the target database accepts after the switch, a rollback is only the connection settings put back: the source database was not changed after the freeze and is current to it. From that write on, what the target database holds exists only there: it is copied back to the source database with a method rehearsed before the window, or accepted as lost. Once the source database is retired (its retirement step, after the GO and the retention the owner decides) there is nothing to go back to. Expected: before the window the owner records the date until which the source database is kept, the method that copies the writes of the target database back or the decision that they are lost, and who calls the rollback. - No command: how long the source is kept and whether the writes made on the target are copied back or lost are decisions of the owner of the application: the source states neither, so the plan names the limit and no date. - Not provided, so left as a placeholder or for the owner to fill in: the date until which the source database is kept; the method that copies the writes of the target database back, or the decision that they are lost.
Clean-up (dump-restore)
Step MAN/data/module.dependencies.module.catalog_rds.aws_rds_cluster.this/cleanup/dump-restore (data cleanup, phase DECOMMISSION); owner: Data Architect.
What. Only after the target has run in production for the period the customer decides and the way back is no longer wanted: remove the move host from parameters.sgw_acl of the instance; delete the dump file <dump-file>.sql and load.log (the dump holds the data); keep a final snapshot of the source for the retention the customer decides before anything is deleted; delete the scratch instance of the rehearsal if it still exists; and replace the credential of the service key if it was ever on a ticket or in a file.
Why. the move leaves an access-list entry, copies of the data and possibly a scratch instance behind; none of them stays
When. after the owner records GO at the end of the verification, and once the way back is no longer wanted
Done when. no dump file is left, the move host is out of the access list, the scratch instance is deleted and the credentials are replaced where they were exposed
Risks.
- the source is not deleted in the same hour as the cutover
Method. This step belongs to the method export-and-import-with-the-engine-clients of the decision DEC-GEN-CONVERT-DATA-MOVEMENT: the plan carries it out only when that decision is answered with it; until it is answered, the steps of every open method are listed.
Rollback. after the cleanup the way back is the final snapshot of the source; there is no other
Write freeze (own-tool)
Step MAN/data/module.dependencies.module.catalog_rds.aws_rds_cluster.this/write-freeze/own-tool (data write freeze, phase CUTOVER); owner: Migration Owner.
What. List who writes (SELECT user, host, db, command, COUNT(*) FROM information_schema.processlist WHERE db IN ('<database-1>', '<database-2>') GROUP BY 1, 2, 3, 4;) and record the connection settings of every client where they can be restored from. Then stop the writers at the application (services, jobs, migrations, cron, replicas that write). Do not make the source read-only and do not change it. Check: SELECT COUNT(*) FROM information_schema.processlist WHERE db IN ('<database-1>', '<database-2>') AND command <> 'Sleep' AND id <> CONNECTION_ID(); is 0.
Why. the source stays read-write and untouched, so the way back needs nothing on the source; with the writers stopped no ALTER, CREATE, DROP, RENAME or TRUNCATE runs during the dump
Needs. the customer's statements in inputs.yaml: source.dataset.downtime
Done when. no client writes to the source
Method. This step belongs to the method migrate-with-a-tool-of-my-own of the decision DEC-GEN-CONVERT-DATA-MOVEMENT: the plan carries it out only when that decision is answered with it; until it is answered, the steps of every open method are listed.
Rollback. start the writers again against the source: nothing was changed
Final sync (own-tool)
Step MAN/data/module.dependencies.module.catalog_rds.aws_rds_cluster.this/final-sync/own-tool (data final sync, phase CUTOVER); owner: Data Architect.
What. Copy the data of module.dependencies.module.catalog_rds.aws_rds_cluster.this to stackit_mariadb_instance.dependencies_catalog_rds_this with the migration tool or the replication you chose: write its steps, the checks before the move, the freeze window it needs and the way back
Why. the draft creates the instance empty and the plan knows nothing of a tool of your own, so it holds the step and the person who chose the tool writes the steps
Needs. the tool, its steps, the checks before the move, the freeze window and the way back, from the person who runs it
Done when. the data of module.dependencies.module.catalog_rds.aws_rds_cluster.this is in stackit_mariadb_instance.dependencies_catalog_rds_this and the checks of the tool hold
Method. This step belongs to the method migrate-with-a-tool-of-my-own of the decision DEC-GEN-CONVERT-DATA-MOVEMENT: the plan carries it out only when that decision is answered with it; until it is answered, the steps of every open method are listed.
Rollback. the writers are stopped, not removed, and nothing the plan does changes the source database, so the source database is the way back until the reconcile records GO: put the writers back on it; before another attempt drop what the tool wrote into the databases of stackit_mariadb_instance.dependencies_catalog_rds_this (the draft created them empty); check that the tool you chose does not change the source database, since the plan knows nothing of it
Reconcile (own-tool)
Step MAN/data/module.dependencies.module.catalog_rds.aws_rds_cluster.this/reconcile/own-tool (data reconcile, phase CUTOVER); owner: Data Architect.
What. Both sides, with the writers stopped: per-table counts (SELECT CONCAT('SELECT ''', table_schema, '.', table_name, ''' AS tbl, COUNT(*) FROM ', table_schema, '.', table_name, ';') FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys'); and run what it prints; the table_rows of information_schema are estimates, not counts), for each table that matters an aggregate of its content (SELECT COUNT(*), MIN(<key>), MAX(<key>), SUM(<numeric-column>) FROM <schema>.<table>;; a CHECKSUM TABLE value is compared only where both servers have been shown to agree on a sample in the rehearsal), the number of routines, triggers, events and views on each side (the queries of the preflight) and their definitions (SHOW CREATE <type> <name>;), SELECT @@GLOBAL.sql_mode, @@GLOBAL.time_zone; equal where they are meant to be, a TIMESTAMP column and a DATETIME column of one row read in the same session time zone, and one read query the application itself runs on its most important data, <application-query>: the query and the answer are the customer's, the source does not state them. Record GO or NO-GO.
Why. the move is accepted only when the numbers equal on both sides and the objects behave as on the source; a mismatch is a NO-GO
Done when. counts, content aggregates, the objects and the application query agree: GO
Method. This step belongs to the method migrate-with-a-tool-of-my-own of the decision DEC-GEN-CONVERT-DATA-MOVEMENT: the plan carries it out only when that decision is answered with it; until it is answered, the steps of every open method are listed.
Rollback. on NO-GO take the rollback without switching anything: the clients still point at the source, which is current to the freeze
Verification: the checks after the transfer
These are the checks the owner makes with the writers stopped before recording GO; the reconcile step in the execution plan states the same checks, with the same ids. A check with no command says why: the plan states no command it cannot back.
- Count on both sides (
table-counts, command): Print one count statement for every base table of the source and of the target, run what it prints on each side, with the writers stopped (the table_rows of information_schema are estimates, not counts). Expected: the same tables with the same number of rows on both sides.
~~~text SELECT CONCAT('SELECT ''', table_schema, '.', table_name, ''' AS tbl, COUNT(*) FROM ', table_schema, '.', table_name, ';') FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys'); ~~~
- Content on both sides (
content-aggregates, command): For each table that matters, take an aggregate of its content on both sides. Expected: the count, the lowest and highest key and the sum are equal on both sides for every table checked.
~~~text SELECT COUNT(*), MIN(<key>), MAX(<key>), SUM(<numeric-column>) FROM <schema>.<table>; ~~~
- Not provided, so left as a placeholder or for the owner to fill in: the key and the numeric column of each table (<key>, <numeric-column>); the tables that matter.
- Content on both sides (
objects-and-settings, command): Compare the routines, triggers, events and views on both sides (their number and their definitions) and the settings that change how they behave: the SQL mode and the time zone; read a TIMESTAMP column and a DATETIME column of one row in the same session time zone. Expected: the objects and their definitions are the same, and the SQL mode and the time zone are equal where they are meant to be.
~~~text SELECT @@GLOBAL.sql_mode, @@GLOBAL.time_zone; SHOW CREATE <type> <name>; ~~~
- Not provided, so left as a placeholder or for the owner to fill in: the routines, triggers, events and views to compare (<type> <name>).
- Application check (
application-check, manual): Run one read the application itself makes on its most important data against the target database and compare its answer with the answer the application gets from the source; then, from a test copy of the application, make one write against the target database and read it back. Expected: the two answers are equal, the write succeeds and the read returns it. - No command: the read and the write are the application's, and the source states neither the query nor the answer. - Not provided, so left as a placeholder or for the owner to fill in: the read the application makes on its most important data and its expected answer; the write the test copy of the application makes. - Rollback limit (
rollback-limit, manual): Record the point after which a rollback loses data. Until the first of the writes that the target database accepts after the switch, a rollback is only the connection settings put back: the source database was not changed after the freeze and is current to it. From that write on, what the target database holds exists only there: it is copied back to the source database with a method rehearsed before the window, or accepted as lost. Once the source database is retired (its retirement step, after the GO and the retention the owner decides) there is nothing to go back to. Expected: before the window the owner records the date until which the source database is kept, the method that copies the writes of the target database back or the decision that they are lost, and who calls the rollback. - No command: how long the source is kept and whether the writes made on the target are copied back or lost are decisions of the owner of the application: the source states neither, so the plan names the limit and no date. - Not provided, so left as a placeholder or for the owner to fill in: the date until which the source database is kept; the method that copies the writes of the target database back, or the decision that they are lost.