Commit 16c97187 authored by Daniel Black's avatar Daniel Black

MDEV-25341: innodb buffer pool soft decommit of memory

When InnoDB isn't using memory its polite to other system
processes to allow that memory to be used.

Create buf_page_t::set_os_unused, to madvise(MADV_FREE)/
DiscardVirtualMemory innodb buffer pool pages to keep
virtual mapping but allow kernel to reclaim memory.

set_os_unused is called by buf_LRU_block_free_non_file_page
for flushing deallocations to free up memory.

set_os_used is called by buf_block_t::initialise (used by
buf_page_create_low and buf_LRU_get_free_only.

Move MSan (memory sanitizer) directive to be associated with
set_os_{un,}used so that the correctness can be determined by
instrumentation and test cases rather than relying on OS behaviour
at specific times.

Remove existing page information poisoning in
buf_LRU_block_free_non_file_page.

Tested by: Matthias Leich
Reviewer: Marko Mäkelä
Windows Review: Vladislav Vaintroub
parent 3ec4241b
......@@ -3091,6 +3091,7 @@ void buf_block_t::initialise(const page_id_t page_id, ulint zip_size,
ut_ad(!page.in_file());
buf_block_init_low(this);
page.init(fix, page_id);
page.set_os_used();
page_zip_set_size(&page.zip, zip_size);
}
......
......@@ -297,7 +297,7 @@ buf_block_t* buf_LRU_get_free_only()
assert_block_ahi_empty(block);
block->page.set_state(buf_page_t::MEMORY);
MEM_MAKE_ADDRESSABLE(block->page.frame, srv_page_size);
block->page.set_os_used();
break;
}
......@@ -989,13 +989,6 @@ buf_LRU_block_free_non_file_page(
block->page.set_state(buf_page_t::NOT_USED);
MEM_UNDEFINED(block->page.frame, srv_page_size);
/* Wipe page_no and space_id */
static_assert(FIL_PAGE_OFFSET % 4 == 0, "alignment");
memset_aligned<4>(block->page.frame + FIL_PAGE_OFFSET, 0xfe, 4);
static_assert(FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID % 4 == 2,
"not perfect alignment");
memset_aligned<2>(block->page.frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
0xfe, 4);
data = block->page.zip.data;
if (data != NULL) {
......@@ -1024,7 +1017,7 @@ buf_LRU_block_free_non_file_page(
pthread_cond_signal(&buf_pool.done_free);
}
MEM_NOACCESS(block->page.frame, srv_page_size);
block->page.set_os_unused();
}
/** Release a memory block to the buffer pool. */
......
......@@ -657,6 +657,20 @@ class buf_page_t
access_time= 0;
}
void set_os_unused()
{
MEM_NOACCESS(frame, srv_page_size);
#ifdef MADV_FREE
madvise(frame, srv_page_size, MADV_FREE);
#elif defined(_WIN32)
DiscardVirtualMemory(frame, srv_page_size);
#endif
}
void set_os_used() const
{
MEM_MAKE_ADDRESSABLE(frame, srv_page_size);
}
public:
const page_id_t &id() const { return id_; }
uint32_t state() const { return zip.fix; }
......
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