升级在迁移过程中失败

您好,

我们正尝试将非常旧版本的 Discourse(v1.2.4)升级到最新的 v2.3.1。我们最初使用 v2.2.0 进行的测试迁移表现出乎意料地好,迁移过程顺利完成,没有任何问题。但现在我们尝试在最终阶段对 v2.3.1 运行该操作时,遇到了以下错误:

PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "idx_unique_rows"
DETAIL:  Key (action_type, user_id, target_topic_id, target_post_id, acting_user_id)=(15, 1140990, 9346002, 9431164, 419835) already exists.
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.0.2/lib/patches/db/pg.rb:110:in `async_exec'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.0.2/lib/patches/db/pg.rb:110:in `async_exec'
(eval):24:in `async_exec'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/mini_sql-0.2.2/lib/mini_sql/postgres/connection.rb:118:in `run'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/mini_sql-0.2.2/lib/mini_sql/postgres/connection.rb:90:in `exec'
/var/www/discourse/plugins/discourse-solved/plugin.rb:64:in `block in activate!'
/var/www/discourse/lib/plugin/instance.rb:328:in `block in notify_after_initialize'
/var/www/discourse/lib/plugin/instance.rb:326:in `each'
/var/www/discourse/lib/plugin/instance.rb:326:in `notify_after_initialize'
/var/www/discourse/config/application.rb:292:in `each'
/var/www/discourse/config/application.rb:292:in `block in <class:Application>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:69:in `block in execute_hook'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:62:in `with_execution_control'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:67:in `execute_hook'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:51:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/application/finisher.rb:75:in `block in <module:Finisher>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/initializable.rb:32:in `instance_exec'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/initializable.rb:32:in `run'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/initializable.rb:61:in `block in run_initializers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/initializable.rb:60:in `run_initializers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/application.rb:361:in `initialize!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/config/environment.rb:7:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `block in require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:257:in `load_dependency'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/application.rb:337:in `require_environment!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/application.rb:520:in `block in run_tasks_blocks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-12.3.2/exe/rake:27:in `<top (required)>'
/var/www/discourse/bin/bundle:5:in `load'
/var/www/discourse/bin/bundle:5:in `<main>'
Tasks: TOP => db:migrate => db:load_config => environment
(See full trace by running task with --trace)

这似乎是由 “20120816050526_add_unique_constraint_to_user_actions.rb” 引起的,如果我查看数据库表 “schema_migrations”,发现该迁移似乎已经应用过了。因为这个迁移似乎是在 2012 年添加的。

您是否知道为什么 “bundle exec rake db:migrate” 会运行已经应用过的迁移,或者我们哪里做错了?
我知道源版本非常旧,但正如所说,我们已经获得了成功的结果。

此致问候

我误解了这个错误。非常抱歉造成混淆。显然,这与提到的迁移文件无关。无论如何,user_actions 中似乎存在某个条目的现有索引。因此,我通过以下语句进行了检查:

SELECT *
FROM user_actions
WHERE action_type=15
    AND user_id=1140990
    AND target_topic_id=9346002
    AND target_post_id=9431164
    AND acting_user_id=419835;

该查询返回 0 条结果。因此,必定存在一个没有对应数据集的索引。

当我遇到类似问题时,我删除了它试图复制的内容。这可能没什么帮助。

或者,确保你在进行备份时处于只读模式?

或者,也许在创建备份时确保数据库处于只读模式?

是的,也许这就是问题所在。我们在数据库正在使用时创建了转储文件。第一次尝试成功了。我将再创建一个并再次尝试。

你好。看起来我们的 user_actions 表损坏了。我可以通过运行 VACUUM (VERBOSE,ANALYZE,DISABLE_PAGE_SKIPPING) user_actions 来修复它。不过还是谢谢你的建议!
可见性映射中缺少了几条记录,导致出现了重复键。