diff --git a/CMakeLists.txt b/CMakeLists.txt index 6df6e736bbd25..8057114c1c02d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,6 +151,7 @@ INCLUDE(pcre) INCLUDE(ctest) INCLUDE(plugin) INCLUDE(install_macros) +INCLUDE(systemd) INCLUDE(mysql_add_executable) # Handle options @@ -328,6 +329,8 @@ CHECK_JEMALLOC() CHECK_PCRE() +CHECK_SYSTEMD() + IF(CMAKE_CROSSCOMPILING) SET(IMPORT_EXECUTABLES "IMPORTFILE-NOTFOUND" CACHE FILEPATH "Path to import_executables.cmake from a native build") INCLUDE(${IMPORT_EXECUTABLES}) diff --git a/cmake/systemd.cmake b/cmake/systemd.cmake new file mode 100644 index 0000000000000..b916928c0fa40 --- /dev/null +++ b/cmake/systemd.cmake @@ -0,0 +1,56 @@ +INCLUDE(FindPkgConfig) +# http://www.cmake.org/cmake/help/v3.0/module/FindPkgConfig.html + +MACRO(CHECK_SYSTEMD) + IF(UNIX) + SET(WITH_SYSTEMD "auto" CACHE STRING "Compile with systemd socket activation and notification") + IF(WITH_SYSTEMD STREQUAL "yes" OR WITH_SYSTEMD STREQUAL "auto") + IF(PKG_CONFIG_FOUND) + IF(WITH_SYSTEMD STREQUAL "yes") + pkg_check_modules(LIBSYSTEMD REQUIRED libsystemd) + ELSE() + pkg_check_modules(LIBSYSTEMD libsystemd) + ENDIF() + IF(HAVE_DLOPEN) + SET(LIBSYSTEMD ${LIBSYSTEMD_LIBRARIES}) + #SET(CMAKE_REQUIRED_FLAGS ${LIBSYSTEMD_CFLAGS}) + SET(MYSQLD_LINK_FLAGS "${MYSQLD_LINK_FLAGS} ${LIBSYSTEMD_LDFLAGS}") + ELSE() + SET(LIBSYSTEMD ${LIBSYSTEMD_STATIC_LIBRARIES}) + #SET(CMAKE_REQUIRED_FLAGS ${LIBSYSTEMD_STATIC_CFLAGS}) + SET(MYSQLD_LINK_FLAGS "${MYSQLD_LINK_FLAGS} ${LIBSYSTEMD_STATIC_LDFLAGS}") + ENDIF() + ELSE() + SET(LIBSYSTEMD systemd) + ENDIF() + SET(CMAKE_REQUIRED_LIBRARIES ${LIBSYSTEMD}) + CHECK_C_SOURCE_COMPILES( + " + #include + int main() + { + sd_listen_fds(0); + }" + HAVE_SYSTEMD) + CHECK_INCLUDE_FILES(systemd/sd-daemon.h HAVE_SYSTEMD_SD_DAEMON_H) + CHECK_FUNCTION_EXISTS(sd_listen_fds HAVE_SYSTEMD_SD_LISTEN_FDS) + CHECK_FUNCTION_EXISTS(sd_notify HAVE_SYSTEMD_SD_NOTIFY) + CHECK_FUNCTION_EXISTS(sd_notifyf HAVE_SYSTEMD_SD_NOTIFYF) + IF(HAVE_SYSTEMD AND HAVE_SYSTEMD_SD_DAEMON_H AND HAVE_SYSTEMD_SD_LISTEN_FDS + AND HAVE_SYSTEMD_SD_NOTIFY AND HAVE_SYSTEMD_SD_NOTIFYF) + ADD_DEFINITIONS(-DHAVE_SYSTEMD) + MESSAGE(STATUS "Systemd features enabled") + ELSE() + UNSET(LIBSYSTEMD) + UNSET(HAVE_SYSTEMD_SD_DAEMON_H) + UNSET(HAVE_SYSTEMD_SD_LISTEN_FDS) + UNSET(HAVE_SYSTEMD_SD_NOTIFY) + UNSET(HAVE_SYSTEMD_SD_NOTIFYF) + MESSAGE(STATUS "Systemd features not enabled") + IF(WITH_SYSTEMD STREQUAL "yes") + MESSAGE(FATAL_ERROR "Requested WITH_SYSTEMD=YES however no dependencies installed/found") + ENDIF() + ENDIF() + ENDIF() + ENDIF() +ENDMACRO() diff --git a/config.h.cmake b/config.h.cmake index 5f5cd30dc199d..95bf2c0dc509a 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -119,6 +119,7 @@ #cmakedefine HAVE_LIBCRYPT 1 #cmakedefine HAVE_LIBMTMALLOC 1 #cmakedefine HAVE_LIBWRAP 1 +#cmakedefine HAVE_SYSTEMD 1 /* Does "struct timespec" have a "sec" and "nsec" field? */ #cmakedefine HAVE_TIMESPEC_TS_SEC 1 diff --git a/debian/dist/Debian/control b/debian/dist/Debian/control index 3c481a2ac614a..758b5ba2f167f 100644 --- a/debian/dist/Debian/control +++ b/debian/dist/Debian/control @@ -10,7 +10,8 @@ Build-Depends: procps | hurd, debhelper, libncurses5-dev (>= 5.0-6), libpam0g-dev, psmisc, po-debconf, chrpath, dpatch, gawk, bison, lsb-release, hardening-wrapper, cmake (>= 2.7), libaio-dev, ${MAYBE_LIBCRACK} - libjemalloc-dev (>= 3.0.0) + libjemalloc-dev (>= 3.0.0), + libsystemd-daemon-dev | libsystemd-dev, dh-systemd Standards-Version: 3.8.3 Homepage: http://mariadb.org/ Vcs-Browser: https://github.com/MariaDB/server/tree/10.1/ diff --git a/debian/dist/Debian/mariadb-server-10.1.files.in b/debian/dist/Debian/mariadb-server-10.1.files.in index f6ffbc3388c99..aaf5b27953fce 100644 --- a/debian/dist/Debian/mariadb-server-10.1.files.in +++ b/debian/dist/Debian/mariadb-server-10.1.files.in @@ -53,6 +53,8 @@ usr/bin/wsrep_sst_mysqldump usr/bin/wsrep_sst_rsync usr/bin/wsrep_sst_xtrabackup usr/bin/wsrep_sst_xtrabackup-v2 +usr/bin/mariadb-socket-convert +usr/bin/mariadb-system-convert usr/share/doc/mariadb-server-10.1/mysqld.sym.gz usr/share/doc/mariadb-server-10.1/INFO_SRC usr/share/doc/mariadb-server-10.1/INFO_BIN diff --git a/debian/dist/Debian/mariadb-server-10.1.postinst b/debian/dist/Debian/mariadb-server-10.1.postinst index fff75988353fb..4175598d94629 100644 --- a/debian/dist/Debian/mariadb-server-10.1.postinst +++ b/debian/dist/Debian/mariadb-server-10.1.postinst @@ -260,6 +260,19 @@ if [ "$1" = "configure" ]; then db_go fi + # create a systemd socket activation file based on current settings + systemd_sockconf=/etc/systemd/system/mariadb.socket.d/migrated-from-my.cnf-settings.conf + if [ -x /usr/bin/mariadb-socket-convert -a ! -f "${systemd_sockconf}" ]; then + mkdir -p /etc/systemd/system/mariadb.socket.d + /usr/bin/mariadb-socket-convert > "${systemd_sockconf}" + fi + # copy out any mysqld_safe settings + systemd_conf=/etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf + if [ -x /usr/bin/mariadb-service-convert -a ! -f "${systemd_conf}" ]; then + mkdir -p /etc/systemd/system/mariadb.service.d + /usr/bin/mariadb-service-convert > "${systemd_conf}" + fi + fi db_stop # in case invoke failes diff --git a/debian/dist/Debian/rules b/debian/dist/Debian/rules index 237be96ca7d38..add6403ca6174 100755 --- a/debian/dist/Debian/rules +++ b/debian/dist/Debian/rules @@ -180,6 +180,10 @@ install: build install -m 0644 $(builddir)/Docs/INFO_SRC $(TMP)/usr/share/doc/mariadb-server-10.1/INFO_SRC install -m 0644 $(builddir)/Docs/INFO_BIN $(TMP)/usr/share/doc/mariadb-server-10.1/INFO_BIN + # systemd helpers + install -m 0755 scripts/mariadb-socket-convert $(TMP)/usr/bin/ + install -m 0755 scripts/mariadb-service-convert $(TMP)/usr/bin/ + # mariadb-test mv $(TMP)/usr/mysql-test $(TMP)/usr/share/mysql @@ -216,7 +220,9 @@ binary-indep: build install dh_installexamples -i dh_installmenu -i dh_installlogrotate -i + dh_systemd_enable -i support-files/mariadb.service support-files/mariadb.socket dh_installinit -i + dh_systemd_start -i --restart-after-upgrade mariadb.socket dh_installcron -i dh_installman -i dh_installinfo -i diff --git a/debian/dist/Ubuntu/control b/debian/dist/Ubuntu/control index ebb34de1761c6..0001ff3da973c 100644 --- a/debian/dist/Ubuntu/control +++ b/debian/dist/Ubuntu/control @@ -10,7 +10,8 @@ Build-Depends: procps | hurd, debhelper, libncurses5-dev (>= 5.0-6), libpam0g-dev, psmisc, po-debconf, chrpath, dpatch, gawk, bison, lsb-release, hardening-wrapper, cmake (>= 2.7), libaio-dev, ${MAYBE_LIBCRACK} - libjemalloc-dev (>= 3.0.0) + libjemalloc-dev (>= 3.0.0), + libsystemd-daemon-dev | libsystemd-dev, dh-systemd Standards-Version: 3.8.2 Homepage: http://mariadb.org/ Vcs-Browser: http://bazaar.launchpad.net/~maria-captains/maria/10.1/files diff --git a/debian/dist/Ubuntu/mariadb-server-10.1.files.in b/debian/dist/Ubuntu/mariadb-server-10.1.files.in index 0e07df3e05fed..b67b7b3472bcb 100644 --- a/debian/dist/Ubuntu/mariadb-server-10.1.files.in +++ b/debian/dist/Ubuntu/mariadb-server-10.1.files.in @@ -55,6 +55,8 @@ usr/bin/wsrep_sst_mysqldump usr/bin/wsrep_sst_rsync usr/bin/wsrep_sst_xtrabackup usr/bin/wsrep_sst_xtrabackup-v2 +usr/bin/mariadb-socket-convert +usr/bin/mariadb-system-convert usr/share/doc/mariadb-server-10.1/mysqld.sym.gz usr/share/doc/mariadb-server-10.1/INFO_SRC usr/share/doc/mariadb-server-10.1/INFO_BIN diff --git a/debian/dist/Ubuntu/mariadb-server-10.1.postinst b/debian/dist/Ubuntu/mariadb-server-10.1.postinst index b30dc5963be23..21c253819259f 100644 --- a/debian/dist/Ubuntu/mariadb-server-10.1.postinst +++ b/debian/dist/Ubuntu/mariadb-server-10.1.postinst @@ -276,6 +276,18 @@ if [ "$1" = "configure" ]; then db_go fi + # create a systemd socket activation file based on current settings + systemd_sockconf=/etc/systemd/system/mariadb.socket.d/migrated-from-my.cnf-settings.conf + if [ -x /usr/bin/mariadb-socket-convert -a ! -f "${systemd_sockconf}" ]; then + mkdir -p /etc/systemd/system/mariadb.socket.d + /usr/bin/mariadb-socket-convert > "${systemd_sockconf}" + fi + # copy out any mysqld_safe settings + systemd_conf=/etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf + if [ -x /usr/bin/mariadb-service-convert -a ! -f "${systemd_conf}" ]; then + mkdir -p /etc/systemd/system/mariadb.service.d + /usr/bin/mariadb-service-convert > "${systemd_conf}" + fi fi db_stop # in case invoke failes diff --git a/debian/dist/Ubuntu/rules b/debian/dist/Ubuntu/rules index 40793980b9964..1e6d30523c1e5 100755 --- a/debian/dist/Ubuntu/rules +++ b/debian/dist/Ubuntu/rules @@ -180,6 +180,10 @@ install: build install -m 0644 $(builddir)/Docs/INFO_SRC $(TMP)/usr/share/doc/mariadb-server-10.1/INFO_SRC install -m 0644 $(builddir)/Docs/INFO_BIN $(TMP)/usr/share/doc/mariadb-server-10.1/INFO_BIN + # systemd helpers + install -m 0755 scripts/mariadb-socket-convert $(TMP)/usr/bin/ + install -m 0755 scripts/mariadb-service-convert $(TMP)/usr/bin/ + # mariadb-test mv $(TMP)/usr/mysql-test $(TMP)/usr/share/mysql @@ -221,7 +225,9 @@ binary-indep: build install dh_installexamples -i dh_installmenu -i dh_installlogrotate -i + dh_systemd_enable -i support-files/mariadb.service support-files/mariadb.socket dh_installinit -i + dh_systemd_start -i --restart-after-upgrade mariadb.socket dh_installcron -i dh_installman -i dh_installinfo -i diff --git a/include/my_systemd.h b/include/my_systemd.h new file mode 100644 index 0000000000000..6b98822db2791 --- /dev/null +++ b/include/my_systemd.h @@ -0,0 +1,17 @@ + +#ifndef MY_SYSTEMD_INCLUDED +#define MY_SYSTEMD_INCLUDED + +#ifdef HAVE_SYSTEMD +#include + +#else + +#define sd_listen_fds(X) (0) + +#define sd_notify(X, Y) +#define sd_notifyf(E, F, ...) + +#endif + +#endif /* MY_SYSTEMD_INCLUDED */ diff --git a/include/mysql/psi/mysql_socket.h b/include/mysql/psi/mysql_socket.h index 33768b20fa8ca..9326b1f1b1f5b 100644 --- a/include/mysql/psi/mysql_socket.h +++ b/include/mysql/psi/mysql_socket.h @@ -281,6 +281,22 @@ inline_mysql_socket_set_state(MYSQL_SOCKET socket, enum PSI_socket_state state) } #endif /* HAVE_PSI_SOCKET_INTERFACE */ +/** + @def mysql_socket_fd(K, F) + Create a socket. + @c mysql_socket_fd is a replacement for @c socket. + @param K PSI_socket_key for this instrumented socket + @param F File descriptor +*/ + +#ifdef HAVE_PSI_SOCKET_INTERFACE + #define mysql_socket_fd(K, F) \ + inline_mysql_socket_fd(K, F) +#else + #define mysql_socket_fd(K, F) \ + inline_mysql_socket_fd(F) +#endif + /** @def mysql_socket_socket(K, D, T, P) Create a socket. @@ -542,6 +558,28 @@ static inline void inline_mysql_socket_register( } #endif +/** mysql_socket_fd */ + +static inline MYSQL_SOCKET +inline_mysql_socket_fd +( +#ifdef HAVE_PSI_SOCKET_INTERFACE + PSI_socket_key key, +#endif + int fd) +{ + MYSQL_SOCKET mysql_socket= MYSQL_INVALID_SOCKET; + mysql_socket.fd= fd; +#ifdef HAVE_PSI_SOCKET_INTERFACE + if (likely(mysql_socket.fd != INVALID_SOCKET)) + { + mysql_socket.m_psi= PSI_SOCKET_CALL(init_socket) + (key, (const my_socket*)&mysql_socket.fd, NULL, 0); + } +#endif + return mysql_socket; +} + /** mysql_socket_socket */ static inline MYSQL_SOCKET diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 13fc69912f651..458ccd92b2226 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -300,6 +300,8 @@ ELSE() mysqld_multi mysqld_safe ${WSREP_BINARIES} + mariadb-service-convert + mariadb-socket-convert ) FOREACH(file ${BIN_SCRIPTS}) IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh) diff --git a/scripts/mariadb-service-convert b/scripts/mariadb-service-convert new file mode 100755 index 0000000000000..863bad5c2e815 --- /dev/null +++ b/scripts/mariadb-service-convert @@ -0,0 +1,63 @@ +#!/bin/bash +# +# Used to generate a mariadb.service file based on the curent mysql/maridb settings +# +# This is to assist distro maintainers in migrating to systemd service definations from +# a user mysqld_safe settings in the my.cnf files. +# +# Redirect output to user directory like /etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf + +tz_old=$TZ + +. /usr/bin/mysqld_safe --simulate + +echo "# converted using $0" +echo "#" +echo + +echo '[Service]' + +echo + + +if [[ ( "$user" != "root" && "$user" != "mysql" ) || "${SET_USER}" == 1 ]]; then + echo User=$user +fi + + +[ -n "${open_files}" ] && echo LimitNOFILE=$open_files +[ -n "${core_file_size}" ] && echo LimitCore=$core_file_size +[ "${niceness}" -gt 0 ] && echo Nice=$niceness +[ "${TZ}" != "${tz_old}" ] && echo Environment=\"TZ=${TZ}\" + +if [ -n "$mysqld_ld_preload" ]; then + new_text="$mysqld_ld_preload" + [ -n "$LD_PRELOAD" ] && new_text="$new_text $LD_PRELOAD" + echo Environment=\"LD_PRELOAD=`shell_quote_string "$new_text"`\" +fi + +if [ -n "$mysqld_ld_library_path" ]; then + new_text="$mysqld_ld_library_path" + [ -n "$LD_LIBRARY_PATH" ] && new_text="$new_text:$LD_LIBRARY_PATH" + echo Environment=\"LD_LIBRARY_PATH=`shell_quote_string "$new_text"`\" +fi + +if [ $want_syslog -eq 1 ]; then + echo StandardError=syslog + echo SyslogFacility=daemon + echo SyslogLevel=error + echo SyslogLevelPrefix=${syslog_tag_mysqld} +fi + +if [ "${flush_caches}" -gt 0 ]; then + echo ExecStartPre=sync + echo ExecStartPre=sysctl -q -w vm.drop_caches=3 +fi + +if [ "${numa_interleave}" -gt 0 ]; then + echo + echo ExecStart=numactl --interleave=all ${cmd} '${OPTIONS}' + echo +fi + +[ -n "${CRASH_SCRIPT}" ] && echo FailureAction=${CRASH_SCRIPT} diff --git a/scripts/mariadb-socket-convert b/scripts/mariadb-socket-convert new file mode 100755 index 0000000000000..4f517153890d7 --- /dev/null +++ b/scripts/mariadb-socket-convert @@ -0,0 +1,179 @@ +#!/bin/bash +# +# Used to generate a mariadb.socket file based on the curent mysql/maridb settings +# +# This is to assist distro maintainers in migrating to systemd socket activation from +# a user system with networking settings somewhere in the my.cnf files. +# +# Redirect output to user directory like /etc/systemd/system/mariadb.socket.d/migrated-from-my.cnf-settings.conf + + +print_ports() +{ + if [ -n "${port}" ]; then + echo "ListenStream=${bind}${port}" + fi + if [ -n "${extraport}" ]; then + echo "ListenStream=${bind}${extraport}" + fi +} + +bindaddress= +port= +extraport= +backlog= +maxconnections= +skip_networking= +socket= +default_port=3306 +default_socket=/var/lib/mysql/mysql.sock + +coproc mysqldefaults { /usr/bin/my_print_defaults --mysqld ; } +while read var; do + key=${var%%=*} + val=${var#*=} + case "${key}" in + --bind-address) + bindaddress=$val + ;; + --bind_address) + bindaddress=$val + ;; + --port) + port=$val + ;; + --extra[-_]port) + extraport=$val + ;; + --backlog) + backlog=$val + ;; + --max-connections) + maxconnections=$val + ;; + --max_connections) + maxconnections=$val + ;; + --skip-networking) + if [ -z "${val}" ]; then + skipnetworking=1 + else + skipnetworking=$val + fi + ;; + --skip_networking) + if [ -z "${val}" ]; then + skipnetworking=1 + else + skipnetworking=$val + fi + ;; + --socket) + socket=$val + ;; + esac +done < /dev/fd/${mysqldefaults[0]} + +echo '[Socket]' + +if [ -n "${backlog}" ]; then + echo "Backlog=${backlog}" +elif [ -n "${maxconnections}" ]; then + if [ $maxconnections -gt 150 ]; then + echo "Backlog=150" + else + echo "Backlog=${maxconnections}" + fi +fi + +if [ -n "${port}" -o \ + -n "${extraport}" -o \ + "${skipnetworking}" = '0' -o \ + -n "${bindaddress}" -o \ + -n "${socket}" ]; then + # we've set unix or inet sockets to non default + echo "# reset the ListenStream list to empty" + echo "ListenStream=" + echo + coproc mysqld { /usr/sbin/mysqld --verbose --help; } + # skip preamble + preamble_finished=0 + while read var; do + if [[ $var =~ ^------- ]]; then + preamble_finished=1 + fi + [ $preamble_finished ] || continue + key=${var%% *} + val=${var##* } + case "${key}" in + socket) + default_socket=$val + ;; + port) + default_port=$val + ;; + esac + done < /dev/fd/${mysqld[0]} + # if port isn't set it really needs to be to + # fill out the details + if [ -z "${port}" ]; then + port=${default_port} + fi + # socket has a default value so ensure that is set + if [ -z "${socket}" ]; then + socket=${default_socket} + fi +else + exit 0 +fi + +if [ -n "${socket}" ]; then + echo "ListenStream=${socket}" +fi + +if [ -n "${skipnetworking}" ]; then + [ "${skipnetworking}" = '0' ] && exit 0 +fi + +if [ -n "${bindaddress}" ]; then + if [ "${bindaddress}" = "*" ]; then + # old wildcard + bind= + print_ports + elif [[ "${bindaddress}" =~ [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]; then + # roughly IPv4 + bind=${bindaddress}: + print_ports + elif [[ "${bindaddress}" =~ ([0-9a-fA-F]{0,4}::?){1,7}[0-9a-fA-F]{0,4} ]]; then + # roughly IPv6 + bind=[${bindaddress}]: + print_ports + elif [ -x /usr/bin/host ]; then + # hostname + # Systemd.sockets don't support it so look it up + coproc hosts { host ${bindaddress}; } + while read var; do + if [[ "${var}" = *IPv6\ address* ]]; then + bind=[${var##* }]: + echo "Warning: using IP ${bind} for hostname ${bindaddress} specified in bindaddress" >&2 + print_ports + break + else + bind=${var##* }: + echo "Warning: using IP ${bind} for hostname ${bindaddress} specified in bindaddress" >&2 + print_ports + fi + done < /dev/fd/${hosts[0]} + else + echo "Warning: bindaddress=${bindaddress} was a hostname we couldn't resolve. using all interfaces" >&2 + bind= + print_ports + fi +else + bind='' + print_ports +fi + + +exit 0 + diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index c96fc4567f0a5..d20e8ad374daa 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -21,9 +21,11 @@ mysqld_ld_library_path= flush_caches=0 numa_interleave=0 wsrep_on=0 +simulate=0 # Initial logging status: error log is not open, and not using syslog logging=init +mysqld_safe_logging=init want_syslog=0 syslog_tag= user='@MYSQLD_USER@' @@ -81,6 +83,7 @@ Usage: $0 [OPTIONS] --malloc-lib=LIB Preload shared library LIB if available --mysqld=FILE Use the specified file as mysqld --mysqld-version=VERSION Use "mysqld-VERSION" as mysqld + --simulate Simulate the start to detect errors but don't start --nice=NICE Set the scheduling priority of mysqld --no-auto-restart Exit after starting mysqld --nowatch Exit after starting mysqld @@ -136,7 +139,7 @@ log_generic () { msg="`date +'%y%m%d %H:%M:%S'` mysqld_safe $*" echo "$msg" - case $logging in + case $mysqld_safe_logging in init) ;; # Just echo the message, don't save it anywhere file) echo "$msg" >> "$err_log" ;; syslog) logger -t "$syslog_tag_mysqld_safe" -p "$priority" "$*" ;; @@ -318,6 +321,7 @@ parse_arguments() { MYSQLD="mysqld" fi ;; + --simulate) simulate=1 ;; --nice=*) niceness="$val" ;; --nowatch|--no[-_]watch|--no[-_]auto[-_]restart) nowatch=1 ;; --open[-_]files[-_]limit=*) open_files="$val" ;; @@ -707,7 +711,11 @@ then fi # Log to err_log file - log_notice "Logging to '$err_log'." + if [ $simulate -eq 0 ] + then + log_notice "Logging to '$err_log'." + mysqld_safe_logging=file + fi logging=file if [ ! -f "$err_log" ]; then # if error log already exists, @@ -723,7 +731,11 @@ else syslog_tag_mysqld_safe="${syslog_tag_mysqld_safe}-$syslog_tag" syslog_tag_mysqld="${syslog_tag_mysqld}-$syslog_tag" fi - log_notice "Logging to syslog." + if [ $simulate -eq 0 ] + then + log_notice "Logging to syslog." + mysqld_safe_logging=syslog + fi logging=syslog fi @@ -735,7 +747,7 @@ then USER_OPTION="--user=$user" fi # Change the err log to the right user, if it is in use - if [ $want_syslog -eq 0 ]; then + if [ $simulate -eq 0 -a $want_syslog -eq 0 ]; then touch "$err_log" chown $user "$err_log" fi @@ -753,7 +765,7 @@ fi safe_mysql_unix_port=${mysql_unix_port:-${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@}} # Make sure that directory for $safe_mysql_unix_port exists mysql_unix_port_dir=`dirname $safe_mysql_unix_port` -if [ ! -d $mysql_unix_port_dir ] +if [ $simulate -eq 0 -a ! -d $mysql_unix_port_dir ] then if ! `mkdir -p $mysql_unix_port_dir` then @@ -777,7 +789,7 @@ does not exist or is not executable. Please cd to the mysql installation directory and restart this script from there as follows: ./bin/mysqld_safe& See http://dev.mysql.com/doc/mysql/en/mysqld-safe.html for more information" - exit 1 + [ $simulate -eq 0 ] && exit 1 fi if test -z "$pid_file" @@ -862,7 +874,7 @@ fi # # If there exists an old pid file, check if the daemon is already running # Note: The switches to 'ps' may depend on your operating system -if test -f "$pid_file" +if test -f "$pid_file" && [ $simulate -eq 0 ] then PID=`cat "$pid_file"` if @CHECK_PID@ @@ -908,7 +920,7 @@ then log_error "sysctl command not found, required for --flush-caches" exit 1 # Purge page cache, dentries and inodes. - elif ! sysctl -q -w vm.drop_caches=3 + elif [ $simulate -eq 0 ] && ! sysctl -q -w vm.drop_caches=3 then log_error "sysctl failed, check the error message for details" exit 1 @@ -937,7 +949,12 @@ fi # ulimit -n 256 > /dev/null 2>&1 # Fix for BSD and FreeBSD systems #fi -cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS" +if [ $simulate -eq 0 ] +then + cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS" +else + cmd='' +fi # # Set mysqld's memory interleave policy. @@ -957,7 +974,7 @@ then fi # Launch mysqld with numactl. - cmd="$cmd numactl --interleave=all" + [ $simulate -eq 0 ] && cmd="$cmd numactl --interleave=all" elif test $numa_interleave -eq 1 then log_error "--numa-interleave is not supported on this platform" @@ -971,9 +988,9 @@ do done cmd="$cmd $args" # Avoid 'nohup: ignoring input' warning -test -n "$NOHUP_NICENESS" && cmd="$cmd < /dev/null" +[ -n "$NOHUP_NICENESS" -a $simulate -eq 0 ] && cmd="$cmd < /dev/null" -log_notice "Starting $MYSQLD daemon with databases from $DATADIR" +[ $simulate -eq 0 ] && log_notice "Starting $MYSQLD daemon with databases from $DATADIR" # variable to track the current number of "fast" (a.k.a. subsecond) restarts fast_restart=0 @@ -987,6 +1004,8 @@ max_wsrep_restarts=0 while true do + [ $simulate ] && break; + rm -f "$pid_file" # Some extra safety start_time=`date +%M%S` @@ -1011,7 +1030,7 @@ do eval_log_error "$cmd" fi - if [ $want_syslog -eq 0 -a ! -f "$err_log" ]; then + if [ $simulate -eq 0 -a $want_syslog -eq 0 -a ! -f "$err_log" ]; then touch "$err_log" # hypothetical: log was renamed but not chown $user "$err_log" # flushed yet. we'd recreate it with chmod "$fmode" "$err_log" # wrong owner next time we log, so set @@ -1101,5 +1120,5 @@ do fi done -log_notice "mysqld from pid file $pid_file ended" +[ $simulate -eq 0 ] && log_notice "mysqld from pid file $pid_file ended" diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 033a0e04ccfde..8c6ff54cc1c4e 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -166,7 +166,8 @@ TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS} mysys mysys_ssl dbug strings vio pcre ${LIBJEMALLOC} ${LIBWRAP} ${LIBCRYPT} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT} ${WSREP_LIB} - ${SSL_LIBRARIES}) + ${SSL_LIBRARIES} + ${LIBSYSTEMD}) IF(WIN32) SET(MYSQLD_SOURCE main.cc nt_servc.cc nt_servc.h message.rc) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6d35f53a1d9c7..c30f6e1e93b12 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -110,6 +110,25 @@ #include #endif +#include + +#ifdef HAVE_SYSTEMD +#include +union sockaddr_union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; +#ifdef HAVE_SYS_UN_H + struct sockaddr_un un; +#endif + struct sockaddr_storage ss; +}; +#define MAX_LISTEN_SOCKETS 10 +static int systemd_listen_cnt=0; +#else /* HAVE_SYSTEMD */ +#define MAX_LISTEN_SOCKETS 3 +#endif + #define mysqld_charset &my_charset_latin1 /* We have HAVE_valgrind below as this speeds up the shutdown of MySQL */ @@ -1887,6 +1906,8 @@ static void __cdecl kill_server(int sig_ptr) else sql_print_error(ER_DEFAULT(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */ + sd_notify(0, "STOPPING=1"); + #ifdef HAVE_SMEM /* Send event to smem_event_connect_request for aborting @@ -2618,8 +2639,11 @@ static void network_init(void) struct sockaddr_un UNIXaddr; int arg; #endif + int systemd_n = 0; DBUG_ENTER("network_init"); + systemd_n = sd_listen_fds(0); + DBUG_PRINT("general",("Systemd listen_fds is %d",systemd_n)); if (MYSQL_CALLBACK_ELSE(thread_scheduler, init, (), 0)) unireg_abort(1); /* purecov: inspected */ @@ -2633,7 +2657,7 @@ static void network_init(void) if (!opt_disable_networking) DBUG_ASSERT(report_port != 0); #endif - if (!opt_disable_networking && !opt_bootstrap) + if (!opt_disable_networking && !opt_bootstrap && systemd_n==0) { if (mysqld_port) base_ip_sock= activate_tcp_port(mysqld_port); @@ -2693,7 +2717,7 @@ static void network_init(void) /* ** Create the UNIX socket */ - if (mysqld_unix_port[0] && !opt_bootstrap) + if (mysqld_unix_port[0] && !opt_bootstrap && systemd_n==0) { DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port)); @@ -6446,6 +6470,14 @@ inline void kill_broken_server() #ifndef EMBEDDED_LIBRARY +#ifdef HAVE_SYSTEMD +static MYSQL_SOCKET systemd_sock[MAX_LISTEN_SOCKETS]; +static PSI_socket_key all_systemd_key[MAX_LISTEN_SOCKETS]; +#ifdef HAVE_PSI_SOCKET_INTERFACE +static PSI_socket_info all_systemd_sockets[MAX_LISTEN_SOCKETS+1]; +#endif +#endif + void handle_connections_sockets() { MYSQL_SOCKET sock= mysql_socket_invalid(); @@ -6459,38 +6491,204 @@ void handle_connections_sockets() int flags=0,retval; st_vio *vio_tmp; bool is_unix_sock; -#ifdef HAVE_POLL + int systemd_n=0, systemd_fd; +#ifdef HAVE_SYSTEMD + union sockaddr_union socketpeer; +#endif + socklen_t socketpeer_len; + char const *family; int socket_count= 0; - struct pollfd fds[3]; // for ip_sock, unix_sock and extra_ip_sock - MYSQL_SOCKET pfs_fds[3]; // for performance schema -#define setup_fds(X) \ + short fd_type[MAX_LISTEN_SOCKETS]; +#ifdef HAVE_POLL + struct pollfd fds[MAX_LISTEN_SOCKETS]; // for ip_sock, extra_ip_sock and unix_sock (could be any order for systemd) + MYSQL_SOCKET pfs_fds[MAX_LISTEN_SOCKETS]; // for performance schema +#define setup_fds(X,T) \ mysql_socket_set_thread_owner(X); \ pfs_fds[socket_count]= (X); \ fds[socket_count].fd= mysql_socket_getfd(X); \ fds[socket_count].events= POLLIN; \ + fd_type[socket_count]= T; \ socket_count++ #else -#define setup_fds(X) FD_SET(mysql_socket_getfd(X),&clientFDs) + int pfs_flags[MAX_LISTEN_SOCKETS]; + MYSQL_SOCKET pfs_fds[MAX_LISTEN_SOCKETS]; // used for non-polling interfaces +#define setup_fds(X,T) FD_SET(mysql_socket_getfd(X),&clientFDs); \ + pfs_fds[socket_count]= (X); \ + fd_type[socket_count]= T; \ + socket_count++ fd_set readFDs,clientFDs; FD_ZERO(&clientFDs); #endif DBUG_ENTER("handle_connections_sockets"); - if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET) +#ifdef HAVE_SYSTEMD + systemd_n = sd_listen_fds(1); + if (systemd_n < 0) + { + my_error(ER_SYSTEMD_LISTEN_FDS, MYF(0), strerror(-systemd_n)); + } + else + if (systemd_n > 0) + { + systemd_fd = SD_LISTEN_FDS_START; + while (systemd_n-- && systemd_listen_cnt < MAX_LISTEN_SOCKETS) + { + /* grab socket info */ + socketpeer_len = sizeof(socketpeer); + if (getsockname(systemd_fd, (struct sockaddr *) &socketpeer, + &socketpeer_len) < 0) + { + sql_print_error("getsockname for fd %d failed (errno= %d).", + systemd_fd, errno); + sd_notifyf(0, "ERRNO=%d", errno); + systemd_fd++; + continue; + } + if (socketpeer_len >=sizeof(socketpeer)) + { + sql_print_error("getsockname for fd %d unsufficient space", systemd_fd); + sd_notifyf(0, "ERRNO=%d", EINVAL); + systemd_fd++; + continue; + } + + /* Get listening sockets from systemd library calls + and set them up the same as other sockets. */ +#ifdef HAVE_SYS_UN_H + if (socketpeer.ss.ss_family == AF_UNIX) + { + sql_print_information("Listening on systemd unix socket for %s.", + socketpeer.un.sun_path); + family= "systemd_unix_socket"; + } + else +#endif + if (socketpeer.ss.ss_family == AF_INET || + socketpeer.ss.ss_family == AF_INET6) + { + unsigned port= ntohs(socketpeer.ss.ss_family == AF_INET ? + socketpeer.in.sin_port : socketpeer.in6.sin6_port); + if (port != 0 && port == mysqld_extra_port) + { + /* extra_port was same as systemd socket so use it as such */ + extra_ip_sock= mysql_socket_fd(all_systemd_key[systemd_listen_cnt], systemd_fd); + mysqld_extra_port= 0; + } + sql_print_information("Listening on systemd family %s port %d.", + socketpeer.ss.ss_family == AF_INET ? "IPv4" : "IPv6", port); + family= socketpeer.ss.ss_family == AF_INET ? "systemd_IPv4" : + "systemd_IPv6"; + } + else + { + sql_print_error("Unrecognised socket family: %d.", + socketpeer.ss.ss_family); + systemd_fd++; + continue; + } + systemd_sock[systemd_listen_cnt]= mysql_socket_fd(all_systemd_key[systemd_listen_cnt], systemd_fd); + mysql_socket_set_thread_owner(systemd_sock[systemd_listen_cnt]); +#ifndef HAVE_POLL + pfs_flags[socket_count]= +#endif + fcntl(systemd_fd, F_GETFL, 0); +#ifdef HAVE_PSI_SOCKET_INTERFACE + all_systemd_sockets[systemd_listen_cnt]= (PSI_socket_info) { &all_systemd_key[systemd_listen_cnt], family, PSI_FLAG_GLOBAL }; +#endif + setup_fds(systemd_sock[systemd_listen_cnt], socketpeer.ss.ss_family); + systemd_fd++; + systemd_listen_cnt++; + } +#ifdef HAVE_PSI_SOCKET_INTERFACE + all_systemd_sockets[systemd_listen_cnt]= (PSI_socket_info) { &key_socket_client_connection, "client_connection", 0}; + mysql_socket_register("sql", all_systemd_sockets, systemd_listen_cnt + 1); +#endif + /* print out unused ones */ + while (systemd_n-- > 0) + { + socketpeer_len = sizeof(socketpeer); + if (getsockname(systemd_fd, (struct sockaddr *) &socketpeer, + &socketpeer_len) < 0) + { + sql_print_error("getsockname for fd %d failed (errno= %d).", + systemd_fd, errno); + sd_notifyf(0, "ERRNO=%d", errno); + systemd_fd++; + continue; + } + if (socketpeer_len >=sizeof(socketpeer)) + { + sql_print_error("getsockname for fd %d unsufficient space", systemd_fd); + sd_notifyf(0, "ERRNO=%d", EINVAL); + systemd_fd++; + continue; + } +#ifdef HAVE_SYS_UN_H + if (socketpeer.ss.ss_family == AF_UNIX) + { + sql_print_error("Exceeded %d sockets NOT listening on systemd unix socket for %s.", + MAX_LISTEN_SOCKETS, socketpeer.un.sun_path); + } + else +#endif + if (socketpeer.ss.ss_family == AF_INET || + socketpeer.ss.ss_family == AF_INET6) + { + sql_print_error("Exceeded %d sockets NOT listening on systemd family %s port %d.", + MAX_LISTEN_SOCKETS, + socketpeer.ss.ss_family == AF_INET ? "IPv4" : "IPv6", + ntohs(socketpeer.ss.ss_family == AF_INET ? + socketpeer.in.sin_port : socketpeer.in6.sin6_port)); + } + systemd_fd++; + } + } + else + { +#endif /* HAVE_SYSTEMD */ + if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET) + { + setup_fds(base_ip_sock, AF_INET); + ip_flags = fcntl(mysql_socket_getfd(base_ip_sock), F_GETFL, 0); + } +#ifdef HAVE_SYS_UN_H + setup_fds(unix_sock, AF_UNIX); + socket_flags=fcntl(mysql_socket_getfd(unix_sock), F_GETFL, 0); +#endif +#ifdef HAVE_SYSTEMD + } +#endif /* HAVE_SYSTEMD */ + + /* here we active a extra port, even if socket activation was is used because the + extra port wasn't activated using socket activation */ + if (!opt_disable_networking && !opt_bootstrap && mysqld_extra_port!=0 && + mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET) { - setup_fds(base_ip_sock); - ip_flags = fcntl(mysql_socket_getfd(base_ip_sock), F_GETFL, 0); + extra_ip_sock= activate_tcp_port(mysqld_extra_port); } if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET) { - setup_fds(extra_ip_sock); + setup_fds(extra_ip_sock, AF_INET); extra_ip_flags = fcntl(mysql_socket_getfd(extra_ip_sock), F_GETFL, 0); } -#ifdef HAVE_SYS_UN_H - setup_fds(unix_sock); - socket_flags=fcntl(mysql_socket_getfd(unix_sock), F_GETFL, 0); + +#ifdef HAVE_SYSTEMD +#ifdef HAVE_POLL + if (systemd_listen_cnt == 0 && systemd_n>0) + { + sd_notify(0, "STATUS=No listening sockets"); + abort_loop=1; + } + else + { #endif + sd_notify(0, "READY=1\n" + "STATUS=Taking your SQL requests now..."); +#ifdef HAVE_POLL + } +#endif /* HAVE_POLL */ +#endif /* HAVE_SYSTEMD */ DBUG_PRINT("general",("Waiting for connections.")); MAYBE_BROKEN_SYSCALL; @@ -6534,6 +6732,7 @@ void handle_connections_sockets() { sock= pfs_fds[i]; flags= fcntl(mysql_socket_getfd(sock), F_GETFL, 0); + is_unix_sock= fd_type[i] == AF_UNIX; break; } } @@ -6542,18 +6741,39 @@ void handle_connections_sockets() { sock= base_ip_sock; flags= ip_flags; + is_unix_sock= FALSE; } else if (FD_ISSET(mysql_socket_getfd(extra_ip_sock),&readFDs)) { sock= extra_ip_sock; flags= extra_ip_flags; + is_unix_sock= FALSE; } +#ifdef HAVE_SYS_UN_H else + if (FD_ISSET(mysql_socket_getfd(unix_sock),&readFDs)) { sock = unix_sock; flags= socket_flags; + is_unix_sock= TRUE; } +#endif +#ifdef HAVE_SYSTEMD + else + { + for (int i= 0; i < socket_count; ++i) + { + if (FD_ISSET(mysql_socket_getfd(pfs_fds[i]),&readFDs)) + { + sock= pfs_fds[i]; + flags= pfs_flags[i]; + is_unix_sock= fd_type[i] == AF_UNIX; + break; + } + } + } +#endif // HAVE_SYSTEMD #endif // HAVE_POLL #if !defined(NO_FCNTL_NONBLOCK) @@ -6668,9 +6888,6 @@ void handle_connections_sockets() /* Set to get io buffers to be part of THD */ set_current_thd(thd); - is_unix_sock= (mysql_socket_getfd(sock) == - mysql_socket_getfd(unix_sock)); - if (!(vio_tmp= mysql_socket_vio_new(new_sock, is_unix_sock ? VIO_TYPE_SOCKET : VIO_TYPE_TCPIP, @@ -6706,6 +6923,7 @@ void handle_connections_sockets() create_new_thread(thd); set_current_thd(0); } + sd_notify(0, "STOPPING=1"); DBUG_VOID_RETURN; } @@ -10220,9 +10438,17 @@ void init_server_psi_keys(void) count= array_elements(all_server_stages); mysql_stage_register(category, all_server_stages, count); - - count= array_elements(all_server_sockets); - mysql_socket_register(category, all_server_sockets, count); +#ifdef HAVE_PSI_SOCKET_INTERFACE +#ifdef HAVE_SYSTEMD + if (systemd_listen_cnt == 0) + { +#endif + count= array_elements(all_server_sockets); + mysql_socket_register(category, all_server_sockets, count); +#ifdef HAVE_SYSTEMD + } +#endif +#endif #ifdef HAVE_PSI_STATEMENT_INTERFACE init_sql_statement_info(); diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 59908dc51c069..6962d27a63225 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7132,6 +7132,8 @@ ER_CANNOT_CONVERT_CHARACTER eng "Cannot convert '%s' character 0x%-.64s to '%s'" ER_INVALID_DEFAULT_VALUE_FOR_FIELD 22007 eng "Incorrect default value '%-.128s' for column '%.192s'" +ER_SYSTEMD_LISTEN_FDS + eng "Systemd error for configured ListenStream '%.192s'" ER_KILL_QUERY_DENIED_ERROR eng "You are not owner of query %lu" ger "Sie sind nicht Eigentümer von Abfrage %lu" diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 514f9bec6474d..cfd3c84164906 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -48,6 +48,8 @@ this program; if not, write to the Free Software Foundation, Inc., #include #endif +#include + /** @file ha_innodb.cc */ /* Include necessary InnoDB headers */ @@ -20012,9 +20014,11 @@ ib_logf( break; case IB_LOG_LEVEL_ERROR: sql_print_error("InnoDB: %s", str); + sd_notifyf(0, "STATUS=InnoDB: Error: %s", str); break; case IB_LOG_LEVEL_FATAL: sql_print_error("InnoDB: %s", str); + sd_notifyf(0, "STATUS=InnoDB: Fatal: %s", str); break; } diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index bb39d9804f6be..15042c6f4b93e 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -30,6 +30,8 @@ Created 9/20/1997 Heikki Tuuri #include // Solaris/x86 header file bug #include +#include + #include "log0recv.h" #ifdef UNIV_NONINL @@ -1872,6 +1874,7 @@ recv_apply_hashed_log_recs( recv_addr_t* recv_addr; ulint i; ibool has_printed = FALSE; + ulong progress; mtr_t mtr; loop: mutex_enter(&(recv_sys->mutex)); @@ -1941,14 +1944,15 @@ recv_apply_hashed_log_recs( } } + progress=(ulong) (i * 100) / hash_get_n_cells(recv_sys->addr_hash); if (has_printed - && (i * 100) / hash_get_n_cells(recv_sys->addr_hash) - != ((i + 1) * 100) - / hash_get_n_cells(recv_sys->addr_hash)) { + && progress != ((i + 1) * 100) + / hash_get_n_cells(recv_sys->addr_hash)) { + + fprintf(stderr, "%lu ", progress); + sd_notifyf(0, "STATUS=Applying batch of log records for Innodb: " + "Progress %lu", progress); - fprintf(stderr, "%lu ", (ulong) - ((i * 100) - / hash_get_n_cells(recv_sys->addr_hash))); } } @@ -2010,6 +2014,7 @@ recv_apply_hashed_log_recs( if (has_printed) { fprintf(stderr, "InnoDB: Apply batch completed\n"); + sd_notify(0, "STATUS=InnoDB: Apply batch completed"); } mutex_exit(&(recv_sys->mutex)); @@ -2157,8 +2162,11 @@ recv_apply_log_recs_for_backup(void) fprintf(stderr, "%lu ", (ulong) ((100 * i) / n_hash_cells)); fflush(stderr); + sd_notifyf(0, "STATUS=Applying batch of log records for backup Innodb: " + "Progress %lu", (ulong) (100 * i) / n_hash_cells); } } + sd_notify(0, "STATUS=InnoDB: Apply batch for backup completed"); recv_sys_empty_hash(); } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 227509a24ccf0..b0e5e93b79a97 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -49,6 +49,9 @@ this program; if not, write to the Free Software Foundation, Inc., #ifdef _WIN32 #include #endif + +#include + /** @file ha_innodb.cc */ /* Include necessary InnoDB headers */ @@ -21140,9 +21143,11 @@ ib_logf( break; case IB_LOG_LEVEL_ERROR: sql_print_error("InnoDB: %s", str); + sd_notifyf(0, "STATUS=InnoDB: Error: %s", str); break; case IB_LOG_LEVEL_FATAL: sql_print_error("InnoDB: %s", str); + sd_notifyf(0, "STATUS=InnoDB: Fatal: %s", str); break; } diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index 08a9b2b386378..2fba02d53aaf7 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -30,6 +30,8 @@ Created 9/20/1997 Heikki Tuuri #include // Solaris/x86 header file bug #include +#include + #include "log0recv.h" #ifdef UNIV_NONINL @@ -1940,6 +1942,7 @@ recv_apply_hashed_log_recs( recv_addr_t* recv_addr; ulint i; ibool has_printed = FALSE; + ulong progress; mtr_t mtr; loop: mutex_enter(&(recv_sys->mutex)); @@ -2009,14 +2012,15 @@ recv_apply_hashed_log_recs( } } + progress=(ulong) (i * 100) / hash_get_n_cells(recv_sys->addr_hash); if (has_printed - && (i * 100) / hash_get_n_cells(recv_sys->addr_hash) - != ((i + 1) * 100) - / hash_get_n_cells(recv_sys->addr_hash)) { + && progress != ((i + 1) * 100) + / hash_get_n_cells(recv_sys->addr_hash)) { + + fprintf(stderr, "%lu ", progress); + sd_notifyf(0, "STATUS=Applying batch of log records for Innodb: " + "Progress %lu", progress); - fprintf(stderr, "%lu ", (ulong) - ((i * 100) - / hash_get_n_cells(recv_sys->addr_hash))); } } @@ -2078,6 +2082,7 @@ recv_apply_hashed_log_recs( if (has_printed) { fprintf(stderr, "InnoDB: Apply batch completed\n"); + sd_notify(0, "STATUS=InnoDB: Apply batch completed"); } mutex_exit(&(recv_sys->mutex)); @@ -2227,8 +2232,11 @@ recv_apply_log_recs_for_backup(void) fprintf(stderr, "%lu ", (ulong) ((100 * i) / n_hash_cells)); fflush(stderr); + sd_notifyf(0, "STATUS=Applying batch of log records for backup Innodb: " + "Progress %lu", (ulong) (100 * i) / n_hash_cells); } } + sd_notify(0, "STATUS=InnoDB: Apply batch for backup completed"); recv_sys_empty_hash(); } diff --git a/support-files/mariadb.service b/support-files/mariadb.service new file mode 100644 index 0000000000000..a36d33c869bca --- /dev/null +++ b/support-files/mariadb.service @@ -0,0 +1,113 @@ +# +# /etc/systemd/system/mariadb.service +# + +[Unit] +Description=MariaDB database server +After=network.target +After=syslog.target +Requires=%p.socket +# OPTINSTANCE ConditionPathExists=/etc/mysql/my%I.cnf +# OPTINSTANCE - install as mariadb@.service and install as mariadb@xxx.service where %I becomes xxx +# from https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/dev-db/mysql-init-scripts/files/mysqld_at.service?view=markup + +[Install] +WantedBy=multi-user.target +Alias=mysql.service +Alias=mysqld.service + + +[Service] + +############################################################################## +## Core requirements +## + +Type=notify + +# Setting this to true can break replication and the Type=notify settings +PrivateNetwork=false + +############################################################################## +## Package maintainers +## + +User=mysql + +# Execute pre and post scripts as root +PermissionsStartOnly=true + +# Needed to create system tables etc. +# ExecStartPre=/usr/bin/mysql_install_db + +# Start main service +# OPTIONS here is for users to set in /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf +# Use the [service] section and Environment="OPTIONS=...". +ExecStart=/usr/sbin/mysqld $OPTIONS +# OPTINSTANCE --defaults-file=/etc/mysql/my%I.cnf + +KillMode=process +KillSignal=SIGTERM +# Don't want to see an automated SIGKILL ever +SendSIGKILL=no + +# Exit status 1 is a fatal config error. Restarting won't help. +RestartPreventExitStatus=1 +Restart=on-failure +RestartSec=5s + +PrivateDevices=true + +UMask=077 + +############################################################################## +## USERs can override +## +## +## by creating a file in /etc/systemd/system/mariadb.service.d/MY_SPECIAL.conf +## and adding/setting the following will override this file's settings. + +# Useful options not previously available in [mysqld_safe] + +# Kernels like killing mysqld when out of memory because its big. +# Lets temper that preference a little. +OOMScoreAdjust=-600 + +# Explicitly start with high IO priority +BlockIOWeight=1000 + +# If you don't use the /tmp directory for SELECT ... OUTFILE and +# LOAD DATA INFILE you can enable PrivateTmp=true for a little more security. +PrivateTmp=false + +## +## Options previously available to be set via [mysqld_safe] +## that now needs to be set by systemd config files as mysqld_safe +## isn't executed. +## + +# Number of files limit. previously [mysqld_safe] open-file-limit +LimitNOFILE=16364 + +# Maximium core size. previously [mysqld_safe] core-file-size +# LimitCore= + +# Nice priority. previously [mysqld_safe] nice +# Nice=-5 + +# Timezone. previously [mysqld_safe] timezone +# Environment="TZ=UTC" + +# Library substitutions. previously [mysqld_safe] malloc-lib with explict paths +# (in LD_LIBRARY_PATH) and library name (in LD_PRELOAD). +# Environment="LD_LIBRARY_PATH=/path1 /path2" "LD_PRELOAD= + +# Flush caches. previously [mysqld_safe] flush-caches=1 +# ExecStartPre=sync +# ExecStartPre=sysctl -q -w vm.drop_caches=3 + +# numa-interleave=1 equalivant +# Change ExecStart=numactl --interleave=all /usr/sbin/mysqld...... + +# crash-script equalivent +# FailureAction= diff --git a/support-files/mariadb.socket b/support-files/mariadb.socket new file mode 100644 index 0000000000000..5b71ca562f99d --- /dev/null +++ b/support-files/mariadb.socket @@ -0,0 +1,41 @@ +[Unit] +Description=MySQL/MariaDB Sockets + +[Install] +WantedBy=sockets.target +Alias=mysql.socket +Alias=mysqld.socket + +[Socket] +############################################################################## +## Core requirements +## + +KeepAlive=true + +# +# NonBlocking=true and NoDelay=true (if NonBlocking=true is unavailable) are +# already set by MariaDB + +############################################################################## +## DISTRIBUTION maintainers +## + +SocketUser=mysql +SocketMode=777 + +############################################################################## +## +## USERs can override +## +## See man systemd.socket.5 for meanings +## +## Override by creating a file in /etc/systemd/system/mariadb.socket.d/MY_SPECIAL.conf +## see man systemd.unit.5 + +ListenStream=/var/lib/mysql/mysql.sock +ListenStream=[::1]:3306 +ListenStream=127.0.0.1:3306 +BindToDevice= + +Backlog=150 diff --git a/support-files/rpm/server-postin.sh b/support-files/rpm/server-postin.sh index cd2aec4d84ae7..0ba56eeea3109 100644 --- a/support-files/rpm/server-postin.sh +++ b/support-files/rpm/server-postin.sh @@ -1,6 +1,18 @@ # Make MySQL start/shutdown automatically when the machine does it. if [ $1 = 1 ] ; then + # create a systemd service/socket activation file based on current settings + systemd_sockconf=/etc/systemd/system/mariadb.socket.d/migrated-from-my.cnf-settings.conf + if [ -x /usr/bin/mariadb-socket-convert -a ! -f "${systemd_sockconf}" ]; then + mkdir -p /etc/systemd/system/mariadb.socket.d + /usr/bin/mariadb-socket-convert > "${systemd_sockconf}" + fi + systemd_conf=/etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf + if [ -x /usr/bin/mariadb-service-convert -a ! -f "${systemd_conf}" ]; then + mkdir -p /etc/systemd/system/mariadb.service.d + /usr/bin/mariadb-service-convert > "${systemd_conf}" + fi + if [ -x /usr/bin/systemctl ] ; then /usr/bin/systemctl daemon-reload >/dev/null 2>&1 fi