MDEV-34167 We fail to terminate transaction early with ER_LOCK_TABLE_FULL when...

MDEV-34167 We fail to terminate transaction early with ER_LOCK_TABLE_FULL when lock memory is growing

This regression is introduced in 10.6 by following commit.
commit b6a24724
MDEV-27891: SIGSEGV in InnoDB buffer pool resize

During DML, we check if buffer pool is running out of data pages in
buf_pool_t::running_out. Here is 75% of the buffer pool is occupied by
non-data pages we rollback the current transaction and exit with
ER_LOCK_TABLE_FULL.

The integer division (n_chunks_new / 4) becomes zero whenever the total
number of chunks are < 4 making the check completely ineffective for
such cases. Also the check is inaccurate for larger chunks.

Fix-1: Correct the check in buf_pool_t::running_out.

Fix-2: While waiting for free page, check for
buf_LRU_check_size_of_non_data_objects.
parent 8047c8bc
...@@ -451,7 +451,10 @@ buf_block_t *buf_LRU_get_free_block(bool have_mutex) ...@@ -451,7 +451,10 @@ buf_block_t *buf_LRU_get_free_block(bool have_mutex)
mysql_mutex_unlock(&buf_pool.flush_list_mutex); mysql_mutex_unlock(&buf_pool.flush_list_mutex);
if (my_cond_timedwait(&buf_pool.done_free, &buf_pool.mutex.m_mutex, if (my_cond_timedwait(&buf_pool.done_free, &buf_pool.mutex.m_mutex,
&abstime)) &abstime))
{
buf_pool.LRU_warn(); buf_pool.LRU_warn();
buf_LRU_check_size_of_non_data_objects();
}
} }
goto got_block; goto got_block;
......
...@@ -1486,7 +1486,7 @@ class buf_pool_t ...@@ -1486,7 +1486,7 @@ class buf_pool_t
{ {
return !recv_recovery_is_on() && return !recv_recovery_is_on() &&
UT_LIST_GET_LEN(free) + UT_LIST_GET_LEN(LRU) < UT_LIST_GET_LEN(free) + UT_LIST_GET_LEN(LRU) <
n_chunks_new / 4 * chunks->size; (n_chunks_new * chunks->size) / 4;
} }
/** @return whether the buffer pool is running low */ /** @return whether the buffer pool is running low */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment