一口气搭建完MySQL主从同步及读写分离
前言
一个半月前,公司的一个生产环境上了MySQL的读写分离,目的是来提高系统的性能,然而没两天就出了问题。那是一个周五的上午,同事开始发现数据变来变去的,如果主库的数据没有同步到从库上去,并且两次读取的数据库不一致的话,的确会产生这种情况。当时以为正常情况,直到错误数据越来越多,事情开始变的严重起来了,主库挂了,从库切换为主库了,但是之前有些数据没有同步到从库上来。
好家伙,赶紧把读写分离给撤了,但是错误数据已经存在了。然后开始漫长的修补数据的过程了,负责人周五晚上就开始搞,周六又整了一天。
直到现在,还有些不是特别影响业务操作的数据是错的。
又想到之前去UU跑腿面试的时候,问了一次读写分离的情况,问我怎么能在写库写完之后立马读到数据?我说那就读写库,他说那这就不是读写分离了。问我有什么别的办法,我觉得是没办法的,又要保证读写分离,又要立马读到写库写入的数据(除非写入的数据和之前的一致,这肯定不会是答案吧)。当时面试官还问我有没有本地搭建过读写分离的环境,那当然是没有了。
上周趁着有不想工作的心情,耗费了大概一天的时间在centos上搭建了MySQL的读写分离环境,项目测试了下也是成功的,这里简要记录下搭建的过程。具体可以参考以下两篇文章
https://blog.csdn.net/M_y_y/article/details/106501840https://blog.51cto.com/bigboss/2103290
环境说明:
服务器:CentOS7数据库:MySQL5.7.34端口:3306、33073306为主数据库3307为从数据库ProxySQL版本:proxysql-1.4.8-1-centos7.x86_64.rpm
第一步:删除数据库
1. 查询之前安装的mysql:
rpm -qa|grep -i mysql
2. 删除,一个一个删除:
rpm -e mysql-community-client-... --nodeps
3. 查询mysql残留文件
find / -name mysql
4. 继续删除:
使用rm -rf 文件路径,一个个删除
第二步:安装数据库实例
1. 下载tar源码包 官网下载
https://dev.mysql.com/downloads/mysql/mysql-5.7.34-el7-x86_64.tar.gz
2. 解压安装包:
tar -zxvf mysql-5.7.34-el7-x86_64.tar.gz
3. 更改解压后的名称
mv mysql-5.7.34-el7-x86_64 mysql5.7.34
4. 创建一些必要文件夹
创建3306文件夹,一并创建data、logs两个文件夹用于存放数据和日志 位置随意
5. 生成my.cnf配置文件
touch my.cnf 同时 vi my.cnf 将以下内容复制到文件中
# For advice on how to change settings please see# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html[mysqld]## Remove leading # and set to the amount of RAM for the most important data# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.# innodb_buffer_pool_size = 128M## Remove leading # to turn on a very important data integrity option: logging# changes to the binary log between backups.# log_bin## Remove leading # to set options mainly useful for reporting servers.# The server defaults are faster for transactions and fast SELECTs.# Adjust sizes as needed, experiment to find the optimal values.# join_buffer_size = 128M# sort_buffer_size = 2M# read_rnd_buffer_size = 2Mdatadir=/var/lib/mysqlsocket=/var/lib/mysql/mysql.socklog-error=/var/log/mysqld.logpid-file=/var/run/mysqld/mysqld.pid
6. 修改配置文件中默认路径为自己服务器上的路径
7. 给3307实例也拷贝一份
cp -r mysql3306/ mysql3307/
8. 修改3307数据库配置文件
使用vi my.cnf打开文件之后,将全局的3306更改为3307
9. 进入之前解压的mysql文件中的bin目录,初始化mysql3306
./mysqld --defaults-file=/opt/k3/mysql/mysql3306/my.cnf --initialize --datadir=/opt/k3/mysql/mysql3306/data/ --basedir=/opt/k3/mysql/mysql5.7.34 --user=root
会有默认密码出现,不用管它
10. 启动mysql3306 跳过密码安全连接、
./mysqld_safe --defaults-extra-file=/opt/k3/mysql/mysql3306/my.cnf --skip-grant-tables &
11. 查看运行状态
这时3306mysql已启动成功,使用以下命令查看运行状态:
ps -ef|grep 3306
12. 连接到mysql3306
./mysql -S /opt/k3/mysql/mysql3306/data/mysql.sock -P 3306
13. 密码修改以及授权远程访问
flush privileges;set password for 'root'@'localhost' = password('root');grant all privileges on *.* to'root' @'%' identified by 'root' with grant option;flush privileges;
14. 本地测试连接
直接Navicat进行连接测试
15. 同理操作mysql3307
第三步:开始做主同步的配置
1.修改3306my.cnf配置文件
log-bin=/opt/k3/mysql/mysql3306/logs/mysql-bin.log //自己存储log的位置server-id=1 //设置数据库服务器唯一ID,这里我们指定为1。binlog-do-db=test_k3_wms //设置需要同步的数据库,如果需要设置多个,则加入多条这行语句。
2.启动3306数据库实例
/opt/k3/mysql/mysql5.7.34/bin/mysqld --defaults-file=/opt/k3/mysql/mysql3306/my.cnf --port=3306
3. 连接3306数据库
/opt/k3/mysql/mysql5.7.34/bin/mysql --socket=/opt/k3/mysql/mysql3306/data/mysql.sock --port=3306 -u root -p
4.添加一个用于备份的用户:名称为slave(可自定义),密码为1234(可自定义)
grant replication slave on *.* to 'slave'@'%' identified by '1234';
5.查看用户是否创建成功
use mysql;select user ,host from user;
6.查看主机配置状态
show master status;
7.修改3307my.cnf配置文件
log-bin=/opt/k3/mysql/mysql3307/logs/mysql-bin.logserver-id=2
8.启动3307数据库实例并连接(同上)
9.创建与主机的关系
master_log_file和master_log_pos对应主库查询到的信息值,见上面图片(此处和图片中不一致,是因为中间执行过很多其他操作)
change master to master_host='192.168.142.*',master_user='slave',master_password='1234',master_port=3306,master_log_file='mysql-bin.000007',master_log_pos=154;
10.启动从机同步
start slave;
11.查看是否成功(这两步都是在从库上执行的)
两个字段都为YES就表示配置成功了
12.测试
这时候可以往主库里添加一条数据,看看从库是否能同步成功
第四步:使用ProxySQL实现读写分离
1.安装ProxySQL
wget https://github.com/sysown/proxysql/releases/download/v1.4.8/proxysql-1.4.8-1-centos7.x86_64.rpm#proxysql需要依赖一些perl库,所以使用yum安装yum install -y proxysql-1.4.8-1-centos7.x86_64.rpm#安装生成的文件:[root@ProxySQL ~]#rpm -ql proxysql/etc/init.d/proxysql #启动脚本/etc/proxysql.cnf #配置文件,仅在第一次(/var/lib/proxysql/proxysql.db文件不存在)启动时有效#启动后可以在proxysql管理端中通过修改数据库的方式修改配置并生效(官方推荐方式。)/usr/bin/proxysql #主程序文件/usr/share/proxysql/tools/proxysql_galera_checker.sh/usr/share/proxysql/tools/proxysql_galera_writer.pl
2.启动ProxySQL
/etc/init.d/proxysql start[]Starting ProxySQL: DONE![]
3.连接proxysql管理端进行配置:
#默认的管理端账号密码都是admin,登录进去之后可以修改变量进行修改账号密码mysql -uadmin -padmin -h127.0.0.1 -P6032[root@ProxySQL ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
注意:如果直接执行此命令失败的话,需求到mysql解压目录的下的bin目录下执行 ./mysql ...
4.添加后端的mysql主机:
insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'192.168.142.x',3306,1,'Write Group');insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(2,'192.168.142.x',3307,1,'Read Group');MySQL [(none)]> select * from mysql_servers;
5.添加可以访问后端主机的账号:
注意:此命令要在mysql中执行,不是上一步登录的mysql,是3306端口的mysql
#在后端mysql中添加可以增删改查的账号GRANT ALL ON *.* TO 'proxysql'@'192.168.142.%' IDENTIFIED BY '123456';#在proxysql主机的mysql_users表中添加刚才创建的账号,proxysql客户端需要使用这个账号来访问数据库。insert into mysql_users(username,password,default_hostgroup,transaction_persistent)values('proxysql','123456',1,1);#default_hostgroup默认组设置为写组,也就是1#当读写分离的路由规则不符合时,会访问默认组的数据库MySQL [(none)]> insert into mysql_users(username,password,default_hostgroup,transaction_persistent)values('proxysql','123456',1,1);Query OK, 1 row affected (0.00 sec)MySQL [(none)]> select * from mysql_users\G 查看新增的用户信息
6.添加健康监测的账号:
这个命令和上面一条的一样,都是在3306端口下的mysql中操作的
#在后端主机中添加可以访问数据库的账号,SELECT权限即可GRANT SELECT ON *.* TO 'monitor'@'192.168.100.%' IDENTIFIED BY 'monitor';#在proxysql管理端中修改变量设置健康检测的账号set mysql-monitor_username='monitor'set mysql-monitor_password='monitor'
7.添加读写分离的路由规则:
insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(1,1,'^SELECT.*FOR UPDATE$',1,1);insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(2,1,'^SELECT',2,1);MySQL [(none)]> select rule_id,active,match_digest,destination_hostgroup,apply from mysql_query_rules;
8.将刚才我们修改的数据加载至RUNTIME中(参考ProxySQL的多层配置结构):
#load进runtime,是配置生效load mysql users to runtime;load mysql servers to runtime;load mysql query rules to runtime;load mysql variables to runtime;load admin variables to runtime;#save到磁盘(/var/lib/proxysql/proxysql.db)中,永久保存配置save mysql users to disk;save mysql servers to disk;save mysql query rules to disk;save mysql variables to disk;save admin variables to disk;
第四步:测试读写分离
1.连接proxysql客户端:
#登录用户是刚才我们在mysql_user表中创建的用户,端口为6033mysql -uproxysql -p123456 -h127.0.0.1 -P6033
2.尝试修改数据库和查询:
#创建两个数据库和查个表。create database test;select user,host from mysql.user;
3.验证读写分离是否成功:
select * from stats_mysql_query_digest;MySQL [(none)]> select * from stats_mysql_query_digest;
结束语
1.在搭建多实例mysql的时候,用8.0.21版本的mysql也是可以的,只不过8以后修改密码和远程登录授权分开了
2.在登录ProxySQL后,以上所有的操作都是在main库中执行的
3.环境搭建好了之后,在项目中直接连接6033端口的ProxySQL就可以了
4.可以把主从复制改为双主热备,再加上keepalived,实现高可用
