-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Ballooning of Prepared_stmt_count on MYSQL #6872
Comments
Interesting, I was not aware there is a limit on the # of prepared statements. After 2.14 we probably changed the usage and behavior of queries. We most probably did not consider this limitation yet, or did not expect it to be relevant. Is this limit per connection or per server (restart)? |
Hey there! I actually had no idea it was a thing either until I ran into this. It's a per server limit, that can be potentially fixed by raising the limit (a global var in MySQL), but I didn't know if this was a symptom of something bigger and didn't want to band-aid something that may continue getting (much) bigger. So the "normal" behavior (as of 2.14) was that the prepared statement count rises gradually through use, and quickly resets itself back down to <100 values. Unfortunately I don't have a great error, but this is a snippet of it.
Error behavior: Thanks for looking into this! :) |
Ok, it is a per server limit but I think the prepared statements are held by connection - so "rotating" the connections could probably help. You could do so by getting a new There is nothing really in the 2.15 release notes that pop out to me: https://github.com/prisma/prisma/releases/tag/2.15.0 Can you tell us a bit more about the queries your application is running? |
That's fair. I'm happy to adapt and implement workarounds if the changes here are actually intended / a necessary side effect. And understood. Before continuing, I'm actually just going to verify and make sure that 2.15 breaks it or if it's a later version to potentially make troubleshooting easier, and report back with findings. I might have went straight to 2.17 to test a preview feature with groupBy/filter on relationals. I'll test with 2.15 all the way up to my first confirmed version where I come across this issue. Thanks again for the receptive help. |
These workarounds are of course only meant as temporary fixes to allow you to upgrade your Prisma version - we will obviously still try to understand and fix this as soon as possible. Right now we are a bit lost though as first manual reproductions did not show an increasing prepared statement count. |
Ahh understood. Much appreciated. It is a GQL based backend that handles all of the traffic for a production deployment, so it runs about 6 pods that use prisma. I don't think we do anything special with our prisma deployment, we strictly just use the client feature (no migrate etc) and we use all the basic CRUD functionality, as well as groupBy/aggregate queries. We have used default config for connection limit/pool size (didn't edit it). We also utilize the basic dataloader as implemented here: https://github.com/graphql/dataloader for most of our nested gql resolvers. Regarding to the things that connect to the DB, there are other things that connect to the database as well, so that bumps the total number up to 10, with between 40-55 simultaneous connections. There are no serverless access to the db. Regarding reproducibility, for us it doesn't seem to take long to detect the discrepancy from one version to another, but I don't know if this would extend to other deployments. Thank you! |
We migrated from Prisma 1 to prisma 2.20 yesterday and came across this issue aswell. However if we downgrade to 2.14 it works like expected and the prepared statements keeps reseting and we do not hit the limit. |
We have the same issue, the From what I can tell, it seems like the connection-pooling did not work in |
Thanks, we will look into this soon. |
Also facing this same issue with prisma |
When is a fix for this planned? |
I am unable to reproduce this with Here are the results that I am getting: Can anyone share a more concrete reproduction? |
The problem is that prisma is using prepared statements when making the request to the mysql db and never drops them. Mysql has a default limit of about 16000 prepared statements which puts an upper limit on how many different prepared statements are allowed to be used globally for the db engine. For instance, when querying the
and it will be sent by the prisma engine to the database as a prepared statement. If the exact same query is run again but with other parameters the prepared statement will be reused by mysql. However, if the query is slightly modified, for instance by adding a new statement in the The prepared statements belongs to the session/connection so if we have multiple instances of the same app and also a connection pool, each session/connection will have their prepared statements cached and these statements will no be dropped until the connection is closed. This means that the overall number of different queries that an application can have is limited to To make things worse, prepared statements will be created for each size of parameters of an IN statement. For instance, this handler:
will issue a new prepared statement for every number of provided ids.
which further reduces the number of queries possible in the application since they are treated as different prepared statements. As I said earlier, the reason this problem arises in versions of prisma > 2.14 is that the connection pool did not work in earlier versions which resulted in a new connection per request (which then dropped the associated prepared statements). I don't know if I would classify this as a bug but since we don't have control over which queries are sent as prepared statements or not it has a severe negative impact on our scaling possibilities. Also, since |
Yes, this is a clear bug as it impacts your ability to use Prisma - and we want you to be able to use Prisma 😄 Your explanation makes a lot of sense, can you help us craft a reproduction app that is optimally set up to reproduce the hitting the limit? We always want to have these before we hand issues like this one over to an Engineer. It will also allow us to test and evaluate quick fixes and workarounds (e.g. a middleware to catch this error, that then instantly cycles the connections somehow and so on). That would be very helpful. |
I have forked the prisma-examples repo and added repro instructions together with some utilities to demonstrate the issue. The easiest way I came up with was to lower the https://github.com/Voady/prisma-examples/tree/latest/typescript/rest-express |
Thanks, @pantharshit00 will take another look at this reproduction. If he can reproduce, we will try some instant workarounds and kick of the work on fixing this properly (unclear to me how this really would look like to be honest - how do other ORMs do this?). |
I wasn't able to reliably reproduce and I was only able to reproduce after I added some concurrency but I still think we should review our cache implementation. cc @pimeys |
Hey @rasberrylasagna and @olif, could you test the development build |
Hi, sorry for the late response. I have tested the First I tried it with Good work! |
Confirming this, wasn't able to repro. Thanks again Jan & Prisma Team! |
@pimeys did all the work - I just made him take a look at this after your description and analysis. Thanks for that, we made Prisma better for everyone (and actually fixed quite a nasty bug). Now only to figure out what we do with that crazy previous default of 1000... Does not seem like a good idea in hindsight 🤣 What do you think a reasonable number would be? |
Maybe not ...🤣. How about the default of mysql_async (32)? |
Looks like this is fixed then :) |
Is this available in 2.25? |
Yes |
Hey @pimeys What value do you recommend for |
Also, I don't see this fix part of 2.25 release logs. |
ProxySQL allocates 20 prepared statements per connection. This explanation by it's author might help: |
2.25.0 added a configuration to change this:
We might change the default value via #7727 |
I actually believe this is actually caused by #8870 |
Mught be this issue... #8870 |
I just hit this issue whilst seeding using
|
I'm also having the same max_prepared_stmt_count issue after setting |
|
We're currently experiencing this issue. Is there a recommended approach to handle this? |
We seem to be also running into this: today and yesterday our db connection "crashed" at the busiest time with the |
That should be enough (if the # of applications/servers using Prisma Client, multiplicated by the configured cache size is lower than the limit). If you are still getting the error, you probably have more applications created prepared statements or something else is weird. |
Hi, We are still facing this issue for prisma version 4.10.1 the prepared_statement_count blows up on production. We have tried setting statement_cache_size value as well but it doesn't seem to work. |
Please open a new issue and provide all the information the issue template asks for, so we can hopefully reproduce, debug and fix. Thanks. |
Bug description
Hey guys, I hope you all are doing well!
I'm running prisma @ 2.14 on MySQL, and after updating to and trying multiple versions (2.18, 2.20.1, 2.21.1), I'm running into issues where my Prepared_stmt_count global MySQL variable is increased by a huge factor compared to 2.14, which leads to me hitting the MAX_PREPARED_STATEMENTS limit. It seems like there is a difference in behavior of these prepared statements from 2.14 and onwards.
Just to reiterate, this is not a problem on 2.14, and was I wondering if there was anything I could do to get the old behavior back on a newer version.
Thank you!
How to reproduce
I'm running this on a production kube deployment, so I'm unsure what specific queries may be triggering this, but I do know that 2.14 and previous never had this behavior
Expected behavior
Expect the Prepared_stmt_count to stay low, this is the current behavior on 2.14.
Actual behavior
Prepared statement count balloons, and stays that way for a long enough time to where my set MAX_PREPARED_STMT_COUNT gets triggered and hangs the db. Note that the actual value in prod gets to 64000+.
Prisma information
Environment & setup
The text was updated successfully, but these errors were encountered: