Skip to content
About
Main content

Bootstrap: snapshot and streaming handoff

How do you combine a snapshot with a live stream without locking the source?

The problem

The change stream starts at a point in time, but the table existed before it. You need the state at the stream's beginning, and the and the stream must meet exactly once: no gap (lost rows) and no unresolvable overlap (wrong final state). Tariq's plain copy broke this rule: changes made during the copy were either missed or applied in the wrong order.

The simple, correct, unacceptable way

Take a locked consistent snapshot at log position L, then start streaming from L. This is correct. It is also unacceptable on a large table, because the lock lasts as long as the snapshot. Copying 300 million rows can take hours, and during that time writers wait.

The lock-free way

The lock-free resolution exploits a property of the target, not the source. If the sink is keyed and applies upserts, then a replayed change is harmless: applying "set order 17 to status shipped" twice leaves the same row.

So you may:

  1. read the snapshot slowly, with no lock, while streaming changes concurrently;
  2. resolve any collision by a total-order rule: a streamed change at a higher log position always wins over a snapshot row that was read earlier.

The variant is more refined. It splits the table into chunks by key range (for example order ids 1 to 100,000, then 100,001 to 200,000, and so on). Before and after reading each chunk, it writes markers into the log itself. Changes that appear in the log between the two markers are changes that happened while the chunk was being read. The log's own ordering then decides, chunk by chunk, which version of each row wins. The advantages: no long lock, and the process can pause and resume after a crash, one chunk at a time.

One chunk, two markers, one rule

The limit of this trick

It does not work if the consumer is path-dependent. An append-only history cannot deduplicate a replayed update, because "again" is meaningful there: it would record the same status step twice.

In one line: consistent bootstrap without locking requires an , keyed sink; the source's total order arbitrates, and the sink absorbs the overlap.