MySQL主从部署(保姆版)

一、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)
  • slavemaster的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 . TO slave1@%

插件认证问题

**报错原因:**表示从库在尝试连接到主库时遇到了认证插件问题。具体来说,它使用了 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;

以上就是部署主从的全部过程了,如有帮助请点赞收藏,谢谢!

相关推荐
这猪好帅22 分钟前
【Redis】初识Redis
数据库·redis·缓存
网络安全-老纪35 分钟前
网络安全的几种攻击方法
网络·数据库·web安全
蒜蓉大猩猩1 小时前
Node.js --- 详解MongoDB与Mongoose
数据库·后端·mongodb·node.js
张声录12 小时前
【ETCD】【源码阅读】深入探索 ETCD 源码:了解 `Range` 操作的底层实现
java·数据库·etcd
VX_CXsjNo12 小时前
免费送源码:Java+ssm+Android 基于Android系统的外卖APP的设计与实现 计算机毕业设计原创定制
android·java·css·spring boot·mysql·小程序·idea
命运之手2 小时前
[ Spring ] Install MySQL on Unbuntu24
mysql·ubuntu24
weixin_438197382 小时前
mysql存储过程创建与删除(参数输入输出)
数据库·sql·mysql
V+zmm101342 小时前
基于微信小程序的汽车销售系统的设计与实现springboot+论文源码调试讲解
java·数据库·spring boot·微信小程序·小程序·毕业设计
cg50173 小时前
Mysql 和 navicat 的使用
数据库·mysql
芊言芊语3 小时前
纯 Python、Django、FastAPI、Flask、Pyramid、Jupyter、dbt 解析和差异分析
数据库·sqlite