diff options
author | Mats Kindahl <mats@mysql.com> | 2008-09-03 22:04:07 +0200 |
---|---|---|
committer | Mats Kindahl <mats@mysql.com> | 2008-09-03 22:04:07 +0200 |
commit | 02a435404434a69f23e02d199e45a724729d9751 (patch) | |
tree | 0866c0d378211ec4b2bc83e6f3af1c3ca4b3b961 /sql/log.cc | |
parent | d62f27a90a7bcc54819bf70667be7b2d96fd5adc (diff) | |
download | mariadb-git-02a435404434a69f23e02d199e45a724729d9751.tar.gz |
Bug #32709: Assertion failed: trx_data->empty(), file log.cc
The assertion indicates that some data was left in the transaction
cache when the server was shut down, which means that a previous
statement did not commit or rollback correctly.
What happened was that a bug in the rollback of a transactional
table caused the transaction cache to be emptied, but not reset.
The error can be triggered by having a failing UPDATE or INSERT,
on a transactional table, causing an implicit rollback.
Fixed by always flushing the pending event to reset the state
properly.
mysql-test/extra/rpl_tests/rpl_row_basic.test:
Testing that a failed update (that writes some rows to the
transaction cache) does not cause the transaction cache to
hold on to the data or forget to reset the transaction cache.
sql/log.cc:
Added call to remove pending event when the transaction cache
is emptied instead of written to binary log. The call will also
clear the outstanding table map count so that the cache is not
left it in a state of "empty but not reset".
Added function MYSQL_BIN_LOG::remove_pending_rows_event().
sql/log.h:
Added function MYSQL_BIN_LOG::remove_pending_rows_event().
sql/sql_class.cc:
Adding function THD::binlog_remove_pending_rows_event().
sql/sql_class.h:
Adding function THD::binlog_remove_pending_rows_event().
Diffstat (limited to 'sql/log.cc')
-rw-r--r-- | sql/log.cc | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/sql/log.cc b/sql/log.cc index 30575b5befd..7775fb44b65 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1421,6 +1421,7 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, If rolling back a statement in a transaction, we truncate the transaction cache to remove the statement. */ + thd->binlog_remove_pending_rows_event(TRUE); if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) trx_data->reset(); else // ...statement @@ -3769,6 +3770,31 @@ THD::binlog_set_pending_rows_event(Rows_log_event* ev) } +/** + Remove the pending rows event, discarding any outstanding rows. + + If there is no pending rows event available, this is effectively a + no-op. + */ +int +MYSQL_BIN_LOG::remove_pending_rows_event(THD *thd) +{ + DBUG_ENTER(__FUNCTION__); + + binlog_trx_data *const trx_data= + (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton); + + DBUG_ASSERT(trx_data); + + if (Rows_log_event* pending= trx_data->pending()) + { + delete pending; + trx_data->set_pending(NULL); + } + + DBUG_RETURN(0); +} + /* Moves the last bunch of rows from the pending Rows event to the binlog (either cached binlog if transaction, or disk binlog). Sets a new pending |