Skip the redundant checkout round-trips the pool paid on every borrow - #15
Merged
Conversation
Datadog spans from production showed the pool's own overhead as the top SQL by count AND total time: every checkout paid a SELECT 1 ping plus two session SETs, and every release paid the two SETs again - three to five ~10-20ms round-trips per borrow from Cloud Run to the database host, ~30-50ms of latency tax on every DB-using request across all apps (and 162M SET statements on the server in 21 days). release() fully resets every connection before re-pooling and closes any connection whose reset fails, so pooled connections are clean by invariant. Checkout now: - runs a LOCAL dirty check (transaction counter + PDO flag, no SQL) and only pays the full reset for a genuinely dirty connection; - pings only connections idle past ping_after_idle (default 30s) - freshly pooled and freshly created connections skip it. A connection that died while idle is still recovered by the reconnector on first query.
…fix docs - normalizeSession() runs the two session SETs once at connection creation for mysql/mariadb, so fresh and recycled connections are indistinguishable - without it, skipping the checkout reset would make isolation level and autocommit depend on whether a connection happened to be fresh whenever the server default differs. - hasDirtyTransactionState() uses getRawPdo(): a never-connected lazy connection cannot be in a transaction, and the check must not trigger a connect. - Correct two comments that overstated ping semantics.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Datadog spans from production showed the pool's own overhead as the top SQL by count and total time: every checkout paid a
SELECT 1ping plus two sessionSETs, and every release paid theSETs again — 3–5 round-trips at ~10–20ms each from Cloud Run to the DB host. That is ~30–50ms of latency tax on every DB-using request in every app, and 162MSETstatements on the MySQL server in 21 days.Change
release()fully resets every connection before re-pooling and closes any whose reset fails, so pooled connections are clean by invariant. Checkout now:ping_after_idle(default 30s); freshly pooled/created connections skip it — a connection that died while idle is still recovered by Laravel's lost-connection retry through the pool's identity-preserving reconnector;Verification
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.