summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorVenkatesh Duggirala <venkatesh.duggirala@oracle.com>2013-01-02 16:31:58 +0530
committerVenkatesh Duggirala <venkatesh.duggirala@oracle.com>2013-01-02 16:31:58 +0530
commitc72f687f21d6fb4750f3d05221be8b039ee11fdf (patch)
tree7dd36d76fc6d62327ef5cefc6e124d7d55cdf501 /mysys
parentf5f40badc5aa189ef902907f60ea8f24e22bf5db (diff)
downloadmariadb-git-c72f687f21d6fb4750f3d05221be8b039ee11fdf.tar.gz
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.
Diffstat (limited to 'mysys')
-rw-r--r--mysys/errors.c24
-rw-r--r--mysys/my_error.c22
-rw-r--r--mysys/my_write.c4
3 files changed, 44 insertions, 6 deletions
diff --git a/mysys/errors.c b/mysys/errors.c
index 4e93f872a55..1199df2f2be 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -101,16 +101,28 @@ void init_glob_errs()
}
#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)
{
- 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))
- my_printf_error(EE_DISK_FULL,
- "Retry in %d secs. Message reprinted in %d secs",
- MYF(ME_BELL | ME_NOREFRESH),
+ {
+ my_printf_warning(EE(EE_DISK_FULL),
+ 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_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));
}
diff --git a/mysys/my_error.c b/mysys/my_error.c
index 20d8438a712..5167598bfae 100644
--- a/mysys/my_error.c
+++ b/mysys/my_error.c
@@ -129,6 +129,28 @@ int my_printf_error(uint error, const char *format, myf 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
SYNOPSIS
diff --git a/mysys/my_write.c b/mysys/my_write.c
index b545ab776b0..d0a59a605b6 100644
--- a/mysys/my_write.c
+++ b/mysys/my_write.c
@@ -36,6 +36,8 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
if (unlikely(!Count))
DBUG_RETURN(0);
+ DBUG_EXECUTE_IF ("simulate_file_write_error_once",
+ { DBUG_SET("+d,simulate_file_write_error");});
for (;;)
{
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);
errors++;
+ DBUG_EXECUTE_IF("simulate_file_write_error_once",
+ { DBUG_SET("-d,simulate_file_write_error");});
continue;
}