MDEV-33813 ERROR 1021 (HY000): Disk full (./org/test1.MAI); waiting for someone to free some space
Fixed that internal temporary tables are not waiting for freed disk space. Other things: - 'kill id' will now kill a query waiting for free disk space instantly. Before it could take up to 60 seconds for the kill would be noticed. - Fixed that sorting one index is not using MY_WAIT_IF_FULL for temp files. - Fixed bug where share->write_flag set MY_WAIT_IF_FULL for temp files. It is quite hard to do a test case for this. Instead I tested all combinations interactively.
This commit is contained in:
parent
33af5575a9
commit
3655cefc42
@ -652,6 +652,7 @@ extern size_t my_fwrite(FILE *stream,const uchar *Buffer,size_t Count,
|
||||
myf MyFlags);
|
||||
extern my_off_t my_fseek(FILE *stream,my_off_t pos,int whence,myf MyFlags);
|
||||
extern my_off_t my_ftell(FILE *stream,myf MyFlags);
|
||||
extern void (*my_sleep_for_space)(unsigned int seconds);
|
||||
|
||||
/* implemented in my_memmem.c */
|
||||
extern void *my_memmem(const void *haystack, size_t haystacklen,
|
||||
|
@ -112,6 +112,13 @@ void init_glob_errs()
|
||||
}
|
||||
#endif
|
||||
|
||||
static void my_space_sleep(uint seconds)
|
||||
{
|
||||
sleep(seconds);
|
||||
}
|
||||
|
||||
void (*my_sleep_for_space)(uint seconds)= my_space_sleep;
|
||||
|
||||
void wait_for_free_space(const char *filename, int errors)
|
||||
{
|
||||
if (errors == 0)
|
||||
@ -123,7 +130,7 @@ void wait_for_free_space(const char *filename, int errors)
|
||||
MYF(ME_BELL | ME_ERROR_LOG | ME_WARNING),
|
||||
MY_WAIT_FOR_USER_TO_FIX_PANIC,
|
||||
MY_WAIT_GIVE_USER_A_MESSAGE * MY_WAIT_FOR_USER_TO_FIX_PANIC );
|
||||
(void) sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC);
|
||||
my_sleep_for_space(MY_WAIT_FOR_USER_TO_FIX_PANIC);
|
||||
}
|
||||
|
||||
const char **get_global_errmsgs(int nr __attribute__((unused)))
|
||||
|
@ -4880,6 +4880,9 @@ static int init_server_components()
|
||||
error_handler_hook= my_message_sql;
|
||||
proc_info_hook= set_thd_stage_info;
|
||||
|
||||
/* Set up hook to handle disk full */
|
||||
my_sleep_for_space= mariadb_sleep_for_space;
|
||||
|
||||
/*
|
||||
Print source revision hash, as one of the first lines, if not the
|
||||
first in error log, for troubleshooting and debugging purposes
|
||||
@ -9216,6 +9219,7 @@ PSI_stage_info stage_user_lock= { 0, "User lock", 0};
|
||||
PSI_stage_info stage_user_sleep= { 0, "User sleep", 0};
|
||||
PSI_stage_info stage_verifying_table= { 0, "Verifying table", 0};
|
||||
PSI_stage_info stage_waiting_for_delay_list= { 0, "Waiting for delay_list", 0};
|
||||
PSI_stage_info stage_waiting_for_disk_space= {0, "Waiting for someone to free space", 0};
|
||||
PSI_stage_info stage_waiting_for_gtid_to_be_written_to_binary_log= { 0, "Waiting for GTID to be written to binary log", 0};
|
||||
PSI_stage_info stage_waiting_for_handler_insert= { 0, "Waiting for handler insert", 0};
|
||||
PSI_stage_info stage_waiting_for_handler_lock= { 0, "Waiting for handler lock", 0};
|
||||
|
@ -644,6 +644,7 @@ extern PSI_stage_info stage_user_sleep;
|
||||
extern PSI_stage_info stage_verifying_table;
|
||||
extern PSI_stage_info stage_waiting_for_ddl;
|
||||
extern PSI_stage_info stage_waiting_for_delay_list;
|
||||
extern PSI_stage_info stage_waiting_for_disk_space;
|
||||
extern PSI_stage_info stage_waiting_for_flush;
|
||||
extern PSI_stage_info stage_waiting_for_gtid_to_be_written_to_binary_log;
|
||||
extern PSI_stage_info stage_waiting_for_handler_insert;
|
||||
|
@ -8323,6 +8323,34 @@ wait_for_commit::unregister_wait_for_prior_commit2()
|
||||
mysql_mutex_unlock(&LOCK_wait_commit);
|
||||
}
|
||||
|
||||
/*
|
||||
Wait # seconds or until someone sends a signal (through kill)
|
||||
|
||||
Note that this must have same prototype as my_sleep_for_space()
|
||||
*/
|
||||
|
||||
C_MODE_START
|
||||
|
||||
void mariadb_sleep_for_space(unsigned int seconds)
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
PSI_stage_info old_stage;
|
||||
if (!thd)
|
||||
{
|
||||
sleep(seconds);
|
||||
return;
|
||||
}
|
||||
mysql_mutex_lock(&thd->LOCK_wakeup_ready);
|
||||
thd->ENTER_COND(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready,
|
||||
&stage_waiting_for_disk_space, &old_stage);
|
||||
if (!thd->killed)
|
||||
mysql_cond_wait(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready);
|
||||
thd->EXIT_COND(&old_stage);
|
||||
return;
|
||||
}
|
||||
|
||||
C_MODE_END
|
||||
|
||||
|
||||
bool Discrete_intervals_list::append(ulonglong start, ulonglong val,
|
||||
ulonglong incr)
|
||||
|
@ -8185,6 +8185,9 @@ extern THD_list server_threads;
|
||||
|
||||
void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps,
|
||||
uint field_count);
|
||||
C_MODE_START
|
||||
void mariadb_sleep_for_space(unsigned int seconds);
|
||||
C_MODE_END
|
||||
|
||||
#endif /* MYSQL_SERVER */
|
||||
#endif /* SQL_CLASS_INCLUDED */
|
||||
|
@ -3390,7 +3390,7 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info,
|
||||
length= page.size;
|
||||
bzero(buff+length,keyinfo->block_length-length);
|
||||
if (write_page(share, new_file, buff, keyinfo->block_length,
|
||||
new_page_pos, MYF(MY_NABP | MY_WAIT_IF_FULL)))
|
||||
new_page_pos, MYF(MY_NABP | MY_WAIT_IF_FULL) & param->myf_rw))
|
||||
{
|
||||
_ma_check_print_error(param,"Can't write indexblock, error: %d",my_errno);
|
||||
goto err;
|
||||
|
@ -601,6 +601,20 @@ uint _ma_file_callback_to_id(void *callback_data)
|
||||
return share ? share->id : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Disable MY_WAIT_IF_FULL flag for temporary tables
|
||||
|
||||
Temporary tables does not have MY_WAIT_IF_FULL in share->write_flags
|
||||
*/
|
||||
|
||||
uint _ma_write_flags_callback(void *callback_data, myf flags)
|
||||
{
|
||||
MARIA_SHARE *share= (MARIA_SHARE*) callback_data;
|
||||
if (share)
|
||||
flags&= ~(~share->write_flag & MY_WAIT_IF_FULL);
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief flushes the data and/or index file of a table
|
||||
|
@ -172,7 +172,6 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share,
|
||||
mysql_mutex_lock(&share->intern_lock);
|
||||
info.read_record= share->read_record;
|
||||
share->reopen++;
|
||||
share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
|
||||
if (share->options & HA_OPTION_READ_ONLY_DATA)
|
||||
{
|
||||
info.lock_type=F_RDLCK;
|
||||
@ -987,6 +986,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags,
|
||||
share->options|= HA_OPTION_READ_ONLY_DATA;
|
||||
share->is_log_table= FALSE;
|
||||
|
||||
share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
|
||||
if (open_flags & HA_OPEN_TMP_TABLE || share->options & HA_OPTION_TMP_TABLE)
|
||||
{
|
||||
share->options|= HA_OPTION_TMP_TABLE;
|
||||
|
@ -687,6 +687,8 @@ static my_bool pagecache_fwrite(PAGECACHE *pagecache,
|
||||
/* FIXME: ENGINE=Aria occasionally writes uninitialized data */
|
||||
__msan_unpoison(args.page, pagecache->block_size);
|
||||
#endif
|
||||
/* Reset MY_WAIT_IF_FULL for temporary tables */
|
||||
flags= _ma_write_flags_callback(filedesc->callback_data, flags);
|
||||
res= (int)my_pwrite(filedesc->file, args.page, pagecache->block_size,
|
||||
((my_off_t) pageno << pagecache->shift), flags);
|
||||
(*filedesc->post_write_hook)(res, &args);
|
||||
|
@ -1745,6 +1745,7 @@ extern my_bool ma_yield_and_check_if_killed(MARIA_HA *info, int inx);
|
||||
extern my_bool ma_killed_standalone(MARIA_HA *);
|
||||
|
||||
extern uint _ma_file_callback_to_id(void *callback_data);
|
||||
extern uint _ma_write_flags_callback(void *callback_data, myf flags);
|
||||
extern void free_maria_share(MARIA_SHARE *share);
|
||||
|
||||
static inline void unmap_file(MARIA_HA *info __attribute__((unused)))
|
||||
|
Loading…
x
Reference in New Issue
Block a user