Search docs.molo17.com

    Validator

    Overview

    How-to guide

    For step-by-step walkthroughs tested on a running Gluesync, see Validate data with the Validator (filters, date and time conversions, edge cases) and Find and fix row differences between source and target.

    Validator compares one replicated entity with the table or collection it is written to. It reports rows that exist only on the source, rows that exist only on the target, rows whose values differ, and schema differences. From the same screen you can write the source values back to the target (reconcile) or leave the differences in place and alert on them.

    Open it from the Control Plane navigation, from an entity’s overflow menu (Validate), or from the entity detail Inspect tables actions. Those links open /data-comparison with pipelineId and entityId already selected.

    Validator compares one entity at a time. A pipeline-wide check is a sequence of entity runs, which is how Chronos schedules it.

    What a run compares

    Each run walks the source and the target in the same key order and records:

    Difference Meaning

    MISSING_IN_TARGET

    The key exists on the source and not on the target. Reconciliation inserts the source row.

    MISSING_IN_SOURCE

    The key exists on the target and not on the source. Reconciliation deletes the target row.

    ROW_MISMATCH

    The key exists on both sides and at least one compared column differs. Reconciliation updates the target from the source.

    SCHEMA_MISMATCH

    A column cannot be compared (missing, or a type that cannot be aligned). Schema differences are counted and are not rewritten as row fixes.

    A finished run is one of:

    Status Meaning

    PENDING

    Accepted, not started.

    RUNNING

    Scanning.

    COMPLETED

    Finished with no differences.

    COMPLETED_WITH_WARNINGS

    Finished, and at least one difference was stored. A run also ends with this status when it stopped at the difference limit, or when a count-only run found different row counts. See Statuses in the Control Plane.

    FAILED

    The run stopped on an error. errorCode and errorMessage are on the summary.

    CANCELLED

    Stopped before completion. Cancelling does not emit a terminal validation event.

    Run it from the Control Plane

    1. Open Validator and pick the pipeline and entity. The source agent, target agent, and primary key are taken from the entity.

    2. Optionally narrow the compared columns, add a WHERE filter per side, or set ordering expressions when the key type needs an explicit cast.

    3. Start the run. The summary shows rows scanned and the four difference counters.

    4. Open a difference to see the key and the column values. Mismatched cells are marked on the row.

    5. Select differences and reconcile them, or reconcile the whole run. Counters update as fixes are applied.

    Reconcile writes to the target. It does not change the source.

    What the results mean

    A run shows a status, a set of counters, a grid of differences, and sometimes a list of notices. Every run of the entity is also listed in Run history at the bottom of the page. Select a run to read it.

    The run summary

    Field in the Control Plane Meaning Name in the API

    Status badge

    Where the run is. See Statuses in the Control Plane.

    status

    Run

    The first part of the run’s job id. Hover over it to see the whole id.

    jobId

    Started, Took

    When the run started and how long it ran. While the run is active, Took reads In progress.

    startedAt, endedAt

    Source rows scanned, Target rows scanned

    Rows read so far on each side, then the total each side held when the run started, for example 190 / 190. While the run is active, a progress bar shows the rows read out of the rows to read.

    sourceRowsScanned, targetRowsScanned, sourceRowsCount, targetRowsCount

    Source only

    Keys that exist in the source and not in the target. The target is missing the row.

    missingInTargetCount

    Target only

    Keys that exist in the target and not in the source. The target holds a row that the source no longer has, or never had.

    missingInSourceCount

    Rows that differ

    Keys that exist on both sides with at least one different value in a compared column.

    rowMismatchesCount

    Schema differences

    Columns that cannot be compared: missing on one side, or with types that cannot be aligned. Notices are not counted here.

    schemaDifferencesCount

    Extra in target

    Rows that the target holds and that the pipeline would never have written, because the entity’s filter or its UDF leaves them out.

    extraInTargetCount

    Not written by the pipeline

    Source rows that the pipeline does not write, because the entity’s filter or its UDF drops them. They are expected to be absent from the target, so they are not differences.

    filteredOutCount

    Duplicate keys

    Comparison keys that more than one row holds on one side.

    duplicateKeysCount

    NULL keys

    Rows with a NULL in a comparison key column. They cannot be matched with the other side.

    unjoinableNullKeyCount

    Transient, discarded

    Differences that were gone when Validator read them again, for example rows the pipeline was still writing. They are not reported.

    transientDifferencesDiscarded

    The summary shows a dash when a counter has no value. The Run history table lists the same counters as columns: Status, Run, Started, Duration, Source rows, Target rows, Source only, Target only, Diff, Extra, and Schema. Hover over a status in that table to read the error of a failed run.

    A run does not refresh after you reconcile. The grid shows the old rows until you start a new run.

    Count-only runs

    A run with Count only on reads no row. The summary shows Source rows, Target rows, a row-count line, and Schema differences. The row-count line reads More rows in source, More rows in target, or Row count difference when the counts are equal. The counters for missing and mismatching rows are not computed, and Run history shows a dash for them.

    When the two counts differ, the run ends as Completed with warnings. The message under the status badge gives both counts and their difference. Run a full comparison, without Count only, to list the rows.

    When the entity’s pipeline has a filter or a UDF that drops rows, the message says so instead. The two counts differ even when the data matches, and only a full comparison tells you which rows are missing.

    Statuses in the Control Plane

    Badge What you see

    Pending, Running

    A progress bar with the rows read so far (Counting rows before the scan before the first read), and Cancel run. Differences are available when the run ends.

    Completed

    No differences found: source and target are in sync for the compared columns and rows.

    Completed with warnings

    One of four cases: the run found differences, found schema differences, stopped at the difference limit, or was a count-only run with different counts. Open the grid. A message under the badge explains the last two cases.

    Failed

    A red message with an error code and the error text. See Error codes on a failed run.

    Cancelled

    This run was cancelled. No differences were recorded. Start a new run.

    Error codes on a failed run

    The red message of a failed run shows the errorCode as its title and the errorMessage as its text. The same two fields are on the run summary in the API.

    errorCode When it appears

    INTERNAL_ERROR

    The run hit an error that is not one of the cases below. The text is the message of the database or of the agent, for example [SQL0206] Column or global variable _RRN not found.

    QUERY_TIMEOUT

    The run exceeded Max runtime (seconds): Job timed out after <n>s.

    RUNTIME_LIMIT_REACHED

    The run stopped at its runtime limit: Runtime limit reached (<n> seconds). Job aborted.

    OrderingViolation

    One side returned its keys in an order the run does not expect: <Source or Target> stream key out of order.

    SchemaIncompatible

    A column of the mapping is not in a table, for example Column '<name>' (mapped to '<target name>') not found in target table <table>.

    ConcurrencyConflict

    A run is already active for the entity, or five comparison jobs already run on Core Hub.

    DuplicateComparisonKey, NullComparisonKey

    The run asked for Validate key uniqueness or refuses NULL keys, and the data breaks the rule.

    UnsupportedConnector

    The source or target agent cannot compare data.

    ConnectionFailed

    Validator could not open its own connection to the database of an agent.

    PermissionDenied

    Your role or the data access policy does not allow the comparison.

    Differences in the grid

    The grid shows the Source table on the left and the Target table on the right. For a key that exists on both sides, the cells that differ are marked. Hover over the tag of a row to read its description.

    Tag in the grid Name in the API Meaning What Reconcile does

    Source only

    MISSING_IN_TARGET

    The row is in the source and missing in the target.

    Inserts the source row.

    Target only

    MISSING_IN_SOURCE

    The row is in the target and missing in the source.

    Deletes the target row.

    Differs

    ROW_MISMATCH

    The row is on both sides with different values.

    Updates the target row with the source values.

    Extra in target

    EXTRA_IN_TARGET

    The target holds a row that the pipeline would never have written.

    Deletes it only when Delete target rows the entity filter excludes is ticked in the options. Otherwise it skips the row.

    Duplicate key

    DUPLICATE_KEY

    More than one row has this comparison key. Pick a unique key to compare these rows.

    Nothing. The row is reported, not fixed.

    NULL key

    UNJOINABLE_NULL_KEY

    A comparison key column is NULL, so the row cannot be matched with the other side.

    Nothing. The row is reported, not fixed.

    The three Operations allowed when reconciling options limit what Reconcile may write. A row that an option forbids is skipped, and it stays in the run.

    Schema differences

    When a column cannot be compared, a card named Schema differences detected lists it with these columns: Column, Issue, Source definition, Target definition, and Discrepancy. The issue is one of:

    Issue Meaning

    Missing in target

    The column is in the source and not in the target table.

    Missing in source

    The column is in the target and not in the source table.

    Type mismatch

    The two types differ.

    Types not comparable

    The run cannot align the two types, so it leaves the column out.

    Reconcile does not rewrite schema differences.

    Notices

    A notice says how a column was compared, or why it was not. It is not a difference and it is not counted. The Notices card lists the column, the notice, and a detail. Notices you may see:

    Notice Meaning

    Equal within tolerance

    A lenient run counted values as equal that match only under a tolerance of the lenient profile. The detail gives the number of values.

    Compared at lower precision

    The two types cannot be compared as strictly as one of them stores the value. The detail names the types.

    Column skipped by an option

    An option of the run leaves the column out, for example Skip BLOB / CLOB columns.

    Target-only column not compared

    A column that exists only in the target is not compared.

    Reader warning

    A warning from the database reader. For example, a text key is ordered with a forced binary collation, so that both sides sort the keys the same way. The warning also names an index that speeds the run up.

    Row count not predictable

    The pipeline drops rows with a filter or a UDF, so the two counts differ even when the data matches.

    Difference limit reached

    The run stopped at Max differences. The rows after that point were not compared.

    Large object truncated, Large object not read

    A large object was cut or could not be read, so its comparison is partial.

    REST API

    All routes are on Core Hub. The caller’s role still applies (view, view differences, reconcile, cancel).

    Start a run

    POST /data-comparison/runs

    The smallest body is the pipeline and the entity:

    {
      "pipelineId": "pipeline-id",
      "entityId": "entity-id"
    }

    When sourceAgentId, targetAgentId, or comparisonKey is omitted or blank, Core Hub fills them from the entity: the source and target agents registered on that entity, and the primary-key columns of the source entity. The Control Plane sends those fields explicitly. Automation (Chronos, MCP) can omit them.

    Optional fields:

    • columns — non-key columns to compare. Default is the mapped columns.

    • columnMapping — source column name to target column name, when the names differ.

    • options — fetchSize (default 10000, max 50000), maxRuntimeSeconds (default 3600, max 86400), maxEmittedDifferences (default 10000, max 50000), countOnly, string and timestamp comparison modes, and reconciliation toggles (reconcileInserts, reconcileDeletes, reconcileUpdates).

    • queryOptions — whereConditionSource, whereConditionTarget, orderBySource, orderByTarget. Ordering values are comma-separated SQL expressions, one per key column, with no ASC, DESC, or NULLS.

    The response is { "jobId", "status": "PENDING", "startedAt" }.

    Read a run

    • GET /data-comparison/runs — list runs. Optional entityId query parameter.

    • GET /data-comparison/runs/{jobId} — one summary: status, row counts, missingInSourceCount, missingInTargetCount, rowMismatchesCount, schemaDifferencesCount, duplicateKeysCount, timestamps, errorCode, errorMessage.

    • GET /data-comparison/runs/{jobId}/differences?limit=&offset= — one page of differences. Each record has id, differenceType, keyJson, and columnDiffsJson.

    • DELETE /data-comparison/runs/{jobId} — cancel a PENDING or RUNNING run, or delete a finished run.

    Reconcile

    POST /data-comparison/runs/{jobId}/reconciliation

    { "reconcileAll": true }

    reconcileAll fixes every remaining difference of that run. Core Hub pages the stored differences itself. Use this from Chronos or any client that should not walk difference ids.

    To fix a selection instead:

    {
      "differenceIds": ["diff-id"],
      "columns": ["status"]
    }

    comparisonKey may be omitted. The key saved with the run is used when it is present. columns limits which mismatched columns are written; omitted means every compared column.

    The response is insertedCount, deletedCount, updatedCount, and skippedCount. A difference is removed only after its write succeeds. A skipped row stays in the run.

    Platform events

    Every run emits CloudEvents that webhook subscriptions, email notifications, and in-app notifications can select. The source of the event is the entity.

    Event Type Severity When

    DATA_VALIDATION_STARTED

    gluesync.validation.started

    INFO

    The run was accepted.

    DATA_VALIDATION_COMPLETED

    gluesync.validation.completed

    INFO

    Status COMPLETED. Source and target match.

    DATA_VALIDATION_DIFFERENCES_FOUND

    gluesync.validation.differences-found

    WARNING

    Status COMPLETED_WITH_WARNINGS.

    DATA_VALIDATION_FAILED

    gluesync.validation.failed

    CRITICAL

    Status FAILED. The message includes errorMessage when Core Hub has one.

    DATA_VALIDATION_RECONCILED

    gluesync.validation.reconciled

    INFO, or WARNING when skippedCount is greater than zero

    A reconcile call inserted, deleted, updated, or skipped rows.

    Terminal event data contains jobId, status, sourceRowsCount, targetRowsCount, sourceRowsScanned, targetRowsScanned, missingInSourceCount, missingInTargetCount, rowMismatchesCount, schemaDifferencesCount, duplicateKeysCount, totalDifferences, startedAt, and, when present, endedAt, errorCode, and errorMessage.

    The reconciled event data contains jobId, insertedCount, deletedCount, updatedCount, skippedCount, and reconcileAll.

    Subscribe to these types from Settings → Notifications or a webhook configuration. The event catalog is served by Core Hub (get_webhook_event_types on the MCP server lists the same names).

    A Chronos job that validates with reconciliation turned off fails the job and stores the difference breakdown as the job error. That failure is what Chronos sends on its own webhook and email path. The platform events above are emitted by Core Hub whether or not Chronos is the caller. See Schedule validation.

    MCP tools

    The embedded MCP server exposes six Validator tools. They call the REST routes above with the caller’s token.

    Tool Category What it does

    trigger_data_comparison

    WRITE

    Starts a run. pipeline_id and entity_id are required. source_agent_id, target_agent_id, and comparison_key are optional.

    list_data_comparison_runs

    READ

    Lists runs, optionally filtered by entity_id.

    get_data_comparison_run

    READ

    Returns one run summary by job_id.

    list_data_comparison_differences

    READ

    Returns one page of differences (limit, offset).

    reconcile_data_comparison_differences

    WRITE

    Reconciles difference_ids, or every remaining difference when reconcile_all is true.

    cancel_data_comparison_run

    WRITE

    Cancels a running job or deletes a finished run.

    These six tools are part of the 142-tool built-in catalog. See Core Hub MCP server.

    Supported connectors

    Validator compares a pair of connectors only when both the source agent and the target agent of the entity can compare data. If one of them cannot, the run does not start. See [connector-not-supported].

    These connectors compare data as a source and as a target:

    • IBM i

    • Db2 LUW (CDC and triggers)

    • Informix

    • MariaDB

    • MySQL

    • Microsoft SQL Server (CDC and Change Tracking)

    • Oracle (CDC, XStream, triggers, and legacy triggers)

    • PostgreSQL

    • SAP HANA

    • SQL Anywhere

    • Sybase (triggers)

    • Vertica

    • YugabyteDB

    • Couchbase

    • MongoDB

    This connector compares data as a source only:

    • Sybase (log reader)

    These connectors compare data as a target only:

    • ClickHouse

    • CockroachDB

    • Databricks

    • Google BigQuery

    • GridGain

    • Amazon Redshift

    • SingleStore

    • Snowflake

    A connector that is not in these lists cannot take part in a run. For those pairs, use Count both on the entity detail page and Query Studio to check counts and data.

    Tables without a primary or logical key

    Validator walks both tables in the order of a comparison key and matches rows by that key. It has no way to match rows without one.

    • The comparison key is the set of key columns of the entity on the source. That is the primary key, or the logical key that you set in Field mapping.

    • The Control Plane fills the key in for you and asks for at least one key column (At least one comparison key is required).

    • A run that has no key, for example one started from the REST API or from Chronos on an entity with no key, is refused with No comparison key provided for entity '<entity id>'.

    What to do:

    1. Give the entity a key before you validate it. Set a logical key on columns that are unique and never NULL, or on IBM i use the relative record number (_RRN). See Choose keys for tables without a primary key.

    2. Check the key. Start a run with Validate key uniqueness on. The run fails with DuplicateComparisonKey if the key is not unique on either side.

    3. Read the Duplicate keys and NULL keys counters of every run. Validator reports those rows and does not fix them. See Differences in the grid.

    A key can still stop the run after you set it:

    • The key columns must have the same ordering on both sides. If the types differ, for example a binary column on the source and a text column on the target, the run fails with SchemaIncompatible and a message such as Comparison key column '<name>' has unsupported key type ('<source type>' / '<target type>') for merge-join ordering. Align the types, choose another key, or set an ordering expression for each side under Advanced: query filters (orderBySource, orderByTarget). A text key needs an expression that casts the text side.

    • A key column that a field function writes holds different values on the two sides. Validator refuses it. Choose a key that no field function writes.

    Sizing for big tables

    Validator does not load a table into memory. It reads the source and the target in pages, in key order, and compares the pages as it goes. Memory use follows the page size, not the table size. These limits apply to a run:

    Limit Default Maximum Where

    Rows per page (fetchSize)

    10000

    50000

    REST API option

    Max runtime (seconds)

    3600

    86400

    Validator options, General, Limits

    Max differences

    10000

    50000

    Validator options, General, Limits

    Comparison jobs at the same time on Core Hub

    5

    5

    Fixed

    Active runs per entity

    1

    1

    Fixed

    What to do for a large table:

    1. Run a Count only run first. It reads no row and tells you whether the counts match. See Statuses in the Control Plane.

    2. Raise Max runtime (seconds) before the first full run. A run that exceeds it fails with QUERY_TIMEOUT. See [query-timeout].

    3. Narrow the rows with a WHERE condition on each side. Validator reads each table in one pass in key order. It does not split a table into parts, so a filter on a key range is how you compare a big table in slices.

    4. Index the key columns on both sides. The Reader warning notice names an index that speeds a run up when it has one to suggest.

    5. Skip BLOB / CLOB columns, which is the default, to keep the pages small.

    6. Do not run a large manual run and a large scheduled job on the same entity at the same time. Spread large jobs over time so that fewer than five run together. See [concurrency-conflict].

    7. For a scheduled job, a run of one entity waits at most SCHEDULER_VALIDATION_TIMEOUT_SECONDS (3600 by default). Raise it together with Max runtime (seconds). See Schedule validation.

    Troubleshooting

    After each fix, start a new run. A run does not refresh itself, so an old failed run stays on the screen until you do. The fix works when the new run ends as Completed, or as Completed with warnings with the counters you expect.

    Problem Possible cause What to do

    A run on an IBM i source fails with INTERNAL_ERROR and [SQL0206] Column or global variable _RRN not found, on an entity whose key is _RRN

    On IBM i, _RRN is the relative record number of a row. It is not a real column of the file. Earlier builds of Validator selected it by name, and Db2 for i refuses that with SQL0206.

    Upgrade Core Hub to the latest Gluesync 2.3 release, which reads the relative record number the way Db2 for i expects. Then start a new run on the entity. If the error stays, check that the run you are reading is the new one, not an old failed run. To use _RRN as a key, read Choose keys for tables without a primary key.

    A run fails with Source stream key out of order: current=…​ < previous=…​ (or Target stream key out of order), mostly on alphanumeric keys of an IBM i table

    The source returned its text keys in a different order than the order Validator expects, so the merge of the two sides cannot continue.

    Upgrade Core Hub to the latest Gluesync 2.3 release. It orders the text keys the same way on both sides. Each run then shows a Reader warning notice that the key column is ordered with a forced binary collation. This notice is expected. The warning also names an index you can create to make the run faster.

    A run fails with SchemaIncompatible and Column '<name>' (mapped to '<target name>') not found in target table <table>, or the Schema differences card shows Missing in target

    The mapping of the entity names a column that the target table does not have. This happens when the column was dropped or renamed on the target, or when the mapping points to the wrong name.

    Check on the target database that the column exists. If it does not, add it, or change the mapping of the entity so that the column points to an existing target column. Then run Validate again.

    A Count only run reads No differences found while the source and the target hold different numbers of rows

    The run used an older Core Hub that ended a count-only run as Completed whatever the counts were.

    Upgrade Core Hub to the latest Gluesync 2.3 release. A count-only run with different counts then ends as Completed with warnings and the message gives both counts and their difference. On the older release, read Source rows and Target rows in the run summary: they show the mismatch even when the status is Completed. To list the rows that differ, run a full validation without Count only.

    Rows that differ lists date and time columns where the target value is a small amount of time away from the source, for example one second

    The two databases store time with a different precision, and the run compares the values as they are.

    Open Validator options. On Columns & rules, search for the column and, under Date & time, choose how to match: Normalize to UTC, Exact match, Ignore fractions of a second, Ignore time, compare date only, or Ignore date and time columns. On Matching, set Comparison profile to Lenient or Strict, and set Temporal precision, the finest unit of time that is compared. Then start a new run and read Rows that differ and Notices.

    After an upgrade, Validate on an entity opens a page that stays on the loading logo (the Validate page does not load). The server logs show no error.

    Validate opens Validator in a new tab at /ui/v2/data-comparison. The browser can serve a copy of that page that it saved before the upgrade. The copy asks for interface files of the previous version, which no longer exist.

    In the tab that stays on the logo, reload without the cache once: press Ctrl+F5 on Windows and Linux, or Cmd+Shift+R on a Mac. If the page still hangs, clear the cached images and files of the site in the browser settings, or open the developer tools with F12, right-click the reload button, and choose Empty cache and hard reload. You can also open Validator from the side navigation or from the entity row, which do not reload the page. Do this once per browser. Core Hub releases after this problem was found tell the browser to check the version of the page each time, so the cached copy is not reused after an upgrade.

    A run on an IBM i source, or a scheduled Validate job, fails at once with [SQL0666] SQL query exceeds specified limit or threshold

    Db2 for i has a query time limit. The Predictive Query Governor refuses a query up front when its estimated runtime is above the limit, and it does not run the query. Older builds handed the query timeout of the run (Max runtime (seconds), 3600 by default) to the governor. A validation of a large table fails before it reads a row.

    Upgrade Core Hub to the latest Gluesync 2.3 release. It cancels a query on wall-clock time when the timeout is reached, so the run starts and compares the table. Then start a new run. If a run still stops with a timeout, see the row about QUERY_TIMEOUT.

    A run fails with QUERY_TIMEOUT and Job timed out after <n>s, or with RUNTIME_LIMIT_REACHED

    The run needed more time than Max runtime (seconds). The default is 3600 seconds and the maximum is 86400.

    In Validator options, General, Limits, raise Max runtime (seconds). For a large table, narrow the rows with a WHERE condition on each side under Advanced: query filters, or compare a sample first. A scheduled job has its own wait limit: see the SCHEDULER_VALIDATION_TIMEOUT_SECONDS variable in the Timeouts section of Schedule validation.

    A scheduled Validate job on many entities ends with a red Last run mark and no error text, or Run now leaves the page frozen, and the entities after the first one were not validated

    Entities of one job run one after another. The first entity that fails, or finds differences with Reconcile differences off, fails the job. The later entities of that run are not started. Three things hide the cause. First, Run now holds one HTTP request open for the whole job, so behind a proxy or ingress with a short timeout (60 seconds is common) the interface gets a gateway timeout while the job keeps running. Second, a second Run now while the first still runs starts an overlapping run of the same entities, which fails with A data comparison job is already running for …​ or Maximum concurrent comparison jobs (5) reached. Third, on an IBM i source each failed entity run can carry [SQL0666] SQL query exceeds specified limit or threshold: see [sql0666-ibm-i].

    Read the error of each entity run in Validator: pick the pipeline and the entity, and read Run history. Hover over the status of a failed run, or select it, to read the error code and the text. The hover text of the Last run mark can be empty in some releases. The error is still in Run history. Do not click Run now a second time: wait for the job to end. Raise the timeout of the proxy in front of Core Hub above the length of the job, or split a large job into several jobs of a few entities each, scheduled apart. Fix the failing entity, or remove it from the job, and run the job again. See Schedule validation for how a job treats differences.

    Validator refuses to start with A data comparison job is already running for …​, or with Maximum concurrent comparison jobs (5) reached

    Only one run can be active for an entity, and Core Hub runs at most five comparison jobs at the same time. A schedule that overlaps a manual run, or two jobs that validate the same entity, start a second run for the same entity.

    Wait for the active run to end, or select Cancel run on it, then start a new one. Spread large scheduled jobs so that they do not overlap.

    Data Validation is not available for this pipeline, or a run fails with Agent '<id>' does not support data comparison

    The source or the target connector of the pipeline cannot compare data.

    Validator cannot compare that pair. Use Count both on the entity detail page and Query Studio to check the counts and the data. See Find and fix row differences between source and target.