在MySQL5.5之前,MySQL 的复制是异步 *** 作,主库和从库的数据之间存在一定的延迟,这样存在一个隐患:当在主库上写入一个事务并提交成功,而从库尚未得到主库推送的Binlog日志时,主库宕机了,例如主库可能因磁盘损坏、内存故障等造成主库上该事务Binlog丢失,此时从库就可能损失这个事务,从而造成主从不一致。
为了解决这个问题, MySQL5.5引人了半同步复制机制。
在MySQL 5.5之前的异步复制时,主库执行完 Commit提交 *** 作后,在主库写入 Binlog日志后即可成功返回客户端,无需等待Binlog日志传送给从库,如图31-7所示。
而半同步复制时,为了保证主库上的每一个 Binlog 事务都能够被可靠的复制到从库上,主库在每次事务成功提交时,并不及时反馈给前端应用用户,而是等待其中一个从库也接收到 Binlog事务并成功写入中继日志后,主库才返回Commit *** 作成功给客户端。 半同步复制保证了事务成功提交后,至少有两份日志记录 ,一份在主库的 Binlog日志上,另一份在至少一个从库的中继日志Relay Log 上,从而更进一步保证了数据的完整性。半同步复制的大致流程如图31-8所示。
半同步复制模式下,假如在图31-8的步骤1、2、3中的任何一个步骤中主库宕机,则事务并未提交成功,从库上也没有收到事务对应的 Binlog日志,所以主从数据是一致的
假如在步骤4传送 Binlog日志到从库时,从库宕机或者网络故障,导致 Binlog并没有及时地传送到从库上,此时主库上的事务会等待一段时间(时间长短由参数rpl_semi_sync_master_timeout设置的毫秒数决定),如果 Binlog 在这段时间内都无法成功推送到从库上,则 MySQL自动调整复制为异步模式,事务正常返回提交结果给客户端。
半同步复制很大程度上取决于主从库之间的网络情况,往返时延RTT 越小决定了从库的实时性越好。通俗地说,主从库之间网络越快,从库越实时。
半同步模式是作为MySQL5.5的一个插件来实现的,主库和从库使用不同的插件。安装比较简单,在上一小节异步复制的环境上,安装半同步复制插件即可。
1、首先,判断MySQL服务器是否支持动态增加插件:
2、安装插件
3、可以查看到已安装的插件
4、在安装完插件后,半同步复制默认是关闭的,这时需设置参数来开启半同步
主:
从:
以上的启动方式是在命令行 *** 作,也可写在配置文件中。
主:
从:
4、重启从上的IO线程
从:
如果没有重启,则默认还是异步复制,重启后,slave会在master上注册为半同步复制的slave角色。这时候,主的error.log中会打印如下信息:
查看半同步是否在运行
主:
从:
这两个变量常用来监控主从是否运行在半同步复制模式下。至此,MySQL半同步复制搭建完毕~
来做个实验,观察半同步状态参数的变化。
1、在主库上insert一条记录,观察下变化;
Rpl_semi_sync_master_net_waits加1,说明刚才的insert已经发送到从机并且主机还接收到从机的反馈响应;
2、我们将从机mysql停止,再次在主机上进行insert后查看状态
可以看到,主机进行insert阻塞了10秒才返回结果。Rpl_semi_sync_master_status变为OFF,Rpl_semi_sync_master_no_tx加1,说明这条insert没有同步到从机。后面再一次执行了insert立马返回了结果,说明此时已经降级为异步复制;Rpl_semi_sync_master_no_tx也是增加了1;
3、现在恢复启动从机,再次在主机上进行insert后查看状态
Rpl_semi_sync_master_status还是OFF,Rpl_semi_sync_master_no_tx又增加了1。说明从库重启并不会自动恢复为原来的半同步复制,需要手动 *** 作:
主 SET GLOBAL rpl_semi_sync_master_enabled = 1
从 SET GLOBAL rpl_semi_sync_slave_enabled = 1STOP SLAVE IO_THREADSTART SLAVE IO_THREAD
上面是从机重启后的变化,那么主到从之间的网络问题呢,我们可以利用防火墙来模拟。
对于全同步复制,当主库提交事务之后,所有的从库节点必须收到,APPLY并且提交这些事务,然后主库线程才能继续做后续 *** 作。这里面有一个很明显的缺点就是,主库完成一个事务的时间被拉长,性能降低。
第阶段:Java面向象编程1.Java基本数据类型与表达式支循环
2.StringStringBuffer使用、则表达式
3.面向象抽象封装继承态类与象象初始化收构造函数、this关键字、参数传递程、static关键字、内部类Java垃极收机制Javadoc介绍
4.象实例化程、覆盖、final关键字、抽象类、接口、继承优点缺点剖析象态性:类父类间转换、抽象类接口态应用、态带处
5.Java异处理异机制原理
6.用设计模式:Singleton、Template、Strategy模式
7.JavaAPI介绍:种基本数据类型包装类SystemRuntime类DateDateFomat类等
8.Java集合介绍:Collection、Set、List、ArrayList、Vector、LinkedList、Hashset、TreeSet、Map、HashMap、TreeMap、Iterator、Enumeration等用集合类API
9.Java
I/O输入输流:FileFileRandomAccess类字节流InputStreamOutputStream字符流Reader
Writer及相应实现类IO性能析字节字符转化流包装流概念及用包装类计算机编码
10.Java高级特性:反射、代理泛型
11.线程原理:何程序创建线程(Thread、Runnable)线程安全问题线程同步线程间通讯、死锁
12.Socket网络编程
第二阶段:Java
Web发
1.Java解析XML文件DOM4J
2.MySql数据库应用、表连接查询应用
3.JspServlet应用
4.Http协议解析
5.Tomcat服务器应用配置
6.WebService服务配置应用
第三阶段:android UI编程
1、Android发环境搭建:Android介绍Android发环境搭建第Android应用程序Android应用程序目录结构
2、Android初级控件使用:
TextView控件使用
Button控件使用
EditText控件使用
ImageView使用
RadioButton使用
Checkbox使用
Menu使用
3、Android高级控件使用:
Autocompletion使用
ListView使用
GridView使用
Adapter使用
Spinner使用
Gallary使用
ScrollView使用
4、框与菜单使用:
Dialog基本概念
AlertDialog使用
DatePickerDialog使用
Menu使用
自定义Menu实现
5、控件布局:
线性布局使用
相布局使用
表格布局使用
6、Acitivity管理:
AndroidManifest.xml文件作用
Intent使用
使用Intent传递数据
启Activity
IntentFilter使用
Activity Group使用
7、自定义控件实现:
自定义ListView实现
折叠ListView使用
自定义Adapter实现
自定义View实现
态控件布局实现
第四阶段:android网络编程与数据存储
1、基于Android平台HTTP通讯:
Http协议顾
Apache Commons 工具包介绍
使用Get向服务器提交数据
解析服务器响应数据
使用POST向服务器提交数据实现
向服务器提交非文本数据实现
使用Http协议实现线程载
使用Http协议实现断点续传
2、Android数据存储技术:
SQLite3数据库简介
SQL语句顾
SQLite3编程接口介绍
SQLite3事务管理
SQLite3游标使用
SQLite3性能析
访问SDCard
访问SharedPreferences
3、ContentProvider使用:ContentProvider实现共享数据、URI
解析与UriMatcher、ContentUris使用、使用ContentResolver *** 作ContentProvider、
ContentProvider监听Android异步 *** 作:Handler使用异步任务基本概念AsyncTask使用
第五阶段:android手机硬件管理
1、图及定位技术:GPS简介LocationManager使用Google Map添加标记查询某附近建筑使用Google Map实现点点导航
2、传器使用:向、加速度(重力)、光线、磁场、距离、温度等传器使用
3、近场通信技术:NFC技术简介NFC技术用场景介绍NFC技术实现
4、媒体管理技术:MediaPlayer使用
5、触摸屏技术:手势识别点触摸技术
第六阶段:Android图形编程技术
1、图形处理基础:2D图形编程基础
2、点、线、面等基本图形元素绘制
3、Android画框架简介
4、位移画实现
5、淡入淡画实现
6、旋转画实现
7、Matrix使用
第七阶段:Android游戏发
1、Android游戏发:Android游戏发概述
2、SurfaceView使用
3、物理球技术
4、碰撞检测技术
5、图片、文字背景音乐等资源使用
6、游戏引擎基础概念
7、Cocoa2d-Android引擎使用
8、OpenGL ES使用
MySQL通过内部两阶段提交协议来提交事务,如下图
具体实现如下图:
第一阶段 :InnoDB prepare,持有prepare_commit_mutex,并且write/sync redo log;将rollback设置为Prepared状态,binlog prepare不作任何 *** 作;
第二阶段 :包含两步,write/sync Binlog及 InnoDB commit (写入COMMIT标记后释放prepare_commit_mutex);
考虑mysql以binlog的写入与否作为事务提交成功与否的标志,如果 在写入innodb commit标志时崩溃(binglog已经写文件但是还没有提交) ,则恢复时,会重新对commit标志进行写入;此时的事务崩溃恢复过程如下:
1)扫描最后一个Binlog文件,提取其中的xid;
2)InnoDB维持了状态为Prepare的事务链表,将这些事务的xid和Binlog中记录的xid做比较,如果在Binlog中存在,则提交,否则回滚事务。
但其中也会存在2个问题:
并发危机:全局大锁prepare_commit_mutex
Mysql5.6.5前的做法,加锁,串行化
无锁方案:如果能保证binlog write 和 Innodb commit的顺序一致性就可以解决该问题。
性能问题:参数sync_binlog =1 ,innodb_flush_log_at_trx_commit =1时,fsync *** 作频繁
数据持久化到磁盘:调用fsync将缓存中的数据刷新到磁盘(普通硬盘150次/s和SSD 1200次/S),影响TPS;Group Commit *** 作,在多个事务并发时,将等待fsync的多个事务合并为仅调用一次fsync *** 作,以解决innodb fsync的问题,对binlog 的fsync也适用
对上述两个问题的解决:
针对并发问题
Group *** 作,三个阶段都在维护一个队列。第一个进队列的线程称为leader线程,负责对队列里所有线程进行 *** 作;之后进入队列的线程称作follower线程,follower 线程进入队列后睡眠,等待leader完成 *** 作后将他们唤醒。注意:前一个队列leader进入后一个队列时,会把自己原队列的follower全加入进去。
针对一致性问题
Group commit 分为三个阶段,每个阶段有一个线程在执行。分阶段的目的在于各个阶段可以并发执行,提升效率。
涉及参数说明:
sync_binlog =1 :启用group commit之后,其实已经不是一个事务去刷一次磁盘了,而是一组事务刷一次磁盘。图中1、2分别代表sync_binlog 不同配置下,通知其他线程(如dump线程)binlog 已经更新了,当配置为1时,要严格等到sync完毕之后才会发送广播通知, 如果sync_binlog配的是别的值,MySQL会把通知提前到1的位置
binlog_group_commit_sync_no_delay_count(组提交sync无延迟时间最大event数)及binlog_group_commit_sync_delay(组提交sync延迟时间,单位:毫秒):一般来说我们认为group commit 中最耗时的 *** 作是sync阶段,于是我们可以在sync阶段在leader真正sync之前进行一个等待,以便让fsync一次性刷新更多的事务。这对需要等待sync 完之后才能进行的 *** 作(比如dump线程)可能有性能提升。
两阶段提交:
MYSQL_BIN_LOG作为协调者
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)