只要赊帐记录在了粉板上或写了帐本上,以后即便掌柜忘记了,
好比停业几天,回复生意后依然能够经过帐本和粉板上的数据明确赊帐帐目mysql
有了redo log,InnoDB就能够保证即便数据库发生异常重启,以前提交的记录都不会丢失,这个能力成为crash-safe2、重要的日志模块:binlogsql
redo是物理的,binlog是逻辑的;如今因为redo是属于InnoDB引擎,因此必需要有binlog,由于你可使用别的引擎数据库
通常采用row,由于遇到时间,从库可能会出现不一致的状况,可是row更新先后都有,会致使日志变大
最后2个参数,保证事务成功,日志必须落盘,这样,数据库crash后,就不会丢失某个事务的数据了bash
一、互联网公司,使用MySQL的功能相对少(存储过程、触发器、函数) session
选择默认的语句模式,Statement Level(默认)
二、公司若是用到使用MySQL的特殊功能(存储过程、触发器、函数) oracle
则选择Mixed模式
三、公司若是用到使用MySQL的特殊功能(存储过程、触发器、函数)又但愿数据最大化一直,此时最好选择Row level模式app
binlog
日志记录效果[root@db01]# mysqlbinlog --base64-output="decode-rows" --verbose mysql-bin.000248 /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 4 #160628 11:06:52 server id 1 end_log_pos 107 Start: binlog v 4, server v 5.5.49-log created 160628 11:06:52 at startup # Warning: this binlog is either in use or was not closed properly. ROLLBACK/*!*/; # at 107 #160628 11:07:09 server id 1 end_log_pos 177 Query thread_id=1 exec_time=0 error_code=0 SET TIMESTAMP=1467083229/*!*/; SET @@session.pseudo_thread_id=1/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=0/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;/*!\C utf8 *//*!*/; SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; BEGIN /*!*/; # at 177 # at 223 #160628 11:07:09 server id 1 end_log_pos 223 Table_map: `oldboy`.`sc` mapped to number 33 #160628 11:07:09 server id 1 end_log_pos 785 Update_rows: table id 33 flags: STMT_END_F ### UPDATE `oldboy`.`sc` ### WHERE ### @1=1 ### @2=1001
图中绿色框表示是在内粗执行,红色框表示是在执行器中执行运维
1.首先客户端经过tcp/ip发送一条sql语句到server层的SQL interfacetcp
2.SQL interface接到该请求后,先对该条语句进行解析,验证权限是否匹配函数
3.验证经过之后,分析器会对该语句分析,是否语法有错误等
4.接下来是优化器器生成相应的执行计划,选择最优的执行计划
5.以后会是执行器根据执行计划执行这条语句。在这一步会去open table,若是该table上有MDL,则等待。若是没有,则加在该表上加短暂的MDL(S),
(若是opend_table太大,代表open_table_cache过小。须要不停的去打开frm文件)
6.进入到引擎层,首先会去innodb_buffer_pool里的data dictionary(元数据信息)获得表信息
7.经过元数据信息,去lock info里查出是否会有相关的锁信息,并把这条update语句须要的锁信息写入到lock info里(锁这里还有待补充)
8.而后涉及到的老数据经过快照的方式存储到innodb_buffer_pool里的undo page里,而且记录undo log修改的redo
(若是data page里有就直接载入到undo page里,若是没有,则须要去磁盘里取出相应page的数据,载入到undo page里)
9.在innodb_buffer_pool的data page作update操做。并把操做的物理数据页修改记录到redo log buffer里
因为update这个事务会涉及到多个页面的修改,因此redo log buffer里会记录多条页面的修改信息。
由于group commit的缘由,此次事务所产生的redo log buffer可能会跟随其它事务一同flush而且sync到磁盘上
10.同时修改的信息,会按照event的格式,记录到binlog_cache中。(这里注意binlog_cache_size是transaction级别的,不是session级别的参数,
一旦commit以后,dump线程会从binlog_cache里把event主动发送给slave的I/O线程)
11.以后把这条sql,须要在二级索引上作的修改,写入到change buffer page,等到下次有其余sql须要读取该二级索引时,再去与二级索引作merge
(随机I/O变为顺序I/O,可是因为如今的磁盘都是SSD,因此对于寻址来讲,随机I/O和顺序I/O差距不大)
12.此时update语句已经完成,须要commit或者rollback。这里讨论commit的状况,而且双1
13.commit操做,因为存储引擎层与server层之间采用的是内部XA(保证两个事务的一致性,这里主要保证redo log和binlog的原子性),
因此提交分为prepare阶段与commit阶段
14.prepare阶段,将事务的xid写入,将binlog_cache里的进行flush以及sync操做(大事务的话这步很是耗时)
15.commit阶段,因为以前该事务产生的redo log已经sync到磁盘了。因此这步只是在redo log里标记commit
16.当binlog和redo log都已经落盘之后,若是触发了刷新脏页的操做,先把该脏页复制到doublewrite buffer里,把doublewrite buffer里的刷新到共享表空间,而后才是经过page cleaner线程把脏页写入到磁盘中
其实在实现上5是调用了6的过程了的,因此是一回事。MySQL server 层和InnoDB层都保存了表结构,因此有书上描述时会拆开说。
必需要保证2份日志一致,使用的2阶段式提交;其实感受像事务,不是成功就是失败,不能让中间环节出现,也就是一个成功,一个失败
若是有一天mysql只有InnoDB引擎了,有redo来实现复制,那么感受oracle的DG就诞生了,物理的速度也将远超逻辑的,毕竟只记录了改动向量
老师,今天MYSQL第二讲中提到binlog和redo log, 我感受binlog不少余,按理是否是只要redo log就够了?[费解]
一个缘由是,redolog只有InnoDB有,别的引擎没有。 另外一个缘由是,redolog是循环写的,不持久保存,binlog的“归档”这个功能,redolog是不具有的。
老师您好,我以前是作运维的,经过binlog恢复误操做的数据,可是实际上,咱们会后知后觉,误删除一段时间了,才发现误删除,此时,我把以前误删除的binlog导入,再把误删除以后binlog导入,会出现问题,好比主键冲突,并且binlog导数据,不一样模式下时间也有不一样,可是通常都是row模式,时间仍是好久,有没什么方式,时间短且数据一致性强的方式
其实恢复数据只能恢复到误删以前到一刻, 误删以后的,不能只靠binlog来作,由于业务逻辑可能由于误删操做的行为,插入了逻辑错误的语句, 因此以后的,跟业务一块儿,从业务快速补数据的。只靠binlog补出来的每每不完整
1 prepare阶段
2 写binlog
3 commit
当在2以前崩溃时
重启恢复:后发现没有commit,回滚。备份恢复:没有binlog 。一致
当在3以前崩溃
重启恢复:虽没有commit,但知足prepare和binlog完整,因此重启后会自动commit。备份:有binlog. 一致
备份时间周期的长短,感受有2个方便
首先,是恢复数据丢失的时间,既然须要恢复,确定是数据丢失了。若是一天一备份的话,只要找到这天的全备,加入这天某段时间的binlog来恢复,若是一周一备份,假设是周一,而你要恢复的数据是周日某个时间点,那就,须要全备+周一到周日某个时间点的所有binlog用来恢复,时间相比前者须要增长不少;看业务能忍受的程度
其次,是数据库丢失,若是一周一备份的话,须要确保整个一周的binlog都无缺无损,不然将没法恢复;而一天一备,只要保证这天的binlog都无缺无损;固然这个能够经过校验,或者冗余等技术来实现,相比之下,上面那点更重要
一、帐本记上 卖一瓶可乐(redo log为 prepare状态), 二、而后收钱放入钱箱(bin log记录) 三、而后回过头在帐本上打个勾(redo log置为commit)表示一笔交易结束。
一、回过头来整理这次交易,发现只有记帐没有收钱,则交易失败,删掉帐本上的记录(回滚); 二、若是收了钱后被终止,而后回过头发现帐本有记录(prepare)并且钱箱有本次收入(bin log),则继续完善帐本(commit),本次交易有效。