Erreur : entier hors de portée

Je rencontre fréquemment cette erreur dans Sidekiq (listes de nouvelles tentatives et de morts) :

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

Les jobs pour lesquels j’ai remarqué cette erreur identique sont :
Jobs::PostAlert
Jobs::ProcessPost
Jobs::NotifyCategoryChange

Cela a déjà été évoqué un peu auparavant ici : Feedback on the new Review Queue (2019) - #250 by markersocial

2 « J'aime »

Pouvez-vous exécuter :

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 « J'aime »

Merci @Falco, je viens de l’exécuter. Voici le résultat :

-[ RECORD 1 ]--
id | 2147483496
4 « J'aime »

D’accord, il s’agit du célèbre problème de la valeur maximale des entiers. Nous devons passer à bigint pour le résoudre. Je vais jeter un coup d’œil à cela.

6 « J'aime »

Pour l’instant, votre solution de contournement consiste à exécuter :

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

C’est la valeur par défaut pour les nouvelles installations, mais les anciennes installations ont le mauvais type de données.

L’exécution de cette solution de contournement peut être difficile car elle va bloquer la table ; vous devrez peut-être réduire d’abord la charge de votre serveur web.

2 « J'aime »

Merci @Falco & @sam - on apprécie :slight_smile:

Concernant la solution de contournement, est-ce que cela devrait être relativement sûr à faire ? On ne s’inquiète pas des temps d’arrêt, mais juste de casser quelque chose.

Cela utilise le conteneur unique standard app.yml. Pour alléger la charge web, pensez-vous que le passage en mode lecture seule et l’exécution de ./launcher stop app, ./launcher start app avant d’appliquer la solution de contournement devraient suffire ?

Cela ne cassera rien ; dans le pire des cas, cela restera simplement « bloqué » pendant très longtemps.

2 « J'aime »

Merci, Sam, j’ai appliqué la solution de contournement. Cependant, je n’ai reçu aucun retour après avoir saisi :

ALTER TABLE notifications ALTER COLUMN id SET DATA TYPE bigint

Je ne sais pas si le processus est encore en cours. Actuellement, je rencontre toujours la même erreur (dans la liste des jobs morts de /sidekiq, pour les derniers essais « à l’instant ») pour :

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

Il semble que vous deviez également inclure la colonne post_id.

1 « J'aime »

Merci ! :slight_smile:

Pour être certain, cela semble-t-il correct ?

ALTER TABLE notifications ALTER COLUMN post_id SET DATA TYPE bigint

Oui, cela devrait être sûr ; une fois que nous ajouterons une migration officielle, cela le permettra.

1 « J'aime »

Parfait, merci :slight_smile:

J’ai exécuté la commande (aucune confirmation ni retour reçu, comme pour la précédente). Le forum ne s’est pas ralenti, donc je ne sais pas si cela a fonctionné. J’obtiens toujours les mêmes erreurs pour le moment.

Peut-être serait-il préférable d’attendre la migration officielle.

1 « J'aime »

Oui, il semble que cela se trouve dans la table post_alerts ; nous devons parcourir de nombreuses tables.

1 « J'aime »

Vous vous demandez où nous en sommes sur ce sujet ? Les erreurs ont-elles cessé ?

À l’origine, nous envisagions de procéder à une migration officielle, mais les risques dépassent largement les avantages. Nous constatons qu’il est extrêmement rare de rencontrer des bases de données contenant plus de 2 147 483 647 publications. 2,1 milliards est un nombre vraiment énorme.

L’inconvénient d’augmenter la taille partout est que les besoins en stockage augmentent.

Nous en sommes actuellement à envisager d’ajouter une tâche rake qui « libère de l’espace » si vous êtes dans un cas atypique où vous avez des tables dans Discourse contenant 2 milliards de lignes (ou qui en ont contenu 2 milliards lors de leur évolution).

1 « J'aime »

Merci pour le suivi @sam

Je viens de passer à la version 2.8.0.beta6 et je rencontre toujours des erreurs de dépassement de capacité entière.

Je pense que ce sont simplement les notifications qui ont atteint un nombre massif, ce qui est plus réaliste pour atteindre la limite par rapport au nombre de publications. De nombreux sujets volumineux avec de nombreuses réponses, likes, etc. provenant de différents utilisateurs peuvent générer un grand nombre de notifications.

Une tâche Rake semble fantastique :slight_smile:

Je sais que c’est un vieux fil de discussion –

Nous venons de rencontrer ce problème dans notre configuration également (devforum.roblox.com) ! Nous utilisons la version v2.8.9, mais nous passerons bientôt à la version 3.0.1.

Nous avons remarqué que quelque chose n’allait pas lorsque les utilisateurs ont commencé à voir des erreurs 403/500 en essayant d’aimer/ne plus aimer des publications.

Ensuite, je suis tombé sur ce fil de discussion et j’ai vérifié notre table de notifications :

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

@sam La solution de contournement ci-dessus est-elle toujours la meilleure suggestion, ou une tâche rake a-t-elle été davantage prise en compte depuis septembre 2021 ?

Plus d’informations –

Après avoir modifié la colonne notifications.id, je rencontre un problème distinct avec le job Jobs::PostAlert

Job exception: 2147498514 est hors de portée pour ActiveModel::Type::Integer avec une limite de 4 octets

Peut-être y a-t-il une autre table/colonne que j’ai manquée ? Ou quelque part dans Ruby qui s’attend toujours au type de données entier ?

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'

Oui, cela reste le seul correctif ici. Je crains de le changer dans le cœur, mais je suppose que cela continuera à se produire sur les forums gigantesques si nous ne corrigeons pas cela.
Le revers de la médaille est une augmentation du stockage.

1 « J'aime »

Savez-vous s’il existe des utilisations dans le service post_actions (ou quelque part dans le processus de notification) qui pourraient encore attendre des entiers après l’exécution de ALTER ?

Nous constatons des erreurs 5xx sur les appels like/unlike vers /post_actions avec la réponse

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

De plus, certaines tâches échouent autour des notifications (Jobs::BookmarkReminderNotifications, Jobs::GrantAnniversaryBadges, Jobs::PostAlert).

J’ai ajouté la trace de la pile pour PostAlert dans mon message précédent ; il semble y avoir un problème lancé pour une limite d’entier par consolidate_or_create dans notification.rb.

Pour notre utilisation, l’augmentation du stockage n’est pas une préoccupation majeure si nous pouvons restaurer la fonctionnalité :crossed_fingers:

Essayez peut-être de redémarrer votre conteneur, il pourrait y avoir des éléments mis en cache en mémoire.