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, ...@@ -3091,6 +3091,7 @@ void buf_block_t::initialise(const page_id_t page_id, ulint zip_size,
ut_ad(!page.in_file()); ut_ad(!page.in_file());
buf_block_init_low(this); buf_block_init_low(this);
page.init(fix, page_id); page.init(fix, page_id);
page.set_os_used();
page_zip_set_size(&page.zip, zip_size); page_zip_set_size(&page.zip, zip_size);
} }
......
...@@ -297,7 +297,7 @@ buf_block_t* buf_LRU_get_free_only() ...@@ -297,7 +297,7 @@ buf_block_t* buf_LRU_get_free_only()
assert_block_ahi_empty(block); assert_block_ahi_empty(block);
block->page.set_state(buf_page_t::MEMORY); block->page.set_state(buf_page_t::MEMORY);
MEM_MAKE_ADDRESSABLE(block->page.frame, srv_page_size); block->page.set_os_used();
break; break;
} }
...@@ -989,13 +989,6 @@ buf_LRU_block_free_non_file_page( ...@@ -989,13 +989,6 @@ buf_LRU_block_free_non_file_page(
block->page.set_state(buf_page_t::NOT_USED); block->page.set_state(buf_page_t::NOT_USED);
MEM_UNDEFINED(block->page.frame, srv_page_size); 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; data = block->page.zip.data;
if (data != NULL) { if (data != NULL) {
...@@ -1024,7 +1017,7 @@ buf_LRU_block_free_non_file_page( ...@@ -1024,7 +1017,7 @@ buf_LRU_block_free_non_file_page(
pthread_cond_signal(&buf_pool.done_free); 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. */ /** Release a memory block to the buffer pool. */
......
...@@ -657,6 +657,20 @@ class buf_page_t ...@@ -657,6 +657,20 @@ class buf_page_t
access_time= 0; 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: public:
const page_id_t &id() const { return id_; } const page_id_t &id() const { return id_; }
uint32_t state() const { return zip.fix; } 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