Add pool_discard_query option (#488)

This commit is contained in:
Andrey 2023-04-24 10:17:45 +03:00 committed by GitHub
parent 76ea5f7169
commit 9a4554fcfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 3 deletions

View File

@ -685,6 +685,27 @@ from the pool.
`pool_discard no` `pool_discard no`
#### pool\_smart\_discard *yes|no*
When this parameter is enabled, Odyssey sends smart discard query instead of default `DISCARD ALL` when it
returns connection to the pool. Its default value may be overwritten by pool\_discard\_string setting.
#### pool\_discard\_string *string*
When resetting a database connection, a pre-defined query string is sent to the server. This query string consists of a set of SQL statements that will be executed during a `DISCARD ALL` command, except for `DEALLOCATE ALL`. The default query string includes the following statements:
```sql
SET SESSION AUTHORIZATION DEFAULT;
RESET ALL;
CLOSE ALL;
UNLISTEN *;
SELECT pg_advisory_unlock_all();
DISCARD PLANS;
DISCARD SEQUENCES;DISCARD TEMP;
```
This sequence of statements is designed to reset the connection to a clean state, without affecting the authentication credentials of the session. By executing these queries, any open transactions will be closed, locks will be released, and any cached execution plans and sequences will be discarded.
#### pool\_cancel *yes|no* #### pool\_cancel *yes|no*
Server pool auto-cancel. Server pool auto-cancel.

View File

@ -97,6 +97,7 @@ typedef enum {
OD_LPOOL_TTL, OD_LPOOL_TTL,
OD_LPOOL_DISCARD, OD_LPOOL_DISCARD,
OD_LPOOL_SMART_DISCARD, OD_LPOOL_SMART_DISCARD,
OD_LPOOL_DISCARD_QUERY,
OD_LPOOL_CANCEL, OD_LPOOL_CANCEL,
OD_LPOOL_ROLLBACK, OD_LPOOL_ROLLBACK,
OD_LPOOL_RESERVE_PREPARED_STATEMENT, OD_LPOOL_RESERVE_PREPARED_STATEMENT,
@ -249,6 +250,7 @@ static od_keyword_t od_config_keywords[] = {
od_keyword("pool_timeout", OD_LPOOL_TIMEOUT), od_keyword("pool_timeout", OD_LPOOL_TIMEOUT),
od_keyword("pool_ttl", OD_LPOOL_TTL), od_keyword("pool_ttl", OD_LPOOL_TTL),
od_keyword("pool_discard", OD_LPOOL_DISCARD), od_keyword("pool_discard", OD_LPOOL_DISCARD),
od_keyword("pool_discard_query", OD_LPOOL_DISCARD_QUERY),
od_keyword("pool_smart_discard", OD_LPOOL_SMART_DISCARD), od_keyword("pool_smart_discard", OD_LPOOL_SMART_DISCARD),
od_keyword("pool_cancel", OD_LPOOL_CANCEL), od_keyword("pool_cancel", OD_LPOOL_CANCEL),
od_keyword("pool_rollback", OD_LPOOL_ROLLBACK), od_keyword("pool_rollback", OD_LPOOL_ROLLBACK),
@ -1360,6 +1362,12 @@ static int od_config_reader_rule_settings(od_config_reader_t *reader,
reader, &rule->pool->smart_discard)) reader, &rule->pool->smart_discard))
return NOT_OK_RESPONSE; return NOT_OK_RESPONSE;
continue; continue;
/* pool_discard_query */
case OD_LPOOL_DISCARD_QUERY:
if (!od_config_reader_string(
reader, &rule->pool->discard_query))
return NOT_OK_RESPONSE;
continue;
/* pool_cancel */ /* pool_cancel */
case OD_LPOOL_CANCEL: case OD_LPOOL_CANCEL:
if (!od_config_reader_yes_no(reader, if (!od_config_reader_yes_no(reader,

View File

@ -20,6 +20,7 @@ od_rule_pool_t *od_rule_pool_alloc()
pool->discard = 1; pool->discard = 1;
pool->smart_discard = 0; pool->smart_discard = 0;
pool->discard_query = NULL;
pool->cancel = 1; pool->cancel = 1;
pool->rollback = 1; pool->rollback = 1;
@ -34,6 +35,9 @@ int od_rule_pool_free(od_rule_pool_t *pool)
if (pool->type) { if (pool->type) {
free(pool->type); free(pool->type);
} }
if (pool->discard_query) {
free(pool->discard_query);
}
free(pool); free(pool);
return OK_RESPONSE; return OK_RESPONSE;
} }

View File

@ -33,6 +33,7 @@ struct od_rule_pool {
char *type; char *type;
char *routing_type; char *routing_type;
char *discard_query;
int size; int size;
int timeout; int timeout;

View File

@ -129,8 +129,9 @@ int od_reset(od_server_t *server)
goto error; goto error;
} }
/* send smard DISCARD ALL */ /* send smart discard */
if (route->rule->pool->smart_discard) { if (route->rule->pool->smart_discard &&
route->rule->pool->discard_query == NULL) {
char query_discard[] = char query_discard[] =
"SET SESSION AUTHORIZATION DEFAULT;RESET ALL;CLOSE ALL;UNLISTEN *;SELECT pg_advisory_unlock_all();DISCARD PLANS;DISCARD SEQUENCES;DISCARD TEMP;"; "SET SESSION AUTHORIZATION DEFAULT;RESET ALL;CLOSE ALL;UNLISTEN *;SELECT pg_advisory_unlock_all();DISCARD PLANS;DISCARD SEQUENCES;DISCARD TEMP;";
rc = od_backend_query(server, "reset-discard-smart", rc = od_backend_query(server, "reset-discard-smart",
@ -139,6 +140,15 @@ int od_reset(od_server_t *server)
if (rc == NOT_OK_RESPONSE) if (rc == NOT_OK_RESPONSE)
goto error; goto error;
} }
if (route->rule->pool->discard_query != NULL) {
rc = od_backend_query(server, "reset-discard-smart-string",
route->rule->pool->discard_query, NULL,
strlen(route->rule->pool->discard_query) +
1,
wait_timeout, 1);
if (rc == NOT_OK_RESPONSE)
goto error;
}
/* ready */ /* ready */
return 1; return 1;

View File

@ -745,7 +745,7 @@ int od_pool_validate(od_logger_t *logger, od_rule_pool_t *pool, char *db_name,
return NOT_OK_RESPONSE; return NOT_OK_RESPONSE;
} }
// reserve prepare statemetn feature // reserve prepare statement feature
if (pool->reserve_prepared_statement && if (pool->reserve_prepared_statement &&
pool->pool == OD_RULE_POOL_SESSION) { pool->pool == OD_RULE_POOL_SESSION) {
od_error( od_error(
@ -771,6 +771,16 @@ int od_pool_validate(od_logger_t *logger, od_rule_pool_t *pool, char *db_name,
return NOT_OK_RESPONSE; return NOT_OK_RESPONSE;
} }
if (pool->discard_query && pool->reserve_prepared_statement) {
if (strcasestr(pool->discard_query, "DEALLOCATE ALL")) {
od_error(
logger, "rules", NULL, NULL,
"rule '%s.%s': cannot support prepared statements when 'DEALLOCATE ALL' present in discard string",
db_name, user_name);
return NOT_OK_RESPONSE;
}
}
return OK_RESPONSE; return OK_RESPONSE;
} }