mariadb: switch init to mysqld_safe and mysqladmin

mysqld_safe is the recommended way to start the server on non-systemd
systems ([1]). For instance, it has a crash detection with auto-restart
function, can update ulimits, setup core files, set the niceness of the
server etc. It looks like it could also be helpful when trying to set up
clusters. It's maintained upstream and adding it means we don't need to
add these features into our init script.

mysqld_safe is a script itself, so it's added to conffiles in case users
want to edit it.

It can't be run under procd, so the init script is converted to a normal
System V type. To stop the server and to reload the privileges tables
mysqladmin is used. To that end mysqladmin is moved into the server
package.

While changing the init script, the Debian init script was used for
ideas. It wasn't copied verbatim and adapted a bit here and there.
Thanks to whoever wrote it!

This commit removes the support for starting the service as a user other
than "mariadb". This makes the init script simpler. If anybody wants to
play around with the user then it's up to them to fix the permissions.

[1] https://mariadb.com/kb/en/mysqld_safe/

Signed-off-by: Sebastian Kemper <sebastian_ml@gmx.net>
This commit is contained in:
Sebastian Kemper 2020-05-11 22:55:24 +02:00
parent a61c97203f
commit fa6ea0b137
4 changed files with 126 additions and 103 deletions

View File

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=mariadb PKG_NAME:=mariadb
PKG_VERSION:=10.4.12 PKG_VERSION:=10.4.12
PKG_RELEASE:=2 PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL := \ PKG_SOURCE_URL := \
@ -123,7 +123,6 @@ MARIADB_CLIENT_EXTRA := \
mysql_find_rows \ mysql_find_rows \
mysql_waitpid \ mysql_waitpid \
mysqlaccess \ mysqlaccess \
mysqladmin \
mysqldump \ mysqldump \
mysqlimport \ mysqlimport \
mysqlshow \ mysqlshow \
@ -134,7 +133,9 @@ MARIADB_SERVER := \
innochecksum \ innochecksum \
my_print_defaults \ my_print_defaults \
mysql_install_db \ mysql_install_db \
mysqld mysqladmin \
mysqld \
mysqld_safe
MARIADB_SERVER_EXTRA := \ MARIADB_SERVER_EXTRA := \
aria_chk \ aria_chk \
@ -156,6 +157,7 @@ MARIADB_SERVER_EXTRA := \
mysql_tzinfo_to_sql \ mysql_tzinfo_to_sql \
mysqlbinlog \ mysqlbinlog \
mysqld_multi \ mysqld_multi \
mysqld_safe_helper \
mysqldumpslow \ mysqldumpslow \
mysqlhotcopy \ mysqlhotcopy \
perror \ perror \
@ -272,6 +274,10 @@ define Package/mariadb-server
PROVIDES:=mysql-server PROVIDES:=mysql-server
endef endef
define Package/mariadb-server/conffiles
/usr/bin/mysqld_safe
endef
define Package/mariadb-server/description define Package/mariadb-server/description
$(call Package/mariadb/description/Default) $(call Package/mariadb/description/Default)

View File

@ -1,7 +1,5 @@
config mysqld 'general' config mysqld 'general'
option enabled '0' option enabled '0' # 0 - disabled, 1 - enabled
option log_stderr '1' option options '--syslog' # Options passed to mysqld_safe
option log_stdout '1'
option options ''

View File

@ -4,48 +4,71 @@
START=95 START=95
STOP=10 STOP=10
USE_PROCD=1
#PROCD_DEBUG=1
NAME=mysqld NAME=mysqld
LOGGER="/usr/bin/logger -p user.err -s -t $NAME --" LOGGER="/usr/bin/logger -p user.err -s -t $NAME --"
COMMAND=/usr/bin/$NAME
MYSQLADMIN=/usr/bin/mysqladmin
MYSQLD=/usr/bin/$NAME
MYSQLDSAFE=/usr/bin/mysqld_safe
# mysqladmin likes to read /root/.my.cnf which could cause issues.
export HOME=/etc/mysql
# Safeguard (relative paths, core dumps...)
cd /
mysqld_get_param() { mysqld_get_param() {
$COMMAND --print-defaults \ $MYSQLD --print-defaults \
| tr " " "\n" \ | tr " " "\n" \
| grep -- "--$1" \ | grep -- "--$1" \
| tail -n 1 \ | tail -n 1 \
| cut -d= -f2 | cut -d= -f2
} }
start_service() { # Checks if a server is running and accessible.
local conf=/etc/mysql/my.cnf #
local dir # check_alive insists on a pingable server
local user # check_dead also fails if there is a lost mysqld in the process list
local group #
# Usage: boolean mysqld_status [check_alive|check_dead]
local logfile mysqld_status() {
if $MYSQLADMIN ping >/dev/null 2>&1; then
local datadir ping_alive=1
local logdir=/var/log/mysql else
local rundir=/var/run/mysqld ping_alive=0
local tmpdir
local enabled
local log_stderr
local log_stdout
local options
local hint="please fix your server configuration in /etc/mysql/"
if [ ! -x $COMMAND ]; then
$LOGGER $COMMAND is missing
exit 1
fi fi
ps_alive=0
pidfile=$(mysqld_get_param pid-file)
if [ -f "$pidfile" ] && kill -0 $(cat "$pidfile") >/dev/null 2>&1; then
ps_alive=1
fi
if { [ "$1" = check_alive ] && [ $ping_alive = 1 ]; } || \
{ [ "$1" = check_dead ] && [ $ping_alive = 0 ] \
&& [ $ps_alive = 0 ]; }
then
return 0 # EXIT_SUCCESS
else
return 1 # EXIT_FAILURE
fi
}
start() {
conf=/etc/mysql/my.cnf
logdir=/var/log/mysql
rundir=/var/run/mysqld
hint="please fix your server configuration in /etc/mysql/"
for i in $MYSQLD $MYSQLADMIN $MYSQLDSAFE; do
if [ ! -x $i ]; then
$LOGGER $i is missing
exit 1
fi
done
if [ ! -r $conf ]; then if [ ! -r $conf ]; then
$LOGGER $conf cannot be read $LOGGER $conf cannot be read
exit 1 exit 1
@ -59,15 +82,10 @@ start_service() {
exit 1 exit 1
fi fi
config_get_bool log_stderr general log_stderr 1
config_get_bool log_stdout general log_stdout 1
config_get options general options config_get options general options
datadir=$(mysqld_get_param datadir) datadir=$(mysqld_get_param datadir)
logfile=$(mysqld_get_param general_log_file)
tmpdir=$(mysqld_get_param tmpdir) tmpdir=$(mysqld_get_param tmpdir)
user=$(mysqld_get_param user)
if [ -z "$datadir" ]; then if [ -z "$datadir" ]; then
$LOGGER datadir is not set $LOGGER datadir is not set
@ -81,76 +99,48 @@ start_service() {
exit 1 exit 1
fi fi
if [ -z "$user" ]; then
$LOGGER user is not set
$LOGGER $hint
exit 1
fi
user_exists "$user" || {
$LOGGER user \""$user"\" does not exist
$LOGGER $hint
exit 1
}
group=$(id -g -n "$user")
group_exists "$group" || {
$LOGGER group \""$group"\" does not exist
$LOGGER user \""$user"\" not configured correctly
exit 1
}
[ -n "$logfile" ] && logdir=$(dirname "$logfile")
# do not touch directories that already exist
# posix shell does not support arrays, hence using awk
awk \
-v user="$user" \
-v group="$group" \
-v a="$datadir" \
-v b="$logdir" \
-v c="$rundir" \
-v d="$tmpdir" \
'
BEGIN {
dir[0]=a
dir[1]=b
dir[2]=c
dir[3]=d
for (x in dir) {
if (system("test ! -e \"" dir[x] "\"" )) {
delete dir[x]
}
}
for (x in dir) {
system("mkdir -p \"" dir[x] "\"" )
system("chmod 750 \"" dir[x] "\"" )
system("chown \"" user "\":\"" group "\" \"" dir[x] "\"" )
}
}
'
if [ ! -f "$datadir/mysql/tables_priv.MAD" ]; then if [ ! -f "$datadir/mysql/tables_priv.MAD" ]; then
local args="--force" args="--force"
local basedir=$(mysqld_get_param basedir) basedir=$(mysqld_get_param basedir)
[ -n "$basedir" ] && args="$args --basedir=$basedir" [ -n "$basedir" ] && args="$args --basedir=$basedir"
$LOGGER Cannot detect privileges table. You might need to run $LOGGER Cannot detect privileges table. You might need to run
$LOGGER \'mysql_install_db $args\' $LOGGER \'mysql_install_db "$args"\'
$LOGGER to initialize the system tables. $LOGGER to initialize the system tables.
exit 1 exit 1
fi fi
procd_open_instance # Start daemon
if mysqld_status check_alive; then
$LOGGER already running
else
for i in $logdir $rundir; do
opts="-m 0750"
if ! [ -e $i ]; then
# $rundir needs to be accessible for
# clients
if [ $i = $rundir ]; then
opts=
fi
mkdir -p $opts $i
[ -d $i ] && chown mariadb:mariadb $i
fi
done
procd_set_param command $COMMAND $options $MYSQLDSAFE $options >/dev/null 2>&1 &
fi
# forward stderr to logd
procd_set_param stderr $log_stderr
# same for stdout
procd_set_param stdout $log_stdout
procd_close_instance
} }
stop() {
if ! mysqld_status check_dead; then
$MYSQLADMIN shutdown
fi
}
reload() {
if mysqld_status check_alive; then
$MYSQLADMIN reload
else
$LOGGER not running
fi
}

View File

@ -0,0 +1,29 @@
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -242,7 +242,7 @@ wsrep_recover_position() {
return 1
fi
- local wr_pidfile="$DATADIR/"`@HOSTNAME@`"-recover.pid"
+ local wr_pidfile="$DATADIR/"$(uci get 'system.@system[0].hostname')"-recover.pid"
local wr_options="--disable-log-error --pid-file='$wr_pidfile'"
@@ -673,7 +673,7 @@ then
* ) err_log="$DATADIR/$err_log" ;;
esac
else
- err_log=$DATADIR/`@HOSTNAME@`.err
+ err_log=$DATADIR/$(uci get 'system.@system[0].hostname').err
fi
fi
@@ -752,7 +752,7 @@ fi
if test -z "$pid_file"
then
- pid_file="`@HOSTNAME@`.pid"
+ pid_file="$(uci get 'system.@system[0].hostname').pid"
fi
# MariaDB wants pid file without datadir
append_arg_to_args "--pid-file=$pid_file"