0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-09 21:45:25 +08:00
discourse/migrations/core/spec/lib/database
Gerhard Schlager b8d389cb1b MT: Only use INSERT OR IGNORE for tables that want it in the shard merge
The sharded write path (#41262) merges every shard table with `INSERT OR
IGNORE`. That's right for `uploads`, but for every other table it silently
swallows a genuine cross-step/cross-shard duplicate row that the single-writer
path would have raised on — so a concurrency bug that doubles a key becomes
silent data loss with no error and no baseline to diff against.

This scopes the `OR IGNORE` back to just the tables that actually want it,
derived from the models rather than a hardcoded table name:

- `IntermediateDB.conflict_strategy_for(table)` resolves a table's model and
  reads its declared `conflict_strategy`, defaulting to `:raise`.
- Only `upload` declares `:ignore` (its rows are content-identical for a given
  id-hash, so first-writer-wins is intended). A future `OR IGNORE` model flips
  its own merge clause with no change to the merge code.
- `Connection#merge_database` takes `dedupe_tables:` and picks the clause per
  table; a plain-table conflict raises, wrapped with the table name, and the
  error surfaces through `Consolidator#drain` as a run failure.

This restores the earlier behaviour where a genuine duplicate on a plain table
is an error, not a dropped row.
2026-07-03 17:05:25 +02:00
..
intermediate_db
connection_spec.rb MT: Only use INSERT OR IGNORE for tables that want it in the shard merge 2026-07-03 17:05:25 +02:00
intermediate_db_spec.rb MT: Only use INSERT OR IGNORE for tables that want it in the shard merge 2026-07-03 17:05:25 +02:00
migrator_spec.rb MT: Run conversion steps concurrently and split the heavy ones across cores 2026-07-03 11:48:25 +02:00
prepared_statement_cache_spec.rb