mysql 日志
- 事务的四大特性?怎么实现?主次关系
A 原子性 用undolog来保证
C数据的一致性
I隔离性:读写锁+mvcc机制
D:持久性 用redolog 和双写缓冲区保证
数据的一致性是目的,原子性、隔离性、持久性就手段;
- 事务实现永久性的三个机制
WAL write-ahead log 先写日志 日志写好就代表事务提交了
CL commit logging 数据持久化后才代表数据提交了
shadow paging(影子分页)
- redolog的记录内容
记录数据页产生的所有变化,包括page header 中的数据记录 槽数量、changebuffer对应的数据页更改、max rowid的变化等
是记录多种数据页 不单指常用的数据表中的数据。
在数据库正常运行的情况下,redolog 的功能是用不到的,数据永久化是通过刷脏页到磁盘的方式;在断电宕机需要crash的情况下才用到redolog的功能,保证数据不丢失。crash时数据的原子性(宕机时未提交 需要undolog的记录的redolog)还有持久性
- redolog的type
有53种 包含简单的 MLOG-8byte MLOG-1byte MLOG-2byte MLOG-4byte
复杂的redolog
- redolog的缓存 log buffer,缓存大小redolog 磁盘持久化
redolog内存空间:默认是16M,分块一块512字节。 show variables like 'innodb_log_buffer_size';
根据参数设置可持久到磁盘中
show variables like "%innodb_log_file_size%"; 磁盘中存储redolog的空间 默认是48M
show variables like "%innodb_log_files_in_group%"; 磁盘中存储redolog的文件个数,默认是两个,最多设置成100个
都是循环写入,当脏页持久化到磁盘后,对应的redolog 日志删除
- innodb_flush_log_at_trx_commit
0:事务提交的时候不持久到磁盘中 等待后台线程 每隔一秒刷新到磁盘,当断电 或者 mysql 崩溃的时候 可能丢失数据
1:缺省设置,事务提交的时候 调用fsync()函数强制刷新到磁盘中;
2.:事务提交的时候,将数据刷新到系统缓冲区中,当myqsl 异常的时候不会丢失数据
- LSN
log squence number 日志的序列号 开始为8704
根据此序列号可以确定 内存中的脏页和redolog 保持一致;联合check point 可以检查redolog 日志文件有没有写满
show engine innodb status \G
Log sequence number:代表系统中的lsn值,也就是当前系统已经写入的redo日志量,包括写入log buffer中的日志。
Log flushed up to:代表flushed_to_disk_lsn的值,也就是当前系统已经写入磁盘的redo日志量。
Pages flushed up to:代表flush链表中被最早修改的那个页面对应的oldest_modification属性值。
Last checkpoint at:当前系统的checkpoint_lsn值。
- redolog 什么时候刷盘
log buffer 达到总容量的一半时
事务提交 innodb_flush_log_at_trx_commit 参数为1的时候
后台线程每隔一秒刷新一次
mysql 正常关闭的时候
- redolog和binlog的区别
redolog:用于恢复因为系统崩溃引起的数据丢失,记录的是具体的表空间的具体页面的具体位置发生的变化逻辑;循环写入文件;根据LSN可以分辨可以和脏页数据保持一致:引擎层 innodb
binlog:用于客户端数据丢失恢复数据的文件,记录的是语句改变的逻辑;追加写入;不能替代redolog, 因为没有LSN和脏页保持一致;server层,依赖于原数数据库的备份文件,在备份文件恢复的基础上进行恢复数据
两者都是记录的数据更改逻辑,都需要依赖原始数据进行更改,
- redolog和双写缓冲区的区别
redolog 恢复数据是要依赖原数据完整的条件下,把数据变化更提到数据页上;
双写缓冲区是在数据页损坏的情况下进行恢复数据页;两者恢复损毁数据的时间段不同
- redolog和change buffer的区别
change buffer 也会记录日志到redolog中,
change buffer 主要记录非唯一的二级索引的变化。
merge的时间点:数据需要访问的时候、正常关闭mysql的时候
- redolog和binlog保证数据一致的2PC
两段式提交 prepare commit
- redolog和undolog的关系
undolog 也会记录日志到redolog中
- 程序持久化磁盘的过程
- undolog是什么
是撤销日志,为了保证事务的原子性采用的日志策略。
以数据页的形式存储。所以也需要记录redo日志 是FIL_PAGE_UNDO_LOG形式的数据页。
insert的回滚日志:需要记录主键id ,回滚时删除聚簇索引和二级索引的数据。
delete的回滚日志:需要记录删除的数据,回滚时好找到原数据;
update的回滚日志:需要记录更改的数据;
- 事务id
对于只读事务(create/start transation read only)中的外部临时表 和读写事务(create/start transation (read write))中的表来说,第一次进行增删改的时候会分配一个trx_id;
trx_id 类似于row_id 是个全局变量,当时256的倍数时 持久化到磁盘里。当重启mysql时会读取到内存中+256作为当前trx_id;
- 版本链
每当数据库执行一个新的DML操作时 就将上一次更改的相反操作记录在undolog版本链中,当前数据行的roll_ptr指向undolog版本链。
1.DDL(DataDefinitionLanguage):数据定义语言,用来定义数据库对象:库、表、列等;
2.DML(DataManipulationLanguage):数据操作语言,用来定义数据库记录(数据);
3.DQL(DataQueryLanguage):数据查询语言,用来查询记录(数据);
4.DCL(DataControlLanguage):数据控制语言,用来定义访问权限和安全级别。
- insert操作的回滚
undo日志只需要记录这条插入语句的id 即可,日志类型为:trx_undo_insert_REC ,当需要回滚的时候,用这个id在主键索引和二级索引中删除即可
- delete操作的回滚
记录的日志类型是 TRX_UNDO_DEL_MARK_REC;
删除一条记录有两个阶段,删除后未提交的阶段,成为delete mark阶段。此阶段delete_mark被修改成了1,但是记录没有从正常数据的版本链中去除(保证了mvcc机制);
当事务提交后,对delete mark比较成1 的记录进行了回收,从正常数据列表中去除,链接到了垃圾列表中,等待被复用,这个阶段成为purge阶段。在page header 中由page free 指向该列表;
当事务没有提交,删除数据处于delete mark阶段时进行回滚,可根据版本链直接修改 数据记录的delete mark的标志
- update操作的回滚
分为三种情况:
1.更改主键:先删除(更改delete mark标志) 再在增加(mvcc机制,别的事务也可以看见这天更改未提交的数据);有两条undo 日志 TRX_UNDO_DEL_MARK REC 和 TRX_UNDO_INSERT_REC
2.不更改主键并且数据大小有变化:针对变长的数据类型 有可能数据增加或者减小了,原来的空间不合适,所以需要把原来的数据记录删除(直接删除)再重新增加一条数据;
3.不更改主键且数据大小无变化:原地更改数据;in place update
- 正常事务执行流程
- 事务回滚的流程