amphp / postgres

Async Postgres client for PHP based on Amp.
MIT License
97 stars 20 forks source link

Errors of statements at PqHandle #19

Closed deadbeat88 closed 5 years ago

deadbeat88 commented 5 years ago

Using the pq extension sometimes get the following errors:

These errors occur only with a high number of requests per second, more than 150. The following results were obtained (total queries 5000-6000, using pool with max_coonnections = 90, timeout = 30 sec)

Also at PqHandle::statementExecute after success assert i had pq\Connection state like this: "status": 0, "transactionStatus": 0, "errorMessage": "ERROR: prepared statement \"amp_c1e68597d8be2371adc09335382ad9f18ab407dd\" does not exist"

trowski commented 5 years ago

Can you please try with the latest master and see if the problem persists?

deadbeat88 commented 5 years ago

These are solved with the latest update, but the pool never releases connections now)

trowski commented 5 years ago

I missed that I created a reference to the statement object in PqHandle, so I reverted to a similar approach as before, but I realized that a refCount was being incremented prior where it should not have been. Can you please try again with the latest master?

deadbeat88 commented 5 years ago

I tried again and got the similar errors: prepared statement "amp_xxx" does not exist or prepared statement "amp_xxx" already exists

trowski commented 5 years ago

Does the same thing happen if you use the pgsql extension?

deadbeat88 commented 5 years ago

I use docker postgres:9.6 and own image based on php:7.3-cli-alpine.

trowski commented 5 years ago

Is it possible you were preparing similar queries with different placeholders? For example, SELECT * FROM users WHERE id=:id and SELECT * FROM users WHERE id=?. I noticed this would result in the same prepared statement name on the connection. I fixed this in master, if you would again give that a try.

deadbeat88 commented 5 years ago

No, all queries are preparing without named placeholders. There are the same errors after latest fix( Also I noticed some weird behavior during test cases:

trowski commented 5 years ago

I spent some more time looking at this today. I use this library in production without issue, so I'm surprised your seeing errors and I'm not. I'm still unable to reproduce the errors you're seeing.

Addressing your points:

I pushed a new branch, remove-statement-pool-caching, that does not retain statement pools within the connection pool, which will free resources much more quickly, but will require more prepares if the same statement is being used over and over again. You can retain a statement object manually for some time if you anticipate using it again. The statement pool will still free connections associated with it in time, preparing a new statement if it is used. Could you please try out this branch and see how your application behaves with it? Thanks!

deadbeat88 commented 5 years ago

I ran few tests without statement pools within the connection pool at new branch remove-statement-pool-caching and there are no any issues)

mmasiukevich commented 5 years ago

Perhaps this information will help a little:

The problem manifested itself mainly (99% of cases) on UPDATE requests. According to the structure, there was a BYTEA field, and it was filled with a rather large value.

https://github.com/php-service-bus/sagas/blob/v3.2/src/Store/Sql/SQLSagaStore.php#L132

However, I can not reproduce the problem as I did not try. There is clearly a problem somewhere, but at what stage it is not clear.

mmasiukevich commented 5 years ago

With the latest changes, the error is not reproduced. Maybe it makes sense to release?

trowski commented 5 years ago

@mmasiukevich Tagged a new release with the changes! Thanks for the input and please let me know if you have any further issues.

deadbeat88 commented 5 years ago

@trowski Nice, thanks)