Внутренняя ошибка сервера при использовании некоторых тегов (ERROR: duplicate key value violates unique constraint "index_tags_on_name")

Это кажется странным, так как проблема затрагивает только некоторые теги — при попытке создать тему с тегом пользователю выводится сообщение о внутренней ошибке сервера. Иногда, когда процесс проходит этот этап, мы видим то же самое сообщение в системе очереди модерации. При переходе на страницы этих затронутых тегов выводится сообщение Упс! Эта страница не существует или является частной.

Вот несколько логов:

ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_tags_on_name"
DETAIL:  Key (name)=(ecommerce) already exists.
)
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.0/lib/patches/db/pg.rb:72:in `async_exec_params'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.0/lib/patches/db/pg.rb:72:in `async_exec_params'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.0/lib/patches/db/pg.rb:72:in `exec_params'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:668:in `block (2 levels) in exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies/interlock.rb:47:in `permit_concurrent_loads'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:667:in `block in exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract_adapter.rb:707:in `block (2 levels) in log'
/usr/local/lib/ruby/2.6.0/monitor.rb:235:in `mon_synchronize'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract_adapter.rb:706:in `block in log'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract_adapter.rb:697:in `log'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:666:in `exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:647:in `execute_and_clear'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:96:in `exec_query'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:135:in `exec_insert'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:130:in `exec_insert'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:162:in `insert'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/query_cache.rb:22:in `insert'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/persistence.rb:375:in `_insert_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/persistence.rb:933:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/counter_cache.rb:163:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/locking/optimistic.rb:70:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/attribute_methods/dirty.rb:211:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/callbacks.rb:332:in `block in _create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:135:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:827:in `_run_create_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/callbacks.rb:332:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/timestamp.rb:111:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/persistence.rb:906:in `create_or_update'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/callbacks.rb:328:in `block in create_or_update'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:135:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:827:in `_run_save_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/callbacks.rb:328:in `create_or_update'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/timestamp.rb:129:in `create_or_update'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/persistence.rb:470:in `save'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/validations.rb:47:in `save'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:315:in `block in save'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:375:in `block in with_transaction_returning_status'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:275:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:212:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:366:in `with_transaction_returning_status'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:315:in `save'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/suppressor.rb:44:in `save'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/persistence.rb:38:in `create'
/var/www/discourse/lib/discourse_tagging.rb:62:in `block in tag_topic_by_names'
/var/www/discourse/lib/discourse_tagging.rb:60:in `each'
/var/www/discourse/lib/discourse_tagging.rb:60:in `tag_topic_by_names'
/var/www/discourse/lib/topic_creator.rb:158:in `setup_tags'
/var/www/discourse/lib/topic_creator.rb:37:in `create'
/var/www/discourse/lib/post_creator.rb:421:in `create_topic'
/var/www/discourse/lib/post_creator.rb:168:in `block in create'
/var/www/discourse/lib/post_creator.rb:345:in `block in transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:275:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:212:in `transaction'
/var/www/discourse/lib/post_creator.rb:344:in `transaction'
/var/www/discourse/lib/post_creator.rb:166:in `create'
/var/www/discourse/app/models/reviewable_queued_post.rb:80:in `perform_approve_post'
/var/www/discourse/app/models/reviewable.rb:319:in `public_send'
/var/www/discourse/app/models/reviewable.rb:319:in `block in perform'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:277:in `block in transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/transaction.rb:280:in `block in within_new_transaction'
/usr/local/lib/ruby/2.6.0/monitor.rb:235:in `mon_synchronize'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/transaction.rb:278:in `within_new_transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:277:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:212:in `transaction'
/var/www/discourse/app/models/reviewable.rb:317:in `perform'
/var/www/discourse/app/controllers/reviewables_controller.rb:184:in `perform'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/abstract_controller/base.rb:196:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/rendering.rb:30:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/abstract_controller/callbacks.rb:42:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:135:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/abstract_controller/callbacks.rb:41:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/rescue.rb:22:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications.rb:180:in `block in instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications.rb:180:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/railties/controller_runtime.rb:27:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/abstract_controller/base.rb:136:in `process'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionview-6.0.0/lib/action_view/rendering.rb:39:in `process'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.0/lib/mini_profiler/profiling_methods.rb:104:in `block in profile_method'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal.rb:191:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal.rb:252:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/route_set.rb:51:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/route_set.rb:33:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/journey/router.rb:49:in `block in serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/journey/router.rb:32:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/journey/router.rb:32:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/route_set.rb:837:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.7/lib/rack/protection/frame_options.rb:31:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:68:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/tempfile_reaper.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/conditional_get.rb:38:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/head.rb:12:in `call'
/var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:274:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:232:in `context'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:226:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/cookies.rb:648:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:101:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.3.3/lib/logster/middleware/reporter.rb:43:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/rack/logger.rb:38:in `call_app'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/rack/logger.rb:28:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:18:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:31:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/var/www/discourse/lib/middleware/enforce_hostname.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/method_override.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/executor.rb:14:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/sendfile.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/host_authorization.rb:77:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.0/lib/mini_profiler/profiler.rb:296:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/message_bus-2.2.2/lib/message_bus/rack/middleware.rb:57:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:176:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/engine.rb:526:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:68:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:605:in `process_client'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:700:in `worker_loop'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:548:in `spawn_missing_workers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:144:in `start'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/bin/unicorn:128:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `<main>'

Failed to handle exception in exception app middleware : PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_tags_on_name"
DETAIL:  Key (name)=(ecommerce) already exists.
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.0/lib/patches/db/pg.rb:72:in `async_exec_params'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.0/lib/patches/db/pg.rb:72:in `exec_params'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:668:in `block (2 levels) in exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/dependencies/interlock.rb:47:in `permit_concurrent_loads'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:667:in `block in exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract_adapter.rb:707:in `block (2 levels) in log'
/usr/local/lib/ruby/2.6.0/monitor.rb:235:in `mon_synchronize'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract_adapter.rb:706:in `block in log'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract_adapter.rb:697:in `log'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:666:in `exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:647:in `execute_and_clear'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:96:in `exec_query'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:135:in `exec_insert'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:130:in `exec_insert'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:162:in `insert'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/query_cache.rb:22:in `insert'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/persistence.rb:375:in `_insert_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/persistence.rb:933:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/counter_cache.rb:163:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/locking/optimistic.rb:70:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/attribute_methods/dirty.rb:211:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/callbacks.rb:332:in `block in _create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:135:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:827:in `_run_create_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/callbacks.rb:332:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/timestamp.rb:111:in `_create_record'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/persistence.rb:906:in `create_or_update'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/callbacks.rb:328:in `block in create_or_update'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:135:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:827:in `_run_save_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/callbacks.rb:328:in `create_or_update'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/timestamp.rb:129:in `create_or_update'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/persistence.rb:470:in `save'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/validations.rb:47:in `save'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:315:in `block in save'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:375:in `block in with_transaction_returning_status'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:275:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:212:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:366:in `with_transaction_returning_status'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:315:in `save'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/suppressor.rb:44:in `save'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/persistence.rb:38:in `create'
/var/www/discourse/lib/discourse_tagging.rb:62:in `block in tag_topic_by_names'
/var/www/discourse/lib/discourse_tagging.rb:60:in `each'
/var/www/discourse/lib/discourse_tagging.rb:60:in `tag_topic_by_names'
/var/www/discourse/lib/topic_creator.rb:158:in `setup_tags'
/var/www/discourse/lib/topic_creator.rb:37:in `create'
/var/www/discourse/lib/post_creator.rb:421:in `create_topic'
/var/www/discourse/lib/post_creator.rb:168:in `block in create'
/var/www/discourse/lib/post_creator.rb:345:in `block in transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:275:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:212:in `transaction'
/var/www/discourse/lib/post_creator.rb:344:in `transaction'
/var/www/discourse/lib/post_creator.rb:166:in `create'
/var/www/discourse/app/models/reviewable_queued_post.rb:80:in `perform_approve_post'
/var/www/discourse/app/models/reviewable.rb:319:in `public_send'
/var/www/discourse/app/models/reviewable.rb:319:in `block in perform'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:277:in `block in transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/transaction.rb:280:in `block in within_new_transaction'
/usr/local/lib/ruby/2.6.0/monitor.rb:235:in `mon_synchronize'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/transaction.rb:278:in `within_new_transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:277:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/transactions.rb:212:in `transaction'
/var/www/discourse/app/models/reviewable.rb:317:in `perform'
/var/www/discourse/app/controllers/reviewables_controller.rb:184:in `perform'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/abstract_controller/base.rb:196:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/rendering.rb:30:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/abstract_controller/callbacks.rb:42:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:135:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/abstract_controller/callbacks.rb:41:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/rescue.rb:22:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications.rb:180:in `block in instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications.rb:180:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.0/lib/active_record/railties/controller_runtime.rb:27:in `process_action'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/abstract_controller/base.rb:136:in `process'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionview-6.0.0/lib/action_view/rendering.rb:39:in `process'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.0/lib/mini_profiler/profiling_methods.rb:104:in `block in profile_method'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal.rb:191:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_controller/metal.rb:252:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/route_set.rb:51:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/route_set.rb:33:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/journey/router.rb:49:in `block in serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/journey/router.rb:32:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/journey/router.rb:32:in `serve'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/routing/route_set.rb:837:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.7/lib/rack/protection/frame_options.rb:31:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:68:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/tempfile_reaper.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/conditional_get.rb:38:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/head.rb:12:in `call'
/var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:274:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:232:in `context'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:226:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/cookies.rb:648:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.0/lib/active_support/callbacks.rb:101:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.3.3/lib/logster/middleware/reporter.rb:43:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/rack/logger.rb:38:in `call_app'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/rack/logger.rb:28:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:18:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:31:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/var/www/discourse/lib/middleware/enforce_hostname.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/method_override.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/executor.rb:14:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/sendfile.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-6.0.0/lib/action_dispatch/middleware/host_authorization.rb:77:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.0/lib/mini_profiler/profiler.rb:296:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/message_bus-2.2.2/lib/message_bus/rack/middleware.rb:57:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:176:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/engine.rb:526:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.0/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:68:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:605:in `process_client'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:700:in `worker_loop'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:548:in `spawn_missing_workers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:144:in `start'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/bin/unicorn:128:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `<main>'

Есть идеи, почему это происходит? Похоже, система пытается создать тег, который уже существует?

Обновление:

В случае одного из тегов, вызывавшего ту же проблему, мы просто попросили пользователя перепостить сообщение без тега, а затем при редактировании я смог добавить тег (и также зайти на страницу тега без проблем). Ранее пользователь мог опубликовать тему, но она попадала в очередь на модерацию (поскольку мы проверяем все первые сообщения/темы), и при попытке одобрить тему возникала внутренняя ошибка сервера.

Однако я не могу добавить другой тег, с которым возникла проблема (ecommerce), так как система по-прежнему сообщает о внутренней ошибке сервера.

Получаю ту же ошибку на другом теге:

ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "index_tags_on_name"
DETAIL:  Key (name)=(file-uploading) already exists.
)
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.2/lib/patches/db/pg.rb:72:in `async_exec_params'

Это баг Discourse или AR/Rails? Похоже, что система пытается создать тег заново, хотя он уже существует?

Посмотрите в Data Explorer в таблице тегов, возможно, есть проблема с регистром: Ecommerce против ecommerce?

1 лайк

Привет, Сэм, я посмотрел в таблицу, и там есть:

ecommerce
e-commerce

Во втором случае (file-uploading) есть:

file-downloading
file-uploading

У обоих есть дефисы, поэтому я задаюсь вопросом, не в этом ли причина?

В настройках у нас отмечена опция «принудительное приведение тегов к нижнему регистру» — не может ли это как-то конфликтовать?

Если нужно, чтобы я проверил что-то ещё, дай знать :blush:

Не уверен на 100%, подождите день или около того. @neil очень хорошо знает систему тегов, возможно, у него есть какие-то идеи по этому поводу.

1 лайк

Сделаю, спасибо, Сэм :smiley:

Я пробовал использовать теги со смешанным регистром и теги, содержащие дефисы, но не смог воспроизвести эту ошибку. Какую именно версию Discourse вы используете? Происходит ли это в категории с ограничениями на теги? Какие ещё настройки тегов вы применяете?

2 лайка

Привет, Нил, я использую версию 2.4.0.beta6 (8ca5aad1e2)

Мне удалось исправить проблему, вручную переименовав теги в консоли Rails — удивительно, но тег e.commerce возвращал nil, хотя он существовал! Я нашёл его по ID, переименовал, и теперь всё работает.

У меня есть ощущение, что это началось с внедрения чувствительности к регистру (проблема существует уже какое-то время, но я обычно жду несколько новых релизов, так как вы обычно довольно быстро исправляете подобные вещи).

Если вам нужно, чтобы я что-то ещё проверил, дайте знать. В противном случае я пройду по всем тегам (или журналам ошибок), найду другие неработающие теги и исправлю их. На всякий случай, вот ответы на ваши вопросы:

Нет — но во всех категориях требуется хотя бы один тег.

1 лайк

Я не понимаю, в чём была проблема. Вы переименовали “e.commerce” из чего во что? Я протестировал включение/отключение настройки принудительного приведения тегов к нижнему регистру, используя теги со смешанным регистром, и система не попыталась создать дубликаты тегов.

3 лайка

Я переименовал tag-name в tag-name2, а затем обратно в tag-name.

Для их поиска я использовал метод поиска по имени:

Tag.find_by name: "tag-name"

Однако это не сработало для e-commerce. Мне пришлось искать его по ID, что кажется странным — не понимаю, почему так произошло.

Единственное, что ещё приходит в голову: возможно, в какой-то момент я массово пометил темы, выполнив поиск, затем открыв несколько тем и выбрав «Добавить тег» в меню опций. Не уверен, может ли это иметь значение, хотя : /

Извини, @neil, я столкнулся с ещё одной проблемой, которая может быть связана.

Две тега с одинаковым именем, но моё ручное исправление на этот раз не работает.

[1] pry(main)> Tag.find_by(name: "liveview")
=> #<Tag:0x000055646b510750
 id: 1843,
 name: "liveview",
 topic_count: 25,
 created_at: Tue, 01 Oct 2019 07:42:44 UTC +00:00,
 updated_at: Tue, 01 Oct 2019 07:42:44 UTC +00:00,
 pm_topic_count: 0>
[2] pry(main)> t=Tag.find_by(id: 1036)
=> #<Tag:0x000055646b653978
 id: 1036,
 name: "liveview",
 topic_count: 150,
 created_at: Sun, 09 Sep 2018 16:19:15 UTC +00:00,
 updated_at: Sun, 09 Sep 2018 16:19:15 UTC +00:00,
 pm_topic_count: 0>
[3] pry(main)> t2=Tag.find_by(id: 1843)
=> #<Tag:0x000055646b6af7a0
 id: 1843,
 name: "liveview",
 topic_count: 25,
 created_at: Tue, 01 Oct 2019 07:42:44 UTC +00:00,
 updated_at: Tue, 01 Oct 2019 07:42:44 UTC +00:00,
 pm_topic_count: 0>
[4] pry(main)> t2.name = "liveview2"
=> "liveview2"
[5] pry(main)> t2.save
=> true
[6] pry(main)> t.name = "liveview1"
=> "liveview1"
[7] pry(main)> t.save
=> true
[8] pry(main)> t.name = "liveview"
=> "liveview"
[9] pry(main)> t.save
=> true
[10] pry(main)> t.name = "liveview1"
=> "liveview1"
[11] pry(main)> 

liveview2 работает, но одинокий liveview — нет, хотя он работает, когда называется liveview1, но при изменении имени обратно на liveview просто выводит Ой! Страница не существует или является приватной.. Связано ли это с индексом?

(ничего нет и в /logs)

Для защиты от этого случая предусмотрено два индекса. Отсутствуют ли индексы в вашей базе данных?

$ bin/rails db

discourse_development=# \d tags
                                          Table "public.tags"
     Column     |            Type             | Collation | Nullable |             Default              
----------------+-----------------------------+-----------+----------+----------------------------------
 id             | integer                     |           | not null | nextval('tags_id_seq'::regclass)
 name           | character varying           |           | not null | 
 topic_count    | integer                     |           | not null | 0
 created_at     | timestamp without time zone |           | not null | 
 updated_at     | timestamp without time zone |           | not null | 
 pm_topic_count | integer                     |           | not null | 0
Indexes:
    "tags_pkey" PRIMARY KEY, btree (id)
    "index_tags_on_lower_name" UNIQUE, btree (lower(name::text))
    "index_tags_on_name" UNIQUE, btree (name)

Миграция от 28 сентября 2018 года должна была исправить теги с дублирующимися именами, а затем создать один из индексов. https://github.com/discourse/discourse/blob/master/db/migrate/20180928105835_add_index_to_tags.rb

Вы импортировали свой сайт из другого программного обеспечения для форумов? Если да, то это могло привести к созданию дублирующихся строк, после чего создание индексов не удалось выполнить.

1 лайк
     Column     |            Type             | Collation | Nullable |             Default              
----------------+-----------------------------+-----------+----------+----------------------------------
 id             | integer                     |           | not null | nextval('tags_id_seq'::regclass)
 name           | character varying           |           | not null | 
 topic_count    | integer                     |           | not null | 0
 created_at     | timestamp without time zone |           |          | 
 updated_at     | timestamp without time zone |           |          | 
 pm_topic_count | integer                     |           | not null | 0
Indexes:
    "tags_pkey" PRIMARY KEY, btree (id)
    "index_tags_on_lower_name" UNIQUE, btree (lower(name::text))
    "index_tags_on_name" UNIQUE, btree (name)

Нет, это всегда был форум на Discourse — единственное, что я сделал, это переехал на другой сервер, что потребовало чистой установки и последующего импорта через резервную копию. Думаю, это было сделано примерно в августе прошлого года — могло ли это стать причиной?

Стоит ли мне выполнить что-то вроде REINDEX TABLE tags; для перестроения индексов, Нил?

Редактирование: только что заметил, что у полей created_at и updated_at нет значения not null в столбце Nullable — имеет ли это значение?

Редактирование 2: Только что заметил, что у нас есть две такие теги:

1862	live-view
1486	live-view

Да, я думаю, что перестроение индекса таблицы необходимо. Но сначала вам нужно переименовать теги с одинаковыми названиями, иначе перестроение не удастся. И будем надеяться, что проблема только в таблице тегов…

Я не вижу, как восстановление могло бы создать эту проблему. Индексы присутствуют, но явно не работают.

2 лайка

Готово :smiley:

Если кому-то еще нужен запрос для поиска дубликатов тегов, то он такой:

SELECT name, COUNT(*)
FROM tags
GROUP BY name
HAVING COUNT(*) > 1

Не пугай меня, Нил! :scream:

Я быстро посмотрел таблицу категорий, и там всё в порядке (есть несколько дубликатов записей по названию, но это подкатегории).

Спасибо за помощь @sam и @neil :blush:

(Перестроение индекса не повлияло на эту проблему, Нил)

У нас есть этот индекс:

Вы на 100% уверены, что он существует в таблице? То, что вы описываете, — это полностью сломанный Postgres, что невероятно маловероятно. Это вызвало бы настоящий шок в сообществе.

Гораздо более вероятно, что в какой-то момент этот индекс был удалён из-за человеческой ошибки…

Как минимум, я рекомендую выполнить create unique index on tags (name), но что ещё может отсутствовать?

3 лайка

Привет, Сэм,

У меня есть:

discourse=> \d tags
                                          Таблица "public.tags"
     Столбец      |            Тип             | Сортировка | Не может быть пустым |             Значение по умолчанию              
----------------+-----------------------------+-----------+----------+----------------------------------
 id             | integer                     |           | not null | nextval('tags_id_seq'::regclass)
 name           | character varying           |           | not null | 
 topic_count    | integer                     |           | not null | 0
 created_at     | timestamp without time zone |           |          | 
 updated_at     | timestamp without time zone |           |          | 
 pm_topic_count | integer                     |           | not null | 0
Индексы:
    "tags_pkey" PRIMARY KEY, btree (id)
    "index_tags_on_lower_name" UNIQUE, btree (lower(name::text))
    "index_tags_on_name" UNIQUE, btree (name)

Чтобы воссоздать индексы, я…

  • переименовал дублирующиеся теги (так что tag_name_1 и tag_name_2 и т. д.)
  • проверил, что дублирующихся тегов больше нет, используя запрос из сообщения выше
  • перешел в rails db и выполнил:
discourse=> REINDEX TABLE tags;
REINDEX

Сэм, нужно ли мне сделать что-то ещё, кроме этого?

Попробуйте вставить дублирующуюся запись и убедитесь, что ваш индекс корректно работает и больше не допускает дубликатов данных.

1 лайк

Выглядит хорошо, Сэм:

[1] pry(main)> t=Tag.new
=> #<Tag:0x000055fe76499830 id: nil, name: nil, topic_count: 0, created_at: nil, updated_at: nil, pm_topic_count: 0>
[2] pry(main)> t
=> #<Tag:0x000055fe76499830 id: nil, name: nil, topic_count: 0, created_at: nil, updated_at: nil, pm_topic_count: 0>
[3] pry(main)> t.name ="test-five"
=> "test-five"
[4] pry(main)> t.save
=> true

[5] pry(main)> Tag.last
=> #<Tag:0x000055fe7671ce90
 id: 1995,
 name: "test-five",
 topic_count: 0,
 created_at: Fri, 08 Nov 2019 02:44:36 UTC +00:00,
 updated_at: Fri, 08 Nov 2019 02:44:36 UTC +00:00,
 pm_topic_count: 0

[6] pry(main)> t=Tag.new
=> #<Tag:0x000055fe76763a70 id: nil, name: nil, topic_count: 0, created_at: nil, updated_at: nil, pm_topic_count: 0>
[7] pry(main)> t.name ="test-five"
=> "test-five"
[8] pry(main)> t.save
=> false
[9] pry(main)> 

Также пробовал через форум в теме:

Если, по вашему мнению, стоит попробовать что-то ещё, дайте знать :smiley:

1 лайк

Также для подтверждения: я не выполнял никаких других действий с базой данных через консоль, поэтому не понимаю, почему это произошло. Мне кажется, что проблема могла начаться после внедрения учёта регистра, но я не уверен. Если нужно, чтобы я проверил что-то ещё для выявления корневой причины проблемы, просто дайте знать, Сэм.