mirror of
https://github.com/postgresml/pgcat.git
synced 2026-03-23 17:36:28 +00:00
Compare commits
1 Commits
dependabot
...
mostafa_we
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60078be9d3 |
2
.github/workflows/chart-lint-test.yaml
vendored
2
.github/workflows/chart-lint-test.yaml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
# Python is required because `ct lint` runs Yamale (https://github.com/23andMe/Yamale) and
|
# Python is required because `ct lint` runs Yamale (https://github.com/23andMe/Yamale) and
|
||||||
# yamllint (https://github.com/adrienverge/yamllint) which require Python
|
# yamllint (https://github.com/adrienverge/yamllint) which require Python
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5.3.0
|
uses: actions/setup-python@v5.1.0
|
||||||
with:
|
with:
|
||||||
python-version: 3.7
|
python-version: 3.7
|
||||||
|
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,4 +12,3 @@ dev/cache
|
|||||||
!dev/cache/.keepme
|
!dev/cache/.keepme
|
||||||
.venv
|
.venv
|
||||||
**/__pycache__
|
**/__pycache__
|
||||||
.bundle
|
|
||||||
26
CONFIG.md
26
CONFIG.md
@@ -36,11 +36,10 @@ Port at which prometheus exporter listens on.
|
|||||||
### connect_timeout
|
### connect_timeout
|
||||||
```
|
```
|
||||||
path: general.connect_timeout
|
path: general.connect_timeout
|
||||||
default: 1000 # milliseconds
|
default: 5000 # milliseconds
|
||||||
```
|
```
|
||||||
|
|
||||||
How long the client waits to obtain a server connection before aborting (ms).
|
How long to wait before aborting a server connection (ms).
|
||||||
This is similar to PgBouncer's `query_wait_timeout`.
|
|
||||||
|
|
||||||
### idle_timeout
|
### idle_timeout
|
||||||
```
|
```
|
||||||
@@ -463,18 +462,10 @@ path: pools.<pool_name>.users.<user_index>.pool_size
|
|||||||
default: 9
|
default: 9
|
||||||
```
|
```
|
||||||
|
|
||||||
Maximum number of server connections that can be established for this user.
|
Maximum number of server connections that can be established for this user
|
||||||
The maximum number of connection from a single Pgcat process to any database in the cluster
|
The maximum number of connection from a single Pgcat process to any database in the cluster
|
||||||
is the sum of pool_size across all users.
|
is the sum of pool_size across all users.
|
||||||
|
|
||||||
### min_pool_size
|
|
||||||
```
|
|
||||||
path: pools.<pool_name>.users.<user_index>.min_pool_size
|
|
||||||
default: 0
|
|
||||||
```
|
|
||||||
|
|
||||||
Minimum number of idle server connections to retain for this pool.
|
|
||||||
|
|
||||||
### statement_timeout
|
### statement_timeout
|
||||||
```
|
```
|
||||||
path: pools.<pool_name>.users.<user_index>.statement_timeout
|
path: pools.<pool_name>.users.<user_index>.statement_timeout
|
||||||
@@ -484,16 +475,6 @@ default: 0
|
|||||||
Maximum query duration. Dangerous, but protects against DBs that died in a non-obvious way.
|
Maximum query duration. Dangerous, but protects against DBs that died in a non-obvious way.
|
||||||
0 means it is disabled.
|
0 means it is disabled.
|
||||||
|
|
||||||
### connect_timeout
|
|
||||||
```
|
|
||||||
path: pools.<pool_name>.users.<user_index>.connect_timeout
|
|
||||||
default: <UNSET> # milliseconds
|
|
||||||
```
|
|
||||||
|
|
||||||
How long the client waits to obtain a server connection before aborting (ms).
|
|
||||||
This is similar to PgBouncer's `query_wait_timeout`.
|
|
||||||
If unset, uses the `connect_timeout` defined globally.
|
|
||||||
|
|
||||||
## `pools.<pool_name>.shards.<shard_index>` Section
|
## `pools.<pool_name>.shards.<shard_index>` Section
|
||||||
|
|
||||||
### servers
|
### servers
|
||||||
@@ -521,3 +502,4 @@ default: "shard0"
|
|||||||
```
|
```
|
||||||
|
|
||||||
Database name (e.g. "postgres")
|
Database name (e.g. "postgres")
|
||||||
|
|
||||||
|
|||||||
23
Cargo.lock
generated
23
Cargo.lock
generated
@@ -192,11 +192,12 @@ checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bb8"
|
name = "bb8"
|
||||||
version = "0.8.6"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d89aabfae550a5c44b43ab941844ffcd2e993cb6900b342debf59e9ea74acdb8"
|
checksum = "98b4b0f25f18bcdc3ac72bdb486ed0acf7e185221fd4dc985bc15db5800b0ba2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -1341,7 +1342,7 @@ checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-webpki 0.101.1",
|
"rustls-webpki",
|
||||||
"sct",
|
"sct",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1355,14 +1356,10 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-pki-types"
|
||||||
version = "0.100.2"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e98ff011474fa39949b7e5c0428f9b4937eda7da7848bbb947786b7be0b27dab"
|
checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
|
||||||
dependencies = [
|
|
||||||
"ring",
|
|
||||||
"untrusted",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
@@ -2038,11 +2035,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki-roots"
|
name = "webpki-roots"
|
||||||
version = "0.23.1"
|
version = "0.26.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338"
|
checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls-webpki 0.100.2",
|
"rustls-pki-types",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ edition = "2021"
|
|||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
md-5 = "0.10"
|
md-5 = "0.10"
|
||||||
bb8 = "=0.8.6"
|
bb8 = "0.8.1"
|
||||||
async-trait = "0.1"
|
async-trait = "0.1"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
@@ -41,7 +41,7 @@ atomic_enum = "0.2.0"
|
|||||||
postgres-protocol = "0.6.5"
|
postgres-protocol = "0.6.5"
|
||||||
fallible-iterator = "0.2"
|
fallible-iterator = "0.2"
|
||||||
pin-project = "1"
|
pin-project = "1"
|
||||||
webpki-roots = "0.23"
|
webpki-roots = "0.26"
|
||||||
rustls = { version = "0.21", features = ["dangerous_configuration"] }
|
rustls = { version = "0.21", features = ["dangerous_configuration"] }
|
||||||
trust-dns-resolver = "0.22.0"
|
trust-dns-resolver = "0.22.0"
|
||||||
tokio-test = "0.4.2"
|
tokio-test = "0.4.2"
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ maintainers:
|
|||||||
- name: Wildcard
|
- name: Wildcard
|
||||||
email: support@w6d.io
|
email: support@w6d.io
|
||||||
appVersion: "1.2.0"
|
appVersion: "1.2.0"
|
||||||
version: 0.2.1
|
version: 0.2.0
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ stringData:
|
|||||||
connect_timeout = {{ .Values.configuration.general.connect_timeout }}
|
connect_timeout = {{ .Values.configuration.general.connect_timeout }}
|
||||||
idle_timeout = {{ .Values.configuration.general.idle_timeout | int }}
|
idle_timeout = {{ .Values.configuration.general.idle_timeout | int }}
|
||||||
server_lifetime = {{ .Values.configuration.general.server_lifetime | int }}
|
server_lifetime = {{ .Values.configuration.general.server_lifetime | int }}
|
||||||
server_tls = {{ .Values.configuration.general.server_tls }}
|
|
||||||
idle_client_in_transaction_timeout = {{ .Values.configuration.general.idle_client_in_transaction_timeout | int }}
|
idle_client_in_transaction_timeout = {{ .Values.configuration.general.idle_client_in_transaction_timeout | int }}
|
||||||
healthcheck_timeout = {{ .Values.configuration.general.healthcheck_timeout }}
|
healthcheck_timeout = {{ .Values.configuration.general.healthcheck_timeout }}
|
||||||
healthcheck_delay = {{ .Values.configuration.general.healthcheck_delay }}
|
healthcheck_delay = {{ .Values.configuration.general.healthcheck_delay }}
|
||||||
@@ -59,21 +58,11 @@ stringData:
|
|||||||
##
|
##
|
||||||
[pools.{{ $pool.name | quote }}.users.{{ $index }}]
|
[pools.{{ $pool.name | quote }}.users.{{ $index }}]
|
||||||
username = {{ $user.username | quote }}
|
username = {{ $user.username | quote }}
|
||||||
{{- if $user.password }}
|
|
||||||
password = {{ $user.password | quote }}
|
password = {{ $user.password | quote }}
|
||||||
{{- else if and $user.passwordSecret.name $user.passwordSecret.key }}
|
|
||||||
{{- $secret := (lookup "v1" "Secret" $.Release.Namespace $user.passwordSecret.name) }}
|
|
||||||
{{- if $secret }}
|
|
||||||
{{- $password := index $secret.data $user.passwordSecret.key | b64dec }}
|
|
||||||
password = {{ $password | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
pool_size = {{ $user.pool_size }}
|
pool_size = {{ $user.pool_size }}
|
||||||
statement_timeout = {{ default 0 $user.statement_timeout }}
|
statement_timeout = {{ $user.statement_timeout }}
|
||||||
min_pool_size = {{ default 3 $user.min_pool_size }}
|
min_pool_size = 3
|
||||||
{{- if $user.server_lifetime }}
|
server_lifetime = 60000
|
||||||
server_lifetime = {{ $user.server_lifetime }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if and $user.server_username $user.server_password }}
|
{{- if and $user.server_username $user.server_password }}
|
||||||
server_username = {{ $user.server_username | quote }}
|
server_username = {{ $user.server_username | quote }}
|
||||||
server_password = {{ $user.server_password | quote }}
|
server_password = {{ $user.server_password | quote }}
|
||||||
|
|||||||
@@ -175,9 +175,6 @@ configuration:
|
|||||||
# Max connection lifetime before it's closed, even if actively used.
|
# Max connection lifetime before it's closed, even if actively used.
|
||||||
server_lifetime: 86400000 # 24 hours
|
server_lifetime: 86400000 # 24 hours
|
||||||
|
|
||||||
# Whether to use TLS for server connections or not.
|
|
||||||
server_tls: false
|
|
||||||
|
|
||||||
# How long a client is allowed to be idle while in a transaction (ms).
|
# How long a client is allowed to be idle while in a transaction (ms).
|
||||||
idle_client_in_transaction_timeout: 0 # milliseconds
|
idle_client_in_transaction_timeout: 0 # milliseconds
|
||||||
|
|
||||||
@@ -318,9 +315,7 @@ configuration:
|
|||||||
# ## Credentials for users that may connect to this cluster
|
# ## Credentials for users that may connect to this cluster
|
||||||
# ## @param users [array]
|
# ## @param users [array]
|
||||||
# ## @param users[0].username Name of the env var (required)
|
# ## @param users[0].username Name of the env var (required)
|
||||||
# ## @param users[0].password Value for the env var (required) leave empty to use existing secret see passwordSecret.name and passwordSecret.key
|
# ## @param users[0].password Value for the env var (required)
|
||||||
# ## @param users[0].passwordSecret.name Name of the secret containing the password
|
|
||||||
# ## @param users[0].passwordSecret.key Key in the secret containing the password
|
|
||||||
# ## @param users[0].pool_size Maximum number of server connections that can be established for this user
|
# ## @param users[0].pool_size Maximum number of server connections that can be established for this user
|
||||||
# ## @param users[0].statement_timeout Maximum query duration. Dangerous, but protects against DBs that died in a non-obvious way.
|
# ## @param users[0].statement_timeout Maximum query duration. Dangerous, but protects against DBs that died in a non-obvious way.
|
||||||
# users: []
|
# users: []
|
||||||
|
|||||||
@@ -309,7 +309,6 @@ async fn prometheus_stats(
|
|||||||
push_pool_stats(&mut lines);
|
push_pool_stats(&mut lines);
|
||||||
push_server_stats(&mut lines);
|
push_server_stats(&mut lines);
|
||||||
push_database_stats(&mut lines);
|
push_database_stats(&mut lines);
|
||||||
lines.push("".to_string()); // Ensure to end the stats with a line terminator as required by the specification.
|
|
||||||
|
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.header("content-type", "text/plain; version=0.0.4")
|
.header("content-type", "text/plain; version=0.0.4")
|
||||||
|
|||||||
@@ -386,18 +386,6 @@ impl QueryRouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines if a query is a mutation or not.
|
|
||||||
fn is_mutation_query(q: &sqlparser::ast::Query) -> bool {
|
|
||||||
use sqlparser::ast::*;
|
|
||||||
|
|
||||||
match q.body.as_ref() {
|
|
||||||
SetExpr::Insert(_) => true,
|
|
||||||
SetExpr::Update(_) => true,
|
|
||||||
SetExpr::Query(q) => Self::is_mutation_query(q),
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Try to infer which server to connect to based on the contents of the query.
|
/// Try to infer which server to connect to based on the contents of the query.
|
||||||
pub fn infer(&mut self, ast: &Vec<sqlparser::ast::Statement>) -> Result<(), Error> {
|
pub fn infer(&mut self, ast: &Vec<sqlparser::ast::Statement>) -> Result<(), Error> {
|
||||||
if !self.pool_settings.query_parser_read_write_splitting {
|
if !self.pool_settings.query_parser_read_write_splitting {
|
||||||
@@ -440,9 +428,8 @@ impl QueryRouter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let has_locks = !query.locks.is_empty();
|
let has_locks = !query.locks.is_empty();
|
||||||
let has_mutation = Self::is_mutation_query(query);
|
|
||||||
|
|
||||||
if has_locks || has_mutation {
|
if has_locks {
|
||||||
self.active_role = Some(Role::Primary);
|
self.active_role = Some(Role::Primary);
|
||||||
} else if !visited_write_statement {
|
} else if !visited_write_statement {
|
||||||
// If we already visited a write statement, we should be going to the primary.
|
// If we already visited a write statement, we should be going to the primary.
|
||||||
@@ -1126,26 +1113,6 @@ mod test {
|
|||||||
assert_eq!(qr.role(), None);
|
assert_eq!(qr.role(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_split_cte_queries() {
|
|
||||||
QueryRouter::setup();
|
|
||||||
let mut qr = QueryRouter::new();
|
|
||||||
qr.pool_settings.query_parser_read_write_splitting = true;
|
|
||||||
qr.pool_settings.query_parser_enabled = true;
|
|
||||||
|
|
||||||
let query = simple_query(
|
|
||||||
"WITH t AS (
|
|
||||||
SELECT id FROM users WHERE name ILIKE '%ja%'
|
|
||||||
)
|
|
||||||
UPDATE user_languages
|
|
||||||
SET settings = '{}'
|
|
||||||
FROM t WHERE t.id = user_id;",
|
|
||||||
);
|
|
||||||
let ast = qr.parse(&query).unwrap();
|
|
||||||
assert!(qr.infer(&ast).is_ok());
|
|
||||||
assert_eq!(qr.role(), Some(Role::Primary));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_infer_replica() {
|
fn test_infer_replica() {
|
||||||
QueryRouter::setup();
|
QueryRouter::setup();
|
||||||
|
|||||||
@@ -1,33 +1,22 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
activemodel (7.1.4)
|
activemodel (7.0.4.1)
|
||||||
activesupport (= 7.1.4)
|
activesupport (= 7.0.4.1)
|
||||||
activerecord (7.1.4)
|
activerecord (7.0.4.1)
|
||||||
activemodel (= 7.1.4)
|
activemodel (= 7.0.4.1)
|
||||||
activesupport (= 7.1.4)
|
activesupport (= 7.0.4.1)
|
||||||
timeout (>= 0.4.0)
|
activesupport (7.0.4.1)
|
||||||
activesupport (7.1.4)
|
|
||||||
base64
|
|
||||||
bigdecimal
|
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
connection_pool (>= 2.2.5)
|
|
||||||
drb
|
|
||||||
i18n (>= 1.6, < 2)
|
i18n (>= 1.6, < 2)
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
mutex_m
|
|
||||||
tzinfo (~> 2.0)
|
tzinfo (~> 2.0)
|
||||||
ast (2.4.2)
|
ast (2.4.2)
|
||||||
base64 (0.2.0)
|
concurrent-ruby (1.1.10)
|
||||||
bigdecimal (3.1.8)
|
|
||||||
concurrent-ruby (1.3.4)
|
|
||||||
connection_pool (2.4.1)
|
|
||||||
diff-lcs (1.5.0)
|
diff-lcs (1.5.0)
|
||||||
drb (2.2.1)
|
i18n (1.12.0)
|
||||||
i18n (1.14.5)
|
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
minitest (5.25.1)
|
minitest (5.17.0)
|
||||||
mutex_m (0.2.0)
|
|
||||||
parallel (1.22.1)
|
parallel (1.22.1)
|
||||||
parser (3.1.2.0)
|
parser (3.1.2.0)
|
||||||
ast (~> 2.4.1)
|
ast (~> 2.4.1)
|
||||||
@@ -63,11 +52,10 @@ GEM
|
|||||||
parser (>= 3.1.1.0)
|
parser (>= 3.1.1.0)
|
||||||
ruby-progressbar (1.11.0)
|
ruby-progressbar (1.11.0)
|
||||||
strscan (3.1.0)
|
strscan (3.1.0)
|
||||||
timeout (0.4.1)
|
|
||||||
toml (0.3.0)
|
toml (0.3.0)
|
||||||
parslet (>= 1.8.0, < 3.0.0)
|
parslet (>= 1.8.0, < 3.0.0)
|
||||||
toxiproxy (2.0.1)
|
toxiproxy (2.0.1)
|
||||||
tzinfo (2.0.6)
|
tzinfo (2.0.5)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
unicode-display_width (2.1.0)
|
unicode-display_width (2.1.0)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user