summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRohit Kalhans <rohit.kalhans@oracle.com>2012-05-29 12:11:30 +0530
committerRohit Kalhans <rohit.kalhans@oracle.com>2012-05-29 12:11:30 +0530
commitd8b2d4a0694156848db0862a230d248653f8ebe5 (patch)
treeb8cc09e4196ef3f0d060ffca61b5cb6e6f4d5907
parent01748ce128ae4c29cfb63e88cd68918e7d48e946 (diff)
downloadmariadb-git-d8b2d4a0694156848db0862a230d248653f8ebe5.tar.gz
Bug#11762667: MYSQLBINLOG IGNORES ERRORS WHILE WRITING OUTPUT
Problem: mysqlbinlog exits without any error code in case of file write error. It is because of the fact that the calls to Log_event::print() method does not return a value and the thus any error were being ignored. Resolution: We resolve this problem by checking for the IO_CACHE::error == -1 after every call to Log_event:: print() and terminating the further execution. client/mysqlbinlog.cc: - handled error conditions during event->print() calls - added check for error in end_io_cache() mysys/my_write.c: Added debug code to simulate file write error. error returned will be ENOSPC=> error no space on the disk sql/log_event.cc: Added debug code to simulate file write error, by reducing the size of io cache.
-rw-r--r--client/mysqlbinlog.cc21
-rw-r--r--mysys/my_write.c12
-rw-r--r--sql/log_event.cc6
3 files changed, 37 insertions, 2 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index db48675ade2..dd09e7a0938 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -690,6 +690,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
DBUG_ENTER("process_event");
print_event_info->short_form= short_form;
Exit_status retval= OK_CONTINUE;
+ IO_CACHE *const head= &print_event_info->head_cache;
/*
Format events are not concerned by --offset and such, we always need to
@@ -753,6 +754,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
}
else
ev->print(result_file, print_event_info);
+ if (head->error == -1)
+ goto err;
break;
case CREATE_FILE_EVENT:
@@ -804,6 +807,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
output of Append_block_log_event::print is only a comment.
*/
ev->print(result_file, print_event_info);
+ if (head->error == -1)
+ goto err;
if ((retval= load_processor.process((Append_block_log_event*) ev)) !=
OK_CONTINUE)
goto end;
@@ -812,6 +817,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
case EXEC_LOAD_EVENT:
{
ev->print(result_file, print_event_info);
+ if (head->error == -1)
+ goto err;
Execute_load_log_event *exv= (Execute_load_log_event*)ev;
Create_file_log_event *ce= load_processor.grab_event(exv->file_id);
/*
@@ -841,6 +848,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
print_event_info->common_header_len=
glob_description_event->common_header_len;
ev->print(result_file, print_event_info);
+ if (head->error == -1)
+ goto err;
if (!remote_opt)
ev->free_temp_buf(); // free memory allocated in dump_local_log_entries
else
@@ -864,6 +873,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
break;
case BEGIN_LOAD_QUERY_EVENT:
ev->print(result_file, print_event_info);
+ if (head->error == -1)
+ goto err;
if ((retval= load_processor.process((Begin_load_query_log_event*) ev)) !=
OK_CONTINUE)
goto end;
@@ -974,6 +985,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
}
default:
ev->print(result_file, print_event_info);
+ if (head->error == -1)
+ goto err;
}
}
@@ -2012,7 +2025,13 @@ err:
end:
if (fd >= 0)
my_close(fd, MYF(MY_WME));
- end_io_cache(file);
+ /*
+ Since the end_io_cache() writes to the
+ file errors may happen.
+ */
+ if (end_io_cache(file))
+ retval= ERROR_STOP;
+
return retval;
}
diff --git a/mysys/my_write.c b/mysys/my_write.c
index f261c768dcb..b545ab776b0 100644
--- a/mysys/my_write.c
+++ b/mysys/my_write.c
@@ -38,7 +38,17 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
for (;;)
{
- if ((writenbytes= write(Filedes, Buffer, Count)) == Count)
+ writenbytes= write(Filedes, Buffer, Count);
+ /**
+ To simulate the write error set the errno = error code
+ and the number pf written bytes to -1.
+ */
+ DBUG_EXECUTE_IF ("simulate_file_write_error",
+ {
+ errno= ENOSPC;
+ writenbytes= (size_t) -1;
+ });
+ if (writenbytes == Count)
break;
if (writenbytes != (size_t) -1)
{ /* Safeguard */
diff --git a/sql/log_event.cc b/sql/log_event.cc
index afcc283a6d1..e7c3419c34f 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -3090,6 +3090,12 @@ void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
{
Write_on_release_cache cache(&print_event_info->head_cache, file);
+ /**
+ reduce the size of io cache so that the write function is called
+ for every call to my_b_write().
+ */
+ DBUG_EXECUTE_IF ("simulate_file_write_error",
+ {(&cache)->write_pos= (&cache)->write_end- 500;});
print_query_header(&cache, print_event_info);
my_b_write(&cache, (uchar*) query, q_len);
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);