最近在esxi的主机上配置了三台centOS7的虚拟机,作为自己的开发环境,今天来学习以及实践一下部署MySQL的主从复制。
分别在这三台虚拟机中安装mysql,将192.168.31.40这台虚拟机上作为主数据库,192.168.31.41和192.168.31.42作为从数据库。
安装MySQL
卸载服务器自带的mariadb
运行命令:
rpm -qa | grep mariadb
如果有返回结果,则运行卸载命令:
sudo yum remove mariadb-libs-5.5.68-1.el7.x86_64
下载和安装
在MySQL官网 dev.mysql.com/downloads/r… 这个地址上选择对应服务器版本的rpm包下载,我这里是centOS7,所以选择如下:
下载好后上传到服务器上,或者使用wget命令进行下载:
wget https://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm
下载好后,执行以下两条安装命令,若权限不够,则命令前加上sudo执行:
sudo rpm -ivh mysql80-community-release-el7-11.noarch.rpm
sudo yum install mysql-community-server -y
开启忽略表名大小写
安装结束后,我这里开启MySQL8的忽略表名大小写功能。
首先关闭mysql:
sudo systemctl stop mysqld
然后删除mysql的数据目录:
sudo rm -rf /var/lib/mysql
再编辑mysql的配置文件,添加一行lower_case_table_names=1
sudo vim /etc/my.cnf
最后再重新启动mysql:
sudo systemctl start mysqld
修改密码以及开启远程登录
用命令查看mysql中root的临时密码:
sudo grep 'temporary password' /var/log/mysqld.log
我这里因为安装和初始化了多次,所以有几条记录,用最新一条的临时密码即可。
命令登录mysql:
mysql -uroot -p
输入上面的临时密码进入mysql,再执行修改密码命令,改成自己需要的密码:
alter user 'root'@'localhost' identified BY 'Qwer@1234';
flush privileges;
开启远程登录功能:
use mysql;
update user set host='%' where user ='root';
flush privileges;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'WITH GRANT OPTION;
flush privileges;
MySQL主从复制基本原理
MySQL主从复制的原理主要是由master主数据库开启bin-log日志,将每次数据变更都记录在bin-log日志中;slave从数据库开启一个IO线程,连接master主数据库,并请求更新的bin-log内容,写入从数据库自己的relay-log日志中,slave从数据库再开启一个SQL线程,用来定时读取relay-log日志的内容,若发现内容有更新,则在本地执行变更的数据操作,通过这样的方式来复制主数据库的数据内容。
主从数据库部署配置
新建测试数据库和表
在主数据库和从数据库上建立测试数据库,我这里创建一个test数据库,库中创建一张person表,含有id,name,age三个字段。主从数据库需要保持一致,我这边是在主数据库创建好后,用mysqldump命令备份test数据库,再上传至从数据库服务器,用命令导入。
主数据库配置文件修改
ssh登录到192.168.31.40虚拟机中,编辑主数据库配置文件my.cnf:
sudo vim /etc/my.cnf
追加:
log-bin=mysql-bin
server-id=1204
binlog-do-db=test
重启mysql:
sudo systemctl restart mysqld
主数据库创建用户
需要在主数据库上创建一个用户并授权,用于给从数据库连接主数据库并复制数据。
先用命令mysql -uroot -p登录主数据库,然后执行创建用户与授权命令,命令中ip根据自己的需要设置:
create user 'node'@'192.168.31.%' identified by 'Asdf@1234';
grant replication slave on *.* to 'node'@'192.168.31.%';
flush privileges;
查看主数据库状态:
show master status;
图里的File和Position值,待会从数据库配置会用到。
从数据库配置
ssh登录到192.168.31.41虚拟机中,编辑从数据库配置文件my.cnf:
sudo vim /etc/my.cnf
追加:
relay-log=mysql-relay-bin
server-id=1205
注意这里server-id不要与主主数据库的重复
重启mysql:
sudo systemctl restart mysqld
执行从数据库配置命令
先用命令mysql -uroot -p登录从数据库,然后执行:
change master to
master_host='192.168.31.40',
master_user='node',
master_password='Asdf@1234',
master_log_file='mysql-bin.000002',
master_log_pos=157;
这里master_host填写主数据库所在机器的ip,master_user和master_password填写上面主数据创建的用户和密码,master_log_file和master_log_pos填写上面主数据库状态中的File和Position值。另外我这里没有改端口,默认就是3306;如果修改了端口,则需要加上master_port来指定主数据库的端口。
接下来执行命令,启动从数据库slave:
start slave;
再执行命令,查看slave状态:
show slave status \G;
这里有一个报错Message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.,导致从数据库连不上主数据库。这是因为MySQL8默认的密码加密方式是caching_sha2_password,而不是mysql_native_password。
对此有两种解决方案,一是去主数据库所在是虚拟机,将创建的node账户密码加密方式改掉:
在主服务器上mysql -uroot -p登录mysql后,执行:
ALTER USER 'node'@'192.168.31.%' IDENTIFIED WITH mysql_native_password BY 'Asdf@1234';
另一种方案是,在从服务器上用创建的node用户远程登录主服务器的mysql,并且加上参数--get-server-public-key去请求公钥:
mysql -h 192.168.31.40 -u node -p --get-server-public-key
输入密码验证登录后,请求到公钥即可。
随后退出主数据库的登录,再次mysql -uroot -p登录从服务器自己的mysql,重新配置slave参数:
先停止slave和重置slave配置:
stop slave;
reset slave;
再执行一次配置,这里需要注意参数需要正确,可以去主数据库再次查看master状态确定参数:
change master to
master_host='192.168.31.40',
master_user='node',
master_password='Asdf@1234',
master_log_file='mysql-bin.000002',
master_log_pos=157;
最后启动slave:
start slave;
执行命令,查看slave状态:
show slave status \G;
可以看到这里已经是连接上主数据了
后面在192.168.31.42的服务器上再次配置一次以上192.168.31.41服务器的从数据库的配置,如果有更多的从数据库,则每个都进行配置。注意每个MySQL的server-id需要唯一
测试主从复制
在主数据库上对test数据库执行一条插入语句:
INSERT INTO person VALUES (1, '张三', 18);
执行成功后,分别到两个从数据库上执行select语句查看复制结果:
这里可以看到在主数据库执行完insert语句后,两台从数据库上都出现了这条数据,表明主从复制已经部署成功。