MySQL多实例
mysql多实例,简单理解就是在一台服务器上,mysql服务开启多个不同的端口(如3306、3307,3308),运行多个服务进程。这些 mysql 服务进程通过不同的 socket来监听不同的数据端口,进而互不干涉的提供各自的服务。
在同一台服务器上,mysql 多实例会去共用一套 mysql 应用程序,因此在部署 mysql的时候只需要部署一次 mysql程序即可,无需多次部署。但是,mysql多实例之间会各自使用不同的 my.cnf 配置文件、启动程序和数据文件。在提供服务方面,mysql多实例在逻辑上看起来是各自独立,互不干涉的,并且多个实例之间是根据配置文件的设定值,来获取相关服务器的硬件资源。
多实例应用场景
-
当一个公司业务访问量不太大,又想节俭成本,并且还希望不同业务的数据库服务能够各自尽量独立,提供服务能够互相不受影响。另外还需要应用主从同步等技术来提供数据库备份或读写分离服务,以及方便后期业务量增大时,数据库架构的扩展和迁移。
-
公司业务访问量不是太大的时候,服务器的资源基本都是过剩状态。此时就很适合 mysql 多实例的应用。如果对 SQL语句 优化做的比较好,mysql 多实例 是一个很值得去使用的技术。
-
测试环境,公司中会需要数据库环境来测试业务,在单机上部署多实例也能够节省成本
MySQL多实例实现方式
mysql 多实例常规来讲,有三种方案可以实现,这三种方案各有利弊,如下:
- 基于多配置文件通过使用多个配置文件来启动不同的进程,以此来实现多实例。
优点:逻辑简单,配置简单
缺点:管理起来不方便
- 基于mysqld_multi通过官方自带的 mysqld_multi 工具,使用单独配置文件来实现多实例
优点: 便于集中管理管理
缺点: 不方便针对每个实例配置进行定制
- 基于IM使用 MySQL 实例管理器(MYSQLMANAGER),这个方法好像比较好不过也有点复杂
优点:便于集中管理
缺点:耦合度高。IM一挂,实例全挂
不方便针对每个实例配置进行定制
本章内容采用第一种方式来是实现,(个人倾向于这种方式),数据库采用mariadb来代替mysql,过程都一样
系统与安装版本信息 操作系统:Centos6.9 数据库:mariadb-10.2.15.tar.gz 三个实例:3306,3307,3308
MySQL多实例安装
安装mysql
-
安装依赖包
yum install bison bison-devel zlib-devel libcurl-devel libarchive-devel boost-devel gcc gcc-c++ cmake libevent-devel gnutls-devel libaio-devel openssl-devel ncurses-devel libxml2-devel
创建mysql用户组
useradd -r mysql
创建实例数据库目录 各实例的数据库目录,配置文件目录,启动程序目录都存放在单独的目录位置,结构如下:
1[root@localhost ~]# mkdir -p /data/mysql/{3306,3307,3308}/{data,etc,log,socket,bin} 2[root@localhost ~]# tree /data 3/data 4├── lost+found 5└── mysql 6 ├── 3306 7 │ ├── bin 8 │ ├── data 9 │ ├── etc 10 │ ├── log 11 │ └── socket 12 ├── 3307 13 │ ├── bin 14 │ ├── data 15 │ ├── etc 16 │ ├── log 17 │ └── socket 18 ├── 3308 19 │ ├── bin 20 │ ├── data 21 │ ├── etc 22 │ ├── log 23 │ └── socket 24 └── mysqld
解压安装源码包
1[root@localhost ~]# tar zxvf mariadb-10.2.15 2[root@localhost ~]# cd mariadb-10.2.15 3 4#编译 5cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DCMAKE-USER=mysql -DCMAKE-GROUP=mysql -DMYSQL_DATADIR=/data/mysql -DWITHOUT_TOKUDB=1
如果执行cmake提示:CMake Error at storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake:183 (message): 添加编译参数:-DWITHOUT_TOKUDB=1
1make -j 4 2make install
安装成功后先不初始化,把配置文件,启动脚本文件都配置完成后再执行初始化
复制配置文件到各实例的etc目录下
配置文件在源码包解压目录下
1[root@localhost support-files]# cp my-huge.cnf /data/mysql/3306/etc/my.cnf 2[root@localhost support-files]# cp my-huge.cnf /data/mysql/3307/etc/my.cnf 3[root@localhost support-files]# cp my-huge.cnf /data/mysql/3308/etc/my.cnf
修改配置文件内容,3306,3307,3308各实例配置文件修改my.cnf内容,修改端口,socket路径,数据存放目录等
1[client] 2#password = your_password 3port = 3306 4socket = /data/mysql/3306/socket/mysql.sock 5 6[mysqld] 7port = 3306 8socket = /data/mysql/3306/socket/mysql.sock 9datadir=/data/mysql/3306
同样,3307,3308实例也要修改相同的配置
编写服务启动脚本
1#!/bin/bash 2 3port=3306 4mysql_user="root" 5mysql_pwd="" 6cmd_path="/usr/local/mysql/bin" 7mysql_basedir="/data/mysql" 8mysql_sock="${mysql_basedir}/${port}/socket/mysql.sock" 9 10function_start_mysql() 11{ 12 if [ ! -e "$mysql_sock" ];then 13 printf "Starting MySQL...\n" 14 ${cmd_path}/mysqld_safe --defaults-file=${mysql_basedir}/${port}/etc/my.cnf &> /dev/null & 15 else 16 printf "MySQL is running...\n" 17 exit 18 fi 19} 20 21 22function_stop_mysql() 23{ 24 if [ ! -e "$mysql_sock" ];then 25 printf "MySQL is stopped...\n" 26 exit 27 else 28 printf "Stoping MySQL...\n" 29# ${cmd_path}/mysqladmin -u ${mysql_user} -S ${mysql_sock} shutdown 30 ${cmd_path}/mysqladmin -u ${mysql_user} -p${mysql_pwd} -S ${mysql_sock} shutdown 31 fi 32} 33 34 35function_restart_mysql() 36{ 37 printf "Restarting MySQL...\n" 38 function_stop_mysql 39 sleep 2 40 function_start_mysql 41} 42 43case $1 in 44start) 45 function_start_mysql 46;; 47stop) 48 function_stop_mysql 49;; 50restart) 51 function_restart_mysql 52;; 53*) 54 printf "Usage: ${mysql_basedir}/${port}/bin/mysqld {start|stop|restart}\n" 55esac
上面的脚本要准备三份,因为mysql实例是各自独立管理的,将上面的脚本参数port变量修改成3307,3308即可,放在 各自实例的bin目录,服务启动是从各自实例的bin目录下执行这脚本
1port=3307 2mysql_user="root" 3mysql_pwd="" 4cmd_path="/usr/local/mysql/bin" 5mysql_basedir="/data/mysql" 6mysql_sock="${mysql_basedir}/${port}/socket/mysql.sock"
初始化数据库
1[root@localhost mysql]# scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ --datadir=/data/mysql/3306/data 2 3[root@localhost mysql]# scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ --datadir=/data/mysql/3307/data 4 5[root@localhost mysql]# scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ --datadir=/data/mysql/3308/data
修改mysql实例目录属主
chown -R mysql:mysql /data/mysql
启动各实例服务
1[root@localhost ~]# /data/mysql/3306/bin/mysqld start 2[root@localhost ~]# /data/mysql/3307/bin/mysqld start 3[root@localhost ~]# /data/mysql/3308/bin/mysqld start 4 5 6[root@localhost mysql]# ss -tnl 7State Recv-Q Send-Q Local Address:Port Peer Address:Port 8LISTEN 0 80 :::3306 :::* 9LISTEN 0 80 :::3307 :::* 10LISTEN 0 80 :::3308 :::* 11LISTEN 0 128 :::22 :::*
测试登录
1[root@localhost ~]# mysql -S /data/mysql/3306/socket/mysql.sock 2Welcome to the MariaDB monitor. Commands end with ; or \g. 3Your MariaDB connection id is 9 4Server version: 10.2.15-MariaDB-log Source distribution 5 6Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. 7 8Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 9 10MariaDB [(none)]>
至此mysql的多实例安装完成,在这种多实例的环境下,可以单独使用个实例进行数据存储,也可以将各实例配置成主从架构进行使用,下面顺便把mysql的主从也介绍使实现一下,关于mysql的主从架构,以后会专门研究各种功能,这里只简单实现,能够帮助理清主从复制的工作过程和配置过程。
MySQL多实例主从复制
在开始主从配置之前先简单介绍一下mysql的主从复制原理, mysql复制原理大致如下: 1,mysql主数据库在事物提交时会把数据变更作为事件events记录在二进制日志文件bin-log中,mysql主库上的sync_binlog参数控制bin-log日志刷新到磁盘
2,主库推送二进制日志文件bin-log中的事件到从库的中继日志Relay Log ,之后从库根据中继日志Relay log重写数据操作将数据写入从库,以此达到主库和从库的数据一致
mysql复制过程中通过3个线程来完成复制操作:其中binlog dump线程在主库上,I/O线程和SQL线程在从库上,当在从库上启动复制(START SLAVE)时,首先会I/O线程连接主库,(连接主库用户用主库创建),主库随后创建binlog dump线程读取数据库事件(binlog日志)并发送给I/O线程,I/O获取到binlog日志数据后更新到从库的中继日志Relay log中,从库上的SQL线程读取中继日志Relay log 中数据写入本地数据库,最终完成主从复制。

一主多从的实现
本文实现一主多重的方式,即上面的3个mysql实例,3306实例作为主库,3307和3308作为从库,实现主从复制的最为关键的是日志文件的设置,主库必须要开启二进制日志,从库要关闭二进制,并且开启中继日志relay log,要点如下:
- 主库创建提供从库的同步用户
- 主库开启二进制日志
- 从库开启中继日志relay log,并关闭二进制日志功能
- 主从之间的server-id不能相同
- 主从时间同步 (由于在同一台主机,步奏略过)
配置主从库实例的配置文件
查看mysql是否开启二进制和中继日志
1MariaDB [(none)]> show variables like 'log_bin'; 2+---------------+-------+ 3| Variable_name | Value | 4+---------------+-------+ 5| log_bin | ON | 6+---------------+-------+ 71 row in set (0.00 sec) 8 9 10MariaDB [(none)]> show variables like 'relay_log'; 11+---------------+-------+ 12| Variable_name | Value | 13+---------------+-------+ 14| relay_log | | 15+---------------+-------+ 161 row in set (0.00 sec)
mysql安装默认会启用二进制日志,但么有启动relay log,所以主库上无需设置,从库需要开启中继日志: 编辑实例3307,3308的my.cnf关闭bin-log,开启中继日志,修改server-id
3307实例:
1#log-bin=mysql-bin 2relay-log=relay-log 3server-id = 2
3308实例:
1#log-bin=mysql-bin 2relay-log=relay-log 3server-id = 3
修改后要重启3307,3308实例
1[root@localhost ~]# /data/mysql/3307/bin/mysqld restart 2Restarting MySQL... 3Stoping MySQL... 4Enter password: 5Starting MySQL... 6 7 8[root@localhost ~]# /data/mysql/3308/bin/mysqld restart 9Restarting MySQL... 10Stoping MySQL... 11Enter password: #这里提示要输入密码,因为中定义了要输入密码 12Starting MySQL...
重启从库实例后检查日志启用情况
1MariaDB [(none)]> show variables like 'relay_log'; 2+---------------+-----------+ 3| Variable_name | Value | 4+---------------+-----------+ 5| relay_log | relay-log | 6+---------------+-----------+ 71 row in set (0.00 sec) 8 9MariaDB [(none)]> show variables like 'log_bin'; 10+---------------+-------+ 11| Variable_name | Value | 12+---------------+-------+ 13| log_bin | OFF | 14+---------------+-------+ 151 row in set (0.00 sec)
主库创建同步复制的用户
1MariaDB [(none)]> grant replication slave on *.* to yufu@'192.168.%.%' identified by '123456'; 2Query OK, 0 rows affected (0.00 sec) 3 4MariaDB [(none)]> flush privileges; 5Query OK, 0 rows affected (0.00 sec)
查看主库的bin-log日志记录位置节点 因为在从库中使用change master to 指令连接主库时要指定连接时主库的bin-log日志记录位置节点。
1MariaDB [(none)]> show master status; 2+------------------+----------+--------------+------------------+ 3| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | 4+------------------+----------+--------------+------------------+ 5| mysql-bin.000001 | 645 | | | 6+------------------+----------+--------------+------------------+ 71 row in set (0.00 sec)
从库连接主库
登录到从库3307实例:
1MariaDB [(none)]> change master to master_host='192.168.214.141',master_user='yufu',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=645; 2Query OK, 0 rows affected (0.11 sec) 3 4MariaDB [(none)]> flush privileges; 5Query OK, 0 rows affected (0.01 sec)
登录到从库3308实例:
1MariaDB [(none)]> change master to master_host='192.168.214.141',master_user='yufu',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=645; 2Query OK, 0 rows affected (0.11 sec) 3 4MariaDB [(none)]> flush privileges; 5Query OK, 0 rows affected (0.00 sec)
启动从库复制功能
启动3307实例并查看复制状态
1MariaDB [(none)]> START SLAVE; # 2Query OK, 0 rows affected (0.80 sec) 3 4MariaDB [(none)]> show slave status\G 5*************************** 1. row *************************** 6 Slave_IO_State: Waiting for master to send event 7 Master_Host: 192.168.214.141 8 Master_User: yufu 9 Master_Port: 3306 10 Connect_Retry: 60 11 Master_Log_File: mysql-bin.000001 12 Read_Master_Log_Pos: 645 13 Relay_Log_File: relay-log.000002 14 Relay_Log_Pos: 555 15 Relay_Master_Log_File: mysql-bin.000001 16 Slave_IO_Running: Yes #同时为yes才能成功同步数据 17 Slave_SQL_Running: Yes
启动3308实例并查看复制状态
1MariaDB [(none)]> start slave; 2Query OK, 0 rows affected (0.01 sec) 3 4MariaDB [(none)]> show slave status\G 5*************************** 1. row *************************** 6 Slave_IO_State: Waiting for master to send event 7 Master_Host: 192.168.214.141 8 Master_User: yufu 9 Master_Port: 3306 10 Connect_Retry: 60 11 Master_Log_File: mysql-bin.000001 12 Read_Master_Log_Pos: 645 13 Relay_Log_File: relay-log.000002 14 Relay_Log_Pos: 555 15 Relay_Master_Log_File: mysql-bin.000001 16 Slave_IO_Running: Yes 17 Slave_SQL_Running: Yes
至此,配置启动都没有问题,下面从主库实例3306中写入一些数据看看看看3307,3308实例能不能正常同步数据
测试同步
登录主库3306实例写一些数据:
1MariaDB [(none)]> create database yufu; 2Query OK, 1 row affected (0.00 sec) 3 4MariaDB [(none)]> use yufu; 5Database changed 6MariaDB [yufu]> create table test( 7 -> id varchar(10), 8 -> name varchar(20) 9 -> ); 10Query OK, 0 rows affected (0.84 sec) 11 12MariaDB [yufu]> insert into test values ('2323','yufuname'); 13Query OK, 1 row affected (0.00 sec)
登录从库3307实例查看数据:
1MariaDB [(none)]> select * from yufu.test; 2+------+----------+ 3| id | name | 4+------+----------+ 5| 2323 | yufuname | 6+------+----------+ 71 row in set (0.00 sec)
登录从库3308实例查看数据:
1MariaDB [(none)]> select * from yufu.test; 2+------+----------+ 3| id | name | 4+------+----------+ 5| 2323 | yufuname | 6+------+----------+ 71 row in set (0.01 sec)
经过测试同步功能正常,文章最后再次总结一下mysql主从复制的要点:
1. 主库必须开启bin-log二进制日志 2. 从库必须开启中继日志Relay-log,关闭bin-log 3. 主从的server-id 必须不能相同 4. 主库创建同步用户 5. 确保上面设置后,登录从库执行 change master to 指令 6. 主从时间同步
在后面的文章里,会比较详细介绍使用mysql的主从复制功能
欢迎访问个人博客站点www.gudaoyufu.com