-
Notifications
You must be signed in to change notification settings - Fork 66
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
MySQLi statement execute ArgumentCountError ("number of parameters") #875
Comments
Thank you for the detailed report - we will investigate this issue. |
Thank you again for the detailed report - I was able to reproduce the behavior you are reporting and will be investigating this further. |
I believe it is related to the agent attempting to "explain" the slower query and the issue reported is triggered. As a temporary workaround you could try setting |
Thanks! That's really helpful. As long as we know which queries are slow (and how slow they are) we can probably do without the explain for now. |
I believe the duration is still available. |
I made some good progress understanding this issue. You noticed the space at the beginning of the SQL for Thank you again for this report - it was well documented and made my job of troubleshooting it much more efficient! |
Thanks, sorry I think we knew removing the semi-colon also helped this particular query, but we were also experiencing the issue on some queries that didn't have spaces at the start or semi-colons at the end (in fact most of them don't). We just didn't manage to make a re-creatable example of one like that. We couldn't find any clear pattern in the queries that failed. 😔 |
Your report with all the details you provided was excellent and extremely useful in determining this pattern. |
…s (GH issue 875) (#881) In GH issue #875 it was reported a warning is generated when using prepared statements with `mysqli`. The issue included excellent instructions on how to reproduce the issue. This PR addresses the cause of the warning. To understand the cause of the warning requires understanding how the agent handles `mysqli::stmt` objects. When a SQL statement is prepared via mysqli the agent will store the SQL string in a global hashmap called `mysqli_queries` *if* the SQL is considered explainable (determined via `nr_php_explain_mysql_query_is_explainable()`), otherwise it is just ignored. Later when a slow SQL query is detected the SQL string is retrieved and used to explain the query. An additional factor is when a `mysqli::stmt` object is released it goes into a free pool PHP keeps which allows it to quickly hand out an allocated section of memory when a new object is created. Each object has a `object ID` (referenced as a `handle` in the agent for the relevant code). When an the allocated object is reused from the free pool it retains the same `object ID`. The agent used the `object ID` (`handle`) as the key for storing the prepared SQL string for explainable SQL strings. Now what if an explainable query comes through, the string is stored, and then that object is released. A new query is prepared with a string that is NOT explainable and gets the object container with the same `object ID` as the explainable one just released. The string stored in `mysqli_queries` using that `object ID` as the key is now stale. If the new, unexplainable query is slow then the agent will pull this stale string and try to run an explain with it - leading to the warning. The fix is to clear any query string for a given `object ID` if the query string is unexplainable. Integration tests were added (based on the reproduction case) that test for a regression of this fix.
I am running into the same issue on PHP 8.1.28, when will the new version of Newrelic be released? I have 10.19.0.9 installed. |
This issue has been fixed in the 10.20.0.10 release. Thank you again for the thorough bug report! |
Thank you! |
I wanted to check back and see if the new release has addressed this report. |
Yes, I am not longer getting the errors I did before. Thank you!
Curtis Black
Senior Web developer / Team Lead
[cid:0e962f48-b401-4b61-a246-a066e0df9a21]
Office +1 (385) 209 1900, x1<tel:+13852091900,1>
Mobile +1 (702) 715 2202<tel:+17027152202>
***@***.******@***.***>
www.descartes.com<https://www.descartes.com/>
…________________________________
From: Michael Fulbright ***@***.***>
Sent: Tuesday, May 14, 2024 1:22 PM
To: newrelic/newrelic-php-agent ***@***.***>
Cc: curtisblack2004 ***@***.***>; Comment ***@***.***>
Subject: Re: [newrelic/newrelic-php-agent] MySQLi statement execute ArgumentCountError ("number of parameters") (Issue #875)
WARNING - EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe.
I wanted to check back and see if the new release has addressed this report.
—
Reply to this email directly, view it on GitHub<#875 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ACDZWF62VWZ5PN64BZ7RVQLZCJP6VAVCNFSM6AAAAABGAYOG7GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMJQHE4DGMRVGE>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Since upgrading to PHP 8.2, we've been getting frequent "ArgumentCountError: The number of variables must match the number of parameters in the prepared statement" errors when executing mysqli prepared statements. Although there are some really strange circumstances around this error, we can recreate it.
We are binding the correct number of variables using bind_param, but for some reason as you'll see from the stack trace the Error is thrown by execute().
This is preventing us upgrading to PHP 8.2.
Description
This Error is thrown regularly on certain statements (about a dozen) in our codebase, and as you'll see from the recreation steps there are quite a few factors that seem to affect whether a statement will error.
A full stack trace of the error looks like the following:
We first experienced this on Amazon Linux 2023 PHP 8.2 (installed newrelic using the tar archive), but we have recreated this on Amazon Linux 2 PHP 8.1 (installing through rpm), and locally in a docker instance based on php:8.1-cli (again using tar).
We have recreated the Error on 10.16.0.5, 10.19.0.9, and 10.10.0.1.
The errors stop when we set
newrelic.enabled = false
, or when we remove our license key from newrelic.ini. And of course, the error does not happen when we haven't installed newrelic PHP agent.Steps to Reproduce
In summary, install PHP >=8.1, with mysqli, enable New Relic and then prepare two statements that have different number of arguments.
Here is our current test script:
Some conditions seem to apply:
Locally, we recreated the issue using docker php:8.1-cli image and mysql:8.0.36. We seeded the test table with 2 million rows with the following sql:
Expected Behavior
$stmt->execute() should not throw an ArgumentCountError when we have bound the correct number of parameters with bind_param. And it shouldn't be affected by the previously prepared query.
Your Environment
We've recreated this on:
This may be related to this change in PHP 8.1, php/php-src#6271
The text was updated successfully, but these errors were encountered: