1、主从复制的理解
在工作用常见Redis作为缓存与MySQL一起使用。当有请求时,首先会从缓存中进行查找,如果存在就直接取出,否则访问数据库,这样 提升了读取的效率,也减少了对后台数据库的访问压力。Redis的缓存架构时高并发架构 中重要的一环
- 作用
读写分离
:通过主从复制的方式来 同步数据 ,然后通过读写分离提高数据库并发处理能力。数据备份
:通过主从复制将主库上的数据复制到从库上,相当于一种热备份机制,也就是在主库正常运行的情况下进行备份,并不会影响到服务具有高可用性
:数据备份实际上是一种冗余机制,通过该方式可以换取数据库的高可用性,也就是当服务器出现故障或宕机的情况下,可以切换到从服务器上,保证数据的正常运行。
2、主从复制的原理
从数据库(Slave)从 主数据库(Master)读取
binlog
来进行数据同步。
2.1、原理刨析
三线程
:在主从复制过程中,会基于三线程来操作,一个主库线程,两个从库线程。二进制日志转储线程(Binlog dump thread)
:是一个主库线程。当从库线程连接的时候,主库可以将二进制日志发送给从库,当主库获取事件的时候,会在Binlog上加锁
,读取完成之后,再将锁释放掉。从库I/O线程
:会连接到主库,向主库发送请求更新 Binlog。这是从库的I/O线程就可以读取到主库的二进制日志转储线程发送的 Binlog 更新部分,并且拷贝到本地的中继日志(relay log)中。从库SQL线程
:会读取从库中的中继日志(relay log)并且执行日志中的事件,将从库中的数据与主库保持同步。
- 不是所有版本的MySQL都默认开启服务器的二进制日志。在进行主从复制的时候,先检查服务器是否已经开启二进制日志
- 除非特殊指定,默认情况下从服务器会执行所有主服务器中保存的事件。也可以通过配置,使从服务器执行特定的事件。
复制三步骤
:- 1、Mater 将写操作记录到二进制日志(binlog)。这些记录叫做二进制日志事件
- 2、Slave 将 Master 的binary log event 拷贝到他的中继日志(relay log)
- 3、Slave 重做 relay log 中的事件,将改变应用到自己的数据库中。MySQL复制是异步且串行化的,而且重启后从
接入点
开始复制
2.2、复制的基本原则
- 每个 Salve 只有一个Master
- 每个 Salve 只能有一个唯一的服务器ID
- 每个 Master 可以有多个Slave
3、主从架构的搭建
一台主机用于处理所有的写操作,一台从机负责所有读请求,如下图所示:
3.1、准备工作(采用虚拟机方式搭建主从复制架构)
- 两台及以上虚拟机
- 安装MySQL
- 修改MySQL的
server-uuid
,使得主从服务器中MySQL的uuid都是独立的并重启mysql服务
[root@slave ~]# vim /var/lib/mysql/auto.cnf
[auto]
server-uuid=7e14fc46-fef9-11ee-98d3-0050562861fc
3.2、主机配置文件
建议MySQL版本保持一致且后台以服务运行,主从所有配置项都在 [mysqld]节点下,且都是小写字母。
具体参数配置如下
- 必选项:
- 主服务器唯一ID:server-id=1
- 启用二进制日志,指名路径:log-bin=rqtanc-bin
- 可选项:
- read-only:0默认表示读写(主机),1表示只读(从机)
- binlog_expire_log_seconds:设置日志文件保留的时长,单位为秒
- max_binlog_size:控制单个二进制日志文件的大小,最大值和默认值是 1GB
- binlog-ignore-db:设置不复制的数据库
- binlog-do-db:设置需要复制的数据库,默认全部
- binlog_format:设置binlog格式
先搭建完主从复制,在创建数据库。MySQL主从复制起始时,从机不继承主机数据。
3.3、从机配置文件
- 必选项:
- 从服务器唯一ID:server-id
- 可选项:
- relay-log:启用中继日志
3.4、主机:建立账户并授权
- 创建用户:create user ‘slave’@‘%’ identified by ‘123456’;
- 授予权限:grant replication slave on . to ‘slave’@‘%’;
- 修改用户身份验证插件和密码:alter user ‘slave’@‘%’ identified with mysql_native_password by ’ 123456’;
- 刷新权限:flush privileges;
mysql> create user 'slave'@'%' identified by '123456';
Query OK, 0 rows affected (8.55 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';
Query OK, 0 rows affected (8.28 sec)
mysql> alter user 'slave'@'%' identified with mysql_native_password by ' 123456';
Query OK, 0 rows affected (1.21 sec)
mysql> flush privileges;
Query OK, 0 rows affected (12.98 sec)
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| rqtanc-bin.000008 | 965 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.26 sec)
mysql>
3.5、从机:配置需要复制的主机
- 从机上复制主机的命令
- change master to master_host=‘主机的IP地址’ , master_user=‘主机用户名’ ,master_password=‘主机用户名密码’ ,master_log_file=‘rqtanc-bin.具体数字’ ,master_log_pos=具体值
mysql> change master to master_host='192.168.12.130' , master_user='slave' ,master_password='123456' ,master_log_file='rqtanc-bin.000008' ,master_log_pos=965;
Query OK, 0 rows affected, 8 warnings (15.63 sec)
如果之前从机做过同步,则先停止。执行:stop slave;
- 启动 slave 同步
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.69 sec)
如果之前生成了relay_log信息,则先执行
reset slave;
删除slave数据库的relaylog文件,并重新启用relaylog文件。
- 查看同步状态:show slave status;
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Connecting to master
Master_Host: 192.168.12.130
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: rqtanc-bin.000008
Read_Master_Log_Pos: 965
Relay_Log_File: rqtanc-relay.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: rqtanc-bin.000008
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 965
Relay_Log_Space: 156
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 1045
Last_IO_Error: error connecting to master 'slave@192.168.12.130:3306' - retry-time: 60 retries: 6 message: Access denied for user 'slave'@'192.168.12.131' (using password: YES)
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
Master_UUID:
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp: 240609 02:26:13
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
Last_IO_Error: error connecting to master ‘slave@192.168.12.130:3306’ - retry-time: 60 retries: 6 message: Access denied for user ‘slave’@‘192.168.12.131’ (using password: YES)
用户密码不匹配导致
3.6、主从复制测试
- master
mysql> create database master_slave;
Query OK, 1 row affected (6.06 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| master_slave |
| mysql |
| performance_schema |
| rqtanc |
| sys |
| test |
+--------------------+
7 rows in set (8.52 sec)
mysql> use master_slave;
Database changed
mysql> create table tb_master_slave(id int ,name varchar(10));
Query OK, 0 rows affected (23.40 sec)
mysql> insert into tb_master_slave values(1,'rqtanc'),(2,'test');
Query OK, 2 rows affected (17.60 sec)
Records: 2 Duplicates: 0 Warnings: 0
- slave
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| master_slave |
| mysql |
| performance_schema |
| rqtanc |
| sys |
| test |
+--------------------+
7 rows in set (29.71 sec)
mysql> use master_slave;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+------------------------+
| Tables_in_master_slave |
+------------------------+
| tb_master_slave |
+------------------------+
1 row in set (0.35 sec)
mysql> select * from tb_master_slave;
+------+--------+
| id | name |
+------+--------+
| 1 | rqtanc |
| 2 | test |
+------+--------+
2 rows in set (0.05 sec)
3.7、停止主从复制
- stop slave
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.94 sec)