diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index ebe98791df8b73ead953d477986c94a9a780a512..dd63c55af3f3b50c20fb8955ce8e121ba0b23cc1 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -2396,10 +2396,15 @@ static bool innodb_init() buf_flush_sync(); recv_sys.debug_free(); ut_ad(!os_aio_pending_reads()); - ut_ad(!os_aio_pending_writes()); ut_d(mysql_mutex_lock(&buf_pool.flush_list_mutex)); ut_ad(!buf_pool.get_oldest_modification(0)); ut_d(mysql_mutex_unlock(&buf_pool.flush_list_mutex)); + /* os_aio_pending_writes() may hold here if some write_io_callback() + did not release the slot yet. However, the page write itself must + have completed, because the buf_pool.flush_list is empty. In debug + builds, we wait for this to happen, hoping to get a hung process if + this assumption does not hold. */ + ut_d(os_aio_wait_until_no_pending_writes(false)); log_sys.close_file(); if (xtrabackup_incremental) diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 27f9a35fb4c1e598d1af46ba7d3f9e84a83f6c22..bcd18e73926aedc005406f9301d4ad901fda430d 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -2804,6 +2804,7 @@ void IORequest::write_complete(int io_error) const ut_ad(fil_validate_skip()); ut_ad(node); ut_ad(is_write()); + node->complete_write(); if (!bpage) { @@ -2816,7 +2817,6 @@ void IORequest::write_complete(int io_error) const else buf_page_write_complete(*this, io_error); - node->complete_write(); node->space->release(); } diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 31876605763b26c237e2b7ca91efeb5c90f90141..4783408f2f9ebd8342f4d2a01a611eced11e620c 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -183,10 +183,16 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn) delete_log_files(); ut_ad(!os_aio_pending_reads()); - ut_ad(!os_aio_pending_writes()); ut_d(mysql_mutex_lock(&buf_pool.flush_list_mutex)); ut_ad(!buf_pool.get_oldest_modification(0)); ut_d(mysql_mutex_unlock(&buf_pool.flush_list_mutex)); + /* os_aio_pending_writes() may hold here if some + write_io_callback() did not release the slot yet. However, + the page write itself must have completed, because the + buf_pool.flush_list is empty. In debug builds, we wait for + this to happen, hoping to get a hung process if this + assumption does not hold. */ + ut_d(os_aio_wait_until_no_pending_writes(false)); log_sys.latch.wr_lock(SRW_LOCK_CALL); log_sys.set_capacity(); @@ -1388,10 +1394,17 @@ dberr_t srv_start(bool create_new_db) end of create_log_file(). */ ut_d(recv_no_log_write = true); ut_ad(!os_aio_pending_reads()); - ut_ad(!os_aio_pending_writes()); ut_d(mysql_mutex_lock(&buf_pool.flush_list_mutex)); ut_ad(!buf_pool.get_oldest_modification(0)); ut_d(mysql_mutex_unlock(&buf_pool.flush_list_mutex)); + /* os_aio_pending_writes() may hold here if + some write_io_callback() did not release the + slot yet. However, the page write itself must + have completed, because the buf_pool.flush_list + is empty. In debug builds, we wait for this to + happen, hoping to get a hung process if this + assumption does not hold. */ + ut_d(os_aio_wait_until_no_pending_writes(false)); /* Close the redo log file, so that we can replace it */ log_sys.close_file();