mirror of
https://github.com/postgresml/pgcat.git
synced 2026-03-23 01:16:30 +00:00
QueryRouter: route to primary when locks exists (select for update) (#782)
Authored-by: Javier Goday <jgoday@gmail.com>
This commit is contained in:
committed by
GitHub
parent
81933b918d
commit
29a476e190
@@ -427,8 +427,12 @@ impl QueryRouter {
|
|||||||
None => (),
|
None => (),
|
||||||
};
|
};
|
||||||
|
|
||||||
// If we already visited a write statement, we should be going to the primary.
|
let has_locks = !query.locks.is_empty();
|
||||||
if !visited_write_statement {
|
|
||||||
|
if has_locks {
|
||||||
|
self.active_role = Some(Role::Primary);
|
||||||
|
} else if !visited_write_statement {
|
||||||
|
// If we already visited a write statement, we should be going to the primary.
|
||||||
self.active_role = match self.primary_reads_enabled() {
|
self.active_role = match self.primary_reads_enabled() {
|
||||||
false => Some(Role::Replica), // If primary should not be receiving reads, use a replica.
|
false => Some(Role::Replica), // If primary should not be receiving reads, use a replica.
|
||||||
true => None, // Any server role is fine in this case.
|
true => None, // Any server role is fine in this case.
|
||||||
@@ -1158,6 +1162,29 @@ mod test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_select_for_update() {
|
||||||
|
QueryRouter::setup();
|
||||||
|
let mut qr = QueryRouter::new();
|
||||||
|
qr.pool_settings.query_parser_read_write_splitting = true;
|
||||||
|
|
||||||
|
let queries_in_primary_role = vec![
|
||||||
|
simple_query("BEGIN"), // Transaction start
|
||||||
|
simple_query("SELECT * FROM items WHERE id = 5 FOR UPDATE"),
|
||||||
|
simple_query("UPDATE items SET name = 'pumpkin' WHERE id = 5"),
|
||||||
|
];
|
||||||
|
|
||||||
|
for query in queries_in_primary_role {
|
||||||
|
assert!(qr.infer(&qr.parse(&query).unwrap()).is_ok());
|
||||||
|
assert_eq!(qr.role(), Some(Role::Primary));
|
||||||
|
}
|
||||||
|
|
||||||
|
// query without lock do not change role
|
||||||
|
let query = simple_query("SELECT * FROM items WHERE id = 5");
|
||||||
|
assert!(qr.infer(&qr.parse(&query).unwrap()).is_ok());
|
||||||
|
assert_eq!(qr.role(), None);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_infer_primary_reads_enabled() {
|
fn test_infer_primary_reads_enabled() {
|
||||||
QueryRouter::setup();
|
QueryRouter::setup();
|
||||||
|
|||||||
Reference in New Issue
Block a user