diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index f762cf65a014818f4387a74640da0c0b7afadfa7..c0dece69cf866a82eaf91446073d66de9477f936 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -414,7 +414,7 @@ static bool buf_page_decrypt_after_read(buf_page_t *bpage, if (node.space->purpose == FIL_TYPE_TEMPORARY && innodb_encrypt_temporary_tables) { - slot = buf_pool.io_buf_reserve(); + slot = buf_pool.io_buf_reserve(false); ut_a(slot); slot->allocate(); @@ -444,7 +444,7 @@ static bool buf_page_decrypt_after_read(buf_page_t *bpage, return false; } - slot = buf_pool.io_buf_reserve(); + slot = buf_pool.io_buf_reserve(false); slot->allocate(); decompress_with_slot: @@ -471,7 +471,7 @@ static bool buf_page_decrypt_after_read(buf_page_t *bpage, return false; } - slot = buf_pool.io_buf_reserve(); + slot = buf_pool.io_buf_reserve(false); slot->allocate(); ut_d(fil_page_type_validate(node.space, dst_frame)); @@ -1513,14 +1513,17 @@ void buf_pool_t::io_buf_t::close() n_slots= 0; } -buf_tmp_buffer_t *buf_pool_t::io_buf_t::reserve() +buf_tmp_buffer_t *buf_pool_t::io_buf_t::reserve(bool wait_for_reads) { for (;;) { for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++) if (s->acquire()) return s; + buf_dblwr.flush_buffered_writes(); os_aio_wait_until_no_pending_writes(); + if (!wait_for_reads) + continue; for (buf_tmp_buffer_t *s= slots, *e= slots + n_slots; s != e; s++) if (s->acquire()) return s; diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 770083127276a652e27386aadb2a49aae3a26884..186fb89ddced4f8ca0fad6b16505794d0b51eedd 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -702,7 +702,7 @@ static byte *buf_page_encrypt(fil_space_t* space, buf_page_t* bpage, byte* s, ut_ad(!bpage->zip_size() || !page_compressed); /* Find free slot from temporary memory array */ - buf_tmp_buffer_t *slot= buf_pool.io_buf_reserve(); + buf_tmp_buffer_t *slot= buf_pool.io_buf_reserve(true); ut_a(slot); slot->allocate(); slot->out_buf= NULL; diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index def7641db1d1636a01f07de4f1d1102158cbf2b6..0e1a4c27f35e6013108ff0f764cf37461b742d5e 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -2030,7 +2030,8 @@ class buf_pool_t a delete-buffering operation is pending. Protected by mutex. */ buf_page_t watch[innodb_purge_threads_MAX + 1]; /** Reserve a buffer. */ - buf_tmp_buffer_t *io_buf_reserve() { return io_buf.reserve(); } + buf_tmp_buffer_t *io_buf_reserve(bool wait_for_reads) + { return io_buf.reserve(wait_for_reads); } /** @return whether any I/O is pending */ bool any_io_pending() @@ -2083,7 +2084,7 @@ class buf_pool_t void close(); /** Reserve a buffer */ - buf_tmp_buffer_t *reserve(); + buf_tmp_buffer_t *reserve(bool wait_for_reads); } io_buf; /** whether resize() is in the critical path */ diff --git a/tpool/tpool_structs.h b/tpool/tpool_structs.h index b49204f2d75ac190a79f63aac2f6b3db68302853..96c250ebd59bf2f0706642af7282177379bacf7a 100644 --- a/tpool/tpool_structs.h +++ b/tpool/tpool_structs.h @@ -138,12 +138,13 @@ template<typename T> class cache { std::unique_lock<std::mutex> lk(m_mtx); assert(!is_full()); + const bool was_empty= is_empty(); // put element to the logical end of the array m_cache[--m_pos] = ele; /* Notify waiters when the cache becomes not empty, or when it becomes full */ - if (m_pos == 1 || (m_waiters && is_full())) + if (was_empty || (is_full() && m_waiters)) m_cv.notify_all(); }