一、mysql 同步复制有关概述
一般数据库都是读取压力大于写数据压力,主从复制即为了实现数据库的负载均衡和读写分离。通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,主服务器只负责写,而从服务器只负责读。
如生产环境中,使用redis数据库作为缓存数据库,用户访问业务数据时,先从缓存数据库查询,如果缓存数据库没有,再从业务数据库读取。架构图如下
1.1 mysql支持的复制方式
-
基于语句的复制
--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 '新密码';
1.2 mysql支持的复制类型
1.2.1异步复制
mysql
数据库默认的复制方式- 异步复制指主库以异步的方式同步数据到一个从库或多个从库中。
- 主节点
不会主动推送数据
到从节点,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理。 - 主节点如果掉了,此时主节点上已经提交的事务可能并没有传到从节点上,如果此时,强行将从节点提升为主节点,可能导致新主节点上的
数据不完整
。
1.2.2 同步复制
- 同步复制是
mysql
主节点特有的复制方式,当主库执行完一个事务,然后所有的从库都复制了该事务并成功执行完才返回成功信息给客户端。
1.2.3 半同步复制
- 介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到
relay log
中才返回成功信息给客户端 - 只能保证主库的
Binlog
至少传输到了一个从节点上,否则需要等待直到超时时间,然后切换成异步模式再提交。
1.2.4 异步复制 / 同步复制 / 半同步复制(图)
1.3 mysql复制解决的问题
数据分布 (Data distribution )
---提高数据操作自然并行度,以达到最优的执行效率的目的负载平衡(load balancing)
---主服务器只负责写,而从服务器只负责读备份(Backups)---灾难恢复
,对损坏的数据进行恢复和还原高可用性和容错行( High availability and failover)
---确保 mysql 数据库在故障和异常情况下仍然能够提供可靠的服务
1.4 mysql复制是如何工作的
复制整体来说有 3
个步骤:
master
将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events)slave
将master
的binary log events拷贝到它的中继日志(relay log)slave
重做中继日志中的事件,将改变反映它自己的数据
二、mysql 同步复制搭建
mysql服务器 | IP |
---|---|
Master(主节点) | 192.168.88.1 |
Slave1(从节点) | 192.168.88.2 |
2.1 主节点配置
#创建二进制日志存储路径
mkdir /var/log/mysql/mysql.binlog/
#授权,如果/var/log/mysql 请先给这个目录授权
chown -R mysql:mysql /var/log/mysql/mysql.binlog
2.2 添加my.cnf参数
必须添加内容如下:
[mysqld]
#二进制日志存储路径
log-bin=/var/log/mysql/mysql.binlog
#配置唯一的服务器ID,一般使用IP最后一位
server-id=1
#设置binlog格式
binlog-format=MIXED
可选参数
# 0表示读写 (主机),1表示只读(从机)
read-only=0
#设置日志文件保留的时长,单位是秒
binlog_expire_logs_seconds=6000
#控制单个二进制日志大小。此参数的最大和默认值是1GB
max_binlog_size=20
#设置不要复制的数据库
binlog-ignore-db=test
#设置需要复制的数据库,不写参数则默认全部记录,可以填写多个
binlog-do-db=需要复制的主数据库名字
例如:
binlog-do-db=dbtest01
binlog-do-db=dbtest02
#设置binlog格式
binlog_format=STATEMENT
下面是我常用的配置,可以参考一下
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/usr/local/mysql/data/mysql.sock
pid_file=/usr/local/mysql/data/mysql.pid
port=3306
collation-server =utf8mb4_general_ci
character_set_server=utf8mb4
user=mysql
#主从配置
log-bin=/var/log/mysql/mysql.binlog
server-id=1
binlog-format=MIXED
#日志
log_error=/usr/local/mysql/data/mysql_errol.log
general=1
general_log_file=/usr/local/mysql/data/mysql_genaral.log
slow_query_log=1
slow_query_log_file=/usr/local/mysql/data/mysql_slow_query.log
#InnoDB
innodb_buffer_pool_size= 128M
innodb_log_file_size= 128M
innodb_file_per_table=1
innodb_flush_method= O_DIRECT
#其他配置
#临时表最大值
tmp_table_size = 32M
#内存堆表最大值
max_heap_table_size = 32M
#最大连接数,理想数为占比服务器上限的10%
max_connections = 1700
#线程缓存大小
thread_cache_size = 384
#表缓存大小,可减少文件打开/关闭次数,一般max_connections*2。
table_open_cache = 1024
#打开文件上线
open_files_limit = 65535
[client]
socket =/usr/local/mysql/data/mysql.sock
port =3306
2.3 检查是否生效
#看看配置的id是否生效
mysql> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 1 |
+---------------+-------+
1 row in set (0.00 sec)
#是否开启二进制日志
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.00 sec)
#默认是OFF关闭状态,启用后主从将无法通信
mysql> show variables like '%skip_networking%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| skip_networking | OFF |
+-----------------+-------+
1 row in set (0.00 sec)
2.4 主节点创建主从复制账号
#创建slave1用户
mysql> create user 'slave1'@'%' identified by 'lmx123';
Query OK, 0 rows affected (0.01 sec)
#给slave1授权
mysql> grant replication slave on *.* to 'slave1'@'%';
Query OK, 0 rows affected (0.00 sec)
#使用mysql_native_password插件认证
mysql> alter user 'slave1'@'%' identified with mysql_native_password by 'lmx123';
Query OK, 0 rows affected (0.00 sec)
#刷新
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
2.5 查看主节点的二进制日志的名称
其中File和Position两个参数需要在从库配置中使用
mysql> show master status;
+--------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+--------------+----------+--------------+------------------+-------------------+
| mysql.000011 | 2388 | | | |
+--------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
2.6 从节点配置
添加my.cnf参数
[mysqld]
#配置唯一的服务器ID,一般使用IP最后一位
server-id=2
#开启中继日志,从主服务器上同步日志文件记录到本地
relay-log=relay-log-bin
可选参数
#定义中继日志文件的位置和名称
relay-log-index=slave-relay-bin.index
2.7 在从节点配置需要复制的主机
mysql> change master to master_host='192.168.88.1',master_user='slave1',
-> master_password='lmx123',master_log_file='mysql.000011',master_log_pos=2388;
Query OK, 0 rows affected, 8 warnings (0.01 sec)
#语法
change master to
master_host='主节点IP',
master_user='主节点用户名',
master_password='用户密码',
master_log_file='mysql-bin.具体数字',
master_log_pos=具体值;
2.8 在从节点开启slave同步,查看同步状态
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.88.1
Master_User: slave1
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql.000011
Read_Master_Log_Pos: 2388
Relay_Log_File: relay-log-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql.000011
Slave_IO_Running: Yes
Slave_SQL_Running: 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;
三、测试主从同步
-
主节点添加
a
库mysql> create database a;
Query OK, 1 row affected (0.00 sec)#添加a1表
mysql> create table a1(id int,name varchar(10),class varchar(10));
Query OK, 0 rows affected (0.01 sec)#插入数据
mysql> insert into a1 values(1,'喜羊羊','1班'),(2,'美羊羊','2班'),(3,'喜懒羊','3班');
Query OK, 3 rows affected (0.05 sec)
Records: 3 Duplicates: 0 Warnings: 0 -
从库查看同步数据
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| a |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)mysql> use a;
mysql> select * from a1;
+------+-----------+-------+
| id | name | class |
+------+-----------+-------+
| 1 | 喜羊羊 | 1班 |
| 2 | 美羊羊 | 2班 |
| 3 | 喜懒羊 | 3班 |
+------+-----------+-------+
3 rows in set (0.00 sec)#删除数据
mysql> delete from a1 where id=1;
Query OK, 1 row affected (0.00 sec)#查看从库
mysql> select * from a1;
+------+-----------+-------+
| id | name | class |
+------+-----------+-------+
| 2 | 美羊羊 | 2班 |
| 3 | 喜懒羊 | 3班 |
+------+-----------+-------+
2 rows in set (0.01 sec)
四、主从同步关闭和开启
#开启slave同步
mysql> start slave;
#关闭slave同步
mysql> stop slave;
#重启slave同步
mysql> reset slave;
五、部署主从常见的问题
权限问题
报错原因 :错误代码 1130
表示连接被拒绝,通常是因为用户权限或网络配置问题。在你的情况下,错误信息指出从库尝试连接到主库时被拒绝了,原因是主机 192.168.88.2
没有被允许连接到主库的MySQL服务器。
-
检查用户权限
#请将'replication_user'@'slave_host'更换为实际的用户名
SHOW GRANTS FOR 'replication_user'@'slave_host';#如果权限有问题请在主库更改为以下权限
GRANT REPLICATION SLAVE ON . TOslave1
@%
插件认证问题
**报错原因:**表示从库在尝试连接到主库时遇到了认证插件问题。具体来说,它使用了 caching_sha2_password
认证插件,但该插件要求使用安全连接(即加密连接)。
-
使用插件认证
#请将'slave1'@'%'更换为实际用户名
mysql> alter user 'slave1'@'%' identified with mysql_native_password by 'lmx123';
IO线程问题
报错原因:无法在运行的从库 I/O 线程上执行此操作
-
停止线程
#停止特定的,将'channel_name'更换成实际的名称
STOP SLAVE IO_THREAD FOR CHANNEL 'channel_name';#如果只有一个默认的复制通道,可以省略 FOR CHANNEL 部分
STOP SLAVE IO_THREAD;
以上就是部署主从的全部过程了,如有帮助请点赞收藏,谢谢!