Commit c6713f65 authored by Darshan M N's avatar Darshan M N Committed by Sergey Vojtovich

Bug#23631471 BUF_BLOCK_ALIGN() MAKES INCORRECT ASSUMPTIONS ABOUT CHUNK SIZE

Issue:
======
Currently the approach we take to find the chunk corresponding to a given
pointer uses srv_buf_pool_chunk_unit based on the assumption that
srv_buf_pool_chunk_unit is the total size of all pages in a buffer pool
chunk. We first step back by srv_buf_pool_chunk_unit bytes and use
std::map::upper_bound() to find the first chunk in the map whose key >= the
resulting pointer.

However, the real size of a chunk (and thus, the total size of its pages)
may differ from the value configured with innodb_buffer_pool_chunk_size
due to rounding up to the OS page size. So, in some cases the above logic
gives us the wrong chunk.

Fix:
====
We find out the chunk corresponding to the give pointer without using
srv_buf_pool_chunk_unit. This is done by using std::map::upper_bound()
to find the next chunk in the map which appears right after the pointer and
decrementing the iterator, which would give us the chunk the pointer
belongs to.

Contribution by Alexey Kopytov.

RB: 13347
Reviewed-by: default avatarDebarun Banerjee <debarun.banerjee@oracle.com>
parent ce101166
......@@ -3940,14 +3940,17 @@ buf_block_from_ahi(const byte* ptr)
ut_ad(buf_chunk_map_ref == buf_chunk_map_reg);
ut_ad(!buf_pool_resizing);
const byte* bound = reinterpret_cast<uintptr_t>(ptr)
> srv_buf_pool_chunk_unit
? ptr - srv_buf_pool_chunk_unit : 0;
it = chunk_map->upper_bound(bound);
buf_chunk_t* chunk;
it = chunk_map->upper_bound(ptr);
ut_a(it != chunk_map->begin());
ut_a(it != chunk_map->end());
if (it == chunk_map->end()) {
chunk = chunk_map->rbegin()->second;
} else {
chunk = (--it)->second;
}
buf_chunk_t* chunk = it->second;
ulint offs = ptr - chunk->blocks->frame;
offs >>= UNIV_PAGE_SIZE_SHIFT;
......
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