Skip to content

Commit fcb3183

Browse files
montywivuvova
authored andcommitted
MDEV-34142 Server crashes in create_internal_tmp_table with low tmp space limit
1 parent 46751d4 commit fcb3183

File tree

4 files changed

+65
-21
lines changed

4 files changed

+65
-21
lines changed

mysql-test/main/tmp_space_usage.result

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,25 @@ ERROR HY000: Local temporary space limit reached
213213
drop table t1;
214214
connection default;
215215
disconnect c1;
216+
#
217+
# MDEV-34142 Server crashes in create_internal_tmp_table with low tmp
218+
# space limit
219+
#
220+
SET MAX_TMP_SESSION_SPACE_USAGE = 128*1024, MAX_HEAP_TABLE_SIZE= 16*1024*1024;
221+
CREATE TABLE t1 (a varchar(1024)) DEFAULT CHARACTER SET utf8mb3;
222+
INSERT INTO t1 SELECT 'x' FROM seq_1_to_50;
223+
SELECT * FROM t1 JOIN seq_1_to_200 INTERSECT ALL SELECT * FROM t1 JOIN seq_1_to_200;
224+
ERROR HY000: Local temporary space limit reached
225+
drop table t1;
226+
#
227+
# MDEV-34149 Corruption-like errors are produced when temporary space
228+
# limit is reached
229+
#
230+
SET MAX_TMP_SESSION_SPACE_USAGE = 400*1024;
231+
Warnings:
232+
Warning 1292 Truncated incorrect max_tmp_session_space_usage value: '409600'
233+
SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_VARIABLES JOIN seq_1_to_100
234+
INTERSECT ALL
235+
SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_VARIABLES JOIN seq_1_to_100;
236+
ERROR HY000: Local temporary space limit reached
216237
# End of 11.5 tests

mysql-test/main/tmp_space_usage.test

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,4 +275,27 @@ drop table t1;
275275
connection default;
276276
disconnect c1;
277277

278+
--echo #
279+
--echo # MDEV-34142 Server crashes in create_internal_tmp_table with low tmp
280+
--echo # space limit
281+
--echo #
282+
283+
SET MAX_TMP_SESSION_SPACE_USAGE = 128*1024, MAX_HEAP_TABLE_SIZE= 16*1024*1024;
284+
CREATE TABLE t1 (a varchar(1024)) DEFAULT CHARACTER SET utf8mb3;
285+
INSERT INTO t1 SELECT 'x' FROM seq_1_to_50;
286+
--error 200
287+
SELECT * FROM t1 JOIN seq_1_to_200 INTERSECT ALL SELECT * FROM t1 JOIN seq_1_to_200;
288+
drop table t1;
289+
290+
--echo #
291+
--echo # MDEV-34149 Corruption-like errors are produced when temporary space
292+
--echo # limit is reached
293+
--echo #
294+
295+
SET MAX_TMP_SESSION_SPACE_USAGE = 400*1024;
296+
--error 200
297+
SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_VARIABLES JOIN seq_1_to_100
298+
INTERSECT ALL
299+
SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_VARIABLES JOIN seq_1_to_100;
300+
278301
--echo # End of 11.5 tests

sql/sql_select.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21252,7 +21252,7 @@ TABLE *Create_tmp_table::start(THD *thd,
2125221252
&m_key_part_info,
2125321253
sizeof(*m_key_part_info)*(param->group_parts+1),
2125421254
&param->start_recinfo,
21255-
sizeof(*param->recinfo)*(field_count*2+4),
21255+
sizeof(*param->start_recinfo)*(field_count*2+4),
2125621256
&param->rec_per_key, sizeof(ulong)*param->group_parts,
2125721257
&tmpname, (uint) strlen(path)+1,
2125821258
&m_group_buff, (m_group && ! m_using_unique_constraint ?
@@ -22714,6 +22714,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *org_keyinfo,
2271422714
and copy all rows to this
2271522715

2271622716
In case of error, my_error() or handler::print_error() will be called.
22717+
Note that in case of error, table->file->ha_rnd_end() may have been called!
2271722718
*/
2271822719

2271922720

sql/sql_union.cc

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,9 @@ int select_unit::send_data(List<Item> &values)
157157
switch (step)
158158
{
159159
case UNION_TYPE:
160+
/* Errors not related to duplicate key are reported by write_record() */
160161
rc= write_record();
161-
/* no reaction with conversion */
162+
/* no reaction with conversion. rc == -1 (dupp key) is ignored by caller */
162163
if (rc == -2)
163164
rc= 0;
164165
break;
@@ -431,18 +432,11 @@ int select_unit::write_record()
431432
tmp_table_param.start_recinfo,
432433
&tmp_table_param.recinfo,
433434
write_err, 1, &is_duplicate))
434-
{
435435
return -2;
436-
}
437-
else
438-
{
439-
return 1;
440-
}
436+
return 1;
441437
}
442438
if (is_duplicate)
443-
{
444439
return -1;
445-
}
446440
}
447441
return 0;
448442
}
@@ -498,26 +492,25 @@ bool select_unit_ext::disable_index_if_needed(SELECT_LEX *curr_sl)
498492
@retval
499493
0 no error
500494
-1 conversion happened
495+
1 error
496+
497+
Note that duplicate keys are ignored (write_record() is returning -1)
501498
*/
502499

503500
int select_unit_ext::unfold_record(ha_rows cnt)
504501
{
505502

506503
DBUG_ASSERT(cnt > 0);
507-
int error= 0;
508-
bool is_convertion_happened= false;
504+
int ret= 0;
509505
while (--cnt)
510506
{
511-
error= write_record();
507+
int error= write_record();
512508
if (error == -2)
513-
{
514-
is_convertion_happened= true;
515-
error= -1;
516-
}
509+
ret= -1; // Conversion happened
510+
else if (error > 0)
511+
return error;
517512
}
518-
if (is_convertion_happened)
519-
return -1;
520-
return error;
513+
return ret;
521514
}
522515

523516
/*
@@ -873,7 +866,7 @@ bool select_unit_ext::send_eof()
873866
if (unlikely(error))
874867
break;
875868

876-
if (unfold_record(dup_cnt) == -1)
869+
if ((error= unfold_record(dup_cnt)) == -1)
877870
{
878871
/* restart the scan */
879872
if (unlikely(table->file->ha_rnd_init_with_error(1)))
@@ -884,8 +877,14 @@ bool select_unit_ext::send_eof()
884877
additional_cnt= table->field[addon_cnt - 2];
885878
else
886879
additional_cnt= NULL;
880+
error= 0;
887881
continue;
888882
}
883+
else if (error > 0)
884+
{
885+
table->file->ha_index_or_rnd_end();
886+
return 1;
887+
}
889888
} while (likely(!error));
890889
table->file->ha_rnd_end();
891890
}

0 commit comments

Comments
 (0)