Skip to content

Bug: failed DDL can rewrite live writing segment before manifest commit #573

Description

@egolearner

Problem

CreateIndex and DropIndex can mutate the live writing segment on disk before all DDL tasks succeed and before the new manifest/schema version is committed.

For an empty writing segment, the current code destroys and recreates writing_segment_ with the new schema before processing persisted segments. If a later persisted-segment task fails, the manifest is still on the old schema, but the writing segment directory may already have been rewritten with the new schema layout.

For a non-empty writing segment, the code also performs disk-visible side effects before the DDL task phase by dumping the current writing segment and switching writing_segment_ to a new segment with the new schema.

Failure Scenario

One observed path is:

  1. A collection has a writing segment using the old schema.
  2. drop_index("text") starts and recreates the empty writing segment with the new schema where the text FTS index is removed.
  3. A persisted segment task later fails, for example while snapshotting a read-only FTS or inverted RocksDB index.
  4. The new schema/version is not committed to the manifest.
  5. On reopen, the manifest still says the writing segment uses the old schema, but the segment directory was already recreated with the new schema.
  6. Opening the collection can fail because the expected index files, column families, or stats for the old schema are missing.

Impact

A failed DDL operation can leave the collection unreopenable. The issue is not limited to FTS; any DDL path that mutates the live writing segment before manifest commit has the same consistency risk.

This is a separate consistency bug from the read-only snapshot flush failure tracked in #568. The snapshot failure can be the trigger, but DDL should still leave the old manifest and old writing segment compatible when any persisted-segment task fails.

Expected Behavior

DDL should be atomic with respect to the live collection state:

  • Before all DDL tasks succeed, the existing writing segment and manifest must remain compatible.
  • Failed DDL should leave the collection reopenable under the old schema.
  • New-schema writing segment directories should only become live after the new version/schema is successfully committed.

Proposed Fix

Use a two-phase ordering for CreateIndex and DropIndex:

  1. If the writing segment has docs, switch it to a persisted segment under the old schema first.
  2. Keep the current empty writing segment unchanged while DDL tasks run.
  3. After all persisted-segment tasks succeed, create a new empty writing segment with the new schema and a new segment id.
  4. Apply and flush the new version.
  5. Only after manifest persistence succeeds, swap the live writing segment and clean up the old one.

Verification

Regression coverage should include:

  • FTS drop_index() failure during persisted-segment snapshot, followed by successful reopen under the old schema.
  • Inverted scalar drop_index() failure during persisted-segment snapshot, followed by successful reopen under the old schema.
  • Empty writing segment DDL where no persisted tasks exist.
  • Non-empty writing segment DDL that first switches the current writing docs under the old schema.

This sub-issue follows up on #565 and complements #568.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
In progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions