Цей виняток передається сервером PostgreSQL 8.3.7 до моєї програми. Хтось знає, що означає ця помилка і що я можу з цим зробити?
ERROR: cached plan must not change result type
STATEMENT: select code,is_deprecated from country where code=$1
Цей виняток передається сервером PostgreSQL 8.3.7 до моєї програми. Хтось знає, що означає ця помилка і що я можу з цим зробити?
ERROR: cached plan must not change result type
STATEMENT: select code,is_deprecated from country where code=$1
Відповіді:
Я зрозумів, що викликає цю помилку.
Мій додаток відкрив підключення до бази даних та підготував операцію SELECT для виконання.
Тим часом, інший скрипт модифікував таблицю бази даних, змінюючи тип даних одного з стовпців, що повертаються у вищевказаному операторі SELECT.
Я вирішив це шляхом перезавантаження програми після зміни таблиці баз даних. Це скидає підключення до бази даних, дозволяючи підготовленому оператору виконуватись без помилок.
org.postgresql.util.PSQLException: ERROR: cached plan must not change result type
. І всі тести працюють як шарм, але тільки Repository.findById()
. Я не змінюю схему в своїх тестах, але я використовую @FlywayTest
для підготовки тестової бази даних для кожного тесту. Якщо я видаляю @FlywayTest
примітку, вона працює добре.
Я додаю цю відповідь для тих, хто приземлився сюди, гуглюючи ERROR: cached plan must not change result type
при спробі вирішити проблему в контексті програми Java / JDBC.
Мені вдалося надійно відтворити помилку, запустивши оновлення схеми (тобто операторів DDL), коли мій бек-енд-додаток, що використовував БД, працював. Якщо додаток запитував таблицю, яку було змінено оновленням схеми (тобто додаток виконував запити до та після оновлення в зміненій таблиці) - драйвер postgres поверне цю помилку, оскільки, очевидно, вона кешує деякі деталі схеми.
Ви можете уникнути проблеми, налаштувавши свій pgjdbc
драйвер на autosave=conservative
. За допомогою цієї опції драйвер зможе опрацювати всі деталі, які він кешує, і вам не доведеться підстрибувати ваш сервер або промивати пул підключень або будь-який інший спосіб, який ви могли б придумати.
Відтворено на Postgres 9.6 (AWS RDS), і моє початкове тестування, схоже, вказує на проблему, яка повністю вирішена за допомогою цієї опції.
Документація: https://jdbc.postgresql.org/documentation/head/connect.html#connection-parameters
Ви можете подивитися в pgjdbc
Github випуску 451 для отримання більш детальної інформації та історії випуску.
Користувачі JRuby ActiveRecords бачать це: https://github.com/jruby/activerecord-jdbc-adapter/blob/master/lib/arjdbc/postgresql/connection_methods.rb#L60
Примітка про продуктивність:
Відповідно до повідомлених проблем щодо продуктивності у вищенаведеному посиланні - перед тим, як увімкнути цю операцію, слід пройти тестування на роботу / завантаження / замочування.
Проводячи тестування продуктивності мого власного додатка, що працює на Postgres 10
екземплярі AWS RDS , включення conservative
налаштування призводить до додаткового використання процесора на сервері баз даних. Хоча це було не так багато, я навіть міг навіть побачити, як autosave
функціональність відображається як використання вимірюваної кількості процесора після того, як я налаштував кожен запит, який використовував мій тест навантаження, і почав наполягати навантажувальний тест.
Для нас перед нами було подібне питання. Наш додаток працює за кількома схемами. Щоразу, коли ми вносили зміни до схеми, ця проблема почала виникати.
Налаштування параметра PrepaThreshold = 0 всередині параметра JDBC вимикає кешування операторів на рівні бази даних. Це вирішило це за нас.