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';
set debug_dbug="d,trigger_garbage_collection";
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
FROM INFORMATION_SCHEMA.GLOBAL_STATUS
WHERE VARIABLE_NAME='Innodb_buffer_pool_pages_dirty';

View file

@ -1,5 +1,5 @@
--source include/have_debug.inc
--source include/linux.inc
--source include/have_cgroupv2.inc
--source include/not_embedded.inc
--source include/have_innodb.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 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
FROM INFORMATION_SCHEMA.GLOBAL_STATUS
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.*;
--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));
m_fds[m_num_fds].fd= -1;
}
m_event_fd= -1;
}
static void pressure_routine(mem_pressure *m);
@ -865,10 +866,8 @@ public:
void trigger_collection()
{
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");
else /* assumed failed to meet intialization criteria, so trigger directy */
buf_pool.garbage_collect();
}
#endif
@ -927,7 +926,7 @@ void mem_pressure::pressure_routine(mem_pressure *m)
else
break;
}
if (!m->m_abort)
if (m->m_abort)
break;
for (pollfd &p : st_::span<pollfd>(m->m_fds, m->m_num_fds))