一般数据库都是读取压力大于写数据压力,主从复制即为了实现数据库的负载均衡和读写分离。通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,主服务器只负责写,而从服务器只负责读。
如生产环境中,使用redis数据库作为缓存数据库,用户访问业务数据时,先从缓存数据库查询,如果缓存数据库没有,再从业务数据库读取。
基于语句的复制--Statement(Statement-Based Replication,SBR)
: 在主服务器上执行的sql
语句,在从服务器上执行同样的语句。mysql默认采用基于语句的复制,效率比较高。一旦发现没法精确复制时,会自动选择基于行的复制,每一条会修改数据的sql
都会记录在 binlog 中。
基于行的复制--Row(Row-Based Replication,RBR)
:把改变的内容复制过去,仅保存哪条记录被修改。而不是把命令在从服务器上执行一遍, 从mysql5.0开始支持。
混合类型的复制--Mixed(Mixed-Based Replication,MBR)
: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制,Statement 和 Row 的混合体。
通过alter user root identified by '新密码';
mysql
数据库默认的复制方式不会主动推送数据
到从节点,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理。数据不完整
。mysql
主节点特有的复制方式,当主库执行完一个事务,然后所有的从库都复制了该事务并成功执行完才返回成功信息给客户端。relay log
中才返回成功信息给客户端Binlog
至少传输到了一个从节点上,否则需要等待直到超时时间,然后切换成异步模式再提交。数据分布 (Data distribution )
—提高数据操作自然并行度,以达到最优的执行效率的目的负载平衡(load balancing)
—主服务器只负责写,而从服务器只负责读备份(Backups)
—灾难恢复,对损坏的数据进行恢复和还原高可用性和容错行( High availability and failover)
—确保 mysql 数据库在故障和异常情况下仍然能够提供可靠的服务复制整体来说有 3
个步骤:
master
将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events)slave
将master
的binary log events拷贝到它的中继日志(relay log)slave
重做中继日志中的事件,将改变反映它自己的数据克隆两台安装好mysql8.0的虚拟机,并修改复制的db-server02(从节点)mysql server的UUID。
[root@db-server ~]# vi /var/lib/mysql/auto.cnf
####修改UUID
[auto]
server-uuid=83822642-0030-11ee-a2cc-000c29c2e1ad
####重启mysql服务
[root@db-server ~]# systemctl restart mysqld
mysql服务器 | Ip |
---|---|
db-server(主节点) | 192.168.181.101 |
db-server02(从节点) | 192.168.181.102 |
###创建二进制日志存储路径
[root@db-server /]# mkdir -p -v /var/log/mysql/mysql-bin
mkdir: created directory ‘/var/log/mysql/mysql-bin’
###赋权mysql用户组合mysql用户
[root@db-server ~]# chown -R mysql:mysql /var/log/mysql
[root@db-server ~]# chown -R mysql:mysql /var/log/mysql/mysql-bin
【必须参数】:
####添加内容
[mysqld]
#配置唯一的服务器ID,一般使用IP最后一位
server-id=1
# 设置需要复制的数据库,默认全部记录。比如: binlog-do-db=db_master_slave
binlog-do-db=db_master_slave
#开启log-bin二进制日志,指名路径。如: 本地的路/var/log/mysql/mysql-bin
log-bin=/var/log/mysql/mysql-bin
#设置binlog格式
binlog_format=STATEMENT
【可选参数】:
# 0表示读写 (主机),1表示只读(从机)
read-only=0
#设置日志文件保留的时长,单位是秒
binlog_expire_logs_seconds=6000
#控制单个二进制日志大小。此参数的最大和默认值是1GB
max_binlog_size=20
#设置不要复制的数据库
binlog-ignore-db=test
#设置需要复制的数据库,默认全部记录。比如: binlog-do-db=dbtest01
binlog-do-db=需要复制的主数据库名字
#设置binlog格式
binlog_format=STATEMENT
[root@db-server mysql]# systemctl restart mysqld
[root@db-server mysql]# systemctl status mysqld
[root@db-server mysql]# mysql -u root -p
mysql> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 1 |
+---------------+-------+
1 row in set (0.02 sec)
mysql>
###开启log-bin二进制日志
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.00 sec)
mysql>
##skip_networking--tcp/ip协议通信,默认是OFF关闭状态,启用后主从将无法通信
mysql> show variables like '%skip_networking%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| skip_networking | OFF |
+-----------------+-------+
1 row in set (0.00 sec)
mysql>
mysql> grant replication slave on *.* to 'slave1'@'%' identified by 'Zyl@123456'; ###用户地址可以指定从机IP192.168.181.102
mysql> create user 'slave1'@'%' identified by 'Zyl@123456';
Query OK, 0 rows affected (0.02 sec)
mysql>grant replication slave on *.* to 'slave1'@'%';
Query OK, 0 rows affected (0.01 sec)
mysql>alter user 'slave1'@'%' identified with mysql_native_password by 'Zyl@123456';
Query OK, 0 rows affected (0.02 sec)
mysql>flush privileges;
Query OK, 0 rows affected (0.02 sec)
mysql> show master status;
+------------------+----------+-----------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+-----------------+------------------+-------------------+
| mysql-bin.000004 | 157 | db_master_slave | | |
+------------------+----------+-----------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql>
【必须参数】:
[mysqld]
#配置唯一的服务器ID,一般使用IP最后一位
server-id=2
###开启中继日志,从主服务器上同步日志文件记录到本地
relay-log=relay-log-bin
【可选参数】:
[mysqld]
###定义中继日志文件的位置和名称
relay-log-index=slave-relay-bin.index
####语法##
change master to
master_host='主节点IP',
master_user='主节点用户名',
master_password='用户密码',
master_log_file='mysql-bin.具体数字',
master_log_pos=具体值;
####本环境配置##
mysql> change master to master_host='192.168.181.101',master_user='slave1',master_password='Zyl@123456',master_log_file='mysql-bin.000004',master_log_pos=157 ;
Query OK, 0 rows affected, 8 warnings (0.06 sec)
mysql>
####开启slave同步
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.05 sec)
####查看同步状态
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.181.101
Master_User: slave1
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 157
Relay_Log_File: relay-log-bin.000006
Relay_Log_Pos: 373
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
mysql>
⛳ 主要看这两个参数,两个参数的值都为Yes
,即主从配置搭建成功:
Slave_IO_Running
:IO线程,负责与主机的io通信Slave_SQL_Running
:SQL线程,责自己的slave MySQL进程如果报错Slave failed to initialize relay_log info structure from the repository
,需要清理之前的relay_log,重新启用新的relay_log即可。
reset slave;
db_master_slave
库####主节点创建数据库db_master_slave
mysql> create database db_master_slave;
Query OK, 1 row affected (0.01 sec)
mysql> use db_master_slave
Database changed
mysql>
####创建表
mysql> CREATE TABLE `tab1` (
-> `id` int NOT NULL,
-> `name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
-> `class` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
-> PRIMARY KEY (`id`) USING BTREE
-> ) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;
Query OK, 0 rows affected, 6 warnings (0.02 sec)
mysql>
####插入测试数据
mysql> INSERT INTO `tab1` VALUES (1001, '曹操', '1班');
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO `tab1` VALUES (1002, '张飞', '1班');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO `tab1` VALUES (1003, '项羽', '3班');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO `tab1` VALUES (1004, '刘备', '2班');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> show databases;
###查看tab1表数据
mysql> select * from tab1;
+------+--------+-------+
| id | name | class |
+------+--------+-------+
| 1001 | 曹操 | 1班 |
| 1002 | 张飞 | 1班 |
| 1003 | 项羽 | 3班 |
| 1004 | 刘备 | 2班 |
+------+--------+-------+
4 rows in set (0.00 sec)
mysql>
从机执行
####开启slave同步
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.05 sec)
####关闭slave同步
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.03 sec)
主从同步复制的内容是二进制文件,在传输过程中会存在主从延迟
的情况,会导致用户在从库读取的数据不是最新数据
----->即数据不一致性
问题。
master
执行操作后直接返回给client
结果,不再等待slave
反馈同步信息,但这种方式数据一致性最弱。slave
复制了该事务并成功执行完就返回成功信息给client
,这种方式提高了数据一致性,但是增加了网络延迟时间,降低了主库写的效率。❓ 了解何为主从复制
❓ mysql支持的复制类型之间区别,以及解决的问题
❓ mysql主从复制搭建
❓ mysql主从复制延迟及解决方案
【上一篇】 |
The End 点点关注,收藏不迷路
|
【下一篇】 |