MDEV-34753 memory pressure - erroneous termination condition

The 'if (!m_abort) break' condition was inverted by accident.

Constrain the test case to environments where there is cgroupv2
runtime environment which is the same case that will pass a memory
pressure initialization.

Remove the explicit garbage_collection trigger as it hides the abnormal
termination error on the event loop for memory pressure. This
also means there is no support in non-cgroupv2 environments
(possibly some container environments).

As the trigger to memory pressure is via a different thread we
need to wait until a "[mM]emory pressure" log message is there to
know it has succeeded or failed.

Thanks Kristian Nielsen for noticing and review.
This commit is contained in:
Daniel Black 2024-08-14 08:03:37 +10:00
parent eca552a1a4
commit eb29190398
4 changed files with 38 additions and 6 deletions

View file

@ -0,0 +1,28 @@
--source include/linux.inc
--error 0,1
perl;
use strict;
use warnings;
use File::Spec;
# Read the cgroup file
my $cgroup_file = '/proc/self/cgroup';
open my $fh, '<', $cgroup_file or exit 1;
my $line = <$fh>;
close $fh;
# Process the cgroup file content
$line =~ s/^0:://;
chomp($line);
# Construct the path
my $path = File::Spec->catdir('/sys/fs/cgroup', $line, 'memory.pressure');
# Check if the file is writable exists
exit 0 if -w $path;
exit 1;
EOF
if ($errno)
{
--skip Requires cgroupv2
}

View file

@ -15,6 +15,7 @@ FROM INFORMATION_SCHEMA.GLOBAL_STATUS
WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty'; WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty';
set debug_dbug="d,trigger_garbage_collection"; set debug_dbug="d,trigger_garbage_collection";
SET GLOBAL innodb_buffer_pool_size=@@innodb_buffer_pool_size; SET GLOBAL innodb_buffer_pool_size=@@innodb_buffer_pool_size;
FOUND 1 /[Mm]emory pressure.*/ in mysqld.1.err
SELECT CAST(VARIABLE_VALUE AS INTEGER) < @dirty_prev AS LESS_DIRTY_IS_GOOD SELECT CAST(VARIABLE_VALUE AS INTEGER) < @dirty_prev AS LESS_DIRTY_IS_GOOD
FROM INFORMATION_SCHEMA.GLOBAL_STATUS FROM INFORMATION_SCHEMA.GLOBAL_STATUS
WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty'; WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty';

View file

@ -1,5 +1,5 @@
--source include/have_debug.inc --source include/have_debug.inc
--source include/linux.inc --source include/have_cgroupv2.inc
--source include/not_embedded.inc --source include/not_embedded.inc
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/have_sequence.inc --source include/have_sequence.inc
@ -33,11 +33,15 @@ WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty';
set debug_dbug="d,trigger_garbage_collection"; set debug_dbug="d,trigger_garbage_collection";
SET GLOBAL innodb_buffer_pool_size=@@innodb_buffer_pool_size; SET GLOBAL innodb_buffer_pool_size=@@innodb_buffer_pool_size;
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
# either a fail or the pressure event
let SEARCH_PATTERN= [Mm]emory pressure.*;
--source include/search_pattern_in_file.inc
SELECT CAST(VARIABLE_VALUE AS INTEGER) < @dirty_prev AS LESS_DIRTY_IS_GOOD SELECT CAST(VARIABLE_VALUE AS INTEGER) < @dirty_prev AS LESS_DIRTY_IS_GOOD
FROM INFORMATION_SCHEMA.GLOBAL_STATUS FROM INFORMATION_SCHEMA.GLOBAL_STATUS
WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty'; WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty';
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
let SEARCH_PATTERN= InnoDB: Memory pressure event freed.*; let SEARCH_PATTERN= InnoDB: Memory pressure event freed.*;
--source include/search_pattern_in_file.inc --source include/search_pattern_in_file.inc

View file

@ -857,6 +857,7 @@ public:
my_close(m_fds[m_num_fds].fd, MYF(MY_WME)); my_close(m_fds[m_num_fds].fd, MYF(MY_WME));
m_fds[m_num_fds].fd= -1; m_fds[m_num_fds].fd= -1;
} }
m_event_fd= -1;
} }
static void pressure_routine(mem_pressure *m); static void pressure_routine(mem_pressure *m);
@ -865,10 +866,8 @@ public:
void trigger_collection() void trigger_collection()
{ {
uint64_t u= 1; uint64_t u= 1;
if (m_event_fd >=0 && write(m_event_fd, &u, sizeof(uint64_t)) != sizeof(uint64_t)) if (m_event_fd < 0 || write(m_event_fd, &u, sizeof(uint64_t)) != sizeof(uint64_t))
sql_print_information("InnoDB: (Debug) Failed to trigger memory pressure"); sql_print_information("InnoDB: (Debug) Failed to trigger memory pressure");
else /* assumed failed to meet intialization criteria, so trigger directy */
buf_pool.garbage_collect();
} }
#endif #endif
@ -927,7 +926,7 @@ void mem_pressure::pressure_routine(mem_pressure *m)
else else
break; break;
} }
if (!m->m_abort) if (m->m_abort)
break; break;
for (pollfd &p : st_::span<pollfd>(m->m_fds, m->m_num_fds)) for (pollfd &p : st_::span<pollfd>(m->m_fds, m->m_num_fds))