130 votes

Postgres: "ERREUR: le plan mis en cache ne doit pas modifier 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 que puis-je faire à ce sujet?

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

0 votes

Pouvez-vous s'il vous plaît partager la version exacte de PostreSQL? 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 instruction SELECT pour l'exécution.

Pendant ce temps, un autre script modifiait la table de la base de données, changeant le type de données d'une des colonnes retournées dans l'instruction SELECT ci-dessus.

J'ai résolu cela en redémarrant l'application après que la table de la base de données a été modifiée. Cela a réinitialisé la connexion à la base de données, permettant à l'instruction 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 que ActiveRecord finira par s'occuper de cela. Je crois que l'appel à MyModel.reset_column_information corrigera les choses à court terme si vous voulez éviter de redémarrer.

1 votes

J'ai perdu une heure à comprendre ce qui n'allait pas. Votre réponse m'a sauvé(e) !

38voto

Shorn Points 1304

Je rajoute cette réponse pour toute personne arrivant ici en recherchant sur Google 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) pendant 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 à jour de schéma (c'est-à-dire que l'application exécutait des requêtes avant et après la mise à jour sur une table modifiée) - le pilote postgres retournerait cette erreur car apparemment il effectue un 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 sera en mesure de 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 toute autre solution de 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 Github 451 de pgjdbc pour plus de détails et l'historique du problème : https://github.com/pgjdbc/pgjdbc/pull/451


Les utilisateurs de JRuby ActiveRecords peuvent consulter ceci : https://github.com/jruby/activerecord-jdbc-adapter/blob/master/lib/arjdbc/postgresql/connection_methods.rb#L60


Remarque sur les performances :

Comme indiqué dans les problèmes de performances rapportés dans le lien ci-dessus, vous devriez effectuer des tests de performances / de charge / d'endurance de votre application avant d'activer cela aveuglément.

En effectuant des tests de performances sur ma propre application fonctionnant sur une instance AWS RDS Postgres 10, activer le paramètre conservative entraîne une augmentation de l'utilisation du CPU sur le serveur de base de données. Ce n'était pas grand-chose cependant, je ne pouvais même voir la fonctionnalité autosave utiliser une quantité mesurable de CPU qu'après avoir optimisé chaque requête que mon test de charge utilisait 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.

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

0 votes

C'est 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 exécuté manuellement la requête select qui ne fonctionnait pas 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