Skip to main content
Version: Next

ServiceNow Mirror Planner — Ingestion & Range Sharding

This guide covers operational use of the Cortex ServiceNow table mirror planner with the high-throughput ingestion pipeline (Phase 4a), optional sys_id range sharding across multiple Table API nodes (Phase 4b), and the runtime schema drift (Phase 5) and relational integrity (Phase 6) enhancements that run during and after mirror jobs.

For first-time setup (connections, table selection, archive database), start with Getting your ServiceNow data.


Overview

High-throughput ingestion

Mirror jobs copy data through a producer–consumer pipeline:

  • The producer fetches keyset pages from the ServiceNow Table API.
  • The consumer batches rows and upserts them into the archive database (DELETE + multi-row INSERT in a single transaction, with row-by-row fallback on failure).

Multiple tables can copy in parallel, bounded by MaxConcurrentMirrorTables and a job-scoped API throttle (GlobalApiConcurrency).

Range sharding

Very large tables can bottleneck on a single keyset cursor and one API endpoint. When sharding is enabled, Cortex splits the 128-bit sys_id hex space into uniform partitions using BigInteger math, then runs independent keyset pipelines per partition.

Each shard:

  • Owns a non-overlapping sys_id range (for example, quartering the space when ShardCount = 4).
  • Can be pinned to a different Table API base URL when you configure extra instance nodes on the mirror job.
  • Persists its own cursor in ServiceNowMirrorJobTableShard so interrupted jobs resume shard-by-shard.

Sharding activates only when both EnableSysIdRangeSharding is true and the table’s expected row count meets ShardRowCountThreshold.

Runtime schema drift

While rows are copying, Cortex can detect new fields (for example custom u_* columns) that were not in the initial sys_dictionary snapshot:

ChannelWhen it runsWhat it does
Proactive (dictionary poll)Producer, every N keyset pagesRe-reads sys_dictionary and merges new column specs into the live registry
Reactive (JSON key scan)Consumer, before each batch insertCompares incoming API row keys against known fields; triggers online ALTER TABLE for unmapped columns

Schema mutations run autocommit under a per-physical-table lock so sharded pipelines do not corrupt each other. This feature is off by default (EnableRuntimeSchemaEvolution: false).

Relational integrity

After data lands, Cortex strengthens the physical mirror for archive navigation:

StageWhenWhat
Per-table indexing (PhaseIndexing)After row copy for each tableCreates idempotent non-clustered indexes on scalar reference columns (IX_sn_r_*)
Job-end reconciliationAfter all tables finishMetadata rescan, catch-up indexes, soft orphan validation, M2M junction views

Orphan validation never fails the job—it writes warnings to the sync log. Junction views (vw_sn_m2m_{parent}_{field}) accelerate many-to-many navigation in the archive viewer.


Prerequisites

  • Cortex admin access and a ServiceNow API data source with admin Table API access.
  • An empty ServiceNow archive database (MariaDB, PostgreSQL, or SQL Server).
  • For multi-node sharding: one or more extra instance base URLs on the mirror job (same credentials as the primary node). Each URL becomes an API client in the job’s pool; shards round-robin across clients up to MaxConcurrentShardsPerTable.

Open the planner at Utilities → ServiceNow table mirror planner (/utilities/servicenow-table-planner) and monitor jobs at Utilities → ServiceNow mirror jobs (/utilities/servicenow-mirror-jobs).


Configuration

Sharding and ingestion settings live under ServiceNowMirror:Ingestion in appsettings.json (or environment variables). All keys have defaults in code—the JSON block is optional and documents tunables for operators.

"ServiceNowMirror": {
"Ingestion": {
"EnableSysIdRangeSharding": false,
"ShardCount": 4,
"ShardRowCountThreshold": 250000,
"MaxConcurrentShardsPerTable": 4
}
}

Environment variable override example:

ServiceNowMirror__Ingestion__EnableSysIdRangeSharding=true
ServiceNowMirror__Ingestion__ShardCount=4

Sharding keys

KeyDefaultOperational meaning
EnableSysIdRangeShardingfalseMaster switch. When true, eligible tables split into parallel sys_id range pipelines.
ShardCount4Number of hex partitions (1–32). Example: 4 quarters the 128-bit space at 4000…, 8000…, C000… boundaries.
ShardRowCountThreshold250000Minimum expected rows before sharding is considered. Smaller tables use a single pipeline even when sharding is enabled.
MaxConcurrentShardsPerTable4Max shard pipelines running at once per table (1–16). Set ≤ number of API nodes you configured on the job.
KeyDefaultRole
MaxConcurrentMirrorTables4Parallel table copies per job
GlobalApiConcurrency8Max concurrent Table API calls per job
KeysetPageSize500Rows per keyset page (application tables)
PrefetchPageDepth2Producer prefetch depth
TargetBatchSize50Rows per consumer batch insert

Schema drift & relational integrity (optional)

SectionKeyDefaultRole
ServiceNowMirror:SchemaDriftEnableRuntimeSchemaEvolutionfalseTurn on proactive + reactive drift handling
DictionaryPollIntervalPages50Pages between dictionary polls
ServiceNowMirror:RelationalIntegrityEnablePostCopyReferenceIndexestruePer-table + job-end reference indexes
EnableJobEndReconciliationtrueJob-end metadata rescan and catch-up
EnableOrphanValidationtrueSoft FK orphan audit (warnings only)
EnableJunctionViewstrueCreate vw_sn_m2m_* views for M2M fields

How it works

Planner workflow (with sharding)

  1. Connection — Primary instance URL + credentials (or saved API data source).
  2. Select tables — Catalog shows storage strategy (TPH, TPC, TPP, Standalone) and physical storage table name.
  3. Analyze & export — Dependency expansion (metadata, references, inheritance, attachments).
  4. Archive database — Target ServiceNow archive connection.
  5. Extra instance URLs (recommended for sharding) — Add additional Table API base URLs for multi-node instances. The job builds one API client per URL; shards distribute across them.
  6. Start mirror job — Background worker runs copy, indexing, and job-end reconciliation.

Shard lifecycle

Table copy starts
→ Expected rows ≥ ShardRowCountThreshold and sharding enabled?
No → Single keyset pipeline (standard copy)
Yes → EnsureShardState: N shard rows in job DB
→ Up to MaxConcurrentShardsPerTable parallel pipelines
→ Each shard: sys_id range filter + dedicated API client index
→ Cursor saved per shard on each page
→ All shards complete → table proceeds to PhaseIndexing

Shard phases in the database: PendingCopyingComplete (or Failed). Resume an interrupted job from the mirror jobs dashboard—shards with saved cursors continue where they left off.

Schema drift channels

Proactive (dictionary poll)

  • Runs on the producer every DictionaryPollIntervalPages keyset pages.
  • Fetches updated sys_dictionary rows for the logical table.
  • Merges new ColumnSpec entries into the shared ServiceNowMirrorRuntimeColumnRegistry (shared across shards on the same physical table).

Reactive (JSON key scan)

  • Runs on the consumer immediately before each batch insert.
  • Compares each row’s API keys to KnownLogicalElements (ignores _display_value and _link suffix keys).
  • For new keys: infers SQL type (dictionary row first, then heuristics on batch values), then runs ALTER TABLE under the table schema coordinator lock.
  • Updates the registry so subsequent pages include the new column in sysparm_fields and insert mapping.

Enable both channels with EnableRuntimeSchemaEvolution: true. Leave off until you have validated drift behavior in a non-production mirror.

Indexing and job-end reconciliation

Per table — PhaseIndexing

After row copy and row-failure retry, before count verification:

  1. Table phase transitions to Indexing (UI label: Creating reference indexes).
  2. ServiceNowMirrorReferenceIndexEvolver scans scalar reference fields whose target table is in the mirror schedule.
  3. Creates idempotent indexes IX_sn_r_{table}_{column}_{seq} (truncated to 63 characters for PostgreSQL).
  4. Phase advances to Verifying.

Job-end — relational integrity coordinator

When all scheduled tables have finished (and the job is not re-queued for resume):

  1. Full metadata rescan (sys_dictionary, sys_m2m).
  2. Catch-up reference indexes for any columns added during Phase 5 drift.
  3. Soft orphan validation — anti-join counts for broken reference links (TRIM(fk) <> '' skips unassigned fields). Warnings only; job still completes.
  4. Junction viewsCREATE VIEW vw_sn_m2m_{parent}_{field} projecting parent_sys_id, child_sys_id, junction_sys_id from M2M link tables. Archive viewer M2M relationships prefer these views over heuristic junction-table queries.

Monitoring & telemetry

Mirror jobs dashboard

Utilities → ServiceNow mirror jobs shows macro job status and per-table phase. Watch for these table phase transitions during a healthy large-table run:

PhaseUI labelMeaning
CopyingCopying rowsKeyset / shard pipelines active
IndexingCreating reference indexesPost-copy reference index DDL
VerifyingVerifyingRow count and failure checks
CompleteCompleteTable finished successfully

For sharded tables, inspect shard rows in the job database (ServiceNowMirrorJobTableShard) if a table stalls in Copying—one failed shard can block completion.

Sync log panel

Each job stores the last 100 structured log lines (SyncLogJson). Log entries include a phase tag:

Phase tagWhen it appears
metadataCatalog / sys_dictionary / sys_db_object loading
schemaDDL, topology, per-table index creation messages
datacopyPage progress during row copy
relationalintegrityJob-end reconciliation, orphan warnings, junction views

Messages to expect at job end (phase tag relationalintegrity):

  • Job-end relational integrity reconciliation starting…
  • Catch-up reference indexes ensured for N physical table(s).
  • Relational integrity: {table}.{column} → {target}: N orphan reference linkage(s). Sample source sys_id(s): … (warnings only)
  • Orphan validation complete: X field(s) scanned, Y with orphan linkages, Z total orphan reference(s).
  • Junction navigation views ensured for N M2M link field(s).
  • Job-end relational integrity reconciliation complete.

Orphan messages indicate data quality gaps in the mirror (missing target rows), not a failed job. Investigate source ACL filtering, partial table selection, or timing if counts are high.

Server debug logs

When log level is Debug, Table API calls include ServiceNowApiCallContext tags:

(phase: datacopy, worker: 2, shard: 1)

Use these to correlate slow pages with a specific shard and API node. See Logging for enabling file or console debug output.


Operational checklist

Enabling sharding for a large mirror

  • Set EnableSysIdRangeSharding to true (config or env var).
  • Confirm ShardCount and MaxConcurrentShardsPerTable match your API node count.
  • Add extra instance base URLs on the mirror job in the planner (one per node).
  • Set ShardRowCountThreshold above your smallest table that should not shard.
  • Monitor mirror jobs dashboard and sync log during first production run.
  • Resume rather than restart if the job interrupts—shard cursors are persisted.

Enabling schema drift (optional)

  • Set ServiceNowMirror:SchemaDrift:EnableRuntimeSchemaEvolution to true.
  • Start with a test mirror; confirm new u_* fields appear without job failure.
  • Watch for DDL timeout messages; increase SchemaMutationTimeoutSeconds if needed.

After job completion

  • Confirm tables reached Complete or Complete with warnings.
  • Review sync log for relationalintegrity orphan warnings.
  • Spot-check archive viewer M2M relationships on tables with sys_m2m metadata.
  • Register or refresh the ServiceNow archive data source in Cortex pointing at the mirror database.

Troubleshooting

SymptomLikely causeAction
Large table slow; single API node saturatedSharding off or no extra URLsEnable sharding; add extra instance URLs; raise MaxConcurrentShardsPerTable
Table stuck in CopyingOne shard failed or stalledCheck shard LastError in job DB; resume job; review API rate limits
Sharding not activatingRow count below thresholdLower ShardRowCountThreshold or accept single-pipeline copy
New columns missing in mirrorSchema drift disabledEnable EnableRuntimeSchemaEvolution
Job completes but orphan warningsExpected with partial mirrorsExpand mirrored reference targets or accept soft warnings
M2M relationships slow in archiveJunction views missingConfirm EnableJunctionViews and mirrored sys_m2m / junction tables

For connection, catalog, and first-time planner issues, see Getting your ServiceNow data.


See also