forked from fedi/mastodon
Improve account index migration (#7684)
* Improve account index migration - Display more progress in stdout - Catch PG::UniqueViolation when re-attributing favourites - Skip callbacks and validations when re-attributing other relationships * Use in_batches to reduce table lock-up during account merge * Use #say_with_time to benchmark each deduplication
This commit is contained in:
parent
1e938b966e
commit
19b4c666f7
|
@ -39,6 +39,7 @@ class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2]
|
||||||
accounts = accounts.first.local? ? accounts.sort_by(&:created_at) : accounts.sort_by(&:updated_at).reverse
|
accounts = accounts.first.local? ? accounts.sort_by(&:created_at) : accounts.sort_by(&:updated_at).reverse
|
||||||
reference_account = accounts.shift
|
reference_account = accounts.shift
|
||||||
|
|
||||||
|
say_with_time "Deduplicating @#{reference_account.acct} (#{accounts.size} duplicates)..." do
|
||||||
accounts.each do |other_account|
|
accounts.each do |other_account|
|
||||||
if other_account.public_key == reference_account.public_key
|
if other_account.public_key == reference_account.public_key
|
||||||
# The accounts definitely point to the same resource, so
|
# The accounts definitely point to the same resource, so
|
||||||
|
@ -55,10 +56,11 @@ class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2]
|
||||||
other_account.destroy
|
other_account.destroy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def merge_accounts!(main_account, duplicate_account)
|
def merge_accounts!(main_account, duplicate_account)
|
||||||
[Status, Favourite, Mention, StatusPin, StreamEntry].each do |klass|
|
[Status, Mention, StatusPin, StreamEntry].each do |klass|
|
||||||
klass.where(account_id: duplicate_account.id).update_all(account_id: main_account.id)
|
klass.where(account_id: duplicate_account.id).in_batches.update_all(account_id: main_account.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Since it's the same remote resource, the remote resource likely
|
# Since it's the same remote resource, the remote resource likely
|
||||||
|
@ -67,19 +69,19 @@ class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2]
|
||||||
# of the index bug users could have *also* followed the reference
|
# of the index bug users could have *also* followed the reference
|
||||||
# account already, therefore mass update will not work and we need
|
# account already, therefore mass update will not work and we need
|
||||||
# to check for (and skip past) uniqueness errors
|
# to check for (and skip past) uniqueness errors
|
||||||
[Follow, FollowRequest, Block, Mute].each do |klass|
|
[Favourite, Follow, FollowRequest, Block, Mute].each do |klass|
|
||||||
klass.where(account_id: duplicate_account.id).find_each do |record|
|
klass.where(account_id: duplicate_account.id).find_each do |record|
|
||||||
begin
|
begin
|
||||||
record.update(account_id: main_account.id)
|
record.update_attribute(:account_id, main_account.id)
|
||||||
rescue ActiveRecord::RecordNotUnique
|
rescue PG::UniqueViolation
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
klass.where(target_account_id: duplicate_account.id).find_each do |record|
|
klass.where(target_account_id: duplicate_account.id).find_each do |record|
|
||||||
begin
|
begin
|
||||||
record.update(target_account_id: main_account.id)
|
record.update_attribute(:target_account_id, main_account.id)
|
||||||
rescue ActiveRecord::RecordNotUnique
|
rescue PG::UniqueViolation
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue