Skip to content

Allow shard setting with comments #293

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

Merged
merged 11 commits into from
Feb 15, 2023

Conversation

jmeagher
Copy link
Contributor

@jmeagher jmeagher commented Jan 24, 2023

What

Allows shard selection by the client to come in via comments like /* shard_id: 1 */ select * from foo;

Why

We're using a setup in Ruby that makes it tough or impossible to inject commands on the connection to set the shard before it gets to the "real" SQL being run. Instead we have an updated PG adapter that allows injection of comments before each executed SQL statement. We need this support in pgcat in order to keep some complex shard picking logic in Ruby code while using pgcat for connection management.

Local Testing

Run postgres and pgcat with the default options. Run psql < tests/sharding/query_routing_setup.sql to setup the database for the tests and run ./tests/pgbench/external_shard_test.sh as often as needed to exercise the shard setting comment test.

This was developed with @drdrsh

@levkk
Copy link
Contributor

levkk commented Jan 25, 2023

Hey there John, nice to be working together again!

I think you're on the right track with this PR. We've been thinking about this functionality for a while now and this is definitely a welcome change.

A few pointers to make this work:

QueryRouter

Take a look at QueryRouter, specifically try_execute_command. It could be nice to incorporate this there. You'll find a lot of similar regexes living there as well.

Test suite

The existing test suite is pretty comprehensive, and you'll also note the presence of Ruby and Python (Mostafa likes Ruby while Zain likes Python, personally I'm more of a bash guy, but everyone is welcome here); pick your favorite.

query_routing_setup.sql does all of the setup so you just need to write your own SQL tests if desired. You'll note the presence of partitions that should validate that your query routing addition works as intended (otherwise there will be insertion errors due to partition bounds). They should not have issues working locally, not sure why Circle is broken (isn't it always in every project ever...).

Backwards compatibility

PgCat is being used in production by a few organizations now, so any functionality that changes core behavior should be optional; the easiest way to make that work is to make it config-driven.

In your case, I'd suggest a config to tell the query parser to either use the existing SQL AST parser or your Regex approach, maybe something like query_parser_mode = "regex" or query_parser_mode = "ast_parser". Then the regex should also be configurable, as you may suspect different people write their SQL comments differently. A bit of historical context: #168

Let me know if I can help further. Welcome to the project!

@jmeagher
Copy link
Contributor Author

I did some cleanup on this to move the logic somewhere it made more sense. I also made it configurable and optional by default. It now also support setting a sharding_key to help support #168. If other special commands are needed via comments it should be easy to expand this to include other options like role.

Let me know how this looks.

@@ -85,6 +85,12 @@ query_parser_enabled = true
# queries. The primary can always be explicitly selected with our custom protocol.
primary_reads_enabled = true

# Allow sharding commands to be passed as statement comments instead of
# separate commands. If these are unset this functionality is disabled.
# sharding_key_regex = '/\* sharding_key: (\d+) \*/'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are commented out because when they were uncommented it caused the Ruby TOML parser to fail when loading the file. These aren't used in tests right now, so it should be fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to figure this out because otherwise this feature won't be tested in end-to-end tests we have in Ruby. I think it's fine to test it with Bash to start, but the Ruby test suit protects us against bad things and we want it to run there too.

Copy link
Contributor

@levkk levkk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LOC LB test is flakey, rerunning it usually helps. We have an action item to fix this. The PR looks good to me to merge. Eventually we would want some tests in bash/Ruby/Python so we don't get hit with a regression. I'll let @drdrsh take a look before merging.

Comment on lines +118 to +120
// Check for any sharding regex matches in any queries
match code as char {
// For Parse and Query messages peek to see if they specify a shard_id as a comment early in the statement
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can avoid this entire branch when the number of shards is 1, we can get that from self.pool_settings.shards. This will make this check even cheaper for the base, unsharded use case

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scratch that, the lack of the regex in the confs should be enough of a gate

@drdrsh
Copy link
Collaborator

drdrsh commented Jan 26, 2023

We'll test this change internally. I will merge it once we are done @levkk

pub shards: BTreeMap<String, Shard>,
pub users: BTreeMap<String, User>,
// Note, don't put simple fields below these configs. There's a compatability issue with TOML that makes it
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having the new fields below user and shard broke our internal tool that generates the TOML config. Since this is a pretty odd error that we hit I'm leaving behind the breadcrumb that got us to fix it.

@drdrsh drdrsh merged commit d5f60b1 into postgresml:main Feb 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants