一.主从复制简介
为什么使用主从复制?
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 ● 性能有一定的降低,响应时间会更长 ● 网络异常或从库宕机,卡主主库,直到超时或从库恢复
网友评论