Documentation menu

Version 3.0.0

Preflight Checks

The checks GoArchive runs before any data moves, which command runs which, and the warnings preflight reports.

Preflight runs before any tracking state is written, and before any row is read for copying or deleting. archive, purge and copy-only run it at startup with their own accounts. validate, for every job or one with --job, and dry-run run it on demand. A passing validate is not carried forward to a later run.

Preflight reads every schema, privilege and replication fact through dbsgomysql , DBS Medya’s MySQL fact library, and GoArchive applies its own rules to those facts.

How preflight works

The checks that run follow the job’s job_type, under validate and dry-run too: a purge job is never asked for destination tables. Checks run in a fixed order and stop at the first failure, so fixing one can reveal the next. validate reports each job as PASSED or FAILED and goes on to the next job.

A failure names the check, says what is wrong, and lists the tables concerned:

PK_COLUMN_CHECK: The configured primary_key must list the PRIMARY KEY's columns, all of them, in
key order (tables: [order_lines(primary_key (id) but the PRIMARY KEY is (order_id, line_no))])

Preflight also computes each key-addressed statement’s cap, the most keys it carries, and fails when a cap cannot be computed. validate and dry-run print the caps; a run logs one Statement cap: line per statement.

Which checks run for which command

In run order. βœ… = enforced, ❌ = not run. validate and dry-run run the column of the job’s type.

Checkarchivepurgecopy-only
TABLE_EXISTENCE_CHECKβœ…βœ…βœ…
PRIMARY_KEY_CHECKβœ…βœ…βœ…
KEY_TYPE_UNSUPPORTEDβœ…βœ…βœ…
PK_COLUMN_CASE_CHECKβœ…βœ…βœ…
PK_COLUMN_CHECKβœ…βœ…βœ…
STORAGE_ENGINE_CHECKβœ…βœ…βœ…
RELATION_KEY_CHECKβœ…βœ…βœ…
FK_INDEX_CHECKβœ…βœ…βœ…
JOB_SCHEMA_PERMISSION_CHECKβœ…βœ…βœ…
DEST_TABLE_EXISTENCE_CHECKβœ…βŒβœ…
DEST_STORAGE_ENGINE_CHECKβœ…βŒβœ…
COLUMN_CHARSET_CHECKβœ…βœ…βœ…
DEST_KEY_IDENTITY_CHECKβœ…βŒβœ…
DEST_SCHEMA_COMPATIBILITY_CHECKβœ…βŒβœ…
DEST_WRITE_PERMISSION_CHECKβœ…βŒβœ…
DEST_INSERT_TRIGGER_VISIBILITY_CHECKβœ…βŒβœ…
DEST_INSERT_TRIGGER_CHECKβœ…βŒβœ…
FK_COVERAGE_VISIBILITY_CHECKβœ…βœ…βŒ
FK_COVERAGE_CHECKβœ…βœ…βœ…
INTERNAL_FK_COVERAGEβœ…βœ…βœ…
FK_PAIRING_CHECKβœ…βœ…βœ…
SELF_FK_DELETE_RULE_CHECKβœ…βœ…βŒ
SOURCE_SELECT_PERMISSION_CHECKβœ…βœ…βœ…
SOURCE_DELETE_PERMISSION_CHECKβœ…βœ…βŒ
DELETE_TRIGGER_VISIBILITY_CHECKβœ…βœ…βŒ
DELETE_TRIGGER_CHECKβœ…βœ…βŒ
MAX_ALLOWED_PACKET_CHECKβœ…βœ…βœ…
  • Purge copies nothing, but its tracking tables live in the destination’s job_schema, so it still connects to the destination and runs JOB_SCHEMA_PERMISSION_CHECK.
  • Copy-only deletes nothing, so no cascade can fire. It skips the foreign-key visibility proof, the self-reference delete rule, the delete permission and the DELETE-trigger checks. It still runs FK_COVERAGE_CHECK, but without PROCESS that check sees only the foreign keys the account can read.
  • Connection checks run before preflight, for every command that connects (archive, purge, copy-only, validate, dry-run).

The checks by group: Connection Checks , Source Structure and Key Checks , Destination Checks , Foreign Key Checks , and Permission, Trigger and Server Variable Checks .

Warnings

Logged, never fatal:

  • ON DELETE CASCADE between two job tables, for archive and purge jobs. GoArchive deletes children first itself, so a cascade is redundant work outside its ordering. Verify that it is intended.
  • A relation declared by several foreign keys with the same columns and pairing: one advisory naming them. It is redundant and harmless to the job.
  • Schema advisories: a collation difference outside the keys and destination unique indexes, a charset difference under sha256 verification, column names that differ only in letter case, and a column order that differs from the source’s (Destination Checks ).
  • A JSON column under verification: count or none, for archive and copy-only jobs: one WARNING: naming every JSON column of the job’s source tables, and every destination column that is JSON where its same-named source column is not. A JSON value is copied as its printed text, so a member’s type is not kept and some values can change, and neither mode compares values. The run proceeds; to have such a change refused, use verification: sha256.

Preflight logs these at warning level under every command, so logging.level: error hides them. The JSON warning is the exception: like the other warnings before a run, it prints on stderr whatever the log level.

Error prefixes that are not checks

These can appear in preflight output. They are not checks and do not point at your schema or grants: they mean GoArchive and its fact library disagree, and preflight refuses rather than guess. Report them with the full message.

PrefixMeaning
PREFLIGHT_INSPECTION_INTEGRITYAn inspection result was internally inconsistent
PREFLIGHT_UNEXPECTED_FACTSA check arrived carrying facts of the wrong type
PREFLIGHT_UNKNOWN_FINDINGThe library returned a check GoArchive does not recognise
PREFLIGHT_UNEXPECTED_DIFFA schema difference GoArchive’s inspection cannot produce
PREFLIGHT_UNKNOWN_DIFFA schema difference kind GoArchive does not recognise

preflight <stage> inspection failed: <cause> is different: a database failure, such as a lost connection or a query error, while reading facts. Diagnose the cause.

These run-time failures are not preflight checks either, and stay active when preflight is bypassed:

IdentifierMeaning
TEMPORAL_READ_CONTRACTA temporal value, its metadata, or a key identity could not be established (Limitations )
INSERT_DIAGNOSTIC_REJECTEDAn INSERT raised a condition GoArchive does not accept; the message carries its code, level and a bounded preview (Batch Processing )
INSERT_DIAGNOSTICS_UNPROVENAn INSERT’s diagnostics could not be read completely

Bypassing preflight

--skip-dangerously-validate-preflight-allow-experimental is accepted by archive, purge, copy-only and dry-run, on the command line only: no configuration key sets it. A run prints a warning before it starts:

WARNING: --skip-dangerously-validate-preflight-allow-experimental: preflight's policy checks are skipped (storage
engines, permissions, triggers, foreign-key coverage, destination compatibility, packet size).
The keys are still read from MySQL; a run still checks the job's log key and binding. A misspelled
foreign_key column fails as a statement-caps error instead of RELATION_KEY_CHECK.

Still enforced on a run: the connection checks , PRIMARY_KEY_CHECK, KEY_TYPE_UNSUPPORTED, COLUMN_CHARSET_CHECK, the statement caps (computed from the source keys and, for archive and copy-only, the destination keys, which must be readable), the job’s startup checks, and the run-time guards above. The JSON warning is still printed. Every other check in the table above is skipped, TABLE_EXISTENCE_CHECK, PK_COLUMN_CHECK, RELATION_KEY_CHECK and FK_INDEX_CHECK included.

dry-run prints the same warning, but it never reads the tracking tables, so it does not test the job’s registration or binding: a dry-run that passes does not promise the run will start. validate has no skip flag.

The flag skips the permission checks, not the need for the privileges: a missing SELECT, DELETE or INSERT then fails during the run, while a missing TRIGGER fails nothing and the run proceeds with triggers it cannot see.

Use it only to recover from an incident, after verifying the schema by hand. It is also the only way to run against a destination engine other than InnoDB, which GoArchive does not test or support: such a table keeps its rows when a batch rolls back, so a failed batch leaves orphan rows there. The old name, --skip-validate-preflight, is refused.