Erro: inteiro fora do intervalo

Estou recebendo muito esse erro no Sidekiq (listas de Retries e Dead):

Jobs::HandledExceptionWrapper: Wrapped ActiveRecord::RangeError: PG::NumericValueOutOfRange: ERROR: integer out of range 

Os jobs para os quais notei esse erro idêntico são:
Jobs::PostAlert
Jobs::ProcessPost
Jobs::NotifyCategoryChange

Isso foi discutido um pouco no passado aqui: Feedback on the new Review Queue (2019) - #250 by markersocial

2 curtidas

Por favor, execute:

cd /var/discourse/
./launcher enter app
su postgres
psql
\x
\connect discourse 
SELECT id FROM notifications ORDER BY 1 DESC LIMIT 1;
\q
exit
4 curtidas

Obrigado, @Falco. Acabei de executá-lo agora. Aqui está o resultado:

-[ RECORD 1 ]--
id | 2147483496
4 curtidas

Ok, então é o famoso problema do max inteiro. Precisamos migrar para bigint para corrigir isso. Vou dar uma olhada nisso.

6 curtidas

Por enquanto, sua solução alternativa é executar:

cd /var/discourse/
./launcher enter app
su postgres
psql
\x
\connect discourse 
ALTER TABLE notifications ALTER COLUMN id SET DATA TYPE bigint
\q
exit

Isso é o padrão para instalações novas, mas instalações antigas têm o tipo de dados incorreto.

Executar a solução alternativa pode ser difícil, pois bloqueará a tabela; talvez você precise reduzir a carga da sua web primeiro.

2 curtidas

Obrigado @Falco & @sam - agradeço :slight_smile:

Quanto à solução alternativa, isso deve ser relativamente seguro de fazer? Não me preocupo com tempo de inatividade, apenas com quebrar algo.

Está usando o app.yml padrão de contêiner único. Para aliviar a carga da web, você acha que usar o modo somente leitura e executar ./launcher stop app, ./launcher start app antes de fazer a solução alternativa provavelmente seria suficiente?

Isso não vai quebrar nada; no pior dos casos, ficará apenas “travado” por muito tempo.

2 curtidas

Obrigado, Sam. Apliquei a solução alternativa. No entanto, não recebi nenhuma confirmação ao executar:

ALTER TABLE notifications ALTER COLUMN id SET DATA TYPE bigint

Não tenho certeza se ainda está processando. Atualmente, estou recebendo o mesmo erro (na lista /sidekiq dead, para as tarefas de última tentativa ‘agora mesmo’) para:

Jobs::PostAlert
Jobs::ProcessPost
Jobs::NotifyCategoryChange

Parece que você também precisa executar com a coluna post_id

1 curtida

Obrigado! :slight_smile:

Só para confirmar, isso parece correto?

ALTER TABLE notifications ALTER COLUMN post_id SET DATA TYPE bigint

Sim, isso deve ser seguro. Assim que adicionarmos uma migração oficial, ela permitirá isso.

1 curtida

Perfeito, obrigado :slight_smile:

Executei isso (sem confirmação/feedback recebido, como no anterior). O fórum não ficou lento, então não tenho certeza se funcionou. Estou recebendo os mesmos erros atualmente.

Talvez seja melhor eu aguardar a migração oficial.

1 curtida

Sim, parece que isso está na tabela post_alerts, precisamos varrer muitas tabelas

1 curtida

Curioso sobre onde você está com relação a esse problema agora? Os erros pararam?

Originalmente, estávamos pensando em fazer uma migração oficial aqui, mas o risco supera em muito o benefício. Achamos extremamente raro encontrar bancos de dados com mais de 2.147.483.647 posts. 2,1 bilhões é um número realmente grande.

A desvantagem de aumentar o tamanho em todos os lugares é que os requisitos de armazenamento aumentam.

Onde estamos agora é que estamos considerando adicionar uma tarefa rake que “libera espaço” se você estiver em um caso atípico onde possui tabelas no Discourse que contêm 2 bilhões de linhas (ou tiveram 2 bilhões de linhas de alteração).

1 curtida

Obrigado pelo retorno, @sam.

Acabei de atualizar para a versão 2.8.0.beta6 e ainda estou recebendo erros de inteiro fora do intervalo.

Acho que são apenas as notificações que atingiram um número massivo, o que é mais realista para alcançar o limite em comparação com o número de posts. Muitos tópicos grandes com várias respostas, curtidas etc. de diferentes usuários podem resultar em um grande volume de notificações.

Uma tarefa rake soa fantástica :slight_smile:

Sei que este é um tópico antigo –

Acabamos de encontrar esse problema em nossa configuração também (devforum.roblox.com)! Estamos executando a v2.8.9, mas atualizaremos para a 3.0.1 em breve.

Notamos que algo estava errado quando os usuários começaram a ver 403/500 ao tentar curtir/descurtir posts.

Então me deparei com este tópico e verifiquei nossa tabela de notificações:

=> SELECT id FROM notifications ORDER BY 1 DESC LIMIT 1;
     id     
------------
 2147483647
(1 row)

@sam A solução alternativa acima ainda é a melhor sugestão, ou foi dada mais consideração a uma tarefa rake desde setembro de 2021?

Mais informações –

Após alterar a coluna notifications.id, estou vendo um problema separado do job Jobs::PostAlert

Job exception: 2147498514 está fora do intervalo para ActiveModel::Type::Integer com limite de 4 bytes

Talvez haja outra tabela/coluna que eu esteja perdendo? Ou em algum lugar no ruby que ainda esteja esperando o tipo de dado inteiro?

backtrace
activemodel-6.1.6.1/lib/active_model/type/integer.rb:49:in `ensure_in_range'

activemodel-6.1.6.1/lib/active_model/type/integer.rb:28:in `serialize'

activemodel-6.1.6.1/lib/active_model/attribute.rb:56:in `value_for_database'

activemodel-6.1.6.1/lib/active_model/attribute.rb:68:in `forgetting_assignment'

activemodel-6.1.6.1/lib/active_model/attribute_set.rb:90:in `transform_values'

activemodel-6.1.6.1/lib/active_model/attribute_set.rb:90:in `map'

activemodel-6.1.6.1/lib/active_model/dirty.rb:262:in `forget_attribute_assignments'

activemodel-6.1.6.1/lib/active_model/dirty.rb:154:in `changes_applied'

activerecord-6.1.6.1/lib/active_record/attribute_methods/dirty.rb:202:in `_create_record'

activerecord-6.1.6.1/lib/active_record/callbacks.rb:461:in `block in _create_record'

activesupport-6.1.6.1/lib/active_support/callbacks.rb:106:in `run_callbacks'

activesupport-6.1.6.1/lib/active_support/callbacks.rb:824:in `_run_create_callbacks'

activerecord-6.1.6.1/lib/active_record/callbacks.rb:461:in `_create_record'

activerecord-6.1.6.1/lib/active_record/timestamp.rb:108:in `_create_record'

activerecord-6.1.6.1/lib/active_record/persistence.rb:900:in `create_or_update'

activerecord-6.1.6.1/lib/active_record/callbacks.rb:457:in `block in create_or_update'

activesupport-6.1.6.1/lib/active_support/callbacks.rb:106:in `run_callbacks'

activesupport-6.1.6.1/lib/active_support/callbacks.rb:824:in `_run_save_callbacks'

activerecord-6.1.6.1/lib/active_record/callbacks.rb:457:in `create_or_update'

activerecord-6.1.6.1/lib/active_record/timestamp.rb:126:in `create_or_update'

activerecord-6.1.6.1/lib/active_record/persistence.rb:507:in `save!'

activerecord-6.1.6.1/lib/active_record/validations.rb:53:in `save!'

activerecord-6.1.6.1/lib/active_record/transactions.rb:302:in `block in save!'

activerecord-6.1.6.1/lib/active_record/transactions.rb:354:in `block in with_transaction_returning_status'

activerecord-6.1.6.1/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `block in transaction'

activerecord-6.1.6.1/lib/active_record/connection_adapters/abstract/transaction.rb:319:in `block in within_new_transaction'

activesupport-6.1.6.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize'

activesupport-6.1.6.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'

activesupport-6.1.6.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'

activesupport-6.1.6.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'

activesupport-6.1.6.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'

activerecord-6.1.6.1/lib/active_record/connection_adapters/abstract/transaction.rb:317:in `within_new_transaction'

activerecord-6.1.6.1/lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `transaction'

activerecord-6.1.6.1/lib/active_record/transactions.rb:350:in `with_transaction_returning_status'

activerecord-6.1.6.1/lib/active_record/transactions.rb:302:in `save!'

activerecord-6.1.6.1/lib/active_record/suppressor.rb:48:in `save!'

/app/app/models/notification.rb:40:in `tap'

/app/app/models/notification.rb:40:in `consolidate_or_create!'

activerecord-6.1.6.1/lib/active_record/relation/delegation.rb:67:in `block in consolidate_or_create!'

activerecord-6.1.6.1/lib/active_record/relation.rb:406:in `block in scoping'

activerecord-6.1.6.1/lib/active_record/relation.rb:804:in `_scoping'

activerecord-6.1.6.1/lib/active_record/relation.rb:406:in `scoping'

activerecord-6.1.6.1/lib/active_record/associations/collection_proxy.rb:1109:in `scoping'

activerecord-6.1.6.1/lib/active_record/relation/delegation.rb:67:in `consolidate_or_create!'

/app/app/services/post_alerter.rb:496:in `create_notification'

/app/app/services/post_alerter.rb:825:in `block in notify_post_users'

/app/app/services/post_alerter.rb:838:in `block (2 levels) in each_user_in_batches'

activerecord-6.1.6.1/lib/active_record/relation/delegation.rb:88:in `each'

activerecord-6.1.6.1/lib/active_record/relation/delegation.rb:88:in `each'

/app/app/services/post_alerter.rb:838:in `block in each_user_in_batches'

/app/app/services/post_alerter.rb:837:in `each'

/app/app/services/post_alerter.rb:837:in `each_slice'

/app/app/services/post_alerter.rb:837:in `each_user_in_batches'

/app/app/services/post_alerter.rb:821:in `notify_post_users'

/app/app/services/post_alerter.rb:162:in `after_save_post'

/app/app/jobs/regular/post_alert.rb:11:in `execute'

/app/app/jobs/base.rb:232:in `block (2 levels) in perform'

/app/lib/rails_multisite/connection_management.rb:80:in `with_connection'

/app/app/jobs/base.rb:221:in `block in perform'

/app/app/jobs/base.rb:217:in `each'

/app/app/jobs/base.rb:217:in `perform'

sidekiq-6.3.1/lib/sidekiq/processor.rb:196:in `execute_job'

sidekiq-6.3.1/lib/sidekiq/processor.rb:164:in `block (2 levels) in process'

sidekiq-6.3.1/lib/sidekiq/middleware/chain.rb:138:in `block in invoke'

/app/lib/sidekiq/pausable.rb:138:in `call'

sidekiq-6.3.1/lib/sidekiq/middleware/chain.rb:140:in `block in invoke'

sidekiq-6.3.1/lib/sidekiq/middleware/chain.rb:143:in `invoke'

sidekiq-6.3.1/lib/sidekiq/processor.rb:163:in `block in process'

sidekiq-6.3.1/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'

sidekiq-6.3.1/lib/sidekiq/job_retry.rb:112:in `local'

sidekiq-6.3.1/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'

sidekiq-6.3.1/lib/sidekiq/rails.rb:14:in `block in call'

activesupport-6.1.6.1/lib/active_support/execution_wrapper.rb:91:in `wrap'

activesupport-6.1.6.1/lib/active_support/reloader.rb:72:in `block in wrap'

activesupport-6.1.6.1/lib/active_support/execution_wrapper.rb:91:in `wrap'

activesupport-6.1.6.1/lib/active_support/reloader.rb:71:in `wrap'

sidekiq-6.3.1/lib/sidekiq/rails.rb:13:in `call'

sidekiq-6.3.1/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'

sidekiq-6.3.1/lib/sidekiq/processor.rb:257:in `stats'

sidekiq-6.3.1/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'

sidekiq-6.3.1/lib/sidekiq/job_logger.rb:13:in `call'

sidekiq-6.3.1/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'

sidekiq-6.3.1/lib/sidekiq/job_retry.rb:79:in `global'

sidekiq-6.3.1/lib/sidekiq/processor.rb:124:in `block in dispatch'

sidekiq-6.3.1/lib/sidekiq/logger.rb:11:in `with'

sidekiq-6.3.1/lib/sidekiq/job_logger.rb:33:in `prepare'

sidekiq-6.3.1/lib/sidekiq/processor.rb:123:in `dispatch'

sidekiq-6.3.1/lib/sidekiq/processor.rb:162:in `process'

sidekiq-6.3.1/lib/sidekiq/processor.rb:78:in `process_one'

sidekiq-6.3.1/lib/sidekiq/processor.rb:68:in `run'

sidekiq-6.3.1/lib/sidekiq/util.rb:43:in `watchdog'

sidekiq-6.3.1/lib/sidekiq/util.rb:52:in `block in safe_thread'

Sim, esta continua sendo a única solução alternativa aqui. Preocupo-me em alterá-la no núcleo, mas acho que isso continuará acontecendo em fóruns gigantescos se não resolvermos isso.
A desvantagem é o aumento do armazenamento.

1 curtida

Você sabe se há algum uso no serviço post_actions (ou em algum lugar no processo de notificação) que ainda possa estar esperando inteiros após a execução do ALTER?

Estamos vendo erros 5xx em chamadas de like/unlike para /post_actions com a resposta

{"errors":["The requested URL or resource could not be found."],"error_type":"not_found"}

Além disso, algumas falhas de jobs em torno de notificações (Jobs::BookmarkReminderNotifications, Jobs::GrantAnniversaryBadges, Jobs::PostAlert).
Adicionei o backtrace para PostAlert em minha mensagem anterior; parece que há um problema sendo lançado para um limite de inteiro por consolidate_or_create em notification.rb.

Para o nosso uso, o aumento do armazenamento não é uma grande preocupação se pudermos restaurar a funcionalidade :crossed_fingers:

Talvez tente reiniciar seu contêiner, pode haver algo em cache na memória.