MariaDB多实例

2018-05-15|Categories: Database|

什么是MariaDB多实例

所谓「MariaDB多实例」,官方称为「Multiple Instances of MariaDB」,或者是「Multiple Copies of MariaDB」。从字面上就可以看出,这是在同一台主机上同时运行多个互不干涉的MariaDB-server。

说得更详细一些,每一个运行中的MariaDB-server都有各自的--basedir--datadir--defaults-file--pid-file--socket,就像下面这样:

$ /bin/ps o user,pid,cmd -p `pgrep mysqld` | tail -n +2 | sort -k3
root      25646 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/mariadb --pid-file=/data/mariadb/vm71.pid
root      52764 /bin/sh /usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mmi/33061/my.cnf
root      53038 /bin/sh /usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mmi/33062/my.cnf
mysql     25761 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mariadb --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/mariadb/vm71.err --pid-file=/data/mariadb/vm71.pid --socket=/tmp/mysql.sock --port=3306
mysql     52849 /usr/local/mysql/bin/mysqld --defaults-file=/data/mmi/33061/my.cnf --basedir=/usr/local/mysql --datadir=/data/mmi/33061/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/mmi/33061/mariadb.log.err --pid-file=/data/mmi/33061/mariadb.pid --socket=/data/mmi/33061/mariadb.sock --port=33061
mysql     53123 /usr/local/mysql/bin/mysqld --defaults-file=/data/mmi/33062/my.cnf --basedir=/usr/local/mysql --datadir=/data/mmi/33062/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/mmi/33062/mariadb.log.err --pid-file=/data/mmi/33062/mariadb.pid --socket=/data/mmi/33062/mariadb.sock --port=33062

配置MariaDB多实例

第一步自然是安装MariaDB-server,链接的文章内介绍了三种安装方式,我采用的是二进制安装,安装过程不再赘述。

准备每一个实例的专用目录

实现多实例的关键是,每一个实例都有专用目录存放自己的数据库文件、配置文件、启动脚本,因此首先需要创建这些专用目录:

# mmi = MariaDB Multiple Instances
# 33061是本次实验中第一个实例的监听端口,作为专用目录名称正合适
mkdir -pv /data/mmi/{33061,33062}/data

chown -R mysql. /data/mmi/
chmod -R 770 /data/mmi/

初始化每个实例的数据库文件

# 必须在这个目录执行`./scripts/mysql_install_db`脚本
cd /usr/local/mysql/

./scripts/mysql_install_db --datadir=/data/mmi/33061/data --user=mysql
./scripts/mysql_install_db --datadir=/data/mmi/33062/data --user=mysql

配置每个实例(my.cnf)

cd /data/mmi/33061/

vi my.cnf

粘贴以下内容:

[mysqld]
port           = 33061
datadir        = /data/mmi/33061/data
socket         = /data/mmi/33061/mariadb.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links = 0

[mysqld_safe]
log-error      = /data/mmi/33061/mariadb.log.err
pid-file       = /data/mmi/33061/mariadb.pid

对于第二个实例(33062),把my.cnf复制到/data/mmi/33062/,然后把其中所有的33061替换为33062

cp my.cnf /data/mmi/33062/

sed -i 's/33061/33062/' /data/mmi/33062/my.cnf

编辑每个实例的启动脚本

vi mysqld

粘贴以下内容:

#!/bin/bash

port="33061"
mysql_user="root"

# 为了防止MariaDB-server被随意关闭,要求关闭时必须输入密码,
# 因为本次实验没有设置密码,所以变量的值为空
mysql_pwd=""

cmd_path="/usr/local/mysql/bin"
mysql_basedir="/data/mmi"
mysql_sock="${mysql_basedir}/${port}/mariadb.sock"

function_start_mysql()
{
    if [ ! -e "$mysql_sock" ];then
      printf "Starting MySQL...\n"
      ${cmd_path}/mysqld_safe --defaults-file=${mysql_basedir}/${port}/my.cnf &>/dev/null &
    else
      printf "MySQL is running...\n"
      exit
    fi
}

function_stop_mysql()
{
    if [ ! -e "$mysql_sock" ];then
       printf "MySQL is stopped...\n"
       exit
    else
       printf "Stoping MySQL...\n"
     
       # 1. 用`mysqladmin shutdown`安全关闭MariaDB-server,防止数据损坏或丢失
       # 2. 关闭时需要密码,防止被随意关闭
       # 3. `man mysqladmin`明确要求,`-p`选项与密码之间「不能」有空格,
       #    `man mysql`也有同样的要求。
       ${cmd_path}/mysqladmin -u ${mysql_user} -p${mysql_pwd} -S ${mysql_sock} shutdown
   fi
}

function_restart_mysql()
{
    printf "Restarting MySQL...\n"
    function_stop_mysql
    sleep 2
    function_start_mysql
}

case $1 in
start)
    function_start_mysql
;;
stop)
    function_stop_mysql
;;
restart)
    function_restart_mysql
;;
*)
    printf "Usage: ${mysql_basedir}/${port}/mysqld {start|stop|restart}\n"
esac

因为脚本中会明文保存密码,所以必须给脚本设置严格的权限:

chmod 700 mysqld

同样把脚本复制到第二个实例目录,然后把port="33061"这一行修改成port="33062"

启动实例

/data/mmi/33061/mysqld start
/data/mmi/33062/mysqld start

查看进程信息:

$ /bin/ps o user,pid,cmd -p `pgrep mysqld`
USER        PID CMD
root      25646 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/mariadb --pid-file=/data/mariadb/vm71.pid
mysql     25761 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mariadb --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-err
root      52764 /bin/sh /usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mmi/33061/my.cnf
mysql     52849 /usr/local/mysql/bin/mysqld --defaults-file=/data/mmi/33061/my.cnf --basedir=/usr/local/mysql --datadir=/data/mmi/33061/data --plugin-dir=/usr
root      53038 /bin/sh /usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mmi/33062/my.cnf
mysql     53123 /usr/local/mysql/bin/mysqld --defaults-file=/data/mmi/33062/my.cnf --basedir=/usr/local/mysql --datadir=/data/mmi/33062/data --plugin-dir=/usr

上面的输出有两点需要说明:

  • PID为2564625761的进程不是在本次实验中启动的,但正好展示了多实例的工作状态。
  • 输出内容超出屏幕宽度的部分被截断了,完整的输出详见本文开头。

连接实例

从本机连接某个实例时,必须指定具体的Socket文件:

$ mysql -S /data/mmi/33061/mariadb.sock -e 'show variables like "port";'
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| port          | 33061 |
+---------------+-------+

$ mysql -S /data/mmi/33062/mariadb.sock -e 'show variables like "port";'
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| port          | 33062 |
+---------------+-------+

停止(关闭)实例

# 脚本内定义了停止操作需要输入密码,但密码变量为空,
# 所以执行脚本时还会提示输入密码,因为本次实验未设置密码,直接回车即可
$ /data/mmi/33061/mysqld stop
Stoping MySQL...
Enter password:

$ /data/mmi/33062/mysqld stop

此时再查看进程信息可以看到,本次实验配置的两个实例已经停止:

$ /bin/ps o user,pid,cmd -p `pgrep mysqld`
USER        PID CMD
root      25646 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/mariadb --pid-file=/data/mariadb/vm71.pid
mysql     25761 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mariadb --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-err

至此,MariaDB多实例已实现。

Leave A Comment