Skip to content

Fix #4706 — managed partitioned tables destructively rebuilt on sharded redeploy#4709

Merged
jeremydmiller merged 1 commit into
masterfrom
fix/4706-managed-partition-migration
Jun 9, 2026
Merged

Fix #4706 — managed partitioned tables destructively rebuilt on sharded redeploy#4709
jeremydmiller merged 1 commit into
masterfrom
fix/4706-managed-partition-migration

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Fixes #4706.

Problem

Re-applying the schema over existing data to a Marten-managed ByList tenant-partitioned document table destructively rebuilds it (create <t>_temp as select * → drop → recreate → insert … select) and fails with 23514: no partition of relation found for row — the rebuilt parent has no child partitions. A fresh database is fine; a single-database managed-ByList store is idempotent. The failure is specific to sharded multi-tenancy on redeploy.

Root cause

On redeploy a fresh DocumentStore builds a fresh store-wide ManagedListPartitions that loads only the first shard's mt_tenant_partitions set. IMartenStorage.ApplyAllConfiguredChangesToDatabaseAsync then diffs every shard against that single set (Parallel.ForEachAsync over databases). For any shard whose real partitions differ from that first set, ListPartitioning.CreateDelta sees the live per-tenant partitions as "unexpected" and returns PartitionDelta.Rebuild → destructive rebuild → 23514.

Fix

DocumentTable sets IgnorePartitionsInMigration = true on Marten-managed LIST-partitioned tables (Partitioning is ListPartitioning { PartitionManager: not null }). The generic schema diff then short-circuits to PartitionDelta.None for those tables, so it never rebuilds them. The per-tenant partitions are reconciled out-of-band by AddMartenManagedTenantsAsync / AddTenantToShardAsync (the additive path), which still creates them because Weasel 9.1.2's additivelyMigrateTablesForNewPartitions clears the flag locally for that explicit path. This is concurrency-immune: the diff no longer depends on the shared partition manager's state.

Bumps Weasel.Postgresql / Weasel.EntityFrameworkCore to 9.1.2 (JasperFx/weasel#303).

Tests

  • Bug_4706_sharded_partitioned_doc_rebuild (sharded) — eager per-DB apply + per-tenant data, then a store-wide parallel re-apply must be idempotent. RED (23514) before the fix, green after.
  • Bug_4706_partitioned_table_idempotent_migration (single-DB control) — managed ByList re-apply is idempotent (passes regardless; proves sharding/concurrency is load-bearing for the bug).

Full TenantPartitionedEventsTests 182/182 and CoreTests partitioning 33/33 green against the published Weasel 9.1.2.

Out of scope

Event tables (mt_events/mt_streams) are intentionally not flagged here — the flag breaks their lazy sharded partition creation, and their redeploy hardening (the #4682 conjoined→partitioned migration) needs a deeper per-database partition-state design.

🤖 Generated with Claude Code

…ed redeploy

Re-applying the schema over existing data to a Marten-managed ByList
tenant-partitioned document table destructively rebuilt it (create _temp /
copy / drop / recreate) and failed with 23514 "no partition of relation found
for row". Root cause: on redeploy a fresh DocumentStore builds a fresh
store-wide ManagedListPartitions that loads only the first shard's partition
set, then ApplyAllConfiguredChangesToDatabaseAsync diffs EVERY shard against
that one set (Parallel.ForEachAsync over databases). Mismatched shards make
ListPartitioning.CreateDelta return PartitionDelta.Rebuild → destructive rebuild.

Fix: DocumentTable sets IgnorePartitionsInMigration on Marten-managed LIST
partitioned tables (PartitionManager != null). The generic schema diff then
short-circuits to PartitionDelta.None for those tables — the per-tenant
partitions are reconciled out-of-band by AddMartenManagedTenantsAsync /
AddTenantToShardAsync (the additive path), which still creates them because
Weasel 9.1.2's additivelyMigrateTablesForNewPartitions clears the flag locally.
Concurrency-immune: the diff no longer depends on the shared partition manager's
state. Bumps Weasel.Postgresql to 9.1.2.

Tests:
- Bug_4706_sharded_partitioned_doc_rebuild (sharded): eager per-DB apply +
  per-tenant data, then store-wide parallel re-apply must be idempotent. RED
  (23514) before the fix, green after.
- Bug_4706_partitioned_table_idempotent_migration (single-DB control): managed
  ByList re-apply is idempotent (passes regardless — proves sharding/concurrency
  is load-bearing for the bug).

Note: event tables (mt_events/mt_streams) are intentionally NOT flagged here —
the flag breaks their lazy sharded partition creation; their redeploy hardening
(the #4682 migration) needs a deeper per-database partition-state design.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Schema migration destructively rebuilds tenant LIST-partitioned document tables on every startup over existing data

1 participant