当前位置: 首页 > news >正文

MySQL数据库复制

文章目录

  • MySQL数据库复制
    • 一、复制的原理
    • 二、复制的搭建
      • 1.编辑配置文件
      • 2.在主库上创建复制的用户
      • 3.获取主库的备份
      • 4.基于从库的恢复
      • 5.建立主从复制
      • 6.开启主从复制
      • 7.查看主从复制状态

MySQL数据库复制

MySQL作为非常流行的数据库,支撑它如此出彩的因素主要有两个,InnoDB存储引擎和复制。InnoDB存储引擎支持事务、行级别锁、MVCC。基于此,MySQL能实现高并发。而复制可以将主库的数据同步到另一个实例,基于此我们可以实现读写分离和数据容灾。

一、复制的原理

MySQL主从复制的核心原理是通过二进制日志(binlog)实现的,熟悉Oracle的同学会问:MySQL不是有redo log吗?为什么不直接基于redo log来实现呢?
实际上redo log是InnoDB存储引擎独有的,作为一个支持可插拨存储引擎的数据库,MySQL不仅支持InnoDB存储引擎,还支持MyISAM、CSV、Memory等存储引擎,对于这些存储引擎的操作同样需要持久化到binlog中。

在这里插入图片描述

MySQL的复制主要涉及以下3个线程:

  • 主库 binlog dump 线程
  • 从库 I/O 线程
  • 从库 SQL 线程

MySQL的复制其运作流程大致如下:

  1. 从库执行完START SLAVE命令后,会创建两个线程:I/O线程SQL线程
  2. I/O线程会建立一个到主库的连接,相应地,主库会创建一个binlog dump线程来响应这个连
  3. 接的请求。此时,对于主库来说,从库的1/O线程就是一个普通的客户端。
  4. I/O线程首先告诉主库应该从何处开始发送二进制日志事件。
  5. 主库的binlog dump线程开始从指定位置点读取二进制日志事件,并发送给I/O线程。
  6. I/O线程接收到二进制日志事件后,会将其写入relay log
  7. SQL线程读取relay log中的二进制日志事件,然后进行重放。

二、复制的搭建

实验版本为 MySQL 8.0.41,部署MySQL异步复制,机器环境如下, 需要分别提前安装数据库软件以及初始化好数据库实例,可以参考我之前的《MySQL数据库安装》的文章

角色IP
主库192.168.50.121
从库192.168.50.122

1.编辑配置文件

主库编辑/etc/my.cnf文件

[mysqld]
basedir = /usr/local/mysql
datadir = /data/mysql/3306/data
socket = /data/mysql/3306/data/mysql.sock
server-id = 1
log-bin = mysql-bing
user = mysql
port = 3306
log-error = /data/mysql/3306/data/mysqld.err
log-timestamps = system

从库/etc/my.cnf文件

[mysqld]
basedir = /usr/local/mysql
datadir = /data/mysql/3306/data
socket = /data/mysql/3306/data/mysql.sock
server-id = 2
log-bin = mysql-bing
user = mysql
port = 3306
log-error = /data/mysql/3306/data/mysqld.err
log-timestamps = system

这里给出的只是搭建复制最简单的参数:

  • log-bin 开启 binlog , 这里的mysql-binbinlog文件的前缀(8.0之后的版本可以不用配置该数,但会习惯性的进行设置)
  • server-id 是服务端ID, 在一个复制组内必需全局唯一,有效值为 1~2^32^-1

注意事项:

  • server-id 支持在线调整,但开启binlog 需要重启实例
  • MySQL8.0之前,binlog默认是关闭的,不显示设置log-bin参数,则不开启binlog。而在MySQL8.0中,binlog默认是开启的,如果要关才binlog,需要显示设置skip_log_bindisable_log_bin

2.在主库上创建复制的用户

在MySQL 8.0 之前可以直接使用第二第命令会隐式创建用户,但官方不推荐这种方式。

create user 'repl'@'192.168.50.122' identified by 'test123';

grant replication slave on *.* to 'repl'@'192.168.50.122';

创建用户后在从库环境验证帐号是否能正常登陆

mysql -urepl -ptest123 -h 192.168.50.121

3.获取主库的备份

这里使用mysqldump工具进行备份,备份集通过scp命令拷贝到从库

mysqldump -uroot -ptest123 -S /data/mysql/3306/data/mysql.sock --single-transaction --source-data=2 -E -R --triggers -A > full_backup.sql

scp  full_backup.sql 192.168.50.122:/data

MySQL 8.0.26开始,开始使用 --source-data 代替之前版本的 --master-data 否则备份文件中会写入以下信息,影响到后续的导入。

WARNING:–master-data is deprecated and will be removed in a future version.use --source-data instead.

4.基于从库的恢复

在从库对备份文件进行导入

mysql -uroot -ptest123 -S /data/mysql/3306/data/mysql.sock < /data/full_backup.sql

5.建立主从复制

在从库执行 CHANGE MASTER TO命令创建主从关系

change master to
master_host='192.168.50.121',
master_port=3306,
master_user='repl',
master_password='test123',
master_log_file='mysql-bing.000001',
master_log_pos=717;

参数具体含义:

参数作用
master_host主库的主机信息,可以为主机名或IP
master_port主库端口,若不指定则默认为3306
master_use复制的用户名
master_password复制用户的密码
master_log_file从库I/O线程启动时,应该从主库的哪个binlog由这个参数决定
master_log_posI/O线程确定binlog后,从哪个位置开始读取二进制日志事件.

我们在备份的时候通过 mysqldump 指定的 --source-data=2 (旧版本用--master-data=2) 他会将备份时的binlog位置信息记录到备份文件中,内容如下

--
-- Position to start replication or point-in-time recovery from
--

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bing.000001', MASTER_LOG_POS=717;


当从库执行完CHANGE MASTER TO命令后,复制的相关信息会保存在两张表中:mysqL.slave_master.infomysql.slave_relay_.log_info

mysql.slave_master_.info主要记录了两类信息:

  • 主库的连接信息,包括主库的IP、端口、复制用户和密码;
  • I/O线程读取的主库binlog的位置点信息。

注意,这个位置点不是实时更新的,它的更新频率与sync_master_.info参数有关。该参数默认为10000,即I/O线程每写入10000个事务会更新mysql.slave_.master_info一次。

mysql.slave_relay_log_info主要记录了以下信息:

  • SQL线程重放relay log的位置点信息。

事务每次提交时都会更新mysqL.slave._relay._log_info

这两张表是MySQL5.6引入的。在此之前复制的相关信息保存在master.info(对应mysql.slave_master.info表)和relay-log.info(对应mysql.slave_.relay_.log_info表)文件中,这两个文件默认位于从库的数据目录下。复制的相关信息是保存在文件还是系统表中由master_info_repository参数决定,其中,FILE代表文件,TABLE代表系统表。从MySQL8.0.2开始,该参数的默认值由FILE调整为TABLE。

6.开启主从复制

在从库上执行如下以下命令

mysql> start slave;

7.查看主从复制状态

重点关注 Slave_IO_RunningSlave_SQL_Running 的结果均为YES代表主从复制搭建成功

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.50.121
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bing.000001
          Read_Master_Log_Pos: 717
               Relay_Log_File: mysql02-relay-bin.000003
                Relay_Log_Pos: 327
        Relay_Master_Log_File: mysql-bing.000001
             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:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 717
              Relay_Log_Space: 696
              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: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
                  Master_UUID: cdc9afd5-fcd8-11ef-9d33-000c29ea0d0a
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     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)

在上面使用 SHOW SLAVE STATUS 命令时,提示了warning通过 show warnings 可以看到,SHOW SLAVE STATUS 已被弃用, 代用SHOW REPLICA STATUS替代。

  • 实际上在MySQL 8.0.22 开始 start slavestop slaveshow slave stausshow slave hostsreset slave 命令都补弃用了,取而代之的是 start replicastop rplicashow replica statusshow replicasreset replica
  • MySQL8.O.23开始,CHANGE MASTER TO命令被弃用,取而代之的是CHANGE REPLICATION SOURCE TO
  • MySQL8.0.26开始,标识符(如系统参数、状态变量)中的MASTER、SLAVEMTS(multithreadedslave的缩写)将分别被SOURCE、REPLICAMTA(multithreaded applier的缩写)替换,这一点需要注意。
mysql> show warnings;
+---------+------+-------------------------------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                                           |
+---------+------+-------------------------------------------------------------------------------------------------------------------+
| Warning | 1287 | 'SHOW SLAVE STATUS' is deprecated and will be removed in a future release. Please use SHOW REPLICA STATUS instead |
+---------+------+-------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

在主库上执行 show processlist 命令,可以看到 ID为23 连接对应的即是 binlog dump线程。

mysql> show processlist\G;

*************************** 3. row ***************************
     Id: 23
   User: repl
   Host: 192.168.50.122:52016
     db: NULL
Command: Binlog Dump
   Time: 152
  State: Source has sent all binlog to replica; waiting for more updates
   Info: NULL

在从库是执行 show processlist 命令, 5和6 的连接分别为 I/O线程和SQL线程

mysql>  show processlist\G;
*************************** 1. row ***************************
     Id: 5
   User: system user
   Host: connecting host
     db: NULL
Command: Connect
   Time: 226
  State: Waiting for source to send event
   Info: NULL
*************************** 2. row ***************************
     Id: 6
   User: system user
   Host:
     db: NULL
Command: Query
   Time: 226
  State: Replica has read all relay log; waiting for more updates
   Info: NULL

至此一个简单的异步复制环境搭建完毕。

相关文章:

  • 轻量级嵌入式WebRTC开发:音视频通话EasyRTC纯C语言实现SFU/MCU架构与QoS优化
  • ENSP实验案例-企业局域网搭建实施设计方案(计算机毕业设计作品)
  • 使用 Golang 操作 MySQL
  • 版本控制器Git(2)
  • 2025.3.13总结
  • SvelteKit 最新中文文档教程(2)—— 路由
  • 版本控制泄露源码 .git
  • kotlin与MVVM结合使用总结(一)
  • (笔记)Linux加载内核驱动模块(第二种)
  • 腾龙T2000边缘计算网关:开启智能物联新时代
  • 爬虫逆向:Unicorn 详细使用指南
  • 华为云容器引擎应用场景
  • 算法每日一练 (11)
  • JavaScript-闭包
  • 22 - 天 TCPIP 四层模型是什么?Cookie、Session、Token 之间有什么区别?从网络角度来看,用户从输入网址到网页显示,期间发生了什么?
  • UART转AHB总线接口参考设计介绍
  • 【cocos creator】游戏优化,内存,性能,包体积大小,加载,drawcall优化
  • 函数调用汇编
  • iPaaS集成平台轻量化架构的重要性
  • xlua 运行原理
  • A股午后回暖,三大股指涨跌互现:港口板块重新走强,两市成交近1.1万亿元
  • “南昌航空一号”成功发射,赣江鄱阳湖有了专属卫星守护
  • 爬坡难下坡险,居民出行难题如何解?
  • 对谈|“大礼议”:嘉靖皇帝的礼法困境与权力博弈
  • 乌克兰官员与法德英美四国官员举行会谈
  • 中国恒大披露清盘进展:要求债权人提交债权证明表