Commit 5cbdb908 authored by Sujatha Sivakumar's avatar Sujatha Sivakumar

Bug#11750014:ASSERTION TRX_DATA->EMPTY() IN BINLOG_CLOSE_CONNECTION

Problem:
=======

trx_data->empty() assert happens at `binlog_close_connection'

Analysis:
========

trx_data->empty() function checks for no pending events
and the transaction cache to be empty.This function returns
"true" if no pending events are present and cache is empty.
Otherwise it returns false. `binlog_close_connection' call
expects the above function to return true. But if the
return value is false then assert is raised.

This bug was reproducible in a diskfull scenario. In this
disk full scenario try to do an insert operation so that
a new pending event is created and flushing this pending
event fails. Due to this failure the server goes down
and invokes `binlog_close_connection' for clean closure.
Since the pending event still remains the assert is caused.
This assert is caused only in non transactional databases.


Fix:
===

In a disk full scenario when the insertion fails the
transaction is rolled back and `binlog_end_trans`
is called to flush the pending events. But flush operation
fails as the disk is full and the function simply returns
`1' without taking any action to delete the pending event.

This leaves the event to remain till the closure of
connection.  `delete pending' statement has been added to 
do the required clean up action.

sql/log.cc:
  Added "delete pending" statement to clean pending event
parent ab7358fb
...@@ -4313,10 +4313,16 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd, ...@@ -4313,10 +4313,16 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
/* /*
Write pending event to log file or transaction cache Write pending event to log file or transaction cache
*/ */
DBUG_EXECUTE_IF("simulate_disk_full_at_flush_pending",
{DBUG_SET("+d,simulate_file_write_error");});
if (pending->write(file)) if (pending->write(file))
{ {
pthread_mutex_unlock(&LOCK_log); pthread_mutex_unlock(&LOCK_log);
set_write_error(thd); set_write_error(thd);
delete pending;
trx_data->set_pending(NULL);
DBUG_EXECUTE_IF("simulate_disk_full_at_flush_pending",
{DBUG_SET("-d,simulate_file_write_error");});
DBUG_RETURN(1); DBUG_RETURN(1);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment