mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
BUG#11753923-SQL THREAD CRASHES ON DISK FULL
Problem:If Disk becomes full while writing into the binlog, then the server instance hangs till someone frees the space. After user frees up the disk space, mysql server crashes with an assert (m_status != DA_EMPTY) Analysis: wait_for_free_space is being called in an infinite loop i.e., server instance will hang until someone frees up the space. So there is no need to set status bit in diagnostic area. Fix: Replace my_error/my_printf_error with sql_print_warning() which prints the warning in error log.
This commit is contained in:
@ -234,6 +234,7 @@ extern char *home_dir; /* Home directory for user */
|
|||||||
extern const char *my_progname; /* program-name (printed in errors) */
|
extern const char *my_progname; /* program-name (printed in errors) */
|
||||||
extern char NEAR curr_dir[]; /* Current directory for user */
|
extern char NEAR curr_dir[]; /* Current directory for user */
|
||||||
extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags);
|
extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags);
|
||||||
|
extern void(*sql_print_warning_hook)(const char *format,...);
|
||||||
extern int (*fatal_error_handler_hook)(uint my_err, const char *str,
|
extern int (*fatal_error_handler_hook)(uint my_err, const char *str,
|
||||||
myf MyFlags);
|
myf MyFlags);
|
||||||
extern uint my_file_limit;
|
extern uint my_file_limit;
|
||||||
@ -675,6 +676,7 @@ extern int my_error _VARARGS((int nr,myf MyFlags, ...));
|
|||||||
extern int my_printf_error _VARARGS((uint my_err, const char *format,
|
extern int my_printf_error _VARARGS((uint my_err, const char *format,
|
||||||
myf MyFlags, ...))
|
myf MyFlags, ...))
|
||||||
ATTRIBUTE_FORMAT(printf, 2, 4);
|
ATTRIBUTE_FORMAT(printf, 2, 4);
|
||||||
|
extern void my_printf_warning _VARARGS((const char * format, ...));
|
||||||
extern int my_error_register(const char **errmsgs, int first, int last);
|
extern int my_error_register(const char **errmsgs, int first, int last);
|
||||||
extern const char **my_error_unregister(int first, int last);
|
extern const char **my_error_unregister(int first, int last);
|
||||||
extern int my_message(uint my_err, const char *str,myf MyFlags);
|
extern int my_message(uint my_err, const char *str,myf MyFlags);
|
||||||
|
@ -101,16 +101,28 @@ void init_glob_errs()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
We cannot call my_error/my_printf_error here in this function.
|
||||||
|
Those functions will set status variable in diagnostic area
|
||||||
|
and there is no provision to reset them back.
|
||||||
|
Here we are waiting for free space and will wait forever till
|
||||||
|
space is created. So just giving warning in the error file
|
||||||
|
should be enough.
|
||||||
|
*/
|
||||||
void wait_for_free_space(const char *filename, int errors)
|
void wait_for_free_space(const char *filename, int errors)
|
||||||
{
|
{
|
||||||
if (errors == 0)
|
|
||||||
my_error(EE_DISK_FULL,MYF(ME_BELL | ME_NOREFRESH),
|
|
||||||
filename,my_errno,MY_WAIT_FOR_USER_TO_FIX_PANIC);
|
|
||||||
if (!(errors % MY_WAIT_GIVE_USER_A_MESSAGE))
|
if (!(errors % MY_WAIT_GIVE_USER_A_MESSAGE))
|
||||||
my_printf_error(EE_DISK_FULL,
|
{
|
||||||
"Retry in %d secs. Message reprinted in %d secs",
|
my_printf_warning(EE(EE_DISK_FULL),
|
||||||
MYF(ME_BELL | ME_NOREFRESH),
|
filename,my_errno,MY_WAIT_FOR_USER_TO_FIX_PANIC);
|
||||||
|
my_printf_warning("Retry in %d secs. Message reprinted in %d secs",
|
||||||
MY_WAIT_FOR_USER_TO_FIX_PANIC,
|
MY_WAIT_FOR_USER_TO_FIX_PANIC,
|
||||||
MY_WAIT_GIVE_USER_A_MESSAGE * MY_WAIT_FOR_USER_TO_FIX_PANIC );
|
MY_WAIT_GIVE_USER_A_MESSAGE * MY_WAIT_FOR_USER_TO_FIX_PANIC );
|
||||||
|
}
|
||||||
|
DBUG_EXECUTE_IF("simulate_file_write_error_once",
|
||||||
|
{
|
||||||
|
VOID(sleep(1));
|
||||||
|
return;
|
||||||
|
});
|
||||||
VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC));
|
VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC));
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,28 @@ int my_printf_error(uint error, const char *format, myf MyFlags, ...)
|
|||||||
DBUG_RETURN((*error_handler_hook)(error, ebuff, MyFlags));
|
DBUG_RETURN((*error_handler_hook)(error, ebuff, MyFlags));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Warning as printf
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
my_printf_warning()
|
||||||
|
format> Format string
|
||||||
|
...> variable list
|
||||||
|
*/
|
||||||
|
void(*sql_print_warning_hook)(const char *format,...);
|
||||||
|
void my_printf_warning(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char wbuff[ERRMSGSIZE];
|
||||||
|
DBUG_ENTER("my_printf_warning");
|
||||||
|
DBUG_PRINT("my", ("Format: %s", format));
|
||||||
|
va_start(args,format);
|
||||||
|
(void) my_vsnprintf (wbuff, sizeof(wbuff), format, args);
|
||||||
|
va_end(args);
|
||||||
|
(*sql_print_warning_hook)(wbuff);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Give message using error_handler_hook
|
Give message using error_handler_hook
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
|
|||||||
if (unlikely(!Count))
|
if (unlikely(!Count))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF ("simulate_file_write_error_once",
|
||||||
|
{ DBUG_SET("+d,simulate_file_write_error");});
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
writenbytes= write(Filedes, Buffer, Count);
|
writenbytes= write(Filedes, Buffer, Count);
|
||||||
@ -69,6 +71,8 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
|
|||||||
{
|
{
|
||||||
wait_for_free_space(my_filename(Filedes), errors);
|
wait_for_free_space(my_filename(Filedes), errors);
|
||||||
errors++;
|
errors++;
|
||||||
|
DBUG_EXECUTE_IF("simulate_file_write_error_once",
|
||||||
|
{ DBUG_SET("-d,simulate_file_write_error");});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4375,6 +4375,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
|
|||||||
After this we can't quit by a simple unireg_abort
|
After this we can't quit by a simple unireg_abort
|
||||||
*/
|
*/
|
||||||
error_handler_hook= my_message_sql;
|
error_handler_hook= my_message_sql;
|
||||||
|
sql_print_warning_hook = sql_print_warning;
|
||||||
start_signal_handler(); // Creates pidfile
|
start_signal_handler(); // Creates pidfile
|
||||||
|
|
||||||
if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
|
if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
|
||||||
|
Reference in New Issue
Block a user