2013-09-11 16:57:02 +05:30
|
|
|
# Purpose:
|
|
|
|
# Simple search with Perl for a pattern in some file.
|
|
|
|
#
|
|
|
|
# The advantages compared to thinkable auxiliary constructs using the
|
|
|
|
# mysqltest language and SQL are:
|
|
|
|
# 1. We do not need a running MySQL server.
|
|
|
|
# 2. SQL causes "noise" during debugging and increases the size of logs.
|
|
|
|
# Perl code does not disturb at all.
|
|
|
|
#
|
|
|
|
# The environment variables SEARCH_FILE and SEARCH_PATTERN must be set
|
|
|
|
# before sourcing this routine.
|
|
|
|
#
|
2014-06-30 13:59:21 +02:00
|
|
|
# Optionally, SEARCH_RANGE can be set to the max number of bytes of the file
|
|
|
|
# to search. If negative, it will search that many bytes at the end of the
|
2017-03-14 15:36:30 +01:00
|
|
|
# file. By default the search happens from the last CURRENT_TEST:
|
|
|
|
# marker till the end of file (appropriate for searching error logs).
|
|
|
|
#
|
2024-11-05 12:26:33 -07:00
|
|
|
# Optionally, SEARCH_ABORT can be specified to abort the search (in error)
|
|
|
|
# if a specific search result is found. Its value is a regular expression
|
|
|
|
# (with an implicit start-of-string anchor '^' prepended), and the search
|
|
|
|
# result that it will match against is either 1) "FOUND <N>", where <N> is
|
|
|
|
# the specific number of matches found, or 2) "NOT FOUND".
|
2014-06-30 13:59:21 +02:00
|
|
|
#
|
2024-11-05 12:26:33 -07:00
|
|
|
# Optionally, SEARCH_WAIT can be specified to wait for a specific search
|
|
|
|
# result. Its usage mimics that of SEARCH_ABORT, in that its value is also
|
|
|
|
# a '^'-prepended regular expression, which will be matched against the same
|
|
|
|
# search result. The timeout can be set in SEARCH_TIMEOUT, default is 60
|
|
|
|
# seconds.
|
2014-06-30 13:59:21 +02:00
|
|
|
#
|
2024-10-18 16:49:51 +02:00
|
|
|
# Optionally, SEARCH_WAIT can be set to "FOUND" or "NOT FOUND", and this
|
|
|
|
# will wait for the condition to occur. The timeout can be set in
|
|
|
|
# SEARCH_TIMEOUT, default is 60 seconds.
|
|
|
|
#
|
2018-08-29 17:25:58 +03:00
|
|
|
# Optionally, SEARCH_OUTPUT can be set to control the format of output.
|
|
|
|
# Supported formats:
|
|
|
|
# - (default) : "FOUND n /pattern/ in FILE " or "NOT FOUND ..."
|
|
|
|
# - "matches" : Each match is printed, on a separate line
|
2024-03-08 15:23:42 +01:00
|
|
|
# - "count" : "FOUND n matches in FILE" or "NOT FOUND ..." (omit pattern)
|
2018-08-29 17:25:58 +03:00
|
|
|
#
|
2013-09-11 16:57:02 +05:30
|
|
|
# In case of
|
|
|
|
# - SEARCH_FILE and/or SEARCH_PATTERN is not set
|
|
|
|
# - SEARCH_FILE cannot be opened
|
|
|
|
# the test will abort immediate.
|
|
|
|
#
|
|
|
|
# Typical use case (check invalid server startup options):
|
|
|
|
# let $error_log= $MYSQLTEST_VARDIR/log/my_restart.err;
|
|
|
|
# --error 0,1
|
|
|
|
# --remove_file $error_log
|
|
|
|
# let SEARCH_FILE= $error_log;
|
|
|
|
# # Stop the server
|
|
|
|
# let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
|
MDEV-16944 Fix file sharing issues on Windows in mysqltest
On Windows systems, occurrences of ERROR_SHARING_VIOLATION due to
conflicting share modes between processes accessing the same file can
result in CreateFile failures.
mysys' my_open() already incorporates a workaround by implementing
wait/retry logic on Windows.
But this does not help if files are opened using shell redirection like
mysqltest traditionally did it, i.e via
--echo exec "some text" > output_file
In such cases, it is cmd.exe, that opens the output_file, and it
won't do any sharing-violation retries.
This commit addresses the issue by introducing a new built-in command,
'write_line', in mysqltest. This new command serves as a brief alternative
to 'write_file', with a single line output, that also resolves variables
like "exec" would.
Internally, this command will use my_open(), and therefore retry-on-error
logic.
Hopefully this will eliminate the very sporadic "can't open file because
it is used by another process" error on CI.
2024-04-15 15:46:50 +02:00
|
|
|
# --write_line wait $restart_file
|
2020-08-20 15:32:35 +03:00
|
|
|
# --shutdown_server
|
2013-09-11 16:57:02 +05:30
|
|
|
# --source include/wait_until_disconnected.inc
|
|
|
|
#
|
|
|
|
# --error 1
|
|
|
|
# --exec $MYSQLD_CMD <whatever wrong setting> > $error_log 2>&1
|
|
|
|
# # The server restart aborts
|
|
|
|
# let SEARCH_PATTERN= \[ERROR\] Aborting;
|
|
|
|
# --source include/search_pattern_in_file.inc
|
|
|
|
#
|
|
|
|
# Created: 2011-11-11 mleich
|
|
|
|
#
|
|
|
|
|
|
|
|
perl;
|
|
|
|
use strict;
|
2017-03-14 15:36:30 +01:00
|
|
|
die "SEARCH_FILE not set" unless $ENV{SEARCH_FILE};
|
|
|
|
my @search_files= glob($ENV{SEARCH_FILE});
|
|
|
|
my $search_pattern= $ENV{SEARCH_PATTERN} or die "SEARCH_PATTERN not set";
|
|
|
|
my $search_range= $ENV{SEARCH_RANGE};
|
2024-10-18 16:49:51 +02:00
|
|
|
my $timeout= $ENV{SEARCH_TIMEOUT} || 60;
|
|
|
|
my @matches;
|
|
|
|
my $res;
|
|
|
|
|
|
|
|
my $start_time= time();
|
|
|
|
for (;;) {
|
|
|
|
my $content;
|
|
|
|
foreach my $search_file (@search_files) {
|
|
|
|
open(FILE, '<', $search_file) || die("Can't open file $search_file: $!");
|
|
|
|
my $file_content;
|
|
|
|
if ($search_range > 0) {
|
|
|
|
read(FILE, $file_content, $search_range, 0);
|
|
|
|
} elsif ($search_range < 0) {
|
|
|
|
my $size= -s $search_file;
|
|
|
|
$search_range = -$size if $size > -$search_range;
|
|
|
|
seek(FILE, $search_range, 2);
|
|
|
|
read(FILE, $file_content, -$search_range, 0);
|
2017-03-14 15:36:30 +01:00
|
|
|
} else {
|
2024-10-18 16:49:51 +02:00
|
|
|
while(<FILE>) { # error log
|
|
|
|
if (/^CURRENT_TEST:/) {
|
|
|
|
$content='';
|
|
|
|
} else {
|
|
|
|
$content.=$_;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close(FILE);
|
|
|
|
$content.= $file_content;
|
|
|
|
}
|
|
|
|
@matches= ($content =~ /$search_pattern/gs);
|
|
|
|
$res=@matches ? "FOUND " . scalar(@matches) : "NOT FOUND";
|
|
|
|
|
2024-11-05 12:26:33 -07:00
|
|
|
if ($ENV{SEARCH_WAIT} and not $res =~ /^$ENV{SEARCH_WAIT}/) {
|
2024-10-18 16:49:51 +02:00
|
|
|
if (time() - $start_time < $timeout) {
|
|
|
|
# Millisceond sleep emulated with select
|
|
|
|
select(undef, undef, undef, 0.1);
|
|
|
|
next;
|
2017-03-14 15:36:30 +01:00
|
|
|
}
|
2024-10-18 16:49:51 +02:00
|
|
|
die "Timeout waiting for $ENV{SEARCH_WAIT} ".
|
|
|
|
"for /$search_pattern/ in $ENV{SEARCH_FILE}\n";
|
2016-12-05 20:19:01 +02:00
|
|
|
}
|
2024-10-18 16:49:51 +02:00
|
|
|
last;
|
2014-06-30 13:59:21 +02:00
|
|
|
}
|
2024-01-25 16:02:45 +01:00
|
|
|
|
2017-03-14 15:36:30 +01:00
|
|
|
$ENV{SEARCH_FILE} =~ s{^.*?([^/\\]+)$}{$1};
|
2018-08-29 17:25:58 +03:00
|
|
|
|
2024-01-25 16:02:45 +01:00
|
|
|
if ($ENV{SEARCH_OUTPUT} eq "matches") {
|
|
|
|
foreach (@matches) {
|
|
|
|
print $_ . "\n";
|
MDEV-32551: "Read semi-sync reply magic number error" warnings on master
rpl_semi_sync_slave_enabled_consistent.test and the first part of
the commit message comes from Brandon Nesterenko.
A test to show how to induce the "Read semi-sync reply magic number
error" message on a primary. In short, if semi-sync is turned on
during the hand-shake process between a primary and replica, but
later a user negates the rpl_semi_sync_slave_enabled variable while
the replica's IO thread is running; if the io thread exits, the
replica can skip a necessary call to kill_connection() in
repl_semisync_slave.slave_stop() due to its reliance on a global
variable. Then, the replica will send a COM_QUIT packet to the
primary on an active semi-sync connection, causing the magic number
error.
The test in this patch exits the IO thread by forcing an error;
though note a call to STOP SLAVE could also do this, but it ends up
needing more synchronization. That is, the STOP SLAVE command also
tries to kill the VIO of the replica, which makes a race with the IO
thread to try and send the COM_QUIT before this happens (which would
need more debug_sync to get around). See THD::awake_no_mutex for
details as to the killing of the replica’s vio.
Notes:
- The MariaDB documentation does not make it clear that when one
enables semi-sync replication it does not matter if one enables
it first in the master or slave. Any order works.
Changes done:
- The rpl_semi_sync_slave_enabled variable is now a default value for
when semisync is started. The variable does not anymore affect
semisync if it is already running. This fixes the original reported
bug. Internally we now use repl_semisync_slave.get_slave_enabled()
instead of rpl_semi_sync_slave_enabled. To check if semisync is
active on should check the @@rpl_semi_sync_slave_status variable (as
before).
- The semisync protocol conflicts in the way that the original
MySQL/MariaDB client-server protocol was designed (client-server
send and reply packets are strictly ordered and includes a packet
number to allow one to check if a packet is lost). When using
semi-sync the master and slave can send packets at 'any time', so
packet numbering does not work. The 'solution' has been that each
communication starts with packet number 1, but in some cases there
is still a chance that the packet number check can fail. Fixed by
adding a flag (pkt_nr_can_be_reset) in the NET struct that one can
use to signal that packet number checking should not be done. This
is flag is set when semi-sync is used.
- Added Master_info::semi_sync_reply_enabled to allow one to configure
some slaves with semisync and other other slaves without semisync.
Removed global variable semi_sync_need_reply that would not work
with multi-master.
- Repl_semi_sync_master::report_reply_packet() can now recognize
the COM_QUIT packet from semisync slave and not give a
"Read semi-sync reply magic number error" error for this case.
The slave will be removed from the Ack listener.
- On Windows, don't stop semisync Ack listener just because one
slave connection is using socket_id > FD_SETSIZE.
- Removed busy loop in Ack_receiver::run() by using
"Self-pipe trick" to signal new slave and stop Ack_receiver.
- Changed some Repl_semi_sync_slave functions that always returns 0
from int to void.
- Added Repl_semi_sync_slave::slave_reconnect().
- Removed dummy_function Repl_semi_sync_slave::reset_slave().
- Removed some duplicate semisync notes from the error log.
- Add test of "if (get_slave_enabled() && semi_sync_need_reply)"
before calling Repl_semi_sync_slave::slave_reply().
(Speeds up the code as we can skip all initializations).
- If epl_semisync_slave.slave_reply() fails, we disable semisync
for that connection.
- We do not call semisync.switch_off() if there are no active slaves.
Instead we check in Repl_semi_sync_master::commit_trx() if there are
no active threads. This simplices the code.
- Changed assert() to DBUG_ASSERT() to ensure that the DBUG log is
flushed in case of asserts.
- Removed the internal rpl_semi_sync_slave_status as it is not needed
anymore. The @@rpl_semi_sync_slave_status status variable is now
mapped to rpl_semi_sync_enabled.
- Removed rpl_semi_sync_slave_enabled as it is not needed anymore.
Repl_semi_sync_slave::get_slave_enabled() contains the active status.
- Added checking that we do not add a slave twice with
Ack_receiver::add_slave(). This could happen with old code.
- Removed Repl_semi_sync_master::check_and_switch() as it is not
needed anymore.
- Ensure that when we call Ack_receiver::remove_slave() that the slave
is removed from the listener before function returns.
- Call listener.listen_on_sockets() outside of mutex for better
performance and less contested mutex.
- Ensure that listening is ignoring newly added slaves when checking for
responses.
- Fixed the master ack_receiver listener is not killed if there are no
connected slaves (and thus stop semisync handling of future
connections). This could happen if all slaves sockets where would be
marked as unreliable.
- Added unlink() to base_ilist_iterator and remove() to
I_List_iterator. This enables us to remove 'dead' slaves in
Ack_recever::run().
- kill_zombie_dump_threads() now does killing of dump threads properly.
- It can now kill several threads (should be impossible but could
happen if IO slaves reconnects very fast).
- We now wait until the dump thread is done before starting the
dump.
- Added an error if kill_zombie_dump_threads() fails.
- Set thd->variables.server_id before calling
kill_zombie_dump_threads(). This simplies the code.
- Added a lot of comments both in code and tests.
- Removed DBUG_EVALUATE_IF "failed_slave_start" as it is not used.
Test changes:
- rpl.rpl_session_var2 added which runs rpl.rpl_session_var test with
semisync enabled.
- Some timings changed slight with startup of slave which caused
rpl_binlog_dump_slave_gtid_state_info.text to fail as it checked the
error log file before the slave had started properly. Fixed by
adding wait_for_pattern_in_file.inc that allows waiting for the
pattern to appear in the log file.
- Tests have been updated so that we first set
rpl_semi_sync_master_enabled on the master and then set
rpl_semi_sync_slave_enabled on the slaves (this is according to how
the MariaDB documentation document how to setup semi-sync).
- Error text "Master server does not have semi-sync enabled" has been
replaced with "Master server does not support semi-sync" for the
case when the master supports semi-sync but semi-sync is not
enabled.
Other things:
- Some trivial cleanups in Repl_semi_sync_master::update_sync_header().
- We should in 11.3 changed the default value for
rpl-semi-sync-master-wait-no-slave from TRUE to FALSE as the TRUE
does not make much sense as default. The main difference with using
FALSE is that we do not wait for semisync Ack if there are no slave
threads. In the case of TRUE we wait once, which did not bring any
notable benefits except slower startup of master configured for
using semisync.
Co-author: Brandon Nesterenko <brandon.nesterenko@mariadb.com>
This solves the problem reported in MDEV-32960 where a new
slave may not be registered in time and the master disables
semi sync because of that.
2023-11-08 16:57:58 -07:00
|
|
|
}
|
2018-08-29 17:25:58 +03:00
|
|
|
}
|
2024-03-28 09:16:57 +02:00
|
|
|
elsif ($ENV{SEARCH_OUTPUT} eq "count")
|
|
|
|
{
|
|
|
|
print "$res matches in $ENV{SEARCH_FILE}\n";
|
|
|
|
}
|
2024-01-25 16:02:45 +01:00
|
|
|
elsif ($ENV{SEARCH_ABORT} and $res =~ /^$ENV{SEARCH_ABORT}/) {
|
|
|
|
die "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n";
|
|
|
|
} else {
|
|
|
|
print "$res /$search_pattern/ in $ENV{SEARCH_FILE}\n";
|
|
|
|
}
|
2013-09-11 16:57:02 +05:30
|
|
|
EOF
|