mysqld_multi设计用于管理在同一台机器上运行的多个mysqld进程,这些进程使用不同的socket文件并监听在不同的端口上。mysqld_multi可以批量启动、关闭、或者报告这些mysqld进程的状态。在这里我们通过这种方式来在同一个机器上启动多个数据库实例,并配置主从关系。
1、下载MySQL压缩包wget http://dev.MySQL.com/get/Downloads/MySQL-5.7/mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz
2、创建安装目录
这里我将Mysql安装在/usr/local/mysql目录里面,也可以安装在其他地方;mkdir /usr/local/mysql
3、解压并复制tar -xvf mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz
mv mysql-5.7.18-linux-glibc2.5-x86_64/* /usr/local/mysql/
4、创建data目录mkdir /usr/local/mysql/data{3306,3307,3308} -p
5、创建mysql用户组及其用户groupadd mysql
useradd -r -g mysql mysql
6、修改权限chown -R mysql:mysql /usr/local/mysql
7、初始化实例的数据库
mysql_install_db 方式已经 deprecated 了,我们使用 mysqld 的 initialize 方法来做初始化# --no-defaults 不读取默认的 /etc/my.cnf 全局配置文件 否则可能存在一些冲突问题
# --initialize-insecure 初始化且不需要生成密码,我不太喜欢那一大串字符...
# --basedir mysql 的安装目录
# --datadir 本实例的数据目录
# --user 这样生成的文件用户为 mysql
# --explicit_defaults_for_timestamp timestamp 已经 deprecated 了
#生成 3306 的数据目录
[root@localhost ~]# mysqld --no-defaults --initialize-insecure --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data3306 --user=mysql --explicit_defaults_for_timestamp
#生成 3307 的数据目录
[root@localhost ~]# mysqld --no-defaults --initialize-insecure --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data3307 --user=mysql --explicit_defaults_for_timestamp
#生成 3307 的数据目录
[root@localhost ~]# mysqld --no-defaults --initialize-insecure --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data3308 --user=mysql --explicit_defaults_for_timestamp
8、将mysql命令加入环境变量
在/etc/profile最后加入两行命令:MYSQL_HOME=/usr/local/mysql
export PATH=$PATH:$MYSQL_HOME/bin
最后执行source /etc/profile,使得配置生效
9、创建/etc/my.cnf[mysqld_multi]
mysqld=/usr/local/mysql/bin/mysqld_safe#mysqld命令的位置,用于启动mysql实例,也可以指定为mysqld_safe命令的位置
mysqladmin=/usr/local/mysql/bin/mysqladmin#用于停止mysql实例
user=root#调用mysqladmin时使用的账号
#password=123456调用mysqladmin时使用的账号的密码,因为我们使用了initialize-insecure,所以root用户最开始是没有密码的
log=/usr/local/mysql/mysql_multi.log
[mysqld3306]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data3306
port=3306
user=mysql
socket=/tmp/mysql.sock3306
server_id=1
log_bin=mysql-bin#主库
[mysqld3307]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data3307
port=3307
user=mysql
socket=/tmp/mysql.sock3307
server_id=2
[mysqld3308]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data3308
port=3308
user=mysql
socket=/tmp/mysql.sock3308
server_id=3
在mysqld_multi中配置的user和password是mysql的用户名和密码。为了使用mysqld_multi命令,每个mysql实例都必须要提供一个相同的用户名和密码,用于启动和停止服务。而且要确保这个用户具有停止mysql实例的权限。提示:在[mysqlN]中配置的user是linux中的用户,是启动mysql服务实例时使用的用户
mysqld_multi提供了start, stop, reload (stop and restart)和report 表示要执行的不同操作。可以参见官方文档查看https://dev.mysql.com/doc/refman/5.7/en/mysqld-multi.html其完整用法,因为命令非常简单,这里不做过多介绍。
10、启动MySQL实例[root@localhost mysql]# mysqld_multi start
11、查看3个实例的运行状态[root@localhost mysql]# mysqld_multi report
Reporting MySQL servers
MySQL server from group: mysqld3306 is running
MySQL server from group: mysqld3307 is running
MySQL server from group: mysqld3308 is running
也可以通过netstat-tln来查看[root@localhost Desktop]# netstat -tln|grep 330*
tcp 0 0 :::3307 :::* LISTEN
tcp 0 0 :::3308 :::* LISTEN
tcp 0 0 :::3306 :::* LISTEN
12 配置主从关系
打开3个命令行窗口,分别执行以下命令登录主从数据库:mysql -h127.0.0.1 -uroot -P3306 -p
mysql -h127.0.0.1 -uroot -P3307 -p
mysql -h127.0.0.1 -uroot -P3308 -p
因为我们初始化数据库的时候,没有为root用生成密码,因此出现提示输入password的时候,直接按enter键就可以了。在这3个命令行窗口都执行以下命令,用于创建复制账号:GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO slave@'localhost' IDENTIFIED BY 'slave';
理论上,只要再主库上创建复制账号即可,但是因为考虑到主备切换的问题,因此在从库上也创建复制账号。另外需要注意的是,从库从主库复制,本身只需要REPLICATION SLAVE权限即可,REPLICATION CLIENT权限是让这个用户拥有执行SHOW MASTER STATUS和SHOW SLAVE STATUS命令,也就是说这个权限是用于授予账户监视Replication状况的权力,我们将在之后看到这两个命令如何使用。
我们需要在3307和3308上,分别执行以下命令,将3306设置为主库,这一步是告诉备库如何连接到主库并重复其二进制日志,旧版本的方式是通过修改my.cnf来配置,但是在新的版本中,修改my.cnf的配置方式已经废弃。而是使用CHANGE MASTER TO 语句,该语句完全替代了my.cnf 中相应的设置,并且允许以后指向别的主库时无须重启备库。下面是复制开始的基本命令:mysql>CHANGE MASTER TO \
MASTER_HOST='localhost',\
MASTER_USER='slave',\
MASTER_PORT=3306,\
MASTER_PASSWORD='slave',\
MASTER_LOG_FILE='mysql-bin.000001',\
MASTER_LOG_POS=0;
只需要配置一次即可,之后重启的时候,slave会自动连接到master同步数据,不需要每次都执行这些命令。
需要注意的是,此时复制并没有真正的开始,我们可以在主库3306上执行以下命令,,查看主库状态:mysql>show master status;
+------------------+----------+--------------+------------------+-------------------+
|File|Position|Binlog_Do_DB|Binlog_Ignore_DB|Executed_Gtid_Set|
+------------------+----------+--------------+------------------+-------------------+
|mysql-bin.000001|154||||
+------------------+----------+--------------+------------------+-------------------+
1row in set(0.00sec)
mysql>show processlist;
+----+------+-----------------+------+---------+------+----------+------------------+
|Id|User|Host|db|Command|Time|State|Info|
+----+------+-----------------+------+---------+------+----------+------------------+
|3|root|localhost:58685|NULL|Query|0|starting|show processlist|
+----+------+-----------------+------+---------+------+----------+------------------+
1row in set(0.00sec)
在从库3307或者3308上,执行以下命令:mysql>show slave status\G;
***************************1.row***************************
Slave_IO_State:
Master_Host:localhost
Master_User:slave
Master_Port:3306
Connect_Retry:60
Master_Log_File:mysql-bin.000001
Read_Master_Log_Pos:4
Relay_Log_File:localhost-relay-bin.000001
Relay_Log_Pos:4
Relay_Master_Log_File:mysql-bin.000001
Slave_IO_Running:No
Slave_SQL_Running:No
Replicate_Do_DB:
Replicate_Ignore_DB:
...omitted....
Seconds_Behind_Master:NULL
...omitted....
1row in set(0.00sec)
Slave_IO_State、Slave_IO_Running、Slave_SQL_Running这三列显示备库复制尚未执行。
此时在从库3307和3308上分别执行以下命令,开始复制:mysql> start slave;
此时在3307和3308上再执行show slave status,可以看到mysql>show slave status\G;
***************************1.row***************************
Slave_IO_State:Waitingformaster to send event#等待主库发送bin-log同步事件
Master_Host:localhost
Master_User:slave
Master_Port:3306
Connect_Retry:60
Master_Log_File:mysql-bin.000001
Read_Master_Log_Pos:4
Relay_Log_File:localhost-relay-bin.000001
Relay_Log_Pos:4
Relay_Master_Log_File:mysql-bin.000001
Slave_IO_Running:Yes#状态变为YES
Slave_SQL_Running:Yes#状态变为YES
Replicate_Do_DB:
Replicate_Ignore_DB:
...omitted....
Seconds_Behind_Master:NULL
...omitted....
此时再查看主库3306的状态mysql>show processlist\G;
***************************1.row***************************
Id:3
User:root
Host:localhost:58685
db:NULL
Command:Query
Time:0
State:starting
Info:show processlist
***************************2.row***************************
Id:4
User:slave
Host:localhost:35312
db:NULL
Command:BinlogDump
Time:161
State:Masterhas sent all binlog to slave;waitingformore updates
Info:NULL
***************************3.row***************************
Id:5
User:slave
Host:localhost:35313
db:NULL
Command:BinlogDump
Time:154
State:Masterhas sent all binlog to slave;waitingformore updates
Info:NULL
3rows in set(0.00sec)
可以看有2个线程执行了Binlog Dump命令,这就是我们的两个从库已经开始复制。
现在在主库3306上创建一个库draon_ha,在其中创建一个表user,并插入一条记录,这数据都会自动同步到两个从库中CREATE DATABASE`dragon_ha`;
use dragon_ha;
CREATE TABLE`user`(
`id`int(11)NOT NULL AUTO_INCREMENT,
`name`varchar(255)NOT NULL,
PRIMARY KEY(`id`)
)ENGINE=InnoDBDEFAULT CHARSET=utf8;
insert into user(name)values('tianshouzhi');
mysql> show databases;分别在3307和3308两个从库中执行以下命令,查看数据是否已经同步:mysql>show databases;
+--------------------+
|Database|
+--------------------+
|information_schema|
|dragon_ha|#插入的库已经同步
|mysql|
|performance_schema|
|sys|
+--------------------+
5rows in set(0.00sec)
mysql>use dragon_ha;
Readingtable informationforcompletion of table and column names
Youcan turn offthisfeature to get a quicker startup with-A
Databasechanged
mysql>show tables;
+---------------------+
|Tables_in_dragon_ha|
+---------------------+
|user|#插入的表已经同步
+---------------------+
1row in set(0.00sec)
mysql>select*from user;
+----+-------------+
|id|name|
+----+-------------+
|1|tianshouzhi|#插入的记录已经同步
+----+-------------+
1row in set(0.00sec)