阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

分析MariaDB初始化脚本mysql_install_db

140次阅读
没有评论

共计 17997 个字符,预计需要花费 45 分钟才能阅读完成。

在初始化 MySQL 的过程中经常会碰到各种问题,如

FATAL ERROR: Could not find ./bin/my_print_defaults
ERROR: 1  Can't create/write to file '/root/test/data/mysql/db.MYI' (Errcode: 13 - Permission denied) 

出现这些问题的原因无非是两种,

1> 没有传递合适的参数。

譬如:

[root@localhost ~]# /usr/test/mariadb-10.1.16-linux-x86_64/scripts/mysql_install_db –datadir=/usr/test/mariadb-10.1.16-linux-x86_64/ –user=mysql &

没有指定 basedir,无法找到 my_print_defaults 命令

2> 目录对当前用户没有权限

譬如:

[root@localhost test]# /usr/test/Percona-Server-5.6.31-rel77.0-Linux.x86_64.ssl101/scripts/mysql_install_db –basedir=/usr/test/Percona-Server-5.6.31-rel77.0-Linux.x86_64.ssl101/ –user=mysql

没有指定 datadir,默认是当前目录下的 data 目录。如果放到 /usr 下执行倒是没有问题,/root 目录本身的权限是 500 的。对于其它用户,它是没有权限在 /root 目录及其子目录创建文件的。

下面对 MariaDB 的初始化脚本进行较为详细的解析。

首先定义初始化变量

这里面 ldata 即数据目录,如果在执行 mysql_install_db 脚本时,没有显示指定 –datadir,则 datadir 默认在当前目录下的 data。

basedir=""
builddir=""
ldata="./data"
langdir=""
srcdir=""

args=""
defaults=""
mysqld_opt=""
user=""

force=0
in_rpm=0
ip_only=0
cross_bootstrap=0

定义 usage 函数

在使用 mysql_install_db –help 即输出的是 usage 函数的内容

usage()
{cat <<EOF
Usage: $0 [OPTIONS]
  --basedir=path       The path to the MariaDB installation directory.
  --builddir=path      If using --srcdir with out-of-directory builds, you
                       will need to set this to the location of the build
                       directory where built files reside.
  --cross-bootstrap    For internal use.  Used when building the MariaDB system
                       tables on a different host than the target.
  --datadir=path       The path to the MariaDB data directory.
  --defaults-extra-file=name
                       Read this file after the global files are read.
  --defaults-file=name Only read default options from the given file name.
  --force              Causes mysql_install_db to run even if DNS does not
                       work.  In that case, grant table entries that
                       normally use hostnames will use IP addresses.
  --help               Display this help and exit.                     
  --ldata=path         The path to the MariaDB data directory. Same as
                       --datadir.
  --no-defaults        Don't read default options from any option file.
  --defaults-file=path Read only this configuration file.
  --rpm                For internal use.  This option is used by RPM files
                       during the MariaDB installation process.
  --skip-name-resolve  Use IP addresses rather than hostnames when creating
                       grant table entries.  This option can be useful if
                       your DNS does not work.
  --srcdir=path        The path to the MariaDB source directory.  This option
                       uses the compiled binaries and support files within the
                       source tree, useful for if you don't want to install
                       MariaDB yet and just want to create the system tables.
  --user=user_name     The login username to use for running mysqld.  Files
                       and directories created by mysqld will be owned by this
                       user.  You must be root to use this option.  By default
                       mysqld runs using your current login name and files and
                       directories that it creates will be owned by you.

All other options are passed to the mysqld program

EOF
  exit 1
}

定义打印函数

s_echo()
{if test "$in_rpm" -eq 0 -a "$cross_bootstrap" -eq 0
  then
    echo "$1"
  fi
}

其中 $in_rpm 对应 –rpm 参数,$cross_bootstrap 对应 –cross-bootstrap 参数。

关于这两个参数的作用,可以参考上面 usage 函数中的说明。

在脚本执行失败时,调用的函数

link_to_help()
{echo
  echo "The latest information about mysql_install_db is available at"
  echo "https://mariadb.com/kb/en/installing-system-tables-mysql_install_db"
}

定义参数解析函数

parse_arg()
{echo "$1" | sed -e 's/^[^=]*=//'
}

其中 s 是替换,^ 代表行首定位符,[]代表匹配一组字符里的任意字符,* 匹配 0 个或多个前一字符,[^]代表匹配不在指定范围内的字符。

这个函数实现的效果是截取“=”号后的字符。

譬如,输入的变量是 –basedir=/usr/test,则输出的结果是 /usr/test

 

定义命令行解析函数

parse_arguments()
{# We only need to pass arguments through to the server if we don't
  # handle them here.  So, we collect unrecognized options (passed on
  # the command line) into the args variable.
  pick_args=
  if test "$1" = PICK-ARGS-FROM-ARGV
  then
    pick_args=1
    shift
  fi

  for arg
  do
    case "$arg" in
      --force) force=1 ;;
      --basedir=*) basedir=`parse_arg "$arg"` ;;
      --builddir=*) builddir=`parse_arg "$arg"` ;;
      --srcdir=*)  srcdir=`parse_arg "$arg"` ;;
      --ldata=*|--datadir=*|--data=*) ldata=`parse_arg "$arg"` ;;
      --user=*)
        # Note that the user will be passed to mysqld so that it runs
        # as 'user' (crucial e.g. if log-bin=/some_other_path/
        # where a chown of datadir won't help)
        user=`parse_arg "$arg"` ;;
      --skip-name-resolve) ip_only=1 ;;
      --verbose) verbose=1 ;; # Obsolete
      --rpm) in_rpm=1 ;;
      --help) usage ;;
      --no-defaults|--defaults-file=*|--defaults-extra-file=*)
        defaults="$arg" ;;

      --cross-bootstrap|--windows)
        # Used when building the MariaDB system tables on a different host than
        # the target. The platform-independent files that are created in
        # --datadir on the host can be copied to the target system.
        #
        # The most common use for this feature is in the Windows installer
        # which will take the files from datadir and include them as part of
        # the install package.  See top-level 'dist-hook' make target.
        #
        # --windows is a deprecated alias
        cross_bootstrap=1 ;;

      *)
        if test -n "$pick_args"
        then
          # This sed command makes sure that any special chars are quoted,
          # so the arg gets passed exactly to the server.
          # XXX: This is broken; true fix requires using eval and proper
          # quoting of every single arg ($basedir, $ldata, etc.)
          #args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.-]\),\\\\\1,g'`
          args="$args $arg"
        fi
        ;;
    esac
  done
}

其中,for arg 相当于 for arg in ‘”$@”‘。

PS:

关于 shell 脚本中 $*,$@和 $# 三者的区别:

脚本名称叫 test.sh 传入三个参数: 1 2 3

运行 test.sh 1 2 3 后

$* 为 ”1 2 3″(一起被引号包住)

$@为 ”1″ “2” “3”(分别被包住)

$# 为 3(参数数量)

判断给定的文件是否存在

find_in_basedir()
{case "$1" in
    --dir)
      return_dir=1; shift
      ;;
  esac

  file=$1; shift

  for dir in "$@"
  do
    if test -f "$basedir/$dir/$file"
    then
      if test -n "$return_dir"
      then
        echo "$basedir/$dir"
      else
        echo "$basedir/$dir/$file"
      fi
      break
    fi
  done
}

其中 test - f 是判断给定的文件是否存在,test - n 代表给定的变量是否为非空。

解析命令行参数

正如它注释中提到的,第一次解析的参数的目录在于得到 my_print_defaults 命令的路径。

# Ok, let's go.  We first need to parse arguments which are required by
# my_print_defaults so that we can execute it first, then later re-parse
# the command line to add any extra bits that we need.
parse_arguments "$@"

确认 my_print_defaults 命令的路径

#
# We can now find my_print_defaults.  This script supports:
#
#   --srcdir=path pointing to compiled source tree
#   --basedir=path pointing to installed binary location
#
# or default to compiled-in locations.
#
if test -n "$srcdir" && test -n "$basedir"
then
  echo "ERROR: Specify either --basedir or --srcdir, not both."
  link_to_help
  exit 1
fi
if test -n "$srcdir"
then
  if test -z "$builddir"
  then
    builddir="$srcdir"
  fi
  print_defaults="$builddir/extra/my_print_defaults"
elif test -n "$basedir"
then
  print_defaults=`find_in_basedir my_print_defaults bin extra`
  if test -z "$print_defaults"
  then
    cannot_find_file my_print_defaults $basedir/bin $basedir/extra
    exit 1
  fi
else
  print_defaults="./bin/my_print_defaults"
fi

首先,判断 srcdir 和 basedir 是否指定,如果两者都指定的话,则会报错,在这里,srcdir 指向的是源码包的编译路径,basedir 指向的是二进制包的解压路径。毕竟是两种不同的安装方式,一个是源码安装,一个是二进制压缩包直接解压,两者的目录层次会不一样。

上述脚本的判断逻辑是,如果 $srcdir 指定了,则 my_print_defaults 命令位于 $builddir/extra 中。

如果没有指定 $srcdir,而指定了 $basedir,则 my_print_defaults 要么位于 $basedir/bin 中,要么位于 $basedir/extra 中。如果没有找到该命令,则直接报错退出脚本。

如果 $srcdir 和 $basedir 都没有指定,则 my_print_defaults 默认在当前目录中的 bin 目录下,此时,它假定你是在 $basedir 上执行该初始化命令的。

判断 my_print_defaults 对于当前用户是否有可执行权限

if test ! -x "$print_defaults"
then
  cannot_find_file "$print_defaults"
  exit 1
fi

获取配置文件中 [mysqld] 和[mysql_install_db]区域的值

# Now we can get arguments from the groups [mysqld] and [mysql_install_db]
# in the my.cfg file, then re-run to merge with command line arguments.
parse_arguments `"$print_defaults" $defaults --mysqld mysql_install_db`

既然能执行 my_print_defaults,则可以根据该命令得到配置文件中 [mysqld] 和[mysql_install_db]区域的值

上面的 $defaults 是之前定义的 –no-defaults,–defaults-file,–defaults-extra-file

譬如如果 –defaults-file=/usr/local/mysql,则 defaults=”–defaults-file=/usr/local/mysql”。

对于下面这个命令 ”$print_defaults” $defaults –mysqld mysql_install_db,针对于我本机的环境,它实际上执行的是

# /usr/test/mariadb-10.1.16-linux-x86_64/bin/my_print_defaults –defaults-file=/usr/test/mariadb-10.1.16-linux-x86_64/my.cnf –mysqld mysql_install_db

–port=3308
–basedir=/usr/test/mariadb-10.1.16-linux-x86_64
–datadir=/usr/test/mariadb-10.1.16-linux-x86_64/data
–skip-external-locking
–user=mysql
–key_buffer_size=16K
–max_allowed_packet=1M
–table_open_cache=4
–sort_buffer_size=64K
–read_buffer_size=256K
–read_rnd_buffer_size=256K
–net_buffer_length=2K
–thread_stack=240K
–server-id=1

其中,–mysqld 前面不用带“–”也行。

但是 5.6.31 MySQL 社区版的 my_print_defaults 只支持不带“–”的 mysqld,由此可见,两者在语法方面还是有一定的差别的。

根据上面的输出的结果,则脚本中的这个命令等价于

parse_arguments –port=3308 –basedir=/usr/test/mariadb-10.1.16-linux-x86_64 –datadir=/usr/test/mariadb-10.1.16-linux-x86_64/data –skip-external-locking –user=mysql –key_buffer_size=16K –max_allowed_packet=1M –table_open_cache=4 –sort_buffer_size=64K –read_buffer_size=256K –read_rnd_buffer_size=256K –net_buffer_length=2K –thread_stack=240K –server-id=1

执行完上面这个命令后,实际上只有三个参数传递进来了,–basedir,–datadir,–user

再次执行命令解析函数

parse_arguments PICK-ARGS-FROM-ARGV "$@"

这次调用的目的是捕捉命令行中传递的其它参数。

譬如执行如下命令

# /usr/test/mariadb-10.1.16-linux-x86_64/scripts/mysql_install_db –defaults-file=/usr/test/mariadb-10.1.16-linux-x86_64/my.cnf –basedir=/usr/test/mariadb-10.1.16-linux-x86_64/ 123 456 789

则 args 中的值为 ’ 123 456 789′

定义初始化所需文件的路径

# Configure paths to support files
if test -n "$srcdir"
then
  basedir="$builddir"
  bindir="$basedir/client"
  extra_bindir="$basedir/extra"
  mysqld="$basedir/sql/mysqld"
  langdir="$basedir/sql/share/english"
  pkgdatadir="$srcdir/scripts"
  scriptdir="$srcdir/scripts"
elif test -n "$basedir"
then
  bindir="$basedir/bin"
  extra_bindir="$bindir"
  mysqld=`find_in_basedir mysqld libexec sbin bin`
  if test -z "$mysqld"
  then
    cannot_find_file mysqld $basedir/libexec $basedir/sbin $basedir/bin
    exit 1
  fi
  langdir=`find_in_basedir --dir errmsg.sys share/english share/mysql/english`
  if test -z "$langdir"
  then
    cannot_find_file errmsg.sys $basedir/share/english $basedir/share/mysql/english
    exit 1
  fi
  pkgdatadir=`find_in_basedir --dir fill_help_tables.sql share share/mysql`
  if test -z "$pkgdatadir"
  then
    cannot_find_file fill_help_tables.sql $basedir/share $basedir/share/mysql
    exit 1
  fi
  scriptdir="$basedir/scripts"
else
  basedir="."
  bindir="./bin"
  extra_bindir="$bindir"
  mysqld="./bin/mysqld"
  pkgdatadir="./share"
  scriptdir="./bin"
fi

也是分三种情况,即指定了 srcdir,指定了 basedir,或者两者都没有指定。

在这里,说说第二种和第三种情况

若指定了 basedir,则会定义三个路径

1> mysqld,mysqld 一般会存放在如下三个路径中,$basedir/libexec/mysqld,$basedir/sbin/mysqld,$basedir/bin/mysqld

2> langdir,该路径是 errmsg.sys 的存放路径,该文件与 mysql 的错误代码有关。升级时该文件即需要更新

3> pkgdatadir,该路径存放 mysql 库,performance_schema 库的创建脚本,不仅仅是 fill_help_tables.sql。

如果没有指定 srcdir 和 basedir,则默认将当前路径设置为 basedir。

定义数据库创建脚本的路径

在上面路径确认好的情况下,进一步确认脚本是否存在,mysqld 是否有可执行权限,确认 errmsg.sys 是否存在

# Set up paths to SQL scripts required for bootstrap
fill_help_tables="$pkgdatadir/fill_help_tables.sql"
create_system_tables="$pkgdatadir/mysql_system_tables.sql"
create_system_tables2="$pkgdatadir/mysql_performance_tables.sql"
fill_system_tables="$pkgdatadir/mysql_system_tables_data.sql"
maria_add_gis_sp="$pkgdatadir/maria_add_gis_sp_bootstrap.sql"

for f in "$fill_help_tables" "$create_system_tables" "$create_system_tables2" "$fill_system_tables" "$maria_add_gis_sp"
do
  if test ! -f "$f"
  then
    cannot_find_file "$f"
    exit 1
  fi
done

if test ! -x "$mysqld"
then
  cannot_find_file "$mysqld"
  exit 1
fi

if test -n "$langdir"
then
  if test ! -f "$langdir/errmsg.sys"
  then
    cannot_find_file "$langdir/errmsg.sys"
    exit 1
  fi
  mysqld_opt="--lc-messages-dir=$langdir/.."
else
  mysqld_opt="--lc-messages=en_US"
fi

确认主机名以及主机名是否有效

它的判断逻辑是如果 –cross-bootstrap,–rpm,–force 没有显式指定的话,则查看主机名是否能被解析成 ip。

首先解析的是主机名,如果没有解析成功,则解析 localhost

# Try to determine the hostname
hostname=`hostname`

# Check if hostname is valid
if test "$cross_bootstrap" -eq 0 -a "$in_rpm" -eq 0 -a "$force" -eq 0
then
  resolved=`"$extra_bindir/resolveip" $hostname 2>&1`
  if test $? -ne 0
  then
    resolved=`"$extra_bindir/resolveip" localhost 2>&1`
    if test $? -ne 0
    then
      echo "Neither host'$hostname'nor'localhost'could be looked up with"
      echo "'$extra_bindir/resolveip'"
      echo "Please configure the'hostname'command to return a correct"
      echo "hostname."
      echo "If you want to solve this at a later stage, restart this script"
      echo "with the --force option"
      link_to_help
      exit 1
    fi
    echo "WARNING: The host'$hostname'could not be looked up with resolveip."
    echo "This probably means that your libc libraries are not 100 % compatible"
    echo "with this binary MariaDB version. The MariaDB daemon, mysqld, should work"
    echo "normally with the exception that host name resolving will not work."
    echo "This means that you should use IP addresses instead of hostnames"
    echo "when specifying MariaDB privileges !"
  fi
fi 

如果指定了 –skip-name-resolve 参数,则将主机名解析为 IP

if test "$ip_only" -eq 1
then
  hostname=`echo "$resolved" | awk '/ /{print $6}'`
fi

创建数据目录

# Create database directories
for dir in "$ldata" "$ldata/mysql" "$ldata/test"
do
  if test ! -d "$dir"
  then
    if ! `mkdir -p "$dir"`
    then
      echo "Fatal error Can't create database directory '$dir'"
      link_to_help
      exit 1
    fi
    chmod 700 "$dir"
  fi
  if test -n "$user"
  then
    chown $user "$dir"
    if test $? -ne 0
    then
      echo "Cannot change ownership of the database directories to the'$user'"
      echo "user.  Check that you have the necessary permissions and try again."
      exit 1
    fi
  fi
done

可以看到,会创建三个目录,datadir,以及 datadir 下的 mysql 目录和 test 目录,这个对应 mysql 库和 test 库。

如果目录不存在,则创建,并将目录权限设置为 700,如果指定了 –user 参数,则将目录的属主修改为指定的用户

如果指定了 –user 参数,则添加到之前的参数列表中

if test -n "$user"
then
  args="$args --user=$user"
fi

–cross-bootstrap 参数是用于跨平台启动的,具体可以参考上面 parse_arguments 函数中对该参数的解释

如果指定了该参数,则会过滤初始化脚本中有关当前主机名的设置。

# When doing a "cross bootstrap" install, no reference to the current
# host should be added to the system tables.  So we filter out any
# lines which contain the current host name.
if test $cross_bootstrap -eq 1
then
  filter_cmd_line="sed -e'/@current_hostname/d'"
else
  filter_cmd_line="cat"
fi 

配置 mysqld 命令行

感觉 MYSQLD_BOOTSTRAP 变量出现得莫名其妙,上文中也没给出任何定义

这样执行的效果是如果定义了 MYSQLD_BOOTSTRAP,则 $MYSQLD_BOOTSTRAP 值赋给 mysqld_bootstrap,如果没有定义,则 $mysqld 的值赋给 mysqld_bootstrap

# Configure mysqld command line
mysqld_bootstrap="${MYSQLD_BOOTSTRAP-$mysqld}"
mysqld_install_cmd_line()
{"$mysqld_bootstrap" $defaults "$mysqld_opt" --bootstrap \
  "--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --enforce-storage-engine="" \
  $args --max_allowed_packet=8M \
  --net_buffer_length=16K
}

若以如下方式初始化 mysql

# /usr/test/mariadb-10.1.16-linux-x86_64/scripts/mysql_install_db –defaults-file=/usr/test/mariadb-10.1.16-linux-x86_64/my.cnf –basedir=/usr/test/mariadb-10.1.16-linux-x86_64/

则上面这个函数相当于

/usr/test/mariadb-10.1.16-linux-x86_64/bin/mysqld –defaults-file=/usr/test/mariadb-10.1.16-linux-x86_64/my.cnf –lc-messages-dir=/usr/test/mariadb-10.1.16-linux-x86_64/share –bootstrap –basedir=/usr/test/mariadb-10.1.16-linux-x86_64/ –datadir=/usr/test/mariadb-10.1.16-linux-x86_64/data –log-warnings=0 –enforce-storage-engine=”” –user=mysql –max_allowed_packet=8M –net_buffer_length=16K

执行数据库初始化脚本

分为三部分

1> 系统表

2> fill_help_tables.sql,该文件用于生成 help contents 的内容

3> OpenGIS

其中,–bootstrap 代表 Used by mysql installation scripts。

虽然同样是执行的 mysqld 命令,但因为指定了 –bootstrap 参数,只是执行了数据库初始化脚本中的命令,并没有启动数据库。

# Create the system and help tables by passing them to "mysqld --bootstrap"
s_echo "Installing MariaDB/MySQL system tables in'$ldata'..."
if {echo "use mysql;"; cat "$create_system_tables" "$create_system_tables2" "$fill_system_tables"; } | eval "$filter_cmd_line" | mysqld_install_cmd_line > /dev/null
then
  s_echo "OK"
else
  echo
  echo "Installation of system tables failed!  Examine the logs in"
  echo "$ldata for more information."
  echo
  echo "The problem could be conflicting information in an external"
  echo "my.cnf files. You can ignore these by doing:"
  echo
  echo "    shell> $scriptdir/scripts/mysql_install_db --defaults-file=~/.my.cnf"
  echo
  echo "You can also try to start the mysqld daemon with:"
  echo
  echo "    shell> $mysqld --skip-grant --general-log &"
  echo
  echo "and use the command line tool $bindir/mysql"
  echo "to connect to the mysql database and look at the grant tables:"
  echo
  echo "    shell> $bindir/mysql -u root mysql"
  echo "    mysql> show tables;"
  echo
  echo "Try'mysqld --help'if you have problems with paths.  Using"
  echo "--general-log gives you a log in $ldata that may be helpful."
  link_to_help
  echo "MariaDB is hosted on launchpad; You can find the latest source and"
  echo "email lists at http://launchpad.net/maria"
  echo
  echo "Please check all of the above before submitting a bug report"
  echo "at http://mariadb.org/jira"
  echo
  exit 1
fi

s_echo "Filling help tables..."
if {echo "use mysql;"; cat "$fill_help_tables"; } | mysqld_install_cmd_line > /dev/null
then
  s_echo "OK"
else
  echo
  echo "WARNING: HELP FILES ARE NOT COMPLETELY INSTALLED!"
  echo "The \"HELP\"command might not work properly."
fi

s_echo "Creating OpenGIS required SP-s..."
if {echo "use test;"; cat "$maria_add_gis_sp"; } | mysqld_install_cmd_line > /dev/null
then
  s_echo "OK"
else
  echo
  echo "WARNING: OPENGIS REQUIRED SP-S WERE NOT COMPLETELY INSTALLED!"
  echo "GIS extentions might not work properly."
fi 

输出相关信息

针对的是 –cross-bootstrap,–srcdir,–rpm 这三个参数。

# Don't output verbose information if running inside bootstrap or using
# --srcdir for testing.  In such cases, there's no end user looking at
# the screen.
if test "$cross_bootstrap" -eq 0 && test -z "$srcdir"
then
  s_echo
  s_echo "To start mysqld at boot time you have to copy"
  s_echo "support-files/mysql.server to the right place for your system"

  echo
  echo "PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !"
  echo "To do so, start the server, then issue the following commands:"
  echo
  echo "'$bindir/mysqladmin'-u root password'new-password'"
  echo "'$bindir/mysqladmin'-u root -h $hostname password'new-password'"
  echo
  echo "Alternatively you can run:"
  echo "'$bindir/mysql_secure_installation'"
  echo
  echo "which will also give you the option of removing the test"
  echo "databases and anonymous user created by default.  This is"
  echo "strongly recommended for production servers."
  echo
  echo "See the MariaDB Knowledgebase at http://mariadb.com/kb or the"
  echo "MySQL manual for more instructions."

  if test "$in_rpm" -eq 0
  then
    echo
    echo "You can start the MariaDB daemon with:"
    echo "cd'$basedir'; $bindir/mysqld_safe --datadir='$ldata'"
    echo
    echo "You can test the MariaDB daemon with mysql-test-run.pl"
    echo "cd'$basedir/mysql-test'; perl mysql-test-run.pl"
  fi

  echo
  echo "Please report any problems at http://mariadb.org/jira"
  echo
  echo "The latest information about MariaDB is available at http://mariadb.org/."
  echo "You can find additional information about the MySQL part at:"
  echo "http://dev.mysql.com"
  echo "Support MariaDB development by buying support/new features from MariaDB"
  echo "Corporation Ab. You can contact us about this at sales@mariadb.com."
  echo "Alternatively consider joining our community based development effort:"
  echo "http://mariadb.com/kb/en/contributing-to-the-mariadb-project/"
  echo
fi

exit 0 

总结:

一、因为 MySQL 社区版本以及 Percona 版本的 mysql_install_db 都是用 perl 写的,只有 MariaDB 是 shell 写的,个人对 shell 比较熟悉,所以就对 MariaDB 的进行分析了。毕竟,这三个版本的初始化逻辑大同小异。

二、MariaDB 的初始化的流程如下(为了简化,在这里就不考虑源码编译的情况,只考虑二进制包的初始化):

1. 首先判断传递的参数中是否有 basedir,如果有,则查找 my_print_defaults 命令所在的路径,如果没有找到,则直接报错退出脚本。

2. 如果没有传递 basedir 参数,则将当前目录下的 bin 目录设置为 my_print_defaults 所在的路径。

3. 判断 my_print_defaults 对于当前用户是否有可执行权限,如果没有,也直接报错退出。

4. 根据 my_print_defaults,查看配置文件中 [mysqld] 和[mysql_install_db]的内容,并通过 parse_arguments 参数赋给对应的变量

5. 查找 mysqld 的路径,如果没有找到,直接退出

6. 查看 errmsg.sys 的路径,如果没有找到,直接退出

7. 查看初始化 SQL 脚本的的路径,如果没有找到,直接退出

8. 确认 mysqld 是否有可执行权限

9. 设置 –lc-messages-dir 目录的位置

10. 确认主机名并解析成 IP

11. 创建数据目录,数据目录下的 mysql,test 目录,设置权限和属主

12. 初始化 mysql

MySQL 数据库初始化的正确姿态

1. 显式的指定 –basedir,–datadir,–user,只需指定这三个参数,即能初始化成功。

2. 如果没有指定 –datadir,则默认是执行初始化命令的当前目录下的 data 目录

3. 当然,–basedir 也不是必需的,可以切换到二进制包的解压目录执行初始化命令,此时,也可初始化成功。

Linux 系统教程:如何检查 MariaDB 服务端版本  http://www.linuxidc.com/Linux/2015-08/122382.htm

MariaDB Proxy 读写分离的实现 http://www.linuxidc.com/Linux/2014-05/101306.htm

Linux 下编译安装配置 MariaDB 数据库的方法 http://www.linuxidc.com/Linux/2014-11/109049.htm

CentOS 系统使用 yum 安装 MariaDB 数据库 http://www.linuxidc.com/Linux/2014-11/109048.htm

安装 MariaDB 与 MySQL 并存 http://www.linuxidc.com/Linux/2014-11/109047.htm

Ubuntu 上如何将 MySQL 5.5 数据库迁移到 MariaDB 10  http://www.linuxidc.com/Linux/2014-11/109471.htm

[翻译]Ubuntu 14.04 (Trusty) Server 安装 MariaDB  http://www.linuxidc.com/Linux/2014-12/110048htm

MariaDB 的详细介绍:请点这里
MariaDB 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-08/133894.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计17997字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中