Guide for using molt verify to compare source and target databases for schema and row-level consistency after a migration. Use when running verify commands, tuning concurrency/sharding, handling schema mismatches, or validating data integrity post-migration.
Installs into .claude/skills of the current project.
Are you the author of Source A0f41452ded7ef77f20ea91a?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/gutsofpratik-source-a0f41452ded7ef77f20ea91a)
---
name: molt-verify
description: Guide for using molt verify to compare source and target databases for schema and row-level consistency after a migration. Use when running verify commands, tuning concurrency/sharding, handling schema mismatches, or validating data integrity post-migration.
compatibility: Requires molt binary. Source and target DBs must be accessible. Oracle requires CGO build.
metadata:
author: cockroachdb
version: "1.0"
---
# molt verify
Compares source and target databases for schema (DDL) and row (data) consistency. Run after `molt fetch` to confirm migration integrity.
## Basic Structure
```bash
molt verify \
--source "<source-conn>" \
--target "<crdb-conn>" \
[options]
```
## Verification Phases
**Phase 1 — Schema:** Compares table presence, columns, types, NOT NULL constraints, and primary key structure.
**Phase 2 — Rows** (default, `--rows=true`): Iterates source rows in PK order and compares against target. Reports missing, extraneous, and mismatched rows per shard.
## Modes
| Mode | Command | Use When |
|------|---------|----------|
| Full (default) | `molt verify --source "..." --target "..."` | Post-migration integrity check |
| Schema-only | `molt verify ... --rows=false` | Fast DDL check; no data I/O |
## Concurrency & Sharding
```bash
# Default: CPU-count tables in parallel, 1 shard/table, 20k rows/batch
molt verify --source "..." --target "..."
# Large tables: parallelize within a single table
molt verify --source "..." --target "..." \
--concurrency 1 --concurrency-per-table 8 --row-batch-size 50000
# Rate-limited (minimize production impact)
molt verify --source "..." --target "..." \
--rows-per-second 1000 --concurrency 2
```
Sharding splits a table's PK range across workers. Supported PK types: INT, FLOAT, DECIMAL, UUID. Falls back to a single full-scan for unsupported types.
## Common Workflows
### 1. Post-migration sanity check
```bash
molt verify \
--source "postgresql://<user>:<password>@pg:5432/db" \
--target "postgresql://root@crdb:26257/db"
```
### 2. Schema-only (CI gate)
```bash
molt verify \
--source "..." --target "..." \
--rows=false --non-interactive --log-file stdout
```
### 3. Filtered verification (subset of tables)
```bash
molt verify \
--source "..." --target "..." \
--table-filter "customers|orders"
```
### 4. Verify with column exclusions
```bash
# transformations.json: {"tables":[{"name":"users","excludedColumns":["temp_col"]}]}
molt verify \
--source "..." --target "..." \
--transformations-file transformations.json
```
## Source-Specific Prerequisites
**PostgreSQL**: No special requirements. Partition tables (child partitions) are not supported — remove them before verifying.
**MySQL**: Queries current database only. `ONLY_FULL_GROUP_BY` may affect queries; disable if issues arise.
**Oracle**: Binary must be built with `CGO_ENABLED=1 -tags="cgo source_all"`. Oracle Instant Client in `LD_LIBRARY_PATH`. Use `--source-cdb` for multi-tenant (CDB) setups. Selective data verification (`--filter-path`) is not supported.
## Output & Reporting
Each table prints a summary per shard:
```
truth rows seen: 10000, success: 9950, missing: 5, mismatch: 45, extraneous: 0
```
- **missing**: rows present on source but absent on target
- **extraneous**: rows on target with no match on source
- **mismatch**: rows present on both but values differ
Schema issues (missing/extra tables or columns, type mismatches, PK differences) are logged as warnings and do not stop row verification.
Prometheus metrics available at `--metrics-listen-addr` (default `127.0.0.1:3030`).
## Error Recovery
| Error | Cause | Fix |
|-------|-------|-----|
| `missing table X on target` | Table not migrated | Rerun fetch or check filters |
| `extraneous table X on target` | Unexpected table | Clean up or adjust `--table-filter` |
| `column type mismatch` | Type conversion issue | Check type mappings or use `--transformations-file` |
| `PRIMARY KEY does not match` | PK structure differs | Inspect schema conversion output |
| `partition table X` | Source has partition tables | Drop/move partitions before verifying |
| `missing a PRIMARY KEY` | No PK on source table | Add PK or use `--rows=false` |
| `TLSModeDisableError` | Insecure connection rejected | Add `--allow-tls-mode-disable` |
| Statement timeout | Query exceeds `--verify-statement-timeout` | Increase timeout or reduce `--row-batch-size` |
## Gotchas
- Schema changes between source and target after migration are not automatically reconciled — fix schema first, then re-run
- `--concurrency` values exceeding 4× CPU count trigger a warning and may degrade performance
- Row verification requires primary keys on both source and target tables; tables without PKs are skipped for row comparison
- `--filter-path` (selective row filters) is not supported for Oracle sources
- Log files contain sensitive query data; avoid `--show-connection-logging` in production logs
- After fetch, always run verify before cutover to confirm data integrity
See [flags reference](references/flags.md) for the full flag list.