Skip to content

Commit 7d3003a

Browse files
zainkabanilevkk
andauthored
Reimplement prepared statements with LRU cache and statement deduplication (#618)
* Initial commit * Cleanup and add stats * Use an arc instead of full clones to store the parse packets * Use mutex instead * fmt * clippy * fmt * fix? * fix? * fmt * typo * Update docs * Refactor custom protocol * fmt * move custom protocol handling to before parsing * Support describe * Add LRU for server side statement cache * rename variable * Refactoring * Move docs * Fix test * fix * Update tests * trigger build * Add more tests * Reorder handling sync * Support when a named describe is sent along with Parse (go pgx) and expecting results * don't talk to client if not needed when client sends Parse * fmt :( * refactor tests * nit * Reduce hashing * Reducing work done to decode describe and parse messages * minor refactor * Merge branch 'main' into zain/reimplment-prepared-statements-with-global-lru-cache * Rewrite extended and prepared protocol message handling to better support mocking response packets and close * An attempt to better handle if there are DDL changes that might break cached plans with ideas about how to further improve it * fix * Minor stats fixed and cleanup * Cosmetic fixes (#64) * Cosmetic fixes * fix test * Change server drop for statement cache error to a `deallocate all` * Updated comments and added new idea for handling DDL changes impacting cached plans * fix test? * Revert test change * trigger build, flakey test * Avoid potential race conditions by changing get_or_insert to promote for pool LRU * remove ps enabled variable on the server in favor of using an option * Add close to the Extended Protocol buffer --------- Co-authored-by: Lev Kokotov <levkk@users.noreply.github.com>
1 parent d37df43 commit 7d3003a

File tree

14 files changed

+1131
-512
lines changed

14 files changed

+1131
-512
lines changed

CONFIG.md

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -259,22 +259,6 @@ Password to be used for connecting to servers to obtain the hash used for md5 au
259259
specified in `auth_query_user`. The connection will be established using the database configured in the pool.
260260
This parameter is inherited by every pool and can be redefined in pool configuration.
261261

262-
### prepared_statements
263-
```
264-
path: general.prepared_statements
265-
default: false
266-
```
267-
268-
Whether to use prepared statements or not.
269-
270-
### prepared_statements_cache_size
271-
```
272-
path: general.prepared_statements_cache_size
273-
default: 500
274-
```
275-
276-
Size of the prepared statements cache.
277-
278262
### dns_cache_enabled
279263
```
280264
path: general.dns_cache_enabled
@@ -324,6 +308,15 @@ If the client doesn't specify, PgCat routes traffic to this role by default.
324308
`replica` round-robin between replicas only without touching the primary,
325309
`primary` all queries go to the primary unless otherwise specified.
326310

311+
### prepared_statements_cache_size
312+
```
313+
path: general.prepared_statements_cache_size
314+
default: 0
315+
```
316+
317+
Size of the prepared statements cache. 0 means disabled.
318+
TODO: update documentation
319+
327320
### query_parser_enabled
328321
```
329322
path: pools.<pool_name>.query_parser_enabled

Cargo.lock

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ itertools = "0.10"
4848
clap = { version = "4.3.1", features = ["derive", "env"] }
4949
tracing = "0.1.37"
5050
tracing-subscriber = { version = "0.3.17", features = ["json", "env-filter", "std"]}
51+
lru = "0.12.0"
5152

5253
[target.'cfg(not(target_env = "msvc"))'.dependencies]
5354
jemallocator = "0.5.0"

pgcat.toml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,6 @@ tcp_keepalives_count = 5
6060
# Number of seconds between keepalive packets.
6161
tcp_keepalives_interval = 5
6262

63-
# Handle prepared statements.
64-
prepared_statements = true
65-
66-
# Prepared statements server cache size.
67-
prepared_statements_cache_size = 500
68-
6963
# Path to TLS Certificate file to use for TLS connections
7064
# tls_certificate = ".circleci/server.cert"
7165
# Path to TLS private key file to use for TLS connections
@@ -156,6 +150,10 @@ load_balancing_mode = "random"
156150
# `primary` all queries go to the primary unless otherwise specified.
157151
default_role = "any"
158152

153+
# Prepared statements cache size.
154+
# TODO: update documentation
155+
prepared_statements_cache_size = 500
156+
159157
# If Query Parser is enabled, we'll attempt to parse
160158
# every incoming query to determine if it's a read or a write.
161159
# If it's a read query, we'll direct it to a replica. Otherwise, if it's a write,

src/admin.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@ where
744744
("age_seconds", DataType::Numeric),
745745
("prepare_cache_hit", DataType::Numeric),
746746
("prepare_cache_miss", DataType::Numeric),
747+
("prepare_cache_eviction", DataType::Numeric),
747748
("prepare_cache_size", DataType::Numeric),
748749
];
749750

@@ -776,6 +777,10 @@ where
776777
.prepared_miss_count
777778
.load(Ordering::Relaxed)
778779
.to_string(),
780+
server
781+
.prepared_eviction_count
782+
.load(Ordering::Relaxed)
783+
.to_string(),
779784
server
780785
.prepared_cache_size
781786
.load(Ordering::Relaxed)

0 commit comments

Comments
 (0)