binlog记录数据库执行的写入性操作(不包括查询select),以二进制存于磁盘,由Server层记录,通过追加方式记录,max_binlog_size
参数设置每个binlog文件大小,达到给定值后生成新文件保存日志。事务提交时记录binlog(位于内存中),通过sync_binlog //(取值0~N,0:系统判断;1:每次commit都将binlog写入磁盘;N:每N个事务,才将binlog写入磁盘)
控制binlog刷盘(刷到磁盘中 )时机。
用途:
格式:
只记录事务对数据页做了哪些修改。redo log包括两部分:一个是内存中的日志缓冲(redo log buffer),另一个是磁盘上的日志文件(redo log file)。mysql每执行一条DML语句,先将记录写入redo log buffer,后续某个时间点再一次性将多个操作记录写到redo log file。先写日志再写磁盘(WAL技术 Write-Ahead Logging)。
逻辑日志,记录相反,一条insert操作对应一个delete操作。段的方式管理。rollback segment称为回滚段,每个回滚段中有1024个undo log segment。
一个事务开始,为防止事务回滚,先写入undolog。然后写入redolog(redo log buffer),根据innodb_flush_log_at_trx_commit
决定何时写入redolog file。事务处于prepare阶段,执行器生成binlog日志,提交事务
读写锁中读写操作仍然互斥。MVCC:写操作更新最新的版本快照,读操作去读旧版本快照,没有互斥关系。类似CopyOnWrite(这个之后会记录)。
事务修改(UPDATE、DELETE、INSERT)会为数据行增加一个版本快照。
脏读和不可重复读根本原因是:事务读取到其它事务未提交的修改。所以未解决该问题,规定只能读取已提交的快照。
多个版本的快照存储在Undo日志中,通过回滚指针Roll_PTR把一个数据行的所有快照连接起来。INSERT、UPDATE、DELETE(额外设置为1)操作会创建一个日志将事务版本号(TRX_ID)写入。
维护一个ReadView结构,主要包含当前系统未提交的事务列表TRX_IDs,还有该列表最小值(TRX_ID_MIN)和最大值(TRX_ID_MAX)。
进行SELECT操作,根据该行快照TRX_ID与TRX_ID_MIN和TRX_ID_MAX关系判断是否可用。
SELETE * FROM table WHERE ? lock in share mode; //加S锁 SELETE * FROM table WHERE ? for update; //加X锁
为了解决MVCC的幻读问题。
锁定记录上的索引,不是记录本身。 如果没设置索引,InnoDB自动在主键上创建隐藏的聚簇索引。
锁定索引之间的间隙,不包括索引本身。
SELECT c FROM t WHERE c BETWEEN 10 AND 20 FOR UPDATE; //不能插入15
将Gap Locks与Record Locks结合。锁定一个前开后闭的区间。
补:
两段锁协议。事务分为两个阶段:1.获得封锁(扩展阶段),事务获得任何数据项上的任何类型的锁,不能释放。2.释放封锁(收缩阶段),事务可以释放任何数据项上的任何类型的锁,不能申请。保证可串行化的方法。
可串行化:多事务的并发执行正确,当且仅当其结果与某一次串行化执行的结果相同