美文网首页
MySQL主从复制

MySQL主从复制

作者: 唯爱熊 | 来源:发表于2019-12-12 17:46 被阅读0次

    一.主从复制简介

    为什么使用主从复制?
    1)高可用
    2)辅助备份
    3)分担负载

    复制是 MySQL 的一项功能,允许服务器将更改从一个实例复制到另一个实例。

    1)主服务器将所有数据和结构更改记录到二进制日志中。
    2)从属服务器从主服务器请求该二进制日志并在本地应用其内容。
    3)IO:请求主库,获取上一次执行过的新的事件,并存放到relaylog
    4)SQL:从relaylog中将sql语句翻译给从库执行

    二.主从复制原理

    主从复制的前提

    1)两台或两台以上的数据库实例
    2)主库要开启二进制日志
    3)主库要有复制用户
    4)主库的server_id和从库不同
    5)从库需要在开启复制功能前,要获取到主库之前的数据(主库备份,并且记录binlog当时位置)
    6)从库在第一次开启主从复制时,时必须获知主库:ip,port,user,password,logfile,pos

    IP:10.0.0.51
    Port:3306
    User:rep
    Password:oldboy123
    logFile:mysql-bin.000002
    Pos:120

    7)从库要开启相关线程:IO、SQL
    8)从库需要记录复制相关用户信息,还应该记录到上次已经从主库请求到哪个二进制日志
    9)从库请求过来的binlog,首先要存下来,并且执行binlog,执行过的信息保存下来

    主从复制涉及到的文件和线程

    主库:

    1)主库binlog:记录主库发生过的修改事件
    2)dump thread:给从库传送(TP)二进制日志线程

    从库:

    1)relay-log(中继日志):存储所有主库TP过来的binlog事件
    会定期清除,在一个SQL线程执行完成之后,并且长时间不用的情况
    2)master.info:存储复制用户信息,上次请求到的主库binlog位置点
    3)IO thread:接收主库发来的binlog日志,也是从库请求主库的线程
    4)SQL thread:执行主库TP过来的日志

    主从复制原理描述:

    1.change master to 时,ip pot user password binlog position写入到master.info进行记录
    2. start slave 时,从库会启动IO线程和SQL线程
    3.IO_T,读取master.info信息,获取主库信息连接主库
    4. 主库会生成一个准备binlog DUMP线程,来响应从库
    5. IO_T根据master.info记录的binlog文件名和position号,请求主库DUMP最新日志
    6. DUMP线程检查主库的binlog日志,如果有新的,TP(传送)给从从库的IO_T
    7. IO_T将收到的日志存储到了TCP/IP 缓存,立即返回ACK给主库 ,主库工作完成
    8.IO_T将缓存中的数据,存储到relay-log日志文件,更新master.info文件binlog 文件名和postion,IO_T工作完成
    9.SQL_T读取relay-log.info文件,获取到上次执行到的relay-log的位置,作为起点,回放relay-log
    10.SQL_T回放完成之后,会更新relay-log.info文件。
    11. relay-log会有自动清理的功能。
    细节:
    1.主库一旦有新的日志生成,会发送“信号”给binlog dump ,IO线程再请求
    

    三.主从复制实践(生产实践)

    主库有数据,并且一直在提供服务,不停库的情况下,添加新的从库

    #1.修改主库的配置
    [root@db01 ~]# vim /etc/my.cnf
    log-bin=mysql-bin
    binlog_format=row
    server_id=10
    
    #2.修改从库的配置
    [root@db02 ~]# vim /etc/my.cnf
    server_id=5
    
    [root@db02 ~]# /etc/init.d/mysqld restart
    Shutting down MySQL.. SUCCESS! 
    Starting MySQL. SUCCESS!
    
    ------
    
    [root@db03 ~]# vim /etc/my.cnf
    server_id=5
    
    [root@db03 ~]# /etc/init.d/mysqld restart
    Shutting down MySQL.. SUCCESS! 
    Starting MySQL. SUCCESS!
    
    #3.主库操作
        #创建主从复制用户
    
    mysql> grant replication slave on *.* to slave@'%' identified by '123';
    
        #查看binlog位置点?(新主从环境)
        mysql> show master status;
        +------------------+----------+
        | File             | Position | 
        +------------------+----------+
        | mysql-bin.000001 |   134    | 
        +------------------+----------+
        
        #有数据的情况,打点全备
        [root@db01 ~]# mysqldump -A -R --triggers --master-data=1 --single-transaction |gzip > /tmp/replication.sql.gz
        
        #将打点全备的数据,发送到从库上
        [root@db01 ~]# scp /tmp/replication.sql.gz 172.16.1.152:/tmp
        [root@db01 ~]# scp /tmp/replication.sql.gz 172.16.1.153:/tmp
        
        #导入数据
        [root@db02 ~]# zcat /tmp/replication.sql.gz |mysql
        [root@db03 ~]# zcat /tmp/replication.sql.gz |mysql
        
        #如果全备数据很大,建议不要scp
        [root@db01 ~]# zcat /tmp/replication.sql.gz |mysql -uroot -p123 -h10.0.0.152
        [root@db01 ~]# zcat /tmp/replication.sql.gz |mysql -uroot -p123 -h10.0.0.153
    
    #4.从库操作
        #找位置点和名字
        [root@db02 ~]# zcat /tmp/replication.sql.gz |head -22|tail -1
        CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=161362;
    
        #执行同步主库
         change master to
         master_user='slave',
         master_password='123',
         master_host='10.0.0.151',
         master_log_file='mysql-bin.000002',
         master_log_pos=161362;
         
         #开启IO和SQL线程
         start slave;
         
         #检查主从复制状态
         show slave status\G
         
         Slave_IO_Running: Yes
         Slave_SQL_Running: Yes
    

    四. MySQL主从复制基本故障处理

    IO

    grant replication slave on *.* to rep@'%' identified by '123';
    
    change master to
    master_host='10.0.0.151',
    master_user='slave',
    master_password='123',
    master_log_file='mysql-bin.000001',
    master_log_pos=250;
    

    1.网络

    ping 10.0.0.151
    

    2.端口

    telnet 10.0.0.151 3306
    tcping 10.0.0.151 3306
    

    3.用户名

    4.密码

    mysql -uslave -p123 -h10.0.0.151
    

    5.反向解析

    vim /etc/my.cnf
    [mysqld]
    skip_name_resolve
    
    #不正经的配置(不建议使用)
    skip-name-resolv
    skip-name-resolve
    skip_name_resolv
    

    6.binlog的名字和位置点一定要一致

    mysql> show master status;
    +------------------+----------+
    | File             | Position |
    +------------------+----------+
    | mysql-bin.000002 |  3149338 |
    +------------------+----------+
    
    mysql> stop slave;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> change master to
        -> master_log_file='mysql-bin.000002',
        -> master_log_pos=3149338;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> start slave;
    Query OK, 0 rows affected (0.00 sec)
    

    7.server_id相同

    mysql> show variables like 'server_id';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | server_id     | 10    |
    +---------------+-------+
    [root@db03 ~]# vim /etc/my.cnf
    server_id=5
    

    8.UUID相同

    #1.修改uuid
    [root@db03 data]# vim auto.cnf 
    [auto]
    server-uuid=54c76db8-20eb-11ea-bed9-000c29e98744
    [root@db03 data]# /etc/init.d/mysqld restart
    Shutting down MySQL.. SUCCESS! 
    Starting MySQL. SUCCESS! 
    
    #2.删除uuid
    [root@db03 data]# rm -fr /application/mysql/data/auto.cnf
    [root@db03 data]# /etc/init.d/mysqld restart
    Shutting down MySQL.. SUCCESS! 
    Starting MySQL. SUCCESS! 
    

    SQL

    主库和从库数据不一致:

    • 主库上有从库没有的数据
    [root@db03 data]# vim /etc/my.cnf
    slave-skip-errors=1032,1062,1007,1049
    
    [root@db03 data]# /etc/init.d/mysqld restart
    
    • 主库上没有从库上有的数据
    set global sql_slave_skip_counter=1;
    
    mysql> stop slave;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> set global sql_slave_skip_counter=1;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> start slave;
    Query OK, 0 rows affected (0.01 sec)
    

    但是以上操作都是有风险存在的

    做主从复制之前,保证主库和从库的数据一致性。

    处理方法三:

    1)重新备份数据库,恢复到从库
    2)给从库设置为只读

    #在命令行临时设置
    set global read_only=1;
    #在配置文件中永久生效
    read_only=1
    

    五.MySQL延时从库

    延时从库,原理,在SQL线程上做手脚,不影响IO线程连接dump线程取数据。
    SQL线程延时:数据已经写入relaylog中了,SQL线程"慢点"运行
    一般企业建议3-6小时,具体看公司运维人员对于故障的反应时间

    延时从库操作步骤

    #停止从库
    mysql> stop slave;
    Query OK, 0 rows affected (0.00 sec)
    #添加延迟配置(也可以在配置之初配置)
    mysql> change master to
        -> master_delay=180;
    Query OK, 0 rows affected (0.01 sec)
    #重启启动slave配置
    mysql> start slave;
    Query OK, 0 rows affected (0.00 sec)
    
    #新从库
    change master to
    master_host='10.0.0.151',
    master_user='slave',
    master_password='123',
    master_log_file='mysql-bin.000001',
    master_port=3306,
    master_log_pos=250,
    master_delay=3600;
    

    企业中一般会延时3-6小时

    企业案例

    思考问题:

    总数据量级500G,正常备份去恢复需要1.5-2小时
    1)配置延时3600秒

    mysql>CHANGE MASTER TO MASTER_DELAY = 3600;
    

    2)主库

    drop database db;
    

    3)怎么利用延时从库,恢复数据?

    思路:

    0.停止线上服务不停止数据库

    1.停止SQL线程

    mysql> stop slave sql_thread;
    

    2.找到relaylog的名字和起始位置点

    [root@db03 data]# cat relay-log.info 
    ./db03-relay-bin.000003
    283
    

    3.查看relay log到删库之前

    [root@db03 data]# mysqlbinlog --base64-output=decode-rows -vvv db03-relay-bin.000003
    12611
    

    4.导出被删除的库

    [root@db03 data]# mysqldump -uroot -p123 -A  > /tmp/zls1_new.sql
    

    5.截取relay log

    [root@db03 data]# mysqlbinlog --start-position=283 --stop-position=12611 db03-relay-bin.000003 > /tmp/delay.sql
    

    6.将导出的sql文件发送到主库

    [root@db03 data]# scp /tmp/*.sql 172.16.1.51:/tmp
    

    7.在主库导入数据

    [root@db01 data]# mysql < /tmp/zls1_new.sql 
    [root@db01 data]# mysql < /tmp/delay.sql 
    

    8.在延时从库开启SQL线程

    mysql> start slave sql_thread;
    Query OK, 0 rows affected (0.00 sec)
    

    六.半同步复制

    半同步主要解决主从数据一致性问题
    半同步复制原理:半同步介于异步复制和全同步复制之间,主库在执行完客户端提交的事务之后不是立刻返回给客户端,而是等待至少一个从库接收到并写入relay log中才返回给客户端,相对于异步复制,半同步复制提高了数据的安全性,但是也造成了一定程度上的延迟,阻塞主库的数据写入,半同步复制最好在低延时的复制节点之间使用。


    事务在主库写完binlog后需要从库返回一个已接受,才放回给客户端;5.5集成到mysql,以插件的形式存在,需要单独安装确保事务提交后binlog至少传输到一个从库不保证从库应用完成这个事务的binlog性能有一定的降低网络异常或从库宕机,卡主库,直到超时或从库恢复。
    半同步复制工作原理的变化
    1. 主库执行新的事务,commit时,更新 show master  status\G ,触发一个信号给
    2. binlog dump 接收到主库的 show master status\G信息,通知从库日志更新了
    3. 从库IO线程请求新的二进制日志事件
    4. 主库会通过dump线程传送新的日志事件,给从库IO线程
    5. 从库IO线程接收到binlog日志,当日志写入到磁盘上的relaylog文件时,给主库ACK_receiver线程
    6. ACK_receiver线程触发一个事件,告诉主库commit可以成功了
    7. 如果ACK达到了我们预设值的超时时间,半同步复制会切换为原始的异步复制.
    

    对比异步复制


    配置操作操作
    #查看半同步复制所需要的插件
    [root@db03 data]# cd /application/mysql/lib/plugin
    

    1.主库配置

    #查看是否有动态支持,在5.6版本之后默认支持
    mysql> show global variables like 'have_dynamic_loading';
    +----------------------+-------+
    | Variable_name        | Value |
    +----------------------+-------+
    | have_dynamic_loading | YES   |
    +----------------------+-------+
    
    #主库安装插件
    INSTALL PLUGIN rpl_semi_sync_master SONAME'semisync_master.so';
    #主库启用插件
    SET GLOBAL rpl_semi_sync_master_enabled = 1;
    
    #检查安装
    mysql> show variables like'rpl%';
    +------------------------------------+----------+
    | Variable_name                      | Value    |
    +------------------------------------+----------+
    | rpl_semi_sync_master_enabled       | ON       |
    | rpl_semi_sync_master_timeout       | 1000     |
    | rpl_semi_sync_master_trace_level   | 32       |
    | rpl_semi_sync_master_wait_no_slave | ON       |
    | rpl_stop_slave_timeout             | 31536000 |
    +------------------------------------+----------+
    注:相关参数说明
    rpl_semi_sync_master_timeout=milliseconds
    设置此参数值(ms),为了防止半同步复制在没有收到确认的情况下发生堵塞,如果Master在超时之前没有收到任何确认,将恢复到正常的异步复制,并继续执行没有半同步的复制操作。
    
    rpl_semi_sync_master_wait_no_slave={ON|OFF}
    如果一个事务被提交,但Master没有任何Slave的连接,这时不可能将事务发送到其它地方保护起来。默认情况下,Master会在时间限制范围内继续等待Slave的连接,并确认该事务已经被正确的写到磁盘上。
    可以使用此参数选项关闭这种行为,在这种情况下,如果没有Slave连接,Master就会恢复到异步复制。
    
    mysql> show global status like 'rpl_semi%';
    +--------------------------------------------+-------+
    | Variable_name                              | Value |
    +--------------------------------------------+-------+
    | Rpl_semi_sync_master_clients               | 1     |  -->表示开启半同步的从库个数
    | Rpl_semi_sync_master_net_avg_wait_time     | 0     |
    | Rpl_semi_sync_master_net_wait_time         | 0     |
    | Rpl_semi_sync_master_net_waits             | 0     |
    | Rpl_semi_sync_master_no_times              | 1     |
    | Rpl_semi_sync_master_no_tx                 | 136   |
    | Rpl_semi_sync_master_status                | ON    |  -->为ON表示主库开启半同步状态
    +--------------------------------------------+-------+
    

    2.从库配置

    #从库上安装插件
    INSTALL PLUGIN rpl_semi_sync_slave SONAME'semisync_slave.so';
    
    #从库启动插件,开启半同步复制。
    SET GLOBAL rpl_semi_sync_slave_enabled = 1;  
    #重启IO线程
    mysql> stop slave io_thread;
    mysql> start slave io_thread;
    

    七.过滤复制

    注意:过滤复制适用特殊需求,如果开启,除了主库配置的白名单的数据库会被记录二进制日志,其它的库将不会被记录,会存在数据丢失无法恢复的情况。
    主库:

    白名单:只记录白名单中列出的库的二进制日志

    binlog-do-db
    黑名单:不记录黑名单列出的库的二进制日志

    binlog-ignore-db
    从库:

    白名单:只执行白名单中列出的库或者表的中继日志

    --replicate-do-db=test
    --replicate-do-table=test.t1
    --replicate-wild-do-table=test.t2
    黑名单:不执行黑名单中列出的库或者表的中继日志

    --replicate-ignore-db
    --replicate-ignore-table
    --replicate-wild-ignore-tabl
    主库配置

    [root@db01 ~]# vim /etc/my.cnf
    binlog_do_db=weiaixiong
    binlog_do_db=weiai
    #配置完成后重启MySQL
    [root@db01 ~]# /etc/init.d/mysqld restart
    #查看配置结果
    mysql> show master status;
    +------------------+----------+------------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB     | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+------------------+------------------+-------------------+
    | mysql-bin.000006 |      238 | weiaixiong,weiai |                  |                   |
    +------------------+----------+------------------+------------------+-------------------+
    1 row in set (0.00 sec)
    

    从库配置

    #从库一
    [root@db02 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=5
    replicate-do-db=weiaixiong
    replicate-ignore-db=weiai
    #配置完成后重启MySQL
    [root@db02 ~]# /etc/init.d/mysqld restart
    #连接从库查看
    mysql> show slave status\G
    ......
    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
    Replicate_Do_DB: weiaixiong
    Replicate_Ignore_DB: weiai
    ......
    
    #从库二
    [root@db03 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=5
    replicate-do-db=weiai
    replicate-ignore-db=weiaixiong
    #配置完后重启MySQL
    [root@db03 ~]# /etc/init.d/mysqld restart
    #连接从库查看
    mysql> show slave status\G
    ......
    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
    Replicate_Do_DB: weiai
    Replicate_Ignore_DB: weiaixiong
    ......
    

    八.基于GTID的主从复制

    GTID介绍

    GTID(Global Transaction ID)是对于一个已提交事务的唯一编号,并且是一个全局(主从复制)唯一的编号。
    它的官方定义如下:
    GTID = source_id :transaction_id
    7E11FA47-31CA-19E1-9E56-C43AA21293967:29
    什么是sever_uuid,和Server-id 区别?
    核心特性: 全局唯一,具备幂等性。

    GTID新特性

    • 支持多线程复制(主库:dump线程,从库:IO线程和 每一个库都开启一个SQL线程)

    • 支持启用GITD,在配置主从复制,传统的方式里,需要找到binlog和pos点,然后change master to 指向。在mysql5.6里,无需再找binlog的名字和位置点,只需要知道master的ip/端口/账号密码即可,因为同步复制是自动的,mysql通过内部机制GTID自动找点同步。(show master status;file/position)

      • change master to
      • master_host='10.0.0.155',
      • master_user='slave',
      • master_password='123',
      • master_auto_position=1;
      #1.grant replication slave on \*.\* to slave@'%' identified by '123';
      #2.在从库上执行以上change语句
      #3.start slave;
      
    • 基于Row复制只保存改变的列,大大节省Disk Space/Network resources和Memory usage.

    • 支持把Master 和Slave的相关信息记录在Table中,原来是记录在文件里,记录在表里,增强可用性

    • 支持延时复制

    GTID核心参数

    重要参数:

    gtid-mode=on
    enforce-gtid-consistency=true
    log-slave-updates=1
    
    gtid-mode=on                        --启用gtid类型,否则就是普通的复制架构
    enforce-gtid-consistency=true               --强制GTID的一致性
    log-slave-updates=1                 --slave更新是否记入日志
    

    先决条件

    1)主库和从库都要开启binlog
    2)主库和从库server-id不同
    3)要有主从复制用户

    主从复制操作

    修改主库配置文件

    [root@db05 ~]# vim /etc/my.cnf
    [mysqld]
    server-id = 6
    log-bin = mysql-bin
    binlog_format=row
    gtid_mode=ON
    enforce_gtid_consistency
    log-slave-updates=1
    #配置完成后重启数据库
    [root@db05 ~]# systemctl restart mysqld
    

    修改从库配置文件

    [root@db06 ~]# vim /etc/my.cnf
    [mysqld]
    server-id = 7
    log-bin = mysql-bin
    binlog_format=row
    gtid_mode=ON
    enforce_gtid_consistency
    log-slave-updates=1
    #配置完成后重启数据库
    [root@db06 ~]# systemctl restart mysqld
    

    主库创建主从复制用户

    mysql> grant replication slave on *.* to slave@'%' identified by '123';
    

    备份主库数据
    说明:这里模拟的是主库已有数据

    [root@db05 ~]# mysqldump -A -B -x --set-gtid-purged=OFF|gzip >/tmp/full1.sql.gz
    #加了--set-gtid-purged=OFF时,会记录binlog日志,如果不加,不记录binlog日志.
    

    拷贝备份数据到远程目录

    [root@db05 ~]# scp /tmp/full1.sql 10.0.0.156:/tmp
    #如果数据量比较大,建议直接远程导入即可
    

    从库导入备份数据

    [root@db06 ~]# zcat /tmp/full1.sql.gz |mysql
    

    构建主从

    mysql> change master to
    master_host='10.0.0.155',
    master_user='slave',
    master_password='123',
    master_auto_position=1;
    

    检测查看

    #主库查看
    mysql> show master status;
    +------------------+----------+--------------+------------------+------------------------------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
    +------------------+----------+--------------+------------------+------------------------------------------+
    | mysql-bin.000004 |      734 |              |                  | a70ab412-11d3-11ea-9ae3-000c29bb6654:1-3 |
    +------------------+----------+--------------+------------------+------------------------------------------+
    1 row in set (0.00 sec)
    #从库查看
    mysql> show slave status\G
    ......
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                Retrieved_Gtid_Set: a70ab412-11d3-11ea-9ae3-000c29bb6654:1-3
                Executed_Gtid_Set: 13fdf075-1fea-11ea-a444-000c2969966c:1-184,
    a70ab412-11d3-11ea-9ae3-000c29bb6654:1-3
                    Auto_Position: 1
    ......
    

    九.主从延迟问题

    1.产生延迟的原因

    1)、MySQL数据库主从同步延迟原理mysql主从同步原理:主库针对写操作,顺序写binlog,从库单线程去主库顺序读”写操作的binlog”,从库取到binlog在本地原样执行(随机写),来保证主从数据逻辑上一致。mysql的主从复制都是单线程的操作,主库对所有DDL和DML产生binlog,binlog是顺序写,所以效率很高,slave的Slave_IO_Running线程到主库取日志,效率比较高,下一步,问题来了,slave的Slave_SQL_Running线程将主库的DDL和DML操作在slave实施。DML和DDL的IO操作是随即的,不是顺序的,成本高很多,还可能可slave上的其他查询产生lock争用,由于Slave_SQL_Running也是单线程的,所以一个DDL卡主了,需要执行10分钟,那么所有之后的DDL会等待这个DDL执行完才会继续执行,这就导致了延时。有朋友会问:“主库上那个相同的DDL也需要执行10分,为什么slave会延时?”,答案是master可以并发,Slave_SQL_Running线程却不可以。

    2)、MySQL数据库主从同步延迟是怎么产生的?当主库的TPS并发较高时,产生的DDL数量超过slave一个sql线程所能承受的范围,那么延时就产生了,当然还有就是可能与slave的大型query语句产生了锁等待。首要原因:数据库在业务上读写压力太大,CPU计算负荷大,网卡负荷大,硬盘随机IO太高次要原因:读写binlog带来的性能影响,网络传输延迟。

    2.MySql数据库从库同步的延迟解决方案

    1)、架构方面

    1.业务的持久化层的实现采用分库架构,mysql服务可平行扩展,分散压力。

    2.单个库读写分离,一主多从,主写从读,分散压力。这样从库压力比主库高,保护主库。

    3.服务的基础架构在业务和mysql之间加入memcache或者redis的cache层。降低mysql的读压力。

    4.不同业务的mysql物理上放在不同机器,分散压力。

    5.使用比主库更好的硬件设备作为slave总结,mysql压力小,延迟自然会变小。

    2)、硬件方面

    1.采用好服务器,比如4u比2u性能明显好,2u比1u性能明显好。

    2.存储用ssd或者盘阵或者san,提升随机写的性能。

    3.主从间保证处在同一个交换机下面,并且是万兆环境。

    总结,硬件强劲,延迟自然会变小。一句话,缩小延迟的解决方案就是花钱和花时间。

    3)、mysql主从同步加速

    1、sync_binlog在slave端设置为0

    2、–logs-slave-updates 从服务器从主服务器接收到的更新不记入它的二进制日志。

    3、直接禁用slave端的binlog

    4、slave端,如果使用的存储引擎是innodb,innodb_flush_log_at_trx_commit =2

    4)、从文件系统本身属性角度优化

    master端修改linux、Unix文件系统中文件的etime属性, 由于每当读文件时OS都会将读取操作发生的时间回写到磁盘上,对于读操作频繁的数据库文件来说这是没必要的,只会增加磁盘系统的负担影响I/O性能。可以通过设置文件系统的mount属性,组织操作系统写atime信息,在linux上的操作为:打开/etc/fstab,加上noatime参数/dev/sdb1 /data reiserfs noatime 1 2然后重新mount文件系统#mount -oremount /data

    5)、同步参数调整主库是写,对数据安全性较高,比如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之类的设置是需要的而slave则不需要这么高的数据安全,完全可以讲sync_binlog设置为0或者关闭binlog,innodb_flushlog也可以设置为0来提高sql的执行效率

    1、sync_binlog=1 oMySQL提供一个sync_binlog参数来控制数据库的binlog刷到磁盘上去。默认,sync_binlog=0,表示MySQL不控制binlog的刷新,由文件系统自己控制它的缓存的刷新。这时候的性能是最好的,但是风险也是最大的。一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。

    如果sync_binlog>0,表示每sync_binlog次事务提交,MySQL调用文件系统的刷新操作将缓存刷下去。最安全的就是sync_binlog=1了,表示每次事务提交,MySQL都会把binlog刷下去,是最安全但是性能损耗最大的设置。这样的话,在数据库所在的主机操作系统损坏或者突然掉电的情况下,系统才有可能丢失1个事务的数据。但是binlog虽然是顺序IO,但是设置sync_binlog=1,多个事务同时提交,同样很大的影响MySQL和IO性能。虽然可以通过group commit的补丁缓解,但是刷新的频率过高对IO的影响也非常大。

    对于高并发事务的系统来说,“sync_binlog”设置为0和设置为1的系统写入性能差距可能高达5倍甚至更多。所以很多MySQL DBA设置的sync_binlog并不是最安全的1,而是2或者是0。这样牺牲一定的一致性,可以获得更高的并发和性能。默认情况下,并不是每次写入时都将binlog与硬盘同步。因此如果操作系统或机器(不仅仅是MySQL服务器)崩溃,有可能binlog中最后的语句丢失了。要想防止这种情况,你可以使用sync_binlog全局变量(1是最安全的值,但也是最慢的),使binlog在每N次binlog写入后与硬盘同步。即使sync_binlog设置为1,出现崩溃时,也有可能表内容和binlog内容之间存在不一致性。

    2、innodb_flush_log_at_trx_commit (这个很管用)抱怨Innodb比MyISAM慢 100倍?那么你大概是忘了调整这个值。默认值1的意思是每一次事务提交或事务外的指令都需要把日志写入(flush)硬盘,这是很费时的。特别是使用电池供电缓存(Battery backed up cache)时。设成2对于很多运用,特别是从MyISAM表转过来的是可以的,它的意思是不写入硬盘而是写入系统缓存。日志仍然会每秒flush到硬 盘,所以你一般不会丢失超过1-2秒的更新。设成0会更快一点,但安全方面比较差,即使MySQL挂了也可能会丢失事务的数据。而值2只会在整个操作系统 挂了时才可能丢数据。

    3、ls(1) 命令可用来列出文件的 atime、ctime 和 mtime。

    atime 文件的access time 在读取文件或者执行文件时更改的ctime 文件的create time 在写入文件,更改所有者,权限或链接设置时随inode的内容更改而更改mtime 文件的modified time 在写入文件时随文件内容的更改而更改ls -lc filename 列出文件的 ctimels -lu filename 列出文件的 atimels -l filename 列出文件的 mtimestat filename 列出atime,mtime,ctimeatime不一定在访问文件之后被修改因为:使用ext3文件系统的时候,如果在mount的时候使用了noatime参数那么就不会更新atime信息。这三个time stamp都放在 inode 中.如果mtime,atime 修改,inode 就一定会改, 既然 inode 改了,那ctime也就跟着改了.之所以在 mount option 中使用 noatime, 就是不想file system 做太多的修改, 而改善读取效能

    3.MySql数据库从库同步其他问题及解决方案

    1)、mysql主从复制存在的问题: ● 主库宕机后,数据可能丢失 ● 从库只有一个sql Thread,主库写压力大,复制很可能延时解决方法: ● 半同步复制---解决数据丢失的问题 ● 并行复制----解决从库复制延迟的问题
    并行复制说明

    并行复制mysql并行复制  ● 社区版5.6中新增  ● 并行是指从库多线程apply binlog  ● 库级别并行应用binlog,同一个库数据更改还是串行的(5.7版并行复制基于事务组)设置set global slave_parallel_workers=10;设置sql线程数为10
    
    原理:从库多线程apply binlog在社区5.6中新增库级别并行应用binlog,同一个库数据更改还是串行的5.7版本并行复制基于事务组
    

    半同步说明

    半同步复制mysql semi-sync(半同步复制)半同步复制:  ● 5.5集成到mysql,以插件的形式存在,需要单独安装  ● 确保事务提交后binlog至少传输到一个从库  ● 不保证从库应用完这个事务的binlog  ● 性能有一定的降低,响应时间会更长  ● 网络异常或从库宕机,卡主主库,直到超时或从库恢复
    

    相关文章

      网友评论

          本文标题:MySQL主从复制

          本文链接:https://www.haomeiwen.com/subject/nbvtnctx.html