Mysql主从复制和读写分离
一、为什么使用主从复制、读写分离
主从复制、读写分离一般是一起使用的。目的很简单,就是为了提高数据库的并发性能。你想,假设是单机,读写都在一台MySQL上面完成,性能肯定不高。如果有三台MySQL,一台mater只负责写操作,两台salve只负责读操作,性能不就能大大提高了吗?
所以主从复制、读写分离就是为了数据库能支持更大的并发。
随着业务量的扩展、如果是单机部署的MySQL,会导致I/O频率过高。采用主从复制、读写分离可以提高数据库的可用性。
二、主从复制的原理
①当Master节点进行insert、update、delete操作时,会按顺序写入到binlog中。
②salve从库连接master主库,Master有多少个slave就会创建多少个binlog dump线程。
③当Master节点的binlog发生变化时,binlog dump 线程会通知所有的salve节点,并将相应的binlog内容推送给slave节点。
④I/O线程接收到 binlog 内容后,将内容写入到本地的 relay-log。
⑤SQL线程读取I/O线程写入的relay-log,并且根据 relay-log 的内容对从数据库做对应的操作。
三、如何实现主从复制
我这里用三台虚拟机(Linux)演示,IP分别是104(Master),106(Slave),107(Slave)。
预期的效果是一主二从,如下图所示:
1、Master配置
使用命令行进入mysql:
mysql -u root -p
接着输入root用户的密码(密码忘记的话就网上查一下重置密码吧~),然后创建用户:
//192.168.0.106是slave从机的IP
GRANT REPLICATION SLAVE ON *.* to 'root'@'192.168.0.106' identified by 'Java@1234';
//192.168.0.107是slave从机的IP
GRANT REPLICATION SLAVE ON *.* to 'root'@'192.168.0.107' identified by 'Java@1234';
//刷新系统权限表的配置
FLUSH PRIVILEGES;
注意:上面的命令是mysql5.7之前的,mysql8之后要用下面的命令:
-- 1. 创建用户并设置密码(如果用户不存在) CREATE USER 'zzh'@'192.168.2.212' IDENTIFIED BY '123456';-- 2. 授予主从复制所需权限(MySQL 8.0.24+ 需要额外权限) GRANT REPLICATION SLAVE, REPLICATION CLIENT, REPLICATION_APPLIER ON *.* TO 'zzh'@'192.168.2.212';-- 3. 刷新权限 FLUSH PRIVILEGES;
创建的这两个用户在配置slave从机时要用到。
接下来在找到mysql的配置文件/etc/my.cnf,增加以下配置:
# 开启binlog,log-bin后面存放的是binlog的存放位置
log-bin=mysql-bin
server-id=104
# 需要同步的数据库,如果不配置则同步全部数据库
binlog-do-db=test_db
# binlog日志保留的天数,清除超过30天的日志
# 防止日志文件过大,导致磁盘空间不足
binlog_expire_logs_seconds=259200
配置完成后,重启mysql:
service mysql restart
可以通过命令行show master status\G;
查看当前binlog日志的信息(后面有用):
2、Slave配置
Slave配置相对简单一点。从机肯定也是一台MySQL服务器,所以和Master一样,找到/etc/my.cnf配置文件,增加以下配置:
# 不要和其他mysql服务id重复即可
server-id=106
接着使用命令行登录到mysql服务器:
mysql -u root -p
然后输入密码登录进去。
进入到mysql后,再输入以下命令:
CHANGE MASTER TO
MASTER_HOST='192.168.0.104',//主机IP
MASTER_USER='zzh',//之前创建的用户账号
MASTER_PASSWORD='123456',//之前创建的用户密码
MASTER_LOG_FILE='mysql-bin.000001',//master主机的binlog日志名称
MASTER_LOG_POS=862,//binlog日志偏移量
master_port=3306;//端口
还没完,设置完之后需要启动:
# 启动slave服务
start slave;
启动完之后怎么校验是否启动成功呢?使用以下命令:
show slave status\G;
注意:
上述配置完之后会报连接不上的错误
原因:MySQL 8.0默认使用caching_sha2_password插件,这个插件在远程连接时可能需要SSL或者RSA密钥对,否则会失败。
Last_IO_Error: Error connecting to source 'zzh@192.168.2.35:3306'. This was attempt 1/86400, with a delay of 60 seconds between attempts. Message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
可以看到如下信息(摘取部分关键信息):
*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 192.168.0.104Master_User: rootMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 619Relay_Log_File: mysqld-relay-bin.000001Relay_Log_Pos: 782Relay_Master_Log_File: mysql-bin.000001 //binlog日志文件名称Slave_IO_Running: Yes //Slave_IO线程、SQL线程都在运行Slave_SQL_Running: YesMaster_Server_Id: 104 //master主机的服务idMaster_UUID: 0ab6b3a6-e21d-11ea-aaa3-080027f8d623Master_Info_File: /var/lib/mysql/master.infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update itMaster_Retry_Count: 86400Auto_Position: 0
(这里我使用解决方案1解决,解决方案2和3没尝试)
解决方案一:
使用复制用户请求服务器公钥:
mysql -u repl -p123 -h 118.31.127.96 -P3307 --get-server-public-key
在这种情况下,服务器将RSA公钥发送给客户端,后者使用它来加密密码并将结果返回给服务器。插件使用服务器端的RSA私钥解密密码,并根据密码是否正确来接受或拒绝连接。
重新在从库配置change masrer to并且start slave,复制可以正常启动:
#停止主从复制
#清空之前的主从复制配置信息
stop slave;
reset slave;#从新配置主从复制
change master to master_user='repl',master_password='123',master_host='118.31.127.96',master_port=3307,master_auto_position=1;
start slave;
解决方案二:
使用复制用户请求服务器公钥:
mysql -u repl -p123 -h 118.31.127.96 -P3307 --server-public-key-path=/mysqldata/my3308/data/public_key1.pem
重新在从库配置change masrer to并且start slave,复制可以正常启动:
#停止主从复制
#清空之前的主从复制配置信息
stop slave;
reset slave;#从新配置主从复制
change master to master_user='repl',master_password='123',master_host='118.31.127.96',master_port=3307,master_auto_position=1;
start slave;
解决方案三:
根据社区提供的方案,修改复制账户,避免使用插件caching_sha2_password。
MySQL MySQL8.0主从同步报错2061问题解决_Cindy的博客-CSDN博客
方法如下:
1.修改repl用户,使其使用别的秘密加密方式,不使用插件caching_sha2_password。
2.
CREATE USER 'repl'@'%' IDENTIFIED WITH 'mysql_native_password' BY 'XXXX';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; #检查复制账户
select user,host,plugin,authentication_string from user \G
*************************** 4. row ***************************user: replhost: %plugin: mysql_native_password
authentication_string: *B2A7A5489FB0EE54E43E3ADCDDVDG5CCF255AF0#重新配置主从配置
另一台slave从机配置一样,不再赘述。
四、读写分离介绍
1、做读写分离的原因
数据库写入效率要低于读取效率,一般系统中数据读取频率高于写入频率,单个数据库实例在写入的时候会影响读取性能,这是做读写分离的原因。
2、MySQL读写分离的基础
实现方式主要基于mysql的主从复制,通过路由的方式使应用对数据库的写请求只在master上进行,读请求在slave上进行。
参考文章:
主从复制报错2061:Authentication plugin 'caching_sha2_password' reported error:Authentication require secure connection - 墨天轮