MySQL主从复制

一.主从复制简介

为什么使用主从复制?
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:123
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主从复制)