-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
MDEV-22186: Add innodb_buffer_pool_in_core_dump to exclude InnoDB buffer pool from cores #4651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| # ------------------------------------------------------------------------------ | ||
| # Test Summary | ||
| # ------------------------------------------------------------------------------ | ||
| # This test checks whether the mariadbd core dump file is expected to be TRIMMED | ||
| # or NOT TRIMMED based on how memory is mapped by the mariadbd process. | ||
| # | ||
| # What this script does: | ||
| # | ||
| # 1. It retrieves MariaDB runtime values: | ||
| # - pid_file (location of mariadbd PID) | ||
| # - innodb_buffer_pool_size | ||
| # | ||
| # 2. Using the PID file, it finds the running mariadbd process ID. | ||
| # | ||
| # 3. It reads /proc/<pid>/smaps to inspect the memory regions allocated | ||
| # by the mariadbd process. | ||
| # | ||
| # 4. From the smaps output, it identifies candidate memory regions that: | ||
| # - are smaller than 192M | ||
| # - contain the "dd" VmFlag (indicating the region is eligible for | ||
| # core dump trimming) | ||
| # | ||
| # 5. It sums the size of these candidate memory regions. | ||
| # | ||
| # 6. If the candidate memory is large enough to cover the buffer pool, | ||
| # the script concludes that the buffer pool will not be part of core dump. | ||
| # Otherwise, it reports it to be part of core dump. | ||
| # | ||
| # Purpose: | ||
| # This helps verify whether InnoDB buffer pool will be excluded from the | ||
| # core dump, preventing unnecessarily large core files. | ||
| # ------------------------------------------------------------------------------ | ||
|
|
||
| # Get the full path name of the PID file | ||
| --let $pid_file= query_get_value(SELECT @@pid_file, @@pid_file, 1) | ||
| --let PIDFILE= $pid_file | ||
|
|
||
| # Get innodb_buffer_pool_size | ||
| --let $innodb_buffer_pool_size= query_get_value(SELECT @@innodb_buffer_pool_size, @@innodb_buffer_pool_size, 1) | ||
| --let BUFFER_POOL_SIZE= $innodb_buffer_pool_size | ||
|
|
||
| perl; | ||
|
|
||
| use strict; | ||
| use warnings; | ||
|
|
||
| my $pid_file = $ENV{'PIDFILE'} or die "PIDFILE not set"; | ||
|
|
||
| # Buffer pool size | ||
| my $buffer_pool_size = $ENV{'BUFFER_POOL_SIZE'}; | ||
|
|
||
| # Convert to KB | ||
| my $buffer_pool_kb = int($buffer_pool_size / 1024); | ||
|
|
||
| # Ignore regions larger than 192M | ||
| my $max_region_kb = 192 * 1024; | ||
|
|
||
| # Sum of candidate regions | ||
| my $candidate_sum_kb = 0; | ||
|
|
||
| # Get PID of mariadbd | ||
| open(my $fh, '<', $pid_file) || die "Cannot open pid file $pid_file\n"; | ||
| my $pid = <$fh>; | ||
| $pid =~ s/\s//g; | ||
| close($fh); | ||
|
|
||
| if ($pid eq "") { | ||
| die "Couldn't retrieve PID from PID file.\n"; | ||
| } | ||
|
|
||
| # Open smaps | ||
| my $smaps_file = "/proc/$pid/smaps"; | ||
|
|
||
| open(my $sm, '<', $smaps_file) or die "Cannot open $smaps_file\n"; | ||
|
|
||
| my $current_size_kb = 0; | ||
|
|
||
| while (my $line = <$sm>) { | ||
|
|
||
| if ($line =~ /^Size:\s+(\d+)\s+kB/) { | ||
| $current_size_kb = $1; | ||
| } | ||
|
|
||
| if ($line =~ /^VmFlags:\s+(.*)/) { | ||
| my $flags = $1; | ||
|
|
||
| # Candidate region conditions | ||
| if ($current_size_kb <= $max_region_kb && | ||
| $flags =~ /\bdd\b/) { | ||
| $candidate_sum_kb += $current_size_kb; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| close($sm); | ||
|
|
||
| if ($candidate_sum_kb >= $buffer_pool_kb) { | ||
| print "Buffer pool not part of core dump.\n"; | ||
| } | ||
| else { | ||
| print "Buffer pool part of core dump.\n"; | ||
| } | ||
|
|
||
| EOF |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| set @old_innodb_buffer_pool_in_core_dump = @@innodb_buffer_pool_in_core_dump; | ||
| # | ||
| # Confirm innodb_buffer_pool_in_core_dump works | ||
| # | ||
| SELECT @@global.innodb_buffer_pool_in_core_dump; | ||
| @@global.innodb_buffer_pool_in_core_dump | ||
| 0 | ||
| Buffer pool not part of core dump. | ||
| # | ||
| # Confirm dynamicity of innodb_buffer_pool_in_core_dump | ||
| # | ||
| SET GLOBAL innodb_buffer_pool_in_core_dump = ON; | ||
| Buffer pool part of core dump. | ||
| SET GLOBAL innodb_buffer_pool_in_core_dump = OFF; | ||
| Buffer pool not part of core dump. | ||
| SET GLOBAL innodb_buffer_pool_in_core_dump = ON; | ||
| Buffer pool part of core dump. | ||
| SET GLOBAL innodb_buffer_pool_in_core_dump = OFF; | ||
| Buffer pool not part of core dump. | ||
| # | ||
| # Confirm innodb_pool_in_core_dump works even | ||
| # after resizing of buffer pool. | ||
| # | ||
| set @old_innodb_buffer_pool_size = @@innodb_buffer_pool_size; | ||
| set global innodb_buffer_pool_size = 64*1024*1024; | ||
| Buffer pool not part of core dump. | ||
| set global innodb_buffer_pool_size = 96*1024*1024; | ||
| Buffer pool not part of core dump. | ||
| set global innodb_buffer_pool_size = @old_innodb_buffer_pool_size; | ||
| set global innodb_buffer_pool_in_core_dump = @old_innodb_buffer_pool_in_core_dump; | ||
| # End of 10.11 tests |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| --loose-skip-innodb-buffer-pool-in-core-dump | ||
| --innodb-buffer-pool-size=128M |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| # | ||
| # MDEV-22186 : Add innodb_buffer_pool_in_core_dump option to trim buffer pool from core file | ||
| # | ||
|
|
||
| --source include/not_windows.inc | ||
| --source include/linux.inc | ||
| --source include/have_innodb.inc | ||
| --source include/not_valgrind.inc | ||
| --source include/not_embedded.inc | ||
|
|
||
| # Disable test on sanitizer builds (MSAN and ASAN) because sanitizers | ||
| # introduce additional VMAs marked with the `dd` (VM_DONTDUMP) flag | ||
| # in /proc/<pid>/smaps, which breaks the assumptions in | ||
| # include/check_core_dump_trim.inc. | ||
| --source include/not_msan.inc | ||
| --source include/not_asan.inc | ||
|
|
||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I remember from my earlier push that I was seeing an additional memory of 256MB marked with dd flag for UBSAN build on buildbots. Now when I checked for that extra size locally, I see that it is only I have removed ( PS: probabbly in
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Even though our CI does not include a UBSAN-only builder, some developers or testers could build and test with different options. The pragmatic reason to combine |
||
| set @old_innodb_buffer_pool_in_core_dump = @@innodb_buffer_pool_in_core_dump; | ||
|
|
||
| --echo # | ||
| --echo # Confirm innodb_buffer_pool_in_core_dump works | ||
| --echo # | ||
| SELECT @@global.innodb_buffer_pool_in_core_dump; | ||
| --source include/check_core_dump_trim.inc | ||
|
|
||
| --echo # | ||
| --echo # Confirm dynamicity of innodb_buffer_pool_in_core_dump | ||
| --echo # | ||
| SET GLOBAL innodb_buffer_pool_in_core_dump = ON; | ||
| --source include/check_core_dump_trim.inc | ||
|
|
||
| SET GLOBAL innodb_buffer_pool_in_core_dump = OFF; | ||
| --source include/check_core_dump_trim.inc | ||
|
|
||
| SET GLOBAL innodb_buffer_pool_in_core_dump = ON; | ||
| --source include/check_core_dump_trim.inc | ||
|
|
||
| SET GLOBAL innodb_buffer_pool_in_core_dump = OFF; | ||
| --source include/check_core_dump_trim.inc | ||
|
|
||
| --echo # | ||
| --echo # Confirm innodb_pool_in_core_dump works even | ||
| --echo # after resizing of buffer pool. | ||
| --echo # | ||
|
|
||
| set @old_innodb_buffer_pool_size = @@innodb_buffer_pool_size; | ||
|
|
||
| set global innodb_buffer_pool_size = 64*1024*1024; | ||
| --source include/check_core_dump_trim.inc | ||
|
|
||
| set global innodb_buffer_pool_size = 96*1024*1024; | ||
| --source include/check_core_dump_trim.inc | ||
|
|
||
| set global innodb_buffer_pool_size = @old_innodb_buffer_pool_size; | ||
| set global innodb_buffer_pool_in_core_dump = @old_innodb_buffer_pool_in_core_dump; | ||
| --echo # End of 10.11 tests | ||
|
dr-m marked this conversation as resolved.
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| set @old_innodb_buffer_pool_in_core_dump = @@innodb_buffer_pool_in_core_dump; | ||
| SET GLOBAL innodb_buffer_pool_in_core_dump=OFF; | ||
| SELECT @@global.innodb_buffer_pool_in_core_dump; | ||
| @@global.innodb_buffer_pool_in_core_dump | ||
| 0 | ||
| SELECT @@session.innodb_buffer_pool_in_core_dump; | ||
| ERROR HY000: Variable 'innodb_buffer_pool_in_core_dump' is a GLOBAL variable | ||
| SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_in_core_dump'; | ||
| Variable_name Value | ||
| innodb_buffer_pool_in_core_dump OFF | ||
| SHOW SESSION VARIABLES LIKE 'innodb_buffer_pool_in_core_dump'; | ||
| Variable_name Value | ||
| innodb_buffer_pool_in_core_dump OFF | ||
| SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name='innodb_buffer_pool_in_core_dump'; | ||
| VARIABLE_NAME VARIABLE_VALUE | ||
| INNODB_BUFFER_POOL_IN_CORE_DUMP OFF | ||
| SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE variable_name='innodb_buffer_pool_in_core_dump'; | ||
| VARIABLE_NAME VARIABLE_VALUE | ||
| INNODB_BUFFER_POOL_IN_CORE_DUMP OFF | ||
| SET SESSION innodb_buffer_pool_in_core_dump=ON; | ||
| ERROR HY000: Variable 'innodb_buffer_pool_in_core_dump' is a GLOBAL variable and should be set with SET GLOBAL | ||
| SET GLOBAL innodb_buffer_pool_in_core_dump=ON; | ||
| SET GLOBAL innodb_buffer_pool_in_core_dump=OFF; | ||
| SET GLOBAL innodb_buffer_pool_in_core_dump = @old_innodb_buffer_pool_in_core_dump; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # | ||
| # Basic test for innodb_buffer_pool_in_core_dump | ||
| # | ||
|
|
||
| --source include/have_innodb.inc | ||
| if (`SELECT COUNT(*) = 0 from INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE LOWER(variable_name) ='innodb_buffer_pool_in_core_dump'`) | ||
| { | ||
| --skip Test requires innodb_buffer_pool_in_core_dump variable. | ||
| } | ||
|
|
||
| set @old_innodb_buffer_pool_in_core_dump = @@innodb_buffer_pool_in_core_dump; | ||
| SET GLOBAL innodb_buffer_pool_in_core_dump=OFF; | ||
|
|
||
| SELECT @@global.innodb_buffer_pool_in_core_dump; | ||
|
|
||
| --error ER_INCORRECT_GLOBAL_LOCAL_VAR | ||
| SELECT @@session.innodb_buffer_pool_in_core_dump; | ||
|
|
||
| SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_in_core_dump'; | ||
| SHOW SESSION VARIABLES LIKE 'innodb_buffer_pool_in_core_dump'; | ||
|
|
||
| SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE variable_name='innodb_buffer_pool_in_core_dump'; | ||
| SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE variable_name='innodb_buffer_pool_in_core_dump'; | ||
|
|
||
| --error ER_GLOBAL_VARIABLE | ||
| SET SESSION innodb_buffer_pool_in_core_dump=ON; | ||
|
|
||
| SET GLOBAL innodb_buffer_pool_in_core_dump=ON; | ||
| SET GLOBAL innodb_buffer_pool_in_core_dump=OFF; | ||
|
|
||
| SET GLOBAL innodb_buffer_pool_in_core_dump = @old_innodb_buffer_pool_in_core_dump; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1250,6 +1250,15 @@ class buf_pool_t | |
| static int madvise_do_dump() noexcept; | ||
| #endif | ||
|
|
||
| #if defined __linux__ || defined __FreeBSD__ | ||
| /** Include or exclude the buffer pool from core dump. */ | ||
| void core_advise() noexcept | ||
| { | ||
| mysql_mutex_assert_owner(&mutex); | ||
| madvise(memory, size_in_bytes, in_core_dump ? MADV_DODUMP : MADV_DONTDUMP); | ||
| } | ||
|
Comment on lines
+1256
to
+1259
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be cleaner to omit the parameter and replace the global variable diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 3213af1518a..217761cbeef 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1828,6 +1828,12 @@ class buf_pool_t
only modified by buf_flush_page_cleaner():
set while holding mutex, cleared while holding flush_list_mutex */
Atomic_relaxed<bool> LRU_warned;
+#if defined __linux__ || defined __FreeBSD__
+public:
+ /** the value of innodb_buffer_pool_in_core_dump */
+ my_bool in_core_dump;
+private:
+#endif
/** withdrawn blocks during resize() */
UT_LIST_BASE_NODE_T(buf_page_t) withdrawn;This is making use of an alignment hole, not increasing In this way, we’d be able to access all parameters via a simple displacement applied on top of the address of I don’t see why we would execute this on the entire virtual address range reservation. The current mapping should be sufficient. All in all, I would write the code as follows: void core_advise() noexcept
{
mysql_mutex_assert_owner(&mutex);
madvise(memory, size_in_bytes, in_core_dump ? MADV_DODUMP : MADV_DONTDUMP);
}
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed the assertion because we are calling this function even from
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can move the initialization of ut_d(mysql_mutex_lock(&mutex));
core_advise();
ut_d(mysql_mutex_unlock(&mutex));In this way, the machine-enforceable documentation of how |
||
| #endif | ||
|
|
||
| /** Hash cell chain in page_hash_table */ | ||
| struct hash_chain | ||
| { | ||
|
|
@@ -1829,6 +1838,13 @@ class buf_pool_t | |
| set while holding mutex, cleared while holding flush_list_mutex */ | ||
| Atomic_relaxed<bool> LRU_warned; | ||
|
|
||
| #if defined __linux__ || defined __FreeBSD__ | ||
| public: | ||
| /** The value of innodb_buffer_pool_in_core_dump */ | ||
| my_bool in_core_dump; | ||
| private: | ||
| #endif | ||
|
|
||
| /** withdrawn blocks during resize() */ | ||
| UT_LIST_BASE_NODE_T(buf_page_t) withdrawn; | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.