Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-31222

Outdated mysqld_safe script

    XMLWordPrintable

Details

    Description

      I was looking through the contents of the script and came across a few lines that didn't make sense to me. More specifically from lines 502 to 536 of the script

      mysqld_safe(MariaDB)

      #
      # First, try to find BASEDIR and ledir (where mysqld is)
      #
       
      MY_PWD=`dirname $0`
      MY_PWD=`cd "$MY_PWD"/.. && pwd`
      # Check for the directories we would expect from a binary release install
      if test -n "$MY_BASEDIR_VERSION" -a -d "$MY_BASEDIR_VERSION"
      then
        # BASEDIR is already overridden on command line.  Do not re-set.
       
        # Use BASEDIR to discover le.
        if test -x "$MY_BASEDIR_VERSION/libexec/mariadbd"
        then
          ledir="$MY_BASEDIR_VERSION/libexec"
        elif test -x "$MY_BASEDIR_VERSION/sbin/mariadbd"
        then
          ledir="$MY_BASEDIR_VERSION/sbin"
        else
          ledir="$MY_BASEDIR_VERSION/bin"
        fi
      elif test -x "$MY_PWD/bin/mariadbd"
      then
        MY_BASEDIR_VERSION="$MY_PWD"		# Where bin, share and data are
        ledir="$MY_PWD/bin"			# Where mysqld is
      # Check for the directories we would expect from a source install
      elif test -x "$MY_PWD/libexec/mariadbd"
      then
        MY_BASEDIR_VERSION="$MY_PWD"		# Where libexec, share and var are
        ledir="$MY_PWD/libexec"		# Where mysqld is
      elif test -x "$MY_PWD/sbin/mariadbd"
      then
        MY_BASEDIR_VERSION="$MY_PWD"		# Where sbin, share and var are
        ledir="$MY_PWD/sbin"			# Where mysqld is
      # Since we didn't find anything, used the compiled-in defaults
      else
        MY_BASEDIR_VERSION='/usr'
        ledir='/usr/bin'
      fi
      

      I was wondering what's the purpose of the first condition in the conditional above. What is the purpose of testing for MY_BASEDIR_VERSION when the variable obviously hasn't been set at that point? The comment #BASEDIR already overridden in the command line also didn't make sense to me. How could MY_BASEDIR_VERSION be overridden by the --basedir provided by the user at that point when the command line arguments haven't even been parsed yet? MY_BASEDIR_VERSION can only be overridden when the parse_arguments() function is called, which didn't happen until line 583.

      Out of curiosity, I downloaded a copy of MySQL server just to look at MySQL's version of mysqld_safe. Here is what it looks like.

      mysqld_safe(MySQL)

      find_basedir_from_cmdline () {
        for arg in "$@"; do
          case $arg in
            --basedir=*)
              MY_BASEDIR_VERSION="`echo "$arg" | sed -e 's;^--[^=]*=;;'`"
              # Convert to full path
              cd "$MY_BASEDIR_VERSION"
              if [ $? -ne 0 ] ; then
                log_error "--basedir set to '$MY_BASEDIR_VERSION', however could not access directory"
                exit 1
              fi
              MY_BASEDIR_VERSION="`pwd`"
              ;;
          esac
        done
      }
       
      #
      # First, try to find BASEDIR and ledir (where mysqld is)
      #
       
      oldpwd="`pwd`"
       
      # Args not parsed yet, check if --basedir was given on command line
      find_basedir_from_cmdline "$@"
      echo "Basedir=$MY_BASEDIR_VERSION"
       
      # --basedir is already overridden on command line
      if test -n "$MY_BASEDIR_VERSION" -a -d "$MY_BASEDIR_VERSION" ; then
        # Search for mysqld and set ledir
        for dir in bin libexec sbin bin ; do
          if test -x "$MY_BASEDIR_VERSION/$dir/mysqld" ; then
            ledir="$MY_BASEDIR_VERSION/$dir"
            break
          fi
        done
       
      else
        # Basedir should be parent dir of bindir, unless some non-standard
        # layout is used
       
        cd "`dirname $0`"
        if [ -h "$0" ] ; then
          realpath="`ls -l  "$0" | awk '{print $NF}'`"
          cd "`dirname "$realpath"`"
        fi
        cd ..
        MY_PWD="`pwd`"
       
        # Search for mysqld and set ledir and BASEDIR
        for dir in bin libexec sbin bin ; do
          if test -x "$MY_PWD/$dir/mysqld" ; then
            MY_BASEDIR_VERSION="$MY_PWD"
            ledir="$MY_BASEDIR_VERSION/$dir"
            break
          fi
        done
       
        # If we still didn't find anything, use the compiled-in defaults
        if test -z "$MY_BASEDIR_VERSION" ; then
          MY_BASEDIR_VERSION='/usr/local/mysql'
          ledir='/usr/local/mysql/bin'
        fi
      fi
      

      The mysqld_safe script distributed with MySQL makes sense to me because it locates the --basedir option from the command line first (via the find_basedir_from_cmdline() function) before attempting to test whether it has been overridden. This led me to wonder if the script shipped with MariaDB is outdated.

      UPDATE:

      After further investigation, I discovered another aspect of the script that doesn't agree with MariaDB's official documentation. It is implied in the mysqld_safe article on the knowledge base that the script will fallback to using @libexecdir@/mysql/bin as ledir if the directory containing the mysqld_safe script isn't a valid base directory. Now unless I'm mistaken, @libexecdir@ refers to a subdirectory inside /usr/local according to GNU standards.

      Again, this logic is implemented in the mysqld_safe script shipped with MySQL 8.0.33, but not in the one shipped with MariaDB 10.11.2-2

      mysqld_safe (MariaDB 10.11.2-2)

      MY_PWD=`dirname $0`
      MY_PWD=`cd "$MY_PWD"/.. && pwd`
      # Check for the directories we would expect from a binary release install
      if test -n "$MY_BASEDIR_VERSION" -a -d "$MY_BASEDIR_VERSION"
      then
        # BASEDIR is already overridden on command line.  Do not re-set.
      .
      .
      (snipped)
      .
      .
        MY_BASEDIR_VERSION="$MY_PWD"		# Where sbin, share and var are
        ledir="$MY_PWD/sbin"			# Where mysqld is
      # Since we didn't find anything, used the compiled-in defaults
      else
        MY_BASEDIR_VERSION='/usr'
        ledir='/usr/bin'
      fi
      

      As you can see, in MariaDB's version, mysqld_safe falls back to /usr/bin as the ledir whereas MySQL falls back to /usr/local/mysql/bin as implied in MariaDB's documentation.

      mysqld_safe (MySQL 8.0.33)

      #
      # First, try to find BASEDIR and ledir (where mysqld is)
      #
       
      oldpwd="`pwd`"
       
      # Args not parsed yet, check if --basedir was given on command line
      find_basedir_from_cmdline "$@"
       
      # --basedir is already overridden on command line
      if test -n "$MY_BASEDIR_VERSION" -a -d "$MY_BASEDIR_VERSION" ; then
      .
      .
      (snipped)
      .
      .
        # If we still didn't find anything, use the compiled-in defaults
        if test -z "$MY_BASEDIR_VERSION" ; then
          MY_BASEDIR_VERSION='/usr/local/mysql'
          ledir='/usr/local/mysql/bin'
        fi
      fi
      

      This once against indicates that MariaDB is using an outdated version of the mysqld_safe script.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              anthony-S93 Anthony Shi
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.