From 1f040ae0485ba16746229f8db9ffbe1af947aa03 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 20 Aug 2024 11:31:58 +0300 Subject: [PATCH] MDEV-34043 Drastically slower query performance between CentOS (2sec) and Rocky (48sec) One cause of the slowdown is because the ftruncate call can be much slower on some systems. ftruncate() is called by Aria for internal temporary tables, tables created by the optimizer, when the upper level asks Aria to delete the previous result set. This is needed when some content from previous tables changes. I have now changed Aria so that for internal temporary tables we don't call ftruncate() anymore for maria_delete_all_rows(). I also had to update the Aria repair code to use the logical datafile size and not the on-disk datafile size, which may contain data from a previous result set. The repair code is called to create indexes for the internal temporary table after it is filled. I also replaced a call to mysql_file_size() with a pwrite() in _ma_bitmap_create_first(). Reviewer: Sergei Petrunia Tester: Dave Gosselin --- storage/maria/ma_bitmap.c | 18 +++++++++++------- storage/maria/ma_check.c | 26 ++++++++++++++++++++++---- storage/maria/ma_delete_all.c | 14 +++++++++++--- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c index 48a0545467c..613dcd18e02 100644 --- a/storage/maria/ma_bitmap.c +++ b/storage/maria/ma_bitmap.c @@ -3070,21 +3070,25 @@ my_bool _ma_check_if_right_bitmap_type(MARIA_HA *info, int _ma_bitmap_create_first(MARIA_SHARE *share) { uint block_size= share->bitmap.block_size; + size_t error; File file= share->bitmap.file.file; - uchar marker[CRC_SIZE]; + uchar *temp_buff; + + if (!(temp_buff= (uchar*) my_alloca(block_size))) + return 1; + bzero(temp_buff, block_size); /* Next write operation of the page will write correct CRC if it is needed */ - int4store(marker, MARIA_NO_CRC_BITMAP_PAGE); + int4store(temp_buff + block_size - CRC_SIZE, MARIA_NO_CRC_BITMAP_PAGE); - if (mysql_file_chsize(file, block_size - sizeof(marker), - 0, MYF(MY_WME)) || - my_pwrite(file, marker, sizeof(marker), - block_size - sizeof(marker), - MYF(MY_NABP | MY_WME))) + error= my_pwrite(file, temp_buff, block_size, 0, MYF(MY_NABP | MY_WME)); + my_afree(temp_buff); + if (error) return 1; + share->state.state.data_file_length= block_size; _ma_bitmap_delete_all(share); return 0; diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 0c80b58d7e3..7f104325d00 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -418,6 +418,8 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info) /* We cannot check file sizes for S3 */ DBUG_RETURN(0); } + /* We should never come here with internal temporary tables */ + DBUG_ASSERT(!share->internal_table); if (!(param->testflag & T_SILENT)) puts("- check file-size"); @@ -713,6 +715,8 @@ static int chk_index_down(HA_CHECK *param, MARIA_HA *info, MARIA_PAGE ma_page; DBUG_ENTER("chk_index_down"); + DBUG_ASSERT(!share->internal_table); + /* Key blocks must lay within the key file length entirely. */ if (page + keyinfo->block_length > share->state.state.key_file_length) { @@ -2464,7 +2468,16 @@ static int initialize_variables_for_repair(HA_CHECK *param, return 1; /* calculate max_records */ - sort_info->filelength= my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0)); + if (!share->internal_table) + { + /* Get real file size */ + sort_info->filelength= my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0)); + } + else + { + /* For internal temporary files we are using the logical file length */ + sort_info->filelength= share->state.state.data_file_length; + } param->max_progress= sort_info->filelength; if ((param->testflag & T_CREATE_MISSING_KEYS) || @@ -2860,7 +2873,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, { fputs(" \r",stdout); fflush(stdout); } - if (mysql_file_chsize(share->kfile.file, + if (!share->internal_table && + mysql_file_chsize(share->kfile.file, share->state.state.key_file_length, 0, MYF(0))) { _ma_check_print_warning(param, @@ -4168,7 +4182,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, if (param->testflag & T_CALC_CHECKSUM) share->state.state.checksum=param->glob_crc; - if (mysql_file_chsize(share->kfile.file, + if (!share->internal_table && + mysql_file_chsize(share->kfile.file, share->state.state.key_file_length, 0, MYF(0))) _ma_check_print_warning(param, "Can't change size of indexfile, error: %d", @@ -4706,7 +4721,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, if (param->testflag & T_CALC_CHECKSUM) share->state.state.checksum=param->glob_crc; - if (mysql_file_chsize(share->kfile.file, + if (!share->internal_table && + mysql_file_chsize(share->kfile.file, share->state.state.key_file_length, 0, MYF(0))) _ma_check_print_warning(param, "Can't change size of indexfile, error: %d", @@ -6108,6 +6124,8 @@ int maria_test_if_almost_full(MARIA_HA *info) { MARIA_SHARE *share= info->s; + DBUG_ASSERT(!share->internal_table); + if (share->options & HA_OPTION_COMPRESS_RECORD) return 0; return mysql_file_seek(share->kfile.file, 0L, MY_SEEK_END, diff --git a/storage/maria/ma_delete_all.c b/storage/maria/ma_delete_all.c index c1019c01c66..d799e213d5f 100644 --- a/storage/maria/ma_delete_all.c +++ b/storage/maria/ma_delete_all.c @@ -103,9 +103,17 @@ int maria_delete_all_rows(MARIA_HA *info) #endif if (_ma_flush_table_files(info, MARIA_FLUSH_DATA|MARIA_FLUSH_INDEX, - FLUSH_IGNORE_CHANGED, FLUSH_IGNORE_CHANGED) || - mysql_file_chsize(info->dfile.file, 0, 0, MYF(MY_WME)) || - mysql_file_chsize(share->kfile.file, share->base.keystart, 0, MYF(MY_WME))) + FLUSH_IGNORE_CHANGED, FLUSH_IGNORE_CHANGED)) + goto err; + /* + Avoid truncate of internal temporary tables as this can have a big + performance overhead when called by mysql_handle_single_derived() + tables in MariaDB as part of split materialization. + */ + if (!share->internal_table && + (mysql_file_chsize(info->dfile.file, 0, 0, MYF(MY_WME)) || + mysql_file_chsize(share->kfile.file, share->base.keystart, 0, + MYF(MY_WME)))) goto err; if (_ma_initialize_data_file(share, info->dfile.file))