Commit 31ea201e authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-30986 Slow full index scan for I/O bound case

buf_page_init_for_read(): Test a condition before acquiring a latch,
not while holding it.

buf_read_ahead_linear(): Do not use a memory transaction, because it
could be too large, leading to frequent retries.
Release the hash_lock as early as possible.
parent 9b1b4a6f
...@@ -147,14 +147,18 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id, ...@@ -147,14 +147,18 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id,
bpage= &block->page; bpage= &block->page;
/* Insert into the hash table of file pages */ /* Insert into the hash table of file pages */
if (hash_page)
{
transactional_lock_guard<page_hash_latch> g
{buf_pool.page_hash.lock_get(chain)};
bpage->set_state(buf_pool.watch_remove(hash_page, chain) +
(buf_page_t::READ_FIX - buf_page_t::UNFIXED));
buf_pool.page_hash.append(chain, &block->page);
}
else
{ {
transactional_lock_guard<page_hash_latch> g transactional_lock_guard<page_hash_latch> g
{buf_pool.page_hash.lock_get(chain)}; {buf_pool.page_hash.lock_get(chain)};
if (hash_page)
bpage->set_state(buf_pool.watch_remove(hash_page, chain) +
(buf_page_t::READ_FIX - buf_page_t::UNFIXED));
buf_pool.page_hash.append(chain, &block->page); buf_pool.page_hash.append(chain, &block->page);
} }
...@@ -561,11 +565,16 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf) ...@@ -561,11 +565,16 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf)
for (page_id_t i= low; i <= high_1; ++i) for (page_id_t i= low; i <= high_1; ++i)
{ {
buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(i.fold()); buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(i.fold());
transactional_shared_lock_guard<page_hash_latch> g page_hash_latch &hash_lock= buf_pool.page_hash.lock_get(chain);
{buf_pool.page_hash.lock_get(chain)}; /* It does not make sense to use transactional_lock_guard here,
because we would have many complex conditions inside the memory
transaction. */
hash_lock.lock_shared();
const buf_page_t* bpage= buf_pool.page_hash.get(i, chain); const buf_page_t* bpage= buf_pool.page_hash.get(i, chain);
if (!bpage) if (!bpage)
{ {
hash_lock.unlock_shared();
if (i == page_id) if (i == page_id)
goto fail; goto fail;
failed: failed:
...@@ -573,6 +582,7 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf) ...@@ -573,6 +582,7 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf)
continue; continue;
goto fail; goto fail;
} }
const unsigned accessed= bpage->is_accessed();
if (i == page_id) if (i == page_id)
{ {
/* Read the natural predecessor and successor page addresses from /* Read the natural predecessor and successor page addresses from
...@@ -583,6 +593,7 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf) ...@@ -583,6 +593,7 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf)
const byte *f= bpage->frame ? bpage->frame : bpage->zip.data; const byte *f= bpage->frame ? bpage->frame : bpage->zip.data;
uint32_t prev= mach_read_from_4(my_assume_aligned<4>(f + FIL_PAGE_PREV)); uint32_t prev= mach_read_from_4(my_assume_aligned<4>(f + FIL_PAGE_PREV));
uint32_t next= mach_read_from_4(my_assume_aligned<4>(f + FIL_PAGE_NEXT)); uint32_t next= mach_read_from_4(my_assume_aligned<4>(f + FIL_PAGE_NEXT));
hash_lock.unlock_shared();
if (prev == FIL_NULL || next == FIL_NULL) if (prev == FIL_NULL || next == FIL_NULL)
goto fail; goto fail;
page_id_t id= page_id; page_id_t id= page_id;
...@@ -612,8 +623,9 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf) ...@@ -612,8 +623,9 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf)
/* The area is not whole */ /* The area is not whole */
goto fail; goto fail;
} }
else
hash_lock.unlock_shared();
const unsigned accessed= bpage->is_accessed();
if (!accessed) if (!accessed)
goto failed; goto failed;
/* Note that buf_page_t::is_accessed() returns the time of the /* Note that buf_page_t::is_accessed() returns the time of the
......
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