• 主从复制


    一、什么是主从复制

    MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。

    主从复制的主要用途

    ① 读写分离:在开发工作中,有时候会遇见某个sql 语句需要锁表,导致暂时不能使用读的服务,这样就会影响现有业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。

    ② 数据实时备份,当系统中某个节点发生故障时,可以方便的故障切换

    ③ 高可用HA

    ④ 架构扩展:随着系统中业务访问量的增大,如果是单机部署数据库,就会导致I/O访问频率过高。有了主从复制,增加多个数据存储节点,将负载分布在多个从节点上,降低单机磁盘I/O访问的频率,提高单个机器的I/O性能。

    主从复制的规则

    ①每个slave只能有一个master。(一对一)

    ②每个slave只能有一个唯一的服务器ID。

    ③每个master可以有多个slave。(一对多)

    在主从复制过程中,最大的问题就是延时。

    二、几种主从复制的形式

    一主一从

    一主多从,提高系统的读性能

    一主一从和一主多从是最常见的主从架构,实施起来简单并且有效,不仅可以实现HA,而且还能读写分离,进而提升集群的并发能力。

    多主一从 (从5.7开始支持)

    多主一从可以将多个mysql数据库备份到一台存储性能比较好的服务器上。

    双主复制

    即互做主从复制,每个master既是master,又是另外一台服务器的slave。这样任何一方所做的变更,都会通过复制应用到另外一方的数据库中。

    级联复制

    级联复制模式下,部分slave的数据同步不连接主节点,而是连接从节点。因为如果主节点有太多的从节点,就会损耗一部分性能用于replication,那么我们可以让3~5个从节点连接主节点,其它从节点作为二级或者三级与从节点连接,这样不仅可以缓解主节点的压力,并且对数据一致性没有负面影响。

    三、主从复制原理

    MySQL主从复制涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread, SQL thread)运行在从节点,如下图所示:

    ① 主节点 binary log dump 线程

    当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。

    ② 从节点I/O线程

    当从节点上执行`start slave`命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地relay-log中。

    ③ 从节点SQL线程

    SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。

    对于每一个主从连接,都需要三个进程来完成。当主节点有多个从节点时,主节点会为每一个当前连接的从节点建一个binary log dump 进程,而每个从节点都有自己的I/O进程,SQL进程。从节点用两个线程将从主库拉取更新和执行分成独立的任务,这样在执行同步数据任务的时候,不会降低读操作的性能。比如,如果从节点没有运行,此时I/O进程可以很快从主节点获取更新,尽管SQL进程还没有执行。如果在SQL进程执行之前从节点服务停止,至少I/O进程已经从主节点拉取到了最新的变更并且保存在本地relay日志中,当服务再次起来之后,就可以完成数据的同步。

    要实施复制,首先必须打开Master 端的binary log(bin-log)功能,否则无法实现。

    slave会从master读取binlog来进行数据同步。主要有以下三个步骤:

    ① master将改变记录到二进制日志(binary log),这些记录过程叫做二进制日志事件(binary log events)。

    ② slave将master的binary log events拷贝到中继日志(relay log)。

    ③ slave重做中继日志中的事件,将改变应用到自己的数据库中。MySQL的复制是异步且串行化的。

    MySQL 主从复制默认是异步的模式。MySQL增删改操作会全部记录在binary log中,当slave节点连接master时,会主动从master处获取最新的bin log文件。并把bin log中的sql relay。

    四、Windows主从配置部署

    一主一从
    环境介绍及说明

    主库所在的操作系统:win7
    主库的版本:mysql-5.7.20-winx64.zip
    主库的ip地址:127.0.0.1
    主库的端口:3310

    从库所在的操作系统:win7
    从库的版本:mysql-5.7.20-winx64.zip
    从库的ip地址:127.0.0.1
    从库的端口:3316

    注:主库和从库版本可以一致也可以不一致,需要说明一点,如果两者版本不一致,一般主库的版本需要比从库的版本低,这样就可以避免由于版本问题,有些sql不能执行的问题。

    由于我下载的mysql都是解压版的,所以只需要把下载好的zip包解压到服务器上即可,就不需要安装了。

    主库(master)的安装及配置

    ① 进入主库mysql-5.7.20-winx64-master目录中,在此目录中新建my.ini文件并添加一下配置。

    具体文件内容如下,将里面的路径修改成你自己的主库路径。

    #==============================客户端的参数
    [client]
    #MySQL 客户端连接服务器端时使用的端口号,默认的端口号为 3306。如果需要更改端口号的话,可以直接在这里修改。
    port = 3310
    [mysql]
    #MySQL 客户端默认的字符集
    default-character-set=utf8
    
    #==============================服务端的参数
    [mysqld]
    
    #====主从复制关键配置 start======
    #主库和从库需要不一致,配一个唯一的ID编号,1至32。 手动设定
    server_id=1 
    #二进制文件存放路径,存放在根目录data
    log-bin=mysql-bin 
    #binlog-do-db=test #需要复制的库,多个库用逗号隔开,如果此项不配置所有主库都参与复制
    #binlog-ignore-db=mysql #不需要复制的库,和上项同理
    #====主从复制关键配置 end======
    
    #服务器端默认的字符集
    character-set-server=utf8
    #MySQL 服务器的端口号
    port = 3310
    #SQL 模式的参数,通过这个参数可以设置检验 SQL 语句的严格程度
    sql_mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"
    #创建数据表时,默认使用的存储引擎
    default_storage_engine=innodb
    #表示缓存的大小,InnoDB 使用一个缓冲池类保存索引和原始数据。
    innodb_buffer_pool_size=1000M
    #表示日志文件的大小
    innodb_log_file_size=50M
    # 设置mysql的安装目录
    basedir=C:installmysqlMSmysql-5.7.20-winx64-master
    # 设置mysql数据库的数据的存放目录
    datadir=C:installmysqlMSmysql-5.7.20-winx64-masterdata
    # 允许同时访问 MySQL 服务器的最大连接数
    max_connections=200
    # skip_grant_tables
    
    [mysql.server]
    default-character-set=utf8
    
    [mysql_safe]
    default-character-set=utf8

    ② cmd进入主库的bin目录中,执行:mysqld --install master --defaults-file="C:installmysqlMSmysql-5.7.20-winx64-mastermy.ini"

    其中的master为主库mysql的服务名称。

    ③ 输入 mysqld --initialize-insecure --user=mysql (执行完这条命令后,MySQL会自建一个data文件夹,并且建好默认数据库,登录的用户名为root,密码为空)

    ④ 启动服务:net start master

    提示:

    net stop master 停止master服务

    sc delete master //删除windows服务(删除之前先停服务)

    mysqld --remove  //删除mysql服务

    tasklist| findstr "mysql" 删除mysql进程

    taskkill/f /t /im mysqld.exe 杀死mysql进程

    ⑤ 修改root用户密码

    使用命令 mysql -uroot -p 登录master数据库(默认安装好的mysql的root用户是没有密码的)

    登录之后,执行:

    use mysql;
    update user set authentication_string=password('123456') where user='root';
    flush privileges;

    从库(slave)的安装与配置

    ① 进入主库mysql-5.7.20-winx64-slave目录中,在此目录中新建my.ini文件并添加一下配置。

    #==============================客户端的参数
    [client]
    #MySQL 客户端连接服务器端时使用的端口号,默认的端口号为 3306。如果需要更改端口号的话,可以直接在这里修改。
    port = 3316
    [mysql]
    #MySQL 客户端默认的字符集
    default-character-set=utf8
    
    #==============================服务端的参数
    [mysqld]
    
    #====主从复制关键配置 start======
    #主库和从库需要不一致
    server_id=2
    relay-log-index=slave-relay-bin.index
    relay-log=slave-relay-bin
    #====主从复制关键配置 end======
    
    #服务器端默认的字符集
    character-set-server=utf8
    #MySQL 服务器的端口号
    port = 3316
    #SQL 模式的参数,通过这个参数可以设置检验 SQL 语句的严格程度
    sql_mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"
    #创建数据表时,默认使用的存储引擎
    default_storage_engine=innodb
    #表示缓存的大小,InnoDB 使用一个缓冲池类保存索引和原始数据。
    innodb_buffer_pool_size=1000M
    #表示日志文件的大小
    innodb_log_file_size=50M
    # 设置mysql的安装目录
    basedir=C:installmysqlMSmysql-5.7.20-winx64-slave
    # 设置mysql数据库的数据的存放目录
    datadir=C:installmysqlMSmysql-5.7.20-winx64-slavedata
    # 允许同时访问 MySQL 服务器的最大连接数
    max_connections=200
    # skip_grant_tables
    
    [mysql.server]
    default-character-set=utf8
    
    [mysql_safe]
    default-character-set=utf8

    ② cmd进入主库的bin目录中,执行:mysqld --install slave --defaults-file="C:installmysqlMSmysql-5.7.20-winx64-slavemy.ini"

    其中的slave为从库mysql的服务名称。

    ③ 初始化:mysqld --initialize-insecure --user=mysql 

    ④ 启动服务:net start slave

    ⑤ mysql -uroot -p 登录slave数据库,修改root用户密码

    use mysql;
    update user set authentication_string=password('123456') where user='root';
    flush privileges;
    关联主库(master)与从库(slave)

    启动master与slave,分别登录到master和slave的mysql中。

    master的mysql 执行命令 show master status查看master的状态。

    slave的mysql  执行命令 show slave status查看slave的状态

    我们可以发现 ,master的状态下,生成了一个二进制的日志文件,而slave下是空的,所以我们现在就要把主库与从库关联起来。只需要让从库(slave)知道主库(master)的地址就可以了。

    ① 首先我们需要在主库(master)中创建一个用户用于与从库同步的用户名和密码(这里我创建一个test用户,密码为mysql),并给test用户授权,以用于主库操作从库。

    相关命令:

    create user test;
    grant replication slave on *.* to '从库用户名(test)'@'从库主机地址(127.0.0.1)'identified by '密码(123456)';
    flush privileges;

    ② 切换到从库(slave)界面,把主库与从库联系起来。

    执行命令:

    change master to master_host='127.0.0.1',master_port=3310,master_user='test',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=988;

    参数说明:

    • master_host= 这里填你主库的IP。 
    • master_port=端口号 
    • master_user=’test’ 刚才我们创建的那个用户。 
    • master_log_file=’mysql-bin.000001’   刚才在主库里面 show master status;得到的值了。
    • master_log_pos=988

    然后执行命令 start slave 开启主从同步。

    执行命令查看 slave的状态:

    show slave status G;

    出现下图红色部分则开启主从跟踪成功

    验证主从同步

    进入master和slave并查看他们的数据库。

    在主库中创建一个数据库user,看一下从库有没有变化。

    五、主从复制的三种模式

    主从复制有三种模式,分别是基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复制(mixed-based replication, MBR)。对应的,binlog的格式也有三种:STATEMENT,ROW,MIXED 

    mysql默认的主从复制模式是ROW。

    模式划分
    STATEMENT模式(SBR)

    记录每一条SQL修改

    • 每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条 sql语句和每一行的数据变化,减少了binlog日志量,节约IO,提高性能。
    • 缺点是在某些情况下会导致 master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题)
    ROW模式(RBR)

    仅记录修改的内容,不记录具体的SQL

    • 不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了。而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。
    • 缺点是会产生大量的日志,尤其是altertable的时候会让日志暴涨。
    MIXED模式(MBR)
    • 以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。

    建议使用MIXED模式。

    如何更改主从复制的模式

    查看当前模式

    show global variables like 'binlog%';

    进入到master服务器的my.cnf文件中,增加一行,设置主从复制模式

    重启master服务器的数据库 。

    时刻与技术进步,每天一点滴,日久一大步!!! 本博客只为记录,用于学习,如有冒犯,请私信于我。
  • 相关阅读:
    C#对List排序的三种方式的比较
    unity跨平台及热更新学习笔记-C#中通过程序域实现DLL的动态加载与卸载
    总结下C#中有关结构体的几个问题
    C#中通过逻辑^(异或)运算交换两个值隐藏的巨坑!!!
    unity实现批量删除Prefab上Miss的脚本组件
    Oracle构造列思想,decode,case,sgin,pivot四大金刚
    Oracle-计算岁数
    Oracle 集合
    Oracle 综合例子应用01
    Oracle 事实表,维表,多对多
  • 原文地址:https://www.cnblogs.com/myitnews/p/13697802.html
Copyright © 2020-2023  润新知