]> cat aescling's git repositories - mastodon.git/commitdiff
Fix account deletion sometimes failing because of optimistic locks (#16317)
authorClaire <claire.github-309c@sitedethib.com>
Wed, 2 Jun 2021 15:41:25 +0000 (17:41 +0200)
committerGitHub <noreply@github.com>
Wed, 2 Jun 2021 15:41:25 +0000 (17:41 +0200)
* Fix account deletion sometimes failing because of optimistic locks

In some rare occasions[1], deleting accounts would fail with a
`StaleObjectError` exception.

Indeed, account deletion manually sets the `AccountStat` values without
handling cases where the optimistic locking on `AccountStat` would fail.

To my knowledge, with the rewrite of account counters in #15913, the
`DeleteAccountService` is now the only place that changes the counters in
a way that is not atomic.

Since in this specific case, we do not care about the previous values of the
account counters, it appears we don't need locking at all for this table
anymore.

[1]: https://discourse.joinmastodon.org/t/account-cant-be-deleted/3602

* Bump MAX_SUPPORTED_VERSION in maintenance script

app/models/account_stat.rb
app/models/concerns/account_counters.rb
db/post_migrate/20210526193025_remove_lock_version_from_account_stats.rb [new file with mode: 0644]
db/schema.rb
lib/mastodon/maintenance_cli.rb

index a826a9af3ba2a6ef79edee2e8c1d8c0355e861ef..44da4f0d00c831de4c754fad049ea6b7b3b0e504 100644 (file)
 #  created_at      :datetime         not null
 #  updated_at      :datetime         not null
 #  last_status_at  :datetime
-#  lock_version    :integer          default(0), not null
 #
 
 class AccountStat < ApplicationRecord
+  self.locking_column = nil
+
   belongs_to :account, inverse_of: :account_stat
 
   update_index('accounts#account', :account)
index fd3f161ad53ae2e67aff0e44c6f4d7bfd4df720d..3fabb520542e078a9a3af9849ff355b5aefea5b1 100644 (file)
@@ -49,7 +49,6 @@ module AccountCounters
               ON CONFLICT (account_id) DO UPDATE
               SET #{key} = account_stats.#{key} + :value,
                   last_status_at = now(),
-                  lock_version = account_stats.lock_version + 1,
                   updated_at = now()
               RETURNING id;
             SQL
@@ -59,7 +58,6 @@ module AccountCounters
                 VALUES (:account_id, :default_value, now(), now())
               ON CONFLICT (account_id) DO UPDATE
               SET #{key} = account_stats.#{key} + :value,
-                  lock_version = account_stats.lock_version + 1,
                   updated_at = now()
               RETURNING id;
             SQL
diff --git a/db/post_migrate/20210526193025_remove_lock_version_from_account_stats.rb b/db/post_migrate/20210526193025_remove_lock_version_from_account_stats.rb
new file mode 100644 (file)
index 0000000..3079bed
--- /dev/null
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class RemoveLockVersionFromAccountStats < ActiveRecord::Migration[5.2]
+  def change
+    safety_assured do
+      remove_column :account_stats, :lock_version, :integer, null: false, default: 0
+    end
+  end
+end
index 583bdf317d4a0de6ab8ef16279df4f730bf4d069..3fcee2d30430920837f6090a8f7a44765e085c0c 100644 (file)
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2021_05_07_001928) do
+ActiveRecord::Schema.define(version: 2021_05_26_193025) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
@@ -111,7 +111,6 @@ ActiveRecord::Schema.define(version: 2021_05_07_001928) do
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
     t.datetime "last_status_at"
-    t.integer "lock_version", default: 0, null: false
     t.index ["account_id"], name: "index_account_stats_on_account_id", unique: true
   end
 
index 8e2084e335671867559cb3c5548ddb8b56264cbd..47e2d78bb1eeb351e59617ec39a3aa1597a2159c 100644 (file)
@@ -14,7 +14,7 @@ module Mastodon
     end
 
     MIN_SUPPORTED_VERSION = 2019_10_01_213028
-    MAX_SUPPORTED_VERSION = 2021_05_07_001928
+    MAX_SUPPORTED_VERSION = 2021_05_26_193025
 
     # Stubs to enjoy ActiveRecord queries while not depending on a particular
     # version of the code/database