I've rewritten my site php-code and added MySQL Stored Procedures.
In my local version everything works fine but after I uploaded my site to hosting server I'm constantly getting fatal error 'Prepared statement needs to be re-prepared'.
Sometimes page loads, sometimes loading fails and I see this error. What's that?
To fix, you can increase the maximal packet size limit max_allowed_packet in my. cnf file, eg. set max_allowed_packet = 128M , then restart your MySQL server: sudo /etc/init. d/mysql restart.
The PREPARE statement prepares a SQL statement and assigns it a name, stmt_name , by which to refer to the statement later. The prepared statement is executed with EXECUTE and released with DEALLOCATE PREPARE . For examples, see Section 13.5, “Prepared Statements”. Statement names are not case-sensitive.
Prepared Statement. Stored procedures are a sequence of SQL statements that access the relational database management system. Prepared statements are queries that contain the placeholders instead of actual values. It can be stored in the database server.
They are written in SQL and stored in the database rather than in the application code. Like prepared statements, they establish a concrete query and populate query variables with user-supplied data in a way that should prevent the query from being modified.
This is a possibility: MySQL bug #42041
They suggest upping the value of table_definition_cache
.
You can read about statement caching in the MySQL docs.
@docwhat's answer seems nice, but on a shared hosting server, not everyone is allowed to touch the table_open_cache
or table_definition_cache
options.
Since this error is related to prepared statements, I have tried to 'emulate' those with PDO by providing the following option:
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, [
PDO::ATTR_EMULATE_PREPARES => true
]);
Note: actually this is in a Laravel 5.6 project, and I added the option in config/database.php
:
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
'options' => [
PDO::ATTR_EMULATE_PREPARES => true,
],
],
(...)
],
I have not tested the impact of emulating prepared statements on the duration of loading my site, but it works against the error SQLSTATE[HY000]: General error: 1615 Prepared statement needs to be re-prepared
I got.
Update on the performance: the emulated version seems to be slightly faster (32.7±1.4ms emulated, 35.0±2.3ms normal, n=10, p-value=0.027 for two-tailed Student's T-test).
In short: Don't use VIEWS in prepared statements.
This seems to be an on-going issue
Views are messy to handle with Dynamic SQL
Earliest Bug was Cannot create VIEWs in prepared statements from 11 years ago. There was a patch put in to address it.
Another bug report, Prepared-Statement fails when MySQL-Server under load, states that error 1615 is not a bug when the underlying tables are busy. (Really ?)
While there is some merit to increasing the table cache size (See MySql error when working with a mysql view), it does not always work (See General error: 1615 Prepared statement needs to be re-prepared (selecting mysql view))
ALTERNATIVES Over a year ago, someone mentioned this in the MySQL Forum (MySql “view”, “prepared statement” and “Prepared statement needs to be re-prepared”).
Someone came up with the simple idea of not using the view in the prepared statement but using the SQL of view in a subquery instead. Another idea would be to create the SQL used by the view and execute it in your client code.
These would seems to be better workarounds that just bumping up the table cache size.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With