Skip to content

Commit 9d2b27a

Browse files
Andrey KazarinovAnisimov-ds
authored andcommitted
cancel aqo timeout action in the critical section
1 parent 79f8548 commit 9d2b27a

File tree

4 files changed

+90
-5
lines changed

4 files changed

+90
-5
lines changed

aqo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ extern bool aqo_show_details;
172172
extern int aqo_join_threshold;
173173
extern bool use_wide_search;
174174
extern bool aqo_learn_statement_timeout;
175+
extern bool aqo_learn_statement_timeout_enable;
175176

176177
/* Parameters for current query */
177178
typedef struct QueryContextData

postprocessing.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "optimizer/optimizer.h"
2323
#include "postgres_fdw.h"
2424
#include "utils/queryenvironment.h"
25+
#include "miscadmin.h"
2526

2627
#include "aqo.h"
2728
#include "hash.h"
@@ -628,8 +629,12 @@ aqo_timeout_handler(void)
628629
MemoryContext oldctx = MemoryContextSwitchTo(AQOLearnMemCtx);
629630
aqo_obj_stat ctx = {NIL, NIL, NIL, false, false};
630631

631-
if (!timeoutCtl.queryDesc || !ExtractFromQueryEnv(timeoutCtl.queryDesc))
632+
if (CritSectionCount > 0 || !timeoutCtl.queryDesc ||
633+
!ExtractFromQueryEnv(timeoutCtl.queryDesc))
634+
{
635+
MemoryContextSwitchTo(oldctx);
632636
return;
637+
}
633638

634639
/* Now we can analyze execution state of the query. */
635640

@@ -664,7 +669,7 @@ set_timeout_if_need(QueryDesc *queryDesc)
664669
{
665670
int64 fintime = (int64) get_timeout_finish_time(STATEMENT_TIMEOUT)-1;
666671

667-
if (aqo_learn_statement_timeout && aqo_statement_timeout > 0)
672+
if (aqo_learn_statement_timeout_enable && aqo_statement_timeout > 0)
668673
{
669674
max_timeout_value = Min(query_context.smart_timeout, (int64) aqo_statement_timeout);
670675
if (max_timeout_value > fintime)
@@ -684,7 +689,7 @@ set_timeout_if_need(QueryDesc *queryDesc)
684689
*/
685690
return false;
686691

687-
if (!get_timeout_active(STATEMENT_TIMEOUT) || !aqo_learn_statement_timeout)
692+
if (!get_timeout_active(STATEMENT_TIMEOUT) || !aqo_learn_statement_timeout_enable)
688693
return false;
689694

690695
if (!ExtractFromQueryEnv(queryDesc))
@@ -829,7 +834,7 @@ aqo_ExecutorEnd(QueryDesc *queryDesc)
829834

830835
error = stat->est_error_aqo[stat->cur_stat_slot_aqo-1] - cardinality_sum_errors/(1 + cardinality_num_objects);
831836

832-
if ( aqo_learn_statement_timeout && aqo_statement_timeout > 0 && error >= 0.1)
837+
if ( aqo_learn_statement_timeout_enable && aqo_statement_timeout > 0 && error >= 0.1)
833838
{
834839
int64 fintime = increase_smart_timeout();
835840
elog(NOTICE, "[AQO] Time limit for execution of the statement was increased. Current timeout is "UINT64_FORMAT, fintime);

preprocessing.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,10 @@ List *cur_classes = NIL;
7171

7272
int aqo_join_threshold = 3;
7373

74+
bool aqo_learn_statement_timeout_enable = false;
75+
7476
static planner_hook_type aqo_planner_next = NULL;
77+
static post_parse_analyze_hook_type aqo_post_parse_analyze_hook = NULL;
7578

7679
static void disable_aqo_for_query(void);
7780
static bool isQueryUsingSystemRelation(Query *query);
@@ -478,9 +481,26 @@ isQueryUsingSystemRelation_walker(Node *node, void *context)
478481
context);
479482
}
480483

484+
static void
485+
aqo_post_parse_analyze(ParseState *pstate, Query *query, JumbleState *jstate)
486+
{
487+
aqo_learn_statement_timeout_enable = false;
488+
/*
489+
* Enable learn_statement_timeout for
490+
* the top level SELECT statement only.
491+
*/
492+
if (query->commandType == CMD_SELECT)
493+
aqo_learn_statement_timeout_enable = aqo_learn_statement_timeout;
494+
495+
if (aqo_post_parse_analyze_hook)
496+
aqo_post_parse_analyze_hook(pstate, query, jstate);
497+
}
498+
481499
void
482500
aqo_preprocessing_init(void)
483501
{
484502
aqo_planner_next = planner_hook ? planner_hook : standard_planner;
485503
planner_hook = aqo_planner;
486-
}
504+
aqo_post_parse_analyze_hook = post_parse_analyze_hook;
505+
post_parse_analyze_hook = aqo_post_parse_analyze;
506+
}

t/003_assertion_error.pl

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use strict;
2+
use warnings;
3+
4+
use Config;
5+
use PostgreSQL::Test::Cluster;
6+
use PostgreSQL::Test::Utils;
7+
8+
use Test::More tests => 1;
9+
10+
my $node = PostgreSQL::Test::Cluster->new('aqotest');
11+
$node->init;
12+
$node->append_conf('postgresql.conf', qq{
13+
shared_preload_libraries = 'aqo'
14+
aqo.join_threshold = 0
15+
aqo.mode = 'learn'
16+
aqo.show_details = 'off'
17+
aqo.learn_statement_timeout = 'on'
18+
});
19+
20+
# Test constants. Default values.
21+
my $TRANSACTIONS = 100;
22+
23+
# Disable connection default settings, forced by PGOPTIONS in AQO Makefile
24+
# $ENV{PGOPTIONS}="";
25+
26+
# Change pgbench parameters according to the environment variable.
27+
if (defined $ENV{TRANSACTIONS})
28+
{
29+
$TRANSACTIONS = $ENV{TRANSACTIONS};
30+
}
31+
32+
my $query_string = '
33+
CREATE TABLE IF NOT EXISTS aqo_test1(a int, b int);
34+
WITH RECURSIVE t(a, b)
35+
AS (
36+
VALUES (1, 2)
37+
UNION ALL
38+
SELECT t.a + 1, t.b + 1 FROM t WHERE t.a < 10
39+
) INSERT INTO aqo_test1 (SELECT * FROM t);
40+
41+
SET statement_timeout = 10;
42+
43+
CREATE TABLE tmp1 AS SELECT t1.a AS a, t2.a AS b, t3.a AS c
44+
FROM aqo_test1 AS t1, aqo_test1 AS t2, aqo_test1 AS t3
45+
WHERE t1.a = t2.b AND t2.a = t3.b;
46+
DROP TABLE tmp1;
47+
';
48+
49+
$node->start();
50+
51+
$node->safe_psql('postgres', 'CREATE EXTENSION IF NOT EXISTS aqo;');
52+
53+
for (1..$TRANSACTIONS) {
54+
$node->psql('postgres', $query_string);
55+
}
56+
57+
ok(1, "There are no segfaults");
58+
59+
$node->stop();

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy