Skip to content

Commit a13786f

Browse files
author
Anirudh Mangipudi
committed
Bug #16776528 RACE CONDITION CAN CAUSE MYSQLD TO REMOVE SOCKET FILE ERRANTLY
Problem Description: A mysqld_safe instance is started. An InnoDB crash recovery begins which takes few seconds to complete. During this crash recovery process happening, another mysqld_safe instance is started with the same server startup parameters. Since the mysqld's pid file is absent during the crash recovery process the second instance assumes there is no other process and tries to acquire a lock on the ibdata files in the datadir. But this step fails and the 2nd instance keeps retrying 100 times each with a delay of 1 second. Now after the 100 attempts, the server goes down, but while going down it hits the mysqld_safe script's cleanup section and without any check it blindly deletes the socket and pid files. Since no lock is placed on the socket file, it gets deleted. Solution: We create a mysqld_safe.pid file in the datadir, which protects the presence server instance resources by storing the mysqld_safe's process id in it. We place a check if the mysqld_safe.pid file is existing in the datadir. If yes then we check if the pid it contains is an active pid or not. If yes again, then the scripts logs an error saying "A mysqld_safe instance is already running". Otherwise it will log the present mysqld_safe's pid into the mysqld_safe.pid file.
2 parents 930ba8d + c2f111a commit a13786f

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

scripts/mysqld_safe.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,31 @@ else
518518
fi
519519
plugin_dir="${plugin_dir}${PLUGIN_VARIANT}"
520520

521+
# A pid file is created for the mysqld_safe process. This file protects the
522+
# server instance resources during race conditions.
523+
safe_pid="$DATADIR/mysqld_safe.pid"
524+
if test -f $safe_pid
525+
then
526+
PID=`cat "$safe_pid"`
527+
if @CHECK_PID@
528+
then
529+
if @FIND_PROC@
530+
then
531+
log_error "A mysqld_safe process already exists"
532+
exit 1
533+
fi
534+
fi
535+
rm -f "$safe_pid"
536+
if test -f "$safe_pid"
537+
then
538+
log_error "Fatal error: Can't remove the mysqld_safe pid file"
539+
exit 1
540+
fi
541+
fi
542+
543+
# Insert pid proerply into the pid file.
544+
ps -e | grep [m]ysqld_safe | awk '{print $1}' | sed -n 1p > $safe_pid
545+
# End of mysqld_safe pid(safe_pid) check.
521546

522547
# Determine what logging facility to use
523548

@@ -528,6 +553,7 @@ then
528553
if [ $? -ne 0 ]
529554
then
530555
log_error "--syslog requested, but no 'logger' program found. Please ensure that 'logger' is in your PATH, or do not specify the --syslog option to mysqld_safe."
556+
rm -f "$safe_pid" # Clean Up of mysqld_safe.pid file.
531557
exit 1
532558
fi
533559
fi
@@ -542,6 +568,7 @@ then
542568

543569
# mysqld does not add ".err" to "--log-error=foo."; it considers a
544570
# trailing "." as an extension
571+
545572
if expr "$err_log" : '.*\.[^/]*$' > /dev/null
546573
then
547574
:
@@ -632,6 +659,7 @@ does not exist or is not executable. Please cd to the mysql installation
632659
directory and restart this script from there as follows:
633660
./bin/mysqld_safe&
634661
See http://dev.mysql.com/doc/mysql/en/mysqld-safe.html for more information"
662+
rm -f "$safe_pid" # Clean Up of mysqld_safe.pid file.
635663
exit 1
636664
fi
637665

@@ -725,6 +753,7 @@ then
725753
if @FIND_PROC@
726754
then # The pid contains a mysqld process
727755
log_error "A mysqld process already exists"
756+
rm -f "$safe_pid" # Clean Up of mysqld_safe.pid file.
728757
exit 1
729758
fi
730759
fi
@@ -735,6 +764,7 @@ then
735764
$pid_file
736765
Please remove it manually and start $0 again;
737766
mysqld daemon not started"
767+
rm -f "$safe_pid" # Clean Up of mysqld_safe.pid file.
738768
exit 1
739769
fi
740770
fi
@@ -866,3 +896,5 @@ rm -f "$pid_file.shutdown"
866896

867897
log_notice "mysqld from pid file $pid_file ended"
868898

899+
rm -f "$safe_pid" # Some Extra Safety. File is deleted
900+
# once the mysqld process ends.

0 commit comments

Comments
 (0)