Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit240ba05

Browse files
queenofpigeonsAlexandra Pervushina
and
Alexandra Pervushina
authored
Fix aqo.dsm_max_size segfault (#178)
Fix aqo.dsm_max_size segfaultAdd test for dsm_max_size---------Co-authored-by: Alexandra Pervushina <a.pervushina@postgrespro.ru>
1 parent470e709 commit240ba05

File tree

6 files changed

+152
-15
lines changed

6 files changed

+152
-15
lines changed

‎aqo.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,8 @@ _PG_init(void)
270270
&dsm_size_max,
271271
100,
272272
0,INT_MAX,
273-
PGC_SUSET,
274-
0,
273+
PGC_POSTMASTER,
274+
GUC_UNIT_MB,
275275
NULL,
276276
NULL,
277277
NULL
@@ -383,5 +383,5 @@ PG_FUNCTION_INFO_V1(invalidate_deactivated_queries_cache);
383383
Datum
384384
invalidate_deactivated_queries_cache(PG_FUNCTION_ARGS)
385385
{
386-
PG_RETURN_POINTER(NULL);
386+
PG_RETURN_POINTER(NULL);
387387
}

‎aqo_shared.c‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ aqo_init_shmem(void)
9797
/* Doesn't use DSA, so can be loaded in postmaster */
9898
aqo_stat_load();
9999
aqo_queries_load();
100+
101+
check_dsa_file_size();
100102
}
101103
}
102104

‎preprocessing.c‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,14 +283,23 @@ aqo_planner(Query *parse, const char *query_string, int cursorOptions,
283283
query_context.learn_aqo,query_context.use_aqo,
284284
query_context.auto_tuning,&aqo_queries_nulls))
285285
{
286+
booldsa_valid= true;
286287
/*
287288
* Add query text into the ML-knowledge base. Just for further
288289
* analysis. In the case of cached plans we may have NULL query text.
289290
*/
290-
if (!aqo_qtext_store(query_context.query_hash,query_string))
291+
if (!aqo_qtext_store(query_context.query_hash,query_string,&dsa_valid))
291292
{
292-
Assert(0);/* panic only on debug installation */
293-
elog(ERROR,"[AQO] Impossible situation was detected. Maybe not enough of shared memory?");
293+
if (!dsa_valid)
294+
{
295+
disable_aqo_for_query();
296+
elog(WARNING,"[AQO] Not enough DSA. AQO was disabled for this query");
297+
}
298+
else
299+
{
300+
Assert(0);/* panic only on debug installation */
301+
elog(ERROR,"[AQO] Impossible situation was detected. Maybe not enough of shared memory?");
302+
}
294303
}
295304
}
296305
else

‎storage.c‎

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ _form_qtext_record_cb(void *ctx, size_t *size)
507507
{
508508
HASH_SEQ_STATUS*hash_seq= (HASH_SEQ_STATUS*)ctx;
509509
QueryTextEntry*entry;
510-
void*data;
510+
void*data;
511511
char*query_string;
512512
char*ptr;
513513

@@ -784,7 +784,7 @@ _deform_qtexts_record_cb(void *data, size_t size)
784784
HASH_ENTER,&found);
785785
Assert(!found);
786786

787-
entry->qtext_dp=dsa_allocate(qtext_dsa,len);
787+
entry->qtext_dp=dsa_allocate_extended(qtext_dsa,len,DSA_ALLOC_NO_OOM |DSA_ALLOC_ZERO);
788788
if (!_check_dsa_validity(entry->qtext_dp))
789789
{
790790
/*
@@ -829,7 +829,7 @@ aqo_qtexts_load(void)
829829

830830
if (!found)
831831
{
832-
if (!aqo_qtext_store(0,"COMMON feature space (do not delete!)"))
832+
if (!aqo_qtext_store(0,"COMMON feature space (do not delete!)",NULL))
833833
elog(PANIC,"[AQO] DSA Initialization was unsuccessful");
834834
}
835835
}
@@ -944,6 +944,49 @@ aqo_queries_load(void)
944944
}
945945
}
946946

947+
staticlong
948+
aqo_get_file_size(constchar*filename)
949+
{
950+
FILE*file;
951+
longsize=0;
952+
953+
file=AllocateFile(filename,PG_BINARY_R);
954+
if (file==NULL)
955+
{
956+
if (errno!=ENOENT)
957+
gotoread_error;
958+
returnsize;
959+
}
960+
961+
fseek(file,0L,SEEK_END);
962+
size=ftell(file);
963+
964+
FreeFile(file);
965+
returnsize;
966+
967+
read_error:
968+
ereport(LOG,
969+
(errcode_for_file_access(),
970+
errmsg("could not read file \"%s\": %m",filename)));
971+
if (file)
972+
FreeFile(file);
973+
unlink(filename);
974+
return-1;
975+
}
976+
977+
void
978+
check_dsa_file_size(void)
979+
{
980+
longqtext_size=aqo_get_file_size(PGAQO_TEXT_FILE);
981+
longdata_size=aqo_get_file_size(PGAQO_DATA_FILE);
982+
983+
if (qtext_size==-1||data_size==-1||
984+
qtext_size+data_size >=dsm_size_max*1024*1024)
985+
{
986+
elog(ERROR,"aqo.dsm_size_max is too small");
987+
}
988+
}
989+
947990
staticvoid
948991
data_load(constchar*filename,deform_record_tcallback,void*ctx)
949992
{
@@ -1090,13 +1133,16 @@ dsa_init()
10901133
* XXX: Maybe merge with aqo_queries ?
10911134
*/
10921135
bool
1093-
aqo_qtext_store(uint64queryid,constchar*query_string)
1136+
aqo_qtext_store(uint64queryid,constchar*query_string,bool*dsa_valid)
10941137
{
10951138
QueryTextEntry*entry;
10961139
boolfound;
10971140
booltblOverflow;
10981141
HASHACTIONaction;
10991142

1143+
if (dsa_valid)
1144+
*dsa_valid= true;
1145+
11001146
Assert(!LWLockHeldByMe(&aqo_state->qtexts_lock));
11011147

11021148
if (query_string==NULL||querytext_max_size==0)
@@ -1135,7 +1181,7 @@ aqo_qtext_store(uint64 queryid, const char *query_string)
11351181

11361182
entry->queryid=queryid;
11371183
size=size>querytext_max_size ?querytext_max_size :size;
1138-
entry->qtext_dp=dsa_allocate0(qtext_dsa,size);
1184+
entry->qtext_dp=dsa_allocate_extended(qtext_dsa,size,DSA_ALLOC_NO_OOM |DSA_ALLOC_ZERO);
11391185

11401186
if (!_check_dsa_validity(entry->qtext_dp))
11411187
{
@@ -1144,7 +1190,10 @@ aqo_qtext_store(uint64 queryid, const char *query_string)
11441190
* that caller recognize it and don't try to call us more.
11451191
*/
11461192
(void)hash_search(qtexts_htab,&queryid,HASH_REMOVE,NULL);
1193+
_aqo_queries_remove(queryid);
11471194
LWLockRelease(&aqo_state->qtexts_lock);
1195+
if (dsa_valid)
1196+
*dsa_valid= false;
11481197
return false;
11491198
}
11501199

@@ -1423,7 +1472,7 @@ aqo_data_store(uint64 fs, int fss, AqoDataArgs *data, List *reloids)
14231472
entry->nrels=nrels;
14241473

14251474
size=_compute_data_dsa(entry);
1426-
entry->data_dp=dsa_allocate0(data_dsa,size);
1475+
entry->data_dp=dsa_allocate_extended(data_dsa,size,DSA_ALLOC_NO_OOM |DSA_ALLOC_ZERO);
14271476

14281477
if (!_check_dsa_validity(entry->data_dp))
14291478
{
@@ -1455,7 +1504,7 @@ aqo_data_store(uint64 fs, int fss, AqoDataArgs *data, List *reloids)
14551504

14561505
/* Need to re-allocate DSA chunk */
14571506
dsa_free(data_dsa,entry->data_dp);
1458-
entry->data_dp=dsa_allocate0(data_dsa,size);
1507+
entry->data_dp=dsa_allocate_extended(data_dsa,size,DSA_ALLOC_NO_OOM |DSA_ALLOC_ZERO);
14591508

14601509
if (!_check_dsa_validity(entry->data_dp))
14611510
{
@@ -2713,7 +2762,7 @@ aqo_query_texts_update(PG_FUNCTION_ARGS)
27132762

27142763
str_buff= (char*)palloc(str_len);
27152764
text_to_cstring_buffer(str,str_buff,str_len);
2716-
res=aqo_qtext_store(queryid,str_buff);
2765+
res=aqo_qtext_store(queryid,str_buff,NULL);
27172766
pfree(str_buff);
27182767

27192768
PG_RETURN_BOOL(res);

‎storage.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ extern StatEntry *aqo_stat_store(uint64 queryid, bool use_aqo,
138138
externvoidaqo_stat_flush(void);
139139
externvoidaqo_stat_load(void);
140140

141-
externboolaqo_qtext_store(uint64queryid,constchar*query_string);
141+
externboolaqo_qtext_store(uint64queryid,constchar*query_string,bool*dsa_valid);
142142
externvoidaqo_qtexts_flush(void);
143143
externvoidaqo_qtexts_load(void);
144144

@@ -156,6 +156,7 @@ extern bool aqo_queries_store(uint64 queryid, uint64 fs, bool learn_aqo,
156156
externvoidaqo_queries_flush(void);
157157
externvoidaqo_queries_load(void);
158158

159+
externvoidcheck_dsa_file_size(void);
159160
/*
160161
* Machinery for deactivated queries cache.
161162
* TODO: Should live in a custom memory context

‎t/004_dsm_size_max.pl‎

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use strict;
2+
use warnings;
3+
4+
use Config;
5+
use PostgreSQL::Test::Cluster;
6+
use PostgreSQL::Test::Utils;
7+
8+
use Test::Moretests=> 5;
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.mode = 'learn'
15+
log_statement = 'ddl'
16+
aqo.join_threshold = 0
17+
aqo.dsm_size_max = 4
18+
aqo.fs_max_items = 30000
19+
aqo.querytext_max_size = 1000000
20+
});
21+
22+
# Disable connection default settings, forced by PGOPTIONS in AQO Makefile
23+
$ENV{PGOPTIONS}="";
24+
25+
# General purpose variables.
26+
my$long_string ='a'x1000000;
27+
28+
$node->start();
29+
$node->psql('postgres','CREATE EXTENSION aqo;');
30+
31+
formy$i (1 .. 3) {
32+
$node->psql('postgres',"select aqo_query_texts_update(" .$i .",\'" .$long_string ."\');");
33+
}
34+
$node->stop();
35+
36+
$node->append_conf('postgresql.conf','aqo.dsm_size_max = 1');
37+
is($node->start(fail_ok=> 1),
38+
0,"node fails to start");
39+
40+
$node->append_conf('postgresql.conf','aqo.dsm_size_max = 4');
41+
is($node->start(),
42+
1,"node starts");
43+
$node->psql('postgres','select * from aqo_reset();');
44+
45+
$long_string ='1,'x10000;
46+
formy$i (1 .. 30) {
47+
$node->psql('postgres',"select aqo_data_update(" .$i .", 1, 1, '{{1}}', '{1}', '{1}', '{" .$long_string ." 1}');");
48+
}
49+
$node->stop();
50+
51+
$node->append_conf('postgresql.conf','aqo.dsm_size_max = 1');
52+
is($node->start(fail_ok=> 1),
53+
0,"node fails to start");
54+
55+
$node->append_conf('postgresql.conf','aqo.dsm_size_max = 4');
56+
is($node->start(),
57+
1,"node starts");
58+
$node->psql('postgres','select * from aqo_reset();');
59+
$node->stop();
60+
61+
my$regex;
62+
$long_string ='a'x100000;
63+
$regex =qr/.*WARNING:\[AQO\] Not enough DSA\. AQO was disabled for this query/;
64+
$node->append_conf('postgresql.conf','aqo.dsm_size_max = 1');
65+
$node->start();
66+
my ($stdout,$stderr);
67+
formy$i (1 .. 20) {
68+
$node->psql('postgres',"create table a as select s, md5(random()::text) from generate_Series(1,100) s;");
69+
$node->psql('postgres',
70+
"SELECT a.s FROM a CROSS JOIN ( SELECT '" .$long_string ."' as long_string) AS extra_rows;",
71+
stdout=> \$stdout,stderr=> \$stderr);
72+
$node->psql('postgres',"drop table a");
73+
}
74+
like($stderr,$regex,'warning for exceeding the dsa limit');
75+
$node->stop;
76+
done_testing();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp