diff options
author | michael.izioumtchenko@oracle.com <> | 2013-04-30 20:39:12 +0200 |
---|---|---|
committer | michael.izioumtchenko@oracle.com <> | 2013-04-30 20:39:12 +0200 |
commit | 0fdc37cad035d07ae4016346646cfa42444513bb (patch) | |
tree | 16e88b13de25925baaad0107527b9228e2c3e7ba /storage | |
parent | ed694b0c090c36737ae2b07dbdf835c8ce2bed0f (diff) | |
download | mariadb-git-0fdc37cad035d07ae4016346646cfa42444513bb.tar.gz |
Bug#16405422 - RECOVERY FAILURE, ASSERT !RECV_NO_LOG_WRITE
eliminate a race condition over recv_sys->n_addrs which might result in a database corruption
in recovery, without reporting a recovery error.
recv_recover_page_func(): move the code segment that decrements recv_sys->n_addrs
to the end of the function, after the call to mtr_commit()
rb://2282 approved by Inaam
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/log/log0recv.c | 25 | ||||
-rw-r--r-- | storage/innodb_plugin/log/log0recv.c | 27 |
2 files changed, 27 insertions, 25 deletions
diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index 9683486238c..d59b605da84 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -1301,6 +1301,19 @@ recv_recover_page( recv = UT_LIST_GET_NEXT(rec_list, recv); } + if (!recover_backup && modification_to_page) { + ut_a(block); + + buf_flush_recv_note_modification(block, start_lsn, end_lsn); + } + + /* Make sure that committing mtr does not change the modification + lsn values of page */ + + mtr.modifications = FALSE; + + mtr_commit(&mtr); + mutex_enter(&(recv_sys->mutex)); if (ut_dulint_cmp(recv_max_page_lsn, page_lsn) < 0) { @@ -1314,18 +1327,6 @@ recv_recover_page( mutex_exit(&(recv_sys->mutex)); - if (!recover_backup && modification_to_page) { - ut_a(block); - - buf_flush_recv_note_modification(block, start_lsn, end_lsn); - } - - /* Make sure that committing mtr does not change the modification - lsn values of page */ - - mtr.modifications = FALSE; - - mtr_commit(&mtr); } /*********************************************************************** diff --git a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c index 96d63144366..9179888cb37 100644 --- a/storage/innodb_plugin/log/log0recv.c +++ b/storage/innodb_plugin/log/log0recv.c @@ -1638,19 +1638,6 @@ recv_recover_page_func( } #endif /* UNIV_ZIP_DEBUG */ - mutex_enter(&(recv_sys->mutex)); - - if (recv_max_page_lsn < page_lsn) { - recv_max_page_lsn = page_lsn; - } - - recv_addr->state = RECV_PROCESSED; - - ut_a(recv_sys->n_addrs); - recv_sys->n_addrs--; - - mutex_exit(&(recv_sys->mutex)); - #ifndef UNIV_HOTBACKUP if (modification_to_page) { ut_a(block); @@ -1665,6 +1652,20 @@ recv_recover_page_func( mtr.modifications = FALSE; mtr_commit(&mtr); + + mutex_enter(&(recv_sys->mutex)); + + if (recv_max_page_lsn < page_lsn) { + recv_max_page_lsn = page_lsn; + } + + recv_addr->state = RECV_PROCESSED; + + ut_a(recv_sys->n_addrs); + recv_sys->n_addrs--; + + mutex_exit(&(recv_sys->mutex)); + } #ifndef UNIV_HOTBACKUP |