Commit 836d7089 authored by Sujatha's avatar Sujatha

MDEV-22451: SIGSEGV in __memmove_avx_unaligned_erms/memcpy from _my_b_write on...

MDEV-22451: SIGSEGV in __memmove_avx_unaligned_erms/memcpy from _my_b_write on CREATE after RESET MASTER

Analysis:
========
RESET MASTER TO # command deletes all binary log files listed in the index
file, resets the binary log index file to be empty, and creates a new binary
log with number #. When the user provided binary log number is greater than
the max allowed value '2147483647' server fails to generate a new binary log.
The RESET MASTER statement marks the binlog closure status as
'LOG_CLOSE_TO_BE_OPENED' and exits. Statements which follow RESET MASTER
try to write to binary log they find the log_state != LOG_CLOSED and
proceed to write to binary log cache and it results in crash.

Fix:
===
During MYSQL_BIN_LOG open, if generation of new binary log name fails then the
"log_state" needs to be marked as "LOG_CLOSED". With this further statements
will find binary log as closed and they will skip writing to the binary log.
parent a6b4d4be
......@@ -49,6 +49,7 @@
call mtr.add_suppression("Can't generate a unique log-filename");
call mtr.add_suppression("Writing one row to the row-based binary log failed.*");
call mtr.add_suppression("Error writing file .*");
call mtr.add_suppression("Could not use master-bin for logging");
SET @old_debug= @@global.debug;
......
call mtr.add_suppression("Next log extension: 2147483647. Remaining log filename extensions: 0");
call mtr.add_suppression("Log filename extension number exhausted:.");
call mtr.add_suppression("Can't generate a unique log-filename");
call mtr.add_suppression("MYSQL_BIN_LOG::open failed to generate new file name.");
call mtr.add_suppression("Could not use master-bin for logging");
"Test case verifies creation of binary log with max entension value."
RESET MASTER TO 2147483647;
show binary logs;
Log_name File_size
master-bin.2147483647 #
FOUND /Next log extension: 2147483647. Remaining log filename extensions: 0./ in mysqld.1.err
CREATE DATABASE db1;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.2147483647 # Gtid # # GTID #-#-#
master-bin.2147483647 # Query # # CREATE DATABASE db1
RESET MASTER TO 2147483648;
ERROR HY000: Can't generate a unique log-filename master-bin.(1-999)
FOUND /Turning logging off for the whole duration of the MySQL server process/ in mysqld.1.err
"Following CREATE DATABSE db2 command will not be present in binary log"
"as binary log got closed due to ER_NO_UNIQUE_LOGFILE error."
CREATE DATABASE db2;
"RESET MASTER command fails to generate a new binary log"
"log-bin will be disabled and server needs to be restarted to"
"re-enable the binary log."
SHOW BINARY LOGS;
ERROR HY000: You are not using binary logging
show binary logs;
Log_name File_size
master-bin.000001 #
SHOW DATABASES LIKE 'db%';
Database (db%)
db1
db2
include/show_binlog_events.inc
DROP DATABASE db1;
DROP DATABASE db2;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP DATABASE db1
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # DROP DATABASE db2
# ==== Purpose ====
#
# Test verifies that when RESET MASTER TO # command is supplied with binlog
# extension number greater than 2147483647 the command should report
# appropriate error and binary log should be disabled. It should not result in
# a crash.
#
# ==== Implementation ====
#
# Steps:
# 0 - Verify case with max binary log extension. Max value is '2147483647'
# 1 - Confirm that SHOW BINARY LOGS displays a binary log with '2147483647'
# 2 - Verify that events are successfully written into max extension file.
# 3 - Try to create a binary log with extension greater than max allowed
# value '2147483648', verify ER_NO_UNIQUE_LOGFILE error is reported.
# 4 - Execute CREATE DATABASE db2 statement and verify server dosn't crash.
# 5 - Execute SHOW BINARY LOG command and verify that it reports
# ER_NO_BINARY_LOGGING error.
# 6 - Restart the server and verify that databse 'db2' exists and it it not
# present in the binary log.
#
# ==== References ====
#
# MDEV-22451: SIGSEGV in __memmove_avx_unaligned_erms/memcpy from
# _my_b_write on CREATE after RESET MASTER
#
--source include/have_log_bin.inc
call mtr.add_suppression("Next log extension: 2147483647. Remaining log filename extensions: 0");
call mtr.add_suppression("Log filename extension number exhausted:.");
call mtr.add_suppression("Can't generate a unique log-filename");
call mtr.add_suppression("MYSQL_BIN_LOG::open failed to generate new file name.");
call mtr.add_suppression("Could not use master-bin for logging");
--echo "Test case verifies creation of binary log with max entension value."
RESET MASTER TO 2147483647;
--source include/show_binary_logs.inc
# Check error log for correct messages.
let $log_error_= `SELECT @@GLOBAL.log_error`;
if(!$log_error_)
{
# MySQL Server on windows is started with --console and thus
# does not know the location of its .err log, use default location
let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err;
}
--let SEARCH_FILE=$log_error_
--let SEARCH_RANGE=-50000
--let SEARCH_PATTERN=Next log extension: 2147483647. Remaining log filename extensions: 0.
--source include/search_pattern_in_file.inc
CREATE DATABASE db1;
--source include/show_binlog_events.inc
--error ER_NO_UNIQUE_LOGFILE
RESET MASTER TO 2147483648;
--let SEARCH_FILE=$log_error_
--let SEARCH_RANGE=-50000
--let SEARCH_PATTERN=Turning logging off for the whole duration of the MySQL server process
--source include/search_pattern_in_file.inc
--echo "Following CREATE DATABSE db2 command will not be present in binary log"
--echo "as binary log got closed due to ER_NO_UNIQUE_LOGFILE error."
CREATE DATABASE db2;
--echo "RESET MASTER command fails to generate a new binary log"
--echo "log-bin will be disabled and server needs to be restarted to"
--echo "re-enable the binary log."
--error ER_NO_BINARY_LOGGING
SHOW BINARY LOGS;
--source include/restart_mysqld.inc
--source include/show_binary_logs.inc
SHOW DATABASES LIKE 'db%';
--source include/show_binlog_events.inc
# Cleanup
DROP DATABASE db1;
DROP DATABASE db2;
--source include/show_binlog_events.inc
......@@ -7,6 +7,7 @@ include/stop_slave.inc
call mtr.add_suppression("Can't generate a unique log-filename");
call mtr.add_suppression("Writing one row to the row-based binary log failed.*");
call mtr.add_suppression("Error writing file .*");
call mtr.add_suppression("Could not use master-bin for logging");
SET @old_debug= @@global.debug;
SELECT repeat('x',8192) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data';
SELECT repeat('x',10) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166-2.data';
......
......@@ -7,6 +7,7 @@ include/stop_slave.inc
call mtr.add_suppression("Can't generate a unique log-filename");
call mtr.add_suppression("Writing one row to the row-based binary log failed.*");
call mtr.add_suppression("Error writing file .*");
call mtr.add_suppression("Could not use master-bin for logging");
SET @old_debug= @@global.debug;
SELECT repeat('x',8192) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data';
SELECT repeat('x',10) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166-2.data';
......
......@@ -3390,6 +3390,8 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
log_type_arg, io_cache_type_arg))
{
sql_print_error("MYSQL_BIN_LOG::open failed to generate new file name.");
if (!is_relay_log)
goto err;
DBUG_RETURN(1);
}
......@@ -3751,7 +3753,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
sql_print_error("Could not use %s for logging (error %d). \
Turning logging off for the whole duration of the MySQL server process. \
To turn it on again: fix the cause, \
shutdown the MySQL server and restart it.", name, errno);
shutdown the MySQL server and restart it.", (name) ? name : log_name, errno);
if (new_xid_list_entry)
delete new_xid_list_entry;
if (file >= 0)
......
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