什么是主从复制

使用两个或两个以上的数据库,一部分数据库当做主数据库,而另一部分数据库当做从数据库。系统在主数据库中进行写操作,从数据库记录在主库上所有的写操作,使得主从数据库的数据保持一致。

一旦主数据库出现问题时,使用从数据库代替主数据库,可以避免服务中断。

什么是读写分离

读写分离是基于主从复制的。系统操作数据库中的数据时,将对数据的增删改也就是写操作,发送到主数据库,将查询的任务交给从数据库。

写操作一般相比读操作更耗时,而系统在大多数情况下都是读多写少。进行读写分离,减少读写操作相互影响,既能提高查询效率,也能减轻主数据库的压力,提高系统性能。

主从复制原理

下图为网上找的一张介绍主从复制的原理图。

简单来讲,有以下四个关键点:

1、主数据库开启bin-log,将所有写操作的sql语句记录到日志文件中。

2、每当有从库连接到主库的时候,主库都会创建一个线程(master bin-log输出线程),用于发送bin-log内容到从库。

3、从数据库开启中继日志relay-log,用于同步回来的主数据库bin-log。

4、从数据库中运行2个线程,一个线程(slave

I/O线程)连接到主库,获取主数据库bin-log日志文件里的SQL,记录到本机的中继日志relay-log文件里,另一个线程(slave

SQL线程)执行本机relay-log文件里的SQL语句,在从数据库重新执行一遍数据操作,保持主从数据库的数据一致。

复制模式介绍

异步复制

说明:MySQL默认的复制模式。主库在执行完客户端提交的事务后,立即将结果返回给客户端,而不等待从库接收处理。

问题:一旦主数据库宕机,已经提交的事务可能并没有传到从数据库上,此时如果进行主备切换,会导致新主库上的数据不完整,牺牲了数据的一致性。

全同步复制

说明:当主库和从库执行完客户端提交的事务后,才返回结果给客户端。

问题:虽然保证了在任何情况下的数据一致性,当由于需要等待所有数据库执行完该事务才能返回结果,操作耗时长,牺牲了性能。

半同步复制

说明:主库在执行完客户端提交的事务后,等待至少一个从库接收到并写到中继日志后,才返回结果给客户端。

相对于异步复制和半同步复制,是保证数据一致性和性能的折中方案。需要注意的是,半同步需要等待从库响应,因此对于网络要求高,仅适用于低延时的网络。

主从复制方案

下图为常见的主从复制的方案。

一主一从:从机可以作为数据的热备,当主节点宕机,备节点顶替。但需要注意的是,并不能代替数据备份,因为错误的操作,也会同步到备节点,数据仍会丢失。

一主多从:适用于读多写少的系统,但从库不可过多,过多会导致响应速度变慢。可以指定一个从库作为备用库,当主节点宕机,备节点顶替。也可以指定一个从库,将报表统计之类的慢查询语句都发到该从库,不至于影响其他查询操作。也可以指定一个从库,供开发人员排障使用,即使不小心删除数据,也不至于影响整体系统业务数据准确性,达到隔离效果。

双主:当大部分业务都为写,而写入性能还不够理想,可以采取双主模式。同时在两个主库写数据,并互相同步。业务上可以通过id取模、哈希计算等方法,奇数往主库1插数据,偶数往主库2插数据,保证主键不重复。

级联同步:为了减低主库的压力,主库只向一个从库同步数据,其他从库同步这个从库的数据。如果主库宕机,同步主库的从库可以直接作为主库使用。但如果这个从库挂了,问题会比较严重,会导致其他从库变为孤儿节点。

环形多主:性能强,但一旦挂了一个,会导致整个系统不可用。

使用Docker 搭建MySQL主从复制

以下演示使用Docker,搭建一主一从的数据库系统。

1、运行docker pull mysql:5.7下载mysql镜像。

2、在/opt目录下创建三个文件夹,分别为/opt/mysql_cluster、/opt/mysql_cluster/master和/opt/mysql_cluster/slave1。其中master和slave1文件夹用于保存需要持久化到宿主机上mysql容器的数据文件、日志文件等。

3、在/opt/mysql_cluster/master编写my.cnf文件,内容如下。需要注意的是,开启bin-log日志后默认记录所有库所有表的操作,可以通过配置来指定需要记录操作的数据库或者表,或指定不记录操作的数据库或者表。[mysqld]

#实例ID,不能和集群中的其他实例相同

server-id=1

#bin log 文件前缀

log-bin=mysql-prefix

# 需要同步的数据库

binlog-do-db=tuling

#不需要同步的数据库

binlog-ignore-db=information_schema

binlog-ignore-db=mysql

binlog-ignore-db=performance_schema

binlog-ignore-db=test

4、在/opt/mysql_cluster/slave1编写my.cnf文件,内容如下:[mysqld]

#实例ID,不能和集群中的其他实例相同

server-id=2

skip-slave-start=true

#限定用户进行数据修改的操作

read_only=ON

#中继日志前缀

relay-log=relay-bin

5、运行以下命令,启动主数据库。向外暴露的端口号为3307,默认的密码为123456,并且挂载宿主机目录到容器中,用于将数据保存到宿主机,保证数据不丢失。docker run -p 3307:3306 --name mysql_master \-v /opt/mysql_cluster/master/conf:/etc/mysql \-v /opt/mysql_cluster/master/logs:/var/log/mysql \-v /opt/mysql_cluster/master/data:/var/lib/mysql \ -v /opt/mysql_cluster/master/my.cnf:/etc/my.cnf \-e MYSQL_ROOT_PASSWORD=123456 \-d mysql:5.7

6、运行docker exec -it mysql_master /bin/bash,进入主数据库容器。

7、运行mysql -uroot -p,输入密码,登录数据库。

8、运行以下命令,添加访问权限,刷新授权表信息,方便后续在其他机器操作该数据库。grant all privileges on *.* to root@'%' identified by "123456";flush privileges;

9、运行以下命令,添加主库复制账号,刷新授权表信息。用户名和密码都是slave。后续从库使用该账号,获取相关bin-log。CREATE USER 'slave'@'%' IDENTIFIED BY 'slave';GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';flush privileges;

10、运行命令show master status;,获取主库当前bin-log文件名(File)和位置(Position)。

11、运行以下命令,启动从数据库。向外暴露的端口号为3308,默认的密码为123456,并且挂载宿主机目录到容器中,用于将数据保存到宿主机,保证数据不丢失。docker run -p 3308:3306 -m 300M --memory-reservation 200M --name mysql_slave \-v /opt/mysql_cluster/slave1/conf:/etc/mysql \-v /opt/mysql_cluster/slave1/logs:/var/log/mysql \-v /opt/mysql_cluster/slave1/data:/var/lib/mysql \ -v /opt/mysql_cluster/slave1/my.cnf:/etc/my.cnf \-e MYSQL_ROOT_PASSWORD=123456 \-d mysql:5.7

12、运行docker exec -it mysql_slave /bin/bash,进入从数据库容器。

13、运行mysql -uroot -p,输入密码,登录数据库。

14、运行以下命令,添加访问权限,刷新授权表信息。方便后续在其他机器操作该数据库。grant all privileges on *.* to root@'%' identified by "123456";flush privileges;

15、运行以下命令,配置从库复制信息。其中,master_host为docker宿主机的ip,master_user和master_slave为主库复制账号,master_log_file是主库运行命令show master status获取的File字段值,master_log_pos为Position字段值。master_port为主数据库向外暴露的端口号。change master to master_host='192.168.255.167',master_user='slave',master_password='slave',master_log_file='mysql-prefix.000004',master_log_pos=1824,master_port=3307;

16、运行start slave;,启动slave服务。

17、运行show slave status\G;,查看slave状态。当参数"Slave_IO_Running"和"Slave_SQL_Running"值都是Yes,主从配置完成。

18、可以通过在主库创建表、插入修改数据后,查看从库是否同步成功,验证是否搭建成功。

19、当需要重新配置主从时,可以在从库上运行以下两条命令,取消当前的主备复制。stop slave;reset master;

mysql df_MySQL主从复制实战相关推荐

  1. 基于Docker部署Mysql主从复制-实战详解篇

    一.前言 MySQL的主从复制详细讲解,根据网上教程也踩了很多坑,浪费了一些时间 ,特地全面的梳理下基于docker构建的mysql主从复制构建过程.遇到的问题以及提供安装包样例等 希望一篇文章足以解 ...

  2. MySQL的主从复制详解

    主从复制:将主数据库中的DDL和DML操作通过二进制日志(BINLOG)传输到从数据库上,然后将这些日志重新执行(重做):从而使得从数据库的数据与主数据库保持一致.当系统访问量大时,单数据库可能无法保 ...

  3. Windows下MySql主从配置实战教程

    Windows下MySql主从配置实战教程 MySql的主从配置教程 主库MySql的安装 1.MySQL的下载 2.MySQL配置文件的编写 3.初始化数据库 4.安装服务 5.启动MySql 6. ...

  4. mysql之主从复制

    MySQL主从复制介绍 MySQL的主从复制是其自带的功能,通过逻辑的binlog日志复制到要同步的服务器本地,主服务器(Master),接收来自用户的内容更新,而一个或多个其他的服务器充当从服务器( ...

  5. 从前慢-Mysql高级及实战

    Mysql高级及实战 1 Linux 系统安装MySQL 1.1 下载Linux 安装包 https://dev.mysql.com/downloads/mysql/5.7.html#download ...

  6. 开发人员MySQL调优-实战篇2-让SQL使用索引详解

    2019独角兽企业重金招聘Python工程师标准>>> 建议先看看开发人员MySQL调优-实战篇0 让执行的SQL使用索引 虽然DBA给我们建了很多索引,但没有经验的开发人员往往只看 ...

  7. [实战]MVC5+EF6+MySql企业网盘实战(16)——逻辑重构3

    写在前面 本篇文章将新建文件夹的逻辑也进行一下修改. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网盘实战(1) [实战]MVC5 ...

  8. mysql的主从复制是如何实现的

    前言 MySQL的主从复制是MySQL本身自带的一个功能,不需要额外的第三方软件就可以实现,其复制功能并不是copy文件来实现的,而是借助binlog日志文件里面的SQL命令实现的主从复制,可以理解为 ...

  9. mysql的主从复制原理与实现

    关于mysql的主从复制,之前一直在听说这个话题,一直没有实现,昨天学习了下,原来是这么回事: 既然是主从复制,那么肯定有主有从,也就说一个主数据库(一般为写库),一个从数据库(读库).主数据库更新了 ...

最新文章

  1. Fragment 之间传递数据
  2. 越南一难倒博士的趣味数学题
  3. 高校计算机通识教育目标,美国高校计算机通识教育研究
  4. mysql workbench kernelbase.dll_电脑出现kernelbase.dll错误的两种解决方法
  5. 探究oracle clob字段是怎样存储的
  6. git钩子放服务器_如何在GitLab中添加服务器端的预接收钩子?
  7. ubuntu 11.10 添加分辨率
  8. class文件打成jar包
  9. 圣诞素材ae模板-圣诞节日聚会派对视频素材ae模板
  10. VS2017 Community C++模块 离线打包安装
  11. 防病毒网关、防火墙与防病毒软件功能及部署对比
  12. 软件测试岗简历模板制作指南
  13. 物联网平台发展的4个阶段和5个实践案例
  14. NOIP2016普及组复赛全国一等奖名单及排名(1~745名)
  15. Linux常用命令 shell脚本for QA-数据脱敏版2
  16. 空格、NBSP 造成的 JSON 解析失败问题
  17. c语言将大小写字母互换,C语言编程:大小写互换
  18. 什么是配置管理?配置管理由专人负责吗?
  19. 数据库45道SQL作业题及答案
  20. vivado flash启动时间提速设置

热门文章

  1. html自定义列表 嵌套,HTML 列表
  2. footer置底的几种方式
  3. js中 json详解
  4. PHP中全局变量的使用global和$GLOBALS[]
  5. js计算浮点数出现小数;解决js计算小数问题;js数组相加出现小数;
  6. JAVA进阶day07JNI(java调用c)B部分
  7. [react] 在React中声明组件时组件名的第一个字母必须是大写吗?为什么?
  8. React开发(125):ant design学习指南之form中的hasFeedback
  9. 前端学习(3132):react-hello-react之react中事件处理
  10. [html] 你有使用过output标签吗?说说它的用途有哪些?