You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Remove deprecated checkpoint system and dead code from index migrator
- Remove QuantizationCheckpoint, BatchUndoBuffer, trigger_bgsave_and_wait,
async_trigger_bgsave_and_wait from reliability.py (dead code)
- Remove checkpoint_path parameter from MigrationExecutor.apply() and
AsyncMigrationExecutor.apply()
- Remove deprecated --resume CLI flag and legacy_resume handling
- Remove TestResumeDeprecation test class
- Update docs to use --backup-dir as primary crash-safe recovery mechanism
- Update cli.rst to document current flags (--backup-dir, --workers, etc.)
- Replace 'checkpoint' wording with 'state file/tracking' in batch commands
| After drop, before quantize | Unchanged | **None** | Re-run apply (or `--resume` if checkpoint exists) |
407
-
| During quantization | Partially quantized | **None** | Re-run with `--resume` to continue from checkpoint |
406
+
| After drop, before quantize | Unchanged | **None** | Re-run apply (or pass `--backup-dir` to resume from backup) |
407
+
| During quantization | Partially quantized | **None** | Re-run with same `--backup-dir` to resume from last batch |
408
408
| After quantization, before create | Quantized | **None** | Re-run apply (will recreate index) |
409
409
| After create | Correct | Rebuilding | Wait for index ready |
410
410
411
-
The underlying documents are **never deleted** by `drop_recreate` mode. For large quantization jobs, use `--resume` to enable checkpoint-based recovery. See [Crash-safe resume for quantization](#crash-safe-resume-for-quantization) below.
411
+
The underlying documents are **never deleted** by `drop_recreate` mode. For large quantization jobs, use `--backup-dir` to enable crash-safe recovery. See [Crash-safe resume for quantization](#crash-safe-resume-for-quantization) below.
412
412
413
413
## Step 4: Apply the Migration
414
414
@@ -444,7 +444,7 @@ The migration executor follows this sequence:
444
444
- Writes back the converted vector to the same document
445
445
- Processes documents in batches of 500 using Redis pipelines
446
446
- Skipped for JSON storage (vectors are re-indexed automatically on recreate)
447
-
- **Checkpoint support**: For large datasets, use `--resume` to enable crash-safe recovery
447
+
- **Backup support**: For large datasets, use `--backup-dir` to enable crash-safe recovery and rollback
448
448
449
449
**STEP 4: Key renames** (if changing key prefix)
450
450
- If the migration changes the key prefix, renames each key from old prefix to new prefix
@@ -495,15 +495,36 @@ See {doc}`/concepts/index-migrations` for detailed async vs sync guidance.
495
495
496
496
### Crash-safe resume for quantization
497
497
498
-
When migrating large datasets with vector quantization (e.g. float32 to float16), the re-encoding step can take minutes or hours. If the process is interrupted (crash, network drop, OOM kill), you don't want to start over. The `--resume` flag enables checkpoint-based recovery.
498
+
When migrating large datasets with vector quantization (e.g. float32 to float16), the re-encoding step can take minutes or hours. If the process is interrupted (crash, network drop, OOM kill), you don't want to start over. The `--backup-dir` flag enables crash-safe recovery.
499
499
500
500
#### How it works
501
501
502
-
1. **Pre-flight estimate**: before any mutations, `apply` prints a disk space estimate showing RDB snapshot cost, AOF growth (if enabled), and post-migration memory savings.
503
-
2. **BGSAVE safety snapshot**: the migrator triggers a Redis `BGSAVE` and waits for it to complete before modifying any data. This gives you a point-in-time snapshot to fall back on.
504
-
3. **Checkpoint file**: when `--resume` is provided, the migrator writes a YAML checkpoint after every batch of 500 documents. The checkpoint records how many keys have been processed and the last batch of keys written.
505
-
4. **Batch undo buffer**: if a single batch fails mid-write, original vector values are rolled back via pipeline before the error propagates. Only the current batch is held in memory.
506
-
5. **Idempotent skip**: on resume, vectors that were already converted are detected by byte-width inspection and skipped automatically.
502
+
When you pass `--backup-dir`, the migrator saves original vector bytes to disk before mutating them. Two files are created:
503
+
504
+
```
505
+
<backup-dir>/
506
+
migration_backup_<index_name>.header # JSON: phase, progress counters, field metadata
507
+
migration_backup_<index_name>.data # Binary: length-prefixed batches of original vectors
508
+
```
509
+
510
+
The **header file** is a small JSON file that tracks progress through a state machine:
511
+
512
+
```
513
+
dump → ready → active → completed
514
+
```
515
+
516
+
- **dump**: original vectors are being read from Redis and written to the data file, one batch at a time
517
+
- **ready**: all original vectors have been backed up; safe to proceed with quantization
518
+
- **active**: quantization is in progress; the header tracks which batches have been written back to Redis
519
+
- **completed**: all batches have been quantized and the migration finished successfully
520
+
521
+
The header is atomically updated (temp file + rename) after every batch, so a crash never corrupts it.
522
+
523
+
The **data file** is append-only binary. Each batch is stored as a 4-byte big-endian length prefix followed by a pickled blob containing the batch's keys and their original vector bytes.
524
+
525
+
On resume, the executor loads the header, sees how many batches were already quantized (`quantize_completed_batches`), and skips ahead in the data file to continue from the next unfinished batch.
526
+
527
+
**Disk usage:** approximately `num_docs × dims × bytes_per_element`. For example, 1M docs with 768-dim float32 vectors ≈ 2.9 GB.
The `--resume` flag takes a path to a checkpoint file. If the file does not exist, a new checkpoint is created. If it already exists (from a previous interrupted run), the migrator resumes from where it left off.
567
+
The `--backup-dir` flag takes a directory path. If no backup exists there, a new one is created. If one already exists (from a previous interrupted run), the migrator resumes from where it left off.
547
568
548
569
**3. If the process crashes or is interrupted:**
549
570
550
-
The checkpoint file (`quantize_checkpoint.yaml`) will contain the progress:
This tells you: all 2000 batches of original vectors were backed up, and 900 of them have been quantized so far.
585
+
565
586
**4. Resume the migration:**
566
587
567
588
Re-run the exact same command:
568
589
569
590
```bash
570
591
rvl migrate apply \
571
592
--plan migration_plan.yaml \
572
-
--resume quantize_checkpoint.yaml \
593
+
--backup-dir /tmp/migration_backups \
573
594
--url redis://localhost:6379 \
574
595
--report-out migration_report.yaml
575
596
```
576
597
577
598
The migrator will:
578
-
- Detect the existing checkpoint and skip already-processed keys
579
-
- Re-enumerate documents via SCAN (the index was already dropped before the crash)
580
-
- Continue quantizing from where it left off
581
-
- Print progress like `[4/6] Quantize vectors: 450,000/1,000,000 docs`
599
+
- Detect the existing backup and skip already-quantized batches
600
+
- Continue quantizing from batch 901 onward
601
+
- Print progress like `Quantize vectors: 450,000/1,000,000 docs`
582
602
583
603
**5. On successful completion:**
584
604
585
-
The checkpoint status is set to `completed`. You can safely delete the checkpoint file.
586
-
587
-
#### What gets rolled back on batch failure
588
-
589
-
If a batch of 500 documents fails mid-write (e.g. Redis returns an error), the migrator:
590
-
1. Restores original vector bytes for all documents in that batch using the undo buffer
591
-
2. Saves the checkpoint (so progress up to the last successful batch is preserved)
592
-
3. Raises the error
593
-
594
-
This means you never end up with partially-written vectors in a single batch.
605
+
The backup phase is set to `completed`. By default, backup files are **automatically deleted** after a successful migration. Pass `--keep-backup` to retain them for post-migration auditing or potential rollback.
595
606
596
607
#### Limitations
597
608
598
-
- **Same-width conversions** (float16 to bfloat16, or int8 to uint8) are **not supported** with `--resume`. These conversions cannot be detected by byte-width inspection, so idempotent skip is impossible. The migrator will refuse to proceed and suggest running without `--resume`.
599
-
- **JSON storage** does not need vector re-encoding (Redis re-indexes JSON vectors on `FT.CREATE`). The checkpoint is still created for consistency but no batched writes occur.
600
-
- The checkpoint file must match the migration plan. If you change the plan, delete the old checkpoint and start fresh.
601
-
602
-
#### Python API with checkpoints
603
-
604
-
```python
605
-
from redisvl.migration import MigrationExecutor
606
-
607
-
executor = MigrationExecutor()
608
-
report = executor.apply(
609
-
plan,
610
-
redis_url="redis://localhost:6379",
611
-
checkpoint_path="quantize_checkpoint.yaml",
612
-
)
613
-
```
614
-
615
-
For async:
616
-
617
-
```python
618
-
from redisvl.migration import AsyncMigrationExecutor
619
-
620
-
executor = AsyncMigrationExecutor()
621
-
report = await executor.apply(
622
-
plan,
623
-
redis_url="redis://localhost:6379",
624
-
checkpoint_path="quantize_checkpoint.yaml",
625
-
)
626
-
```
609
+
- **Same-width conversions** (float16 to bfloat16, or int8 to uint8) are **not supported** for resume. These conversions cannot be detected by byte-width inspection, so idempotent skip is impossible.
610
+
- **JSON storage** does not need vector re-encoding (Redis re-indexes JSON vectors on `FT.CREATE`). The backup is still created for consistency but no batched writes occur.
611
+
- The backup must match the migration plan. If you change the plan, delete the old backup directory and start fresh.
627
612
628
613
## Step 5: Validate the Result
629
614
@@ -706,7 +691,7 @@ rvl migrate validate \
706
691
- `--indexes` : Explicit list of index names
707
692
- `--indexes-file` : File containing index names (one per line)
708
693
- `--schema-patch` : Path to shared schema patch YAML
0 commit comments