From 4bfeb52d928a10321f7e6bf99a036b4e6b3c57b6 Mon Sep 17 00:00:00 2001 From: Sujatha Sivakumar Date: Mon, 17 Sep 2012 11:48:02 +0530 Subject: 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 | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sql/log.cc') diff --git a/sql/log.cc b/sql/log.cc index 57c14b24782..7e0e90e28c0 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4313,10 +4313,16 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd, /* 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)) { pthread_mutex_unlock(&LOCK_log); 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); } -- cgit v1.2.1