New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Cached plan must not change result type" when using PreparedStatement cache across schemas #496
Comments
I think it is a driver's issue. It should not issue "execute server-prepared statement" commands and rely on backend to properly replan/pick cached version for the specific I'm afraid your only workaround is to ether avoid "altering the schema_path", or disable server-prepared statements. I think #451 would help you, however it is not yet merged in.
I think you are right here. Adding schema_path to the equation should help. Do you want to try implementing the fix? |
Here's discussion of similar problem in pgsql-hackers: http://www.postgresql.org/message-id/22921.1358876659@sss.pgh.pa.us |
Thanks for the help. Based on the patch that came out of that discussion, it looks like schema_path is the only other major thing that impacts the plan cache, aside from DDL changes. How would you suggest fixing this? I assume it would be too expensive to get the current search path from postgres each time you cache a prepared statement, but relying on |
I've started discussion on hackers list to get idea of "the proper fix": http://www.postgresql.org/message-id/flat/CAB=Je-GtFy=Qa1Eku1mgRZ8RabUfqnUE2Z6ye2CJJZNN9B3Odg@mail.gmail.com#CAB=Je-GtFy=Qa1Eku1mgRZ8RabUfqnUE2Z6ye2CJJZNN9B3Odg@mail.gmail.com
I think we can detect "SET" statements and renew Here's sample trace:
However,
Proper dependency tracking should detect that prepared statement is "not that valid". In other words, the result depends on the order of 3 & 4. However, I think the case should not be wildly used in public, thus it can be neglected. Alternative direction is to create a connection property that would disable server-side prepared statements caching across |
Guys, I can steadily reproduce the same issue using the latest driver v42.0.0, server v9.5.1 and our integration tests. If a test class has a parameterized test which is executed multiple times with different parameters, every second test run fails (i.e. odds pass, evens fail). If there's a single run, then such test passes just fine. I can't share our tests, but can help diagnosing this from my side. Previously we were using driver v9.2-1002, and everything went just fine. Sample stack trace:
|
@unix-junkie , I wonder if you can enable, capture and share pgjdbc trace logs: https://jdbc.postgresql.org/documentation/head/logging.html#configuration For instance, add Do you use |
@vlsi First, thanks for the quick response. I will capture the logs and send them to you this Thursday or Friday. Speaking of DDL -- yes we do. Basically, it looks like prepared statements are not invalidated when tables they're related to get changed in an incompatible way (i.e. the same table gets recreated, but its columns have different (incompatible) types). I observe the same when running parameterized prepared statements (the driver keeps using a stale cached instance instead of preparing a new one), with a slightly different error message:
-- this one showed up when inserting a timestamp after a similar test which was inserting an integer. Forcing |
Unfortunately, backend does not notify clients which statements get invalidated by a particular DDL execution. If it is just test code that fails, then you might have luck if you could issue In case your production code requires that DDL, you might want to drop a message to PostgreSQL mailing list. The third option is to keep adding "invalidate statement cache on each ALTER, CREATE, etc, etc". The flip side there is prepared statement cache improves performance a lot, so invalidating it here and there might hurt. |
@vlsi Thank you Vladimir. I will use the workarounds you suggested. |
I'm using
9.4.1207
against a PostgreSQL 9.4 system, with a multi-tenant setup that has a single Postgres schema per customer. Table names may be repeated across customer schemas, but with different columns, datatypes, etc.The java application sets the
search_path
as the first statement in any transaction, but keeps the jdbc Connection open between transactions (via a Tomcat jdbc pool, version 8.0.24.)This appears to lead to errors like this:
Looking at the code it seems like the problem could be with the re-use of PreparedStatements via the cache implemented in #319. The
CallableQueryKey
only keys off the parsed SQL, when it might also need to pay attention to thesearch_path
.All of the above may be moot, however, if the issue is instead with Postgres itself. See the Notes section for the behavior of
PREPARE
- http://www.postgresql.org/docs/current/static/sql-prepare.html This seems to imply that statement reparsing occurs when thesearch_path
changes (as of 9.3), but this test case can trigger the issue (again on 9.4):Thanks for your help.
The text was updated successfully, but these errors were encountered: