130 votes

Postgres: "ERREUR: le plan mis en cache ne doit pas changer le type de résultat"

Cette exception est lancée par le serveur PostgreSQL 8.3.7 vers mon application. Est-ce que quelqu'un sait ce que signifie cette erreur et ce que je peux faire à ce sujet ?

ERREUR: le plan mis en cache ne doit pas changer le type de résultat
DECLARATION: select code,is_deprecated from country where code=$1

0 votes

Pouvez-vous s'il vous plaît partager la version exacte de PostgreSQL? 8.3.X?

211voto

Jin Kim Points 2529

J'ai compris ce qui causait cette erreur.

Mon application a ouvert une connexion à la base de données et a préparé une requête SELECT à exécuter.

Pendant ce temps, un autre script modifiait la table de la base de données, en changeant le type de données d'une des colonnes renvoyées dans la requête SELECT ci-dessus.

J'ai résolu ce problème en redémarrant l'application après que la table de la base de données ait été modifiée. Cela a réinitialisé la connexion à la base de données, permettant à la requête préparée de s'exécuter sans erreurs.

4 votes

J'ai obtenu ceci sur PostgreSQL 9.0.4, avec Ruby on Rails 3.1-pre5. Il semble que cela devrait être géré automatiquement par ActiveRecord, non?

3 votes

Oui, j'espère qu'ActiveRecord va finalement s'occuper de cela. Je crois que l'appel à MyModel.reset_column_information va régler les choses à court terme si vous voulez éviter de redémarrer.

1 votes

J'ai passé une heure à comprendre ce qui s'était passé de travers. Ta réponse m'a sauvé!

38voto

Shorn Points 1304

Je rajoute cette réponse pour toute personne arrivant ici en googlant ERROR: cached plan must not change result type en essayant de résoudre le problème dans le contexte d'une application Java / JDBC.

J'ai pu reproduire l'erreur de manière fiable en exécutant des mises à jour de schéma (c'est-à-dire des instructions DDL) alors que mon application back-end utilisant la base de données était en cours d'exécution. Si l'application interrogeait une table qui avait été modifiée par la mise à niveau du schéma (c'est-à-dire si l'application exécutait des requêtes avant et après la mise à niveau sur une table modifiée) - le pilote postgres retournerait cette erreur car il semble qu'il fait du caching de certains détails du schéma.

Vous pouvez éviter le problème en configurant votre pilote pgjdbc avec autosave=conservative. Avec cette option, le pilote pourra vider les détails qu'il met en cache et vous ne devriez pas avoir à redémarrer votre serveur ou à vider votre pool de connexions ou à tout autre contournement que vous auriez pu trouver.

Reproduit sur Postgres 9.6 (AWS RDS) et mes premiers tests semblent indiquer que le problème est complètement résolu avec cette option.

Documentation : https://jdbc.postgresql.org/documentation/head/connect.html#connection-parameters

Vous pouvez consulter le problème pgjdbc Github issue 451 pour plus de détails et l'historique du problème.


Les utilisateurs de ActiveRecord JRuby voient cela : https://github.com/jruby/activerecord-jdbc-adapter/blob/master/lib/arjdbc/postgresql/connection_methods.rb#L60


Remarque sur les performances :

En ce qui concerne les problèmes de performances signalés dans le lien ci-dessus - vous devriez effectuer des tests de performances / de charge / de saturation de votre application avant d'activer cela aveuglément.

Après avoir effectué des tests de performance sur mon application tournant sur une instance Postgres 10 AWS RDS, activer le réglage conservative entraîne une utilisation supplémentaire du CPU sur le serveur de base de données. Ce n'était pas grand chose cependant, je pouvais seulement voir la fonctionnalité autosave consommer une quantité mesurable de CPU après avoir optimisé chaque requête de mon test de charge et commencé à pousser fort le test de charge.

10 votes

Pourquoi n'est-ce pas la valeur par défaut?

1 votes

Fonctionne comme annoncé. Mes tests simples n'ont montré aucun impact sur les performances.

1 votes

Comment configurer cela avec le pilote Ruby Postgres ?

3voto

irscomp Points 79

Pour nous, nous étions confrontés à un problème similaire. Notre application fonctionne sur plusieurs schémas. Chaque fois que nous apportions des modifications au schéma, ce problème commençait à se produire.

La configuration du paramètre prepareThreshold=0 à l'intérieur du paramètre JDBC désactive le cache des instructions au niveau de la base de données. Cela a résolu le problème pour nous.

0 votes

Voilà l'idée. J'ai utilisé "preparedStatementCacheQueries=0" à la place.

1voto

Esmaeil Mirzaee Points 320

Les utilisateurs de Prisma doivent redémarrer votre application. Les erreurs se produisent lorsque vous modifiez le fichier prisma/schema.prisma et mettez à jour votre base de données sans redémarrer votre application.

0voto

Sumant Dey Points 1

J'ai obtenu cette erreur, j'ai manuellement exécuté la requête de sélection qui échouait et cela a corrigé l'erreur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X