mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
MDEV-32861 InnoDB hangs when running out of I/O slots
When the constant OS_AIO_N_PENDING_IOS_PER_THREAD is changed from 256 to 1 and the server is run with the minimum parameters innodb_read_io_threads=1 and innodb_write_io_threads=2, two hangs were observed. tpool::cache<T>::put(T*): Ensure that get() in io_slots::acquire() will be woken up when the cache previously was empty. buf_pool_t::io_buf_t::reserve(): Schedule a possibly partial doublewrite batch so that os_aio_wait_until_no_pending_writes() has a chance of returning. Add a Boolean parameter and pass wait_for_reads=false inside buf_page_decrypt_after_read(), because those calls will be executed inside a read completion callback, and therefore os_aio_wait_until_no_pending_reads() would block indefinitely.
This commit is contained in:
parent
de31ca6a21
commit
78c9a12c8f
4 changed files with 13 additions and 8 deletions
|
@ -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 @@ decompress:
|
|||
return false;
|
||||
}
|
||||
|
||||
slot = buf_pool.io_buf_reserve();
|
||||
slot = buf_pool.io_buf_reserve(false);
|
||||
slot->allocate();
|
||||
|
||||
decompress_with_slot:
|
||||
|
@ -471,7 +471,7 @@ decrypt_failed:
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -2030,7 +2030,8 @@ public:
|
|||
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 @@ private:
|
|||
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 */
|
||||
|
|
|
@ -138,12 +138,13 @@ public:
|
|||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue