rake posts:reorder_posts で `UniqueViolation` エラーが発生します

コンテキスト:投稿を分割しようとしています。そのためには、次のような手順が必要だと思います。

  • トピックに新しい投稿を作成します。
  • 両方の投稿の内容を希望どおりに編集します。
  • 作成した投稿の所有者を元の投稿と同じに変更します。
  • 作成した投稿のタイムスタンプを元の投稿と同じに変更します(数秒追加するかもしれません)。
  • トピック内の正しい位置に返信を移動するために posts:reorder_posts[topic_id] を実行します。

最初に試したのは posts:reorder_post の呼び出しでした。「ただ見てみるために」実行しましたが、失敗しました。

root@discourse1-app:/var/www/discourse# rake "posts:reorder_posts[879]"
rake aborted!
PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "post_timings_unique"
DETAIL:  Key (topic_id, post_number, user_id)=(879, 93, 1) already exists.
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:110:in `exec'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:110:in `async_exec'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/postgres/connection.rb:209:in `run'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/active_record_postgres/connection.rb:38:in `block in run'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/active_record_postgres/connection.rb:34:in `block in with_lock'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/active_record_postgres/connection.rb:34:in `with_lock'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/active_record_postgres/connection.rb:38:in `run'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/mini_sql-1.4.0/lib/mini_sql/postgres/connection.rb:181:in `exec'
/var/www/discourse/lib/tasks/posts.rake:383:in `block (3 levels) in <main>'
/var/www/discourse/lib/tasks/posts.rake:366:in `each'
/var/www/discourse/lib/tasks/posts.rake:366:in `block (2 levels) in <main>'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.4.1/lib/active_record/connection_adapters/abstract/transaction.rb:319:in `block in within_new_transaction'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activesupport-7.0.4.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.4.1/lib/active_record/connection_adapters/abstract/transaction.rb:317:in `within_new_transaction'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.4.1/lib/active_record/connection_adapters/abstract/database_statements.rb:316:in `transaction'
/var/www/discourse/vendor/bundle/ruby/3.1.0/gems/activerecord-7.0.4.1/lib/active_record/transactions.rb:209:in `transaction'
/var/www/discourse/lib/tasks/posts.rake:329:in `block in <main>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'
Tasks: TOP => posts:reorder_posts
(See full trace by running task with --trace)

興味深いことに、トピックに番号 93 の投稿は見当たりません。92 と 94 が見えます。ユーザー 1 は私ですが、投稿 92 と 94 は私のものではありません。

以前にトピックを分割したので、93 が別のトピックに移動したのかもしれません。わかりません。

「いいね!」 1

同じ問題、同じトレースに遭遇しています。解決策はありますか?

これは不可能だと思います。投稿がトピックから分割された場合、投稿番号は再計算されます(投稿IDではなく、トピック内の投稿の順序であるため)。「実際の」投稿のように見えない小さなアクション投稿である可能性がありますが、それでも1つの投稿としてカウントされます(ささやきもカウントされますが、rakeタスクを実行している場合、それらを見ることができる管理者であると想定されます)。

この状況で、その小さなアクション投稿を削除することが役立ったのではないかと思いますか?これはあなたにとって問題の原因になりうると思いますか、@UndecidedAdmin

「いいね!」 2

どういう意味かよくわかりません。「small action post」が何を指すのかわかりませんが、トピックを分割する投稿のことなら、それが問題の可能性があります。このエラーが出ています。

PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "post_timings_unique" (PG::UniqueViolation)
DETAIL: Key (topic_id, post_number, user_id)=(54, 2150, 1) already exists.

このURLにアクセスすると:

https://[site]/t/[slug]/54/2150

投稿は実際には2151で、「Split this topic on Dec 11, 2021」と表示されています。そのすぐ上の投稿は2143なので、2150が別のトピックに移動され、何らかのテーブルがそれに間違った参照をしているのではないかと推測しています。

「いいね!」 1

Unable to move posts between topics - #2 by nat でこのエラーの修正が発表されました。

「いいね!」 3

このトピックは、最後の返信から90日後に自動的にクローズされました。新しい返信は許可されていません。