Skip to content

Commit

Permalink
MDEV-25923: Aria parallel repair MY_THREAD_SPECIFIC mismatch in realloc
Browse files Browse the repository at this point in the history
maria_repair_parallel() clears the MY_THREAD_SPECIFIC flag for allocations
since it uses different threads. But it still did one _ma_alloc_buffer()
call as thread-specific which would later assert if another thread needed
to extend the buffer with realloc.

This patch, due to Monty, removes the MY_THREAD_SPECIFIC flag for
allocations that need to realloc in different threads, and preserves
it for those that are allocated/freed in the user's thread.

Also fixes MDEV-33562.

Reviewed-by: Monty <monty@mariadb.org>
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
  • Loading branch information
knielsen committed Mar 15, 2024
1 parent 77b9b28 commit 51abae5
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 11 deletions.
26 changes: 26 additions & 0 deletions mysql-test/suite/maria/alter.result
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,29 @@ ALTER TABLE t1 DISABLE KEYS;
INSERT INTO t1 VALUES (1, 'Nine chars or more');
ALTER TABLE t1 ENABLE KEYS;
DROP TABLE t1;
#
# MDEV-25923 Memory not freed or Assertion `old_flags == ((my_flags &
# 0x10000U) ? 1 : 0)' failed in my_realloc upon ALTER on Aria table
# with GIS column
#
CREATE TABLE t1 (pk INT PRIMARY KEY, a POINT DEFAULT ST_GEOMFROMTEXT('Point(1 1)')) ENGINE=Aria;
INSERT INTO t1 (pk) SELECT seq FROM seq_1_to_100;
SET @old_threads= @@SESSION.aria_repair_threads;
SET SESSION aria_repair_threads= 2;
ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
DROP TABLE t1;
#
# MDEV-33562: Assertion `(old_flags & 1) == ((my_flags & 0x10000U) ?
# 1 : 0)' failed in my_realloc from sort_get_next_record on INSERT
#
SET @old_mode= @@SESSION.sql_mode;
SET sql_mode='';
CREATE TEMPORARY TABLE t (b TEXT, INDEX s(b(300))) ROW_FORMAT=DYNAMIC ENGINE=Aria;
INSERT INTO t VALUES (REPEAT ('a',10000000));
Warnings:
Warning 1265 Data truncated for column 'b' at row 1
CREATE TABLE ti LIKE t;
INSERT INTO ti SELECT * FROM t;
DROP TABLE t, ti;
SET SESSION aria_repair_threads= @old_threads;
SET SESSION sql_mode= @old_mode;
28 changes: 28 additions & 0 deletions mysql-test/suite/maria/alter.test
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,31 @@ ALTER TABLE t1 DISABLE KEYS;
INSERT INTO t1 VALUES (1, 'Nine chars or more');
ALTER TABLE t1 ENABLE KEYS;
DROP TABLE t1;

--echo #
--echo # MDEV-25923 Memory not freed or Assertion `old_flags == ((my_flags &
--echo # 0x10000U) ? 1 : 0)' failed in my_realloc upon ALTER on Aria table
--echo # with GIS column
--echo #

CREATE TABLE t1 (pk INT PRIMARY KEY, a POINT DEFAULT ST_GEOMFROMTEXT('Point(1 1)')) ENGINE=Aria;
INSERT INTO t1 (pk) SELECT seq FROM seq_1_to_100;
SET @old_threads= @@SESSION.aria_repair_threads;
SET SESSION aria_repair_threads= 2;
ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
DROP TABLE t1;

--echo #
--echo # MDEV-33562: Assertion `(old_flags & 1) == ((my_flags & 0x10000U) ?
--echo # 1 : 0)' failed in my_realloc from sort_get_next_record on INSERT
--echo #

SET @old_mode= @@SESSION.sql_mode;
SET sql_mode='';
CREATE TEMPORARY TABLE t (b TEXT, INDEX s(b(300))) ROW_FORMAT=DYNAMIC ENGINE=Aria;
INSERT INTO t VALUES (REPEAT ('a',10000000));
CREATE TABLE ti LIKE t;
INSERT INTO ti SELECT * FROM t;
DROP TABLE t, ti;
SET SESSION aria_repair_threads= @old_threads;
SET SESSION sql_mode= @old_mode;
24 changes: 13 additions & 11 deletions storage/maria/ma_check.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ void maria_chk_init(HA_CHECK *param)
param->max_stage= 1;
param->stack_end_ptr= &my_thread_var->stack_ends_here;
param->max_allowed_lsn= (LSN) ~0ULL;
/* Flag when initializing buffers possible used by parallel repair threads */
param->malloc_flags= MY_THREAD_SPECIFIC;
}

Expand Down Expand Up @@ -2130,7 +2131,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)

if (!(record= (uchar*) my_malloc(PSI_INSTRUMENT_ME,
share->base.default_rec_buff_size,
MYF(param->malloc_flags))))
MYF(MY_THREAD_SPECIFIC))))
{
_ma_check_print_error(param,"Not enough memory for record");
DBUG_RETURN(-1);
Expand Down Expand Up @@ -2766,10 +2767,10 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
if (!(sort_param.record=
(uchar *) my_malloc(PSI_INSTRUMENT_ME, (uint)
share->base.default_rec_buff_size,
MYF(param->malloc_flags))) ||
MYF(MY_THREAD_SPECIFIC))) ||
_ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
share->base.default_rec_buff_size,
MYF(param->malloc_flags)))
MYF(MY_THREAD_SPECIFIC)))
{
_ma_check_print_error(param, "Not enough memory for extra record");
goto err;
Expand Down Expand Up @@ -3721,7 +3722,7 @@ int maria_filecopy(HA_CHECK *param, File to,File from,my_off_t start,

buff_length=(ulong) MY_MIN(param->write_buffer_length,length);
if (!(buff=my_malloc(PSI_INSTRUMENT_ME, buff_length,
MYF(param->malloc_flags))))
MYF(MY_THREAD_SPECIFIC))))
{
buff=tmp_buff; buff_length=IO_SIZE;
}
Expand Down Expand Up @@ -3867,10 +3868,10 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
if (!(sort_param.record=
(uchar*) my_malloc(PSI_INSTRUMENT_ME,
(size_t) share->base.default_rec_buff_size,
MYF(param->malloc_flags))) ||
MYF(MY_THREAD_SPECIFIC))) ||
_ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
share->base.default_rec_buff_size,
MYF(param->malloc_flags)))
MYF(MY_THREAD_SPECIFIC)))
{
_ma_check_print_error(param, "Not enough memory for extra record");
goto err;
Expand All @@ -3889,7 +3890,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
sort_param.wordlist=NULL;
init_alloc_root(PSI_INSTRUMENT_ME, &sort_param.wordroot,
FTPARSER_MEMROOT_ALLOC_SIZE, 0,
MYF(param->malloc_flags));
MYF(MY_THREAD_SPECIFIC));

sort_param.key_cmp=sort_key_cmp;
sort_param.lock_in_memory=maria_lock_memory;
Expand Down Expand Up @@ -4457,7 +4458,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
if (!(sort_param=(MARIA_SORT_PARAM *)
my_malloc(PSI_INSTRUMENT_ME, (uint) share->base.keys *
(sizeof(MARIA_SORT_PARAM) + share->base.pack_reclength),
MYF(MY_ZEROFILL | param->malloc_flags))))
MYF(MY_ZEROFILL | MY_THREAD_SPECIFIC))))
{
_ma_check_print_error(param,"Not enough memory for key!");
goto err;
Expand Down Expand Up @@ -4515,9 +4516,10 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,

sort_param[i].record= (((uchar *)(sort_param+share->base.keys))+
(share->base.pack_reclength * i));
/* These buffers are per thread */
if (_ma_alloc_buffer(&sort_param[i].rec_buff, &sort_param[i].rec_buff_size,
share->base.default_rec_buff_size,
MYF(param->malloc_flags)))
MYF(0)))
{
_ma_check_print_error(param,"Not enough memory!");
goto err;
Expand Down Expand Up @@ -4546,7 +4548,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
init_alloc_root(PSI_INSTRUMENT_ME, &sort_param[i].wordroot,
FTPARSER_MEMROOT_ALLOC_SIZE, 0,
MYF(param->malloc_flags));
MYF(MY_THREAD_SPECIFIC));
}
}
sort_info.total_keys=i;
Expand Down Expand Up @@ -6105,7 +6107,7 @@ static MA_SORT_KEY_BLOCKS *alloc_key_blocks(HA_CHECK *param, uint blocks,
if (!(block= (MA_SORT_KEY_BLOCKS*)
my_malloc(PSI_INSTRUMENT_ME,
(sizeof(MA_SORT_KEY_BLOCKS)+buffer_length+IO_SIZE)*blocks,
MYF(param->malloc_flags))))
MYF(MY_THREAD_SPECIFIC))))
{
_ma_check_print_error(param,"Not enough memory for sort-key-blocks");
return(0);
Expand Down

0 comments on commit 51abae5

Please sign in to comment.