内容简介:Innodb中的buffer poll和redo undo log
内存缓冲池
buffer pool
,如果 mysql 不使用内存缓冲池,每次读取数据时,都需要访问磁盘,会大大的增加磁盘的IO请求,导致效率低下;在Innodb引擎在读取数据的时候,把相应的数据和索引载入到内存的缓冲池(buffer pool)中,一定程度的提高了数据的读写速度
buffer pool
占用大量内存,用来存放各种数据的缓存包括:索引页,数据页,undo页,插入缓冲,自适应哈希索引,innodb存储的锁信息,数据字典等。工作方式是将数据库文件按照页(每页16k)读取到缓冲池,然后按照最近最少使用算法( LRU
)来保留缓冲池中的缓冲数据。如果数据库文件需要修改,总是首先修改在缓冲池中的页(发生修改后即成为 脏页
),然后在按照一定的频率将缓冲池中的脏页刷新到文件
表空间
表空间可以看作是InnoDB存储引擎逻辑结构的最高层。表空间文件:InnoDB默认的表空间文件为 ibdata1
-
页: 每页数据为16kb ,且不能进行修改。常见的页类型有:数据页,Undo页,系统页,事务数据页,插入缓冲位图页,插入缓冲空闲列表页,未压缩的二进制大对象页,压缩的二进制大对象页
-
区:由 64 个连续的页组成,每个页大小为 16kb ,即 每个区的大小为1024kb即1MB
-
段:表空间由各个段组成,常见的段有数据段,索引段,回滚段(undo log段)等
redo log和undo log
mysql中的原则是 日志先行
。为了满足事务的持久性,防止 buffer pool
数据丢失,innodb引入了 redo log
。为了满足事务的原子性,innodb引入了 undo log
redo log
redo log就是保存执行的 SQL 语句到一个指定的log文件,当mysql进行数据恢复的时候,重新执行redo log记录的SQL操作即可。引入buffer pool会导致更新的数据不会实时地将数据持久化到硬盘,当系统崩溃时,虽然buffer pool中的数据丢失,数据没有持久化。但是系统可以根据redo log的内容,将所有数据恢复到最新的状态。redo log在磁盘上作为一个独立的文件存在,默认情况下会有两个文件,名称分别为 ib_logfile0
和 ib_logfile1
innodb_additional_mem_pool_size = 100M innodb_buffer_pool_size = 128M innodb_data_home_dir = /home/mysql/local/mysql/var innodb_data_file_path = ibdata1:1G:autoextend innodb_file_io_threads = 4 innodb_thread_concurrency = 16 innodb_flush_log_at_trx_commit = 1 innodb_log_buffer_size = 8M innodb_log_file_size = 128M innodb_log_file_in_group = 2 innodb_log_group_home_dir = /home/mysql/local/mysql/var
redo log的记录内容
undo log和redo log本身是分开的。Innodb的undo log是记录在数据文件(ibd)中的,而且innodb将undo log的内容看做是数据,因此对undo log本身的操作(如向undo log插入一条undo log记录等),都会记录redo log。undo log可以不必立即持久化到磁盘上。即便丢失了,也可以通过redo log将其恢复。因此当插入一条记录时:
-
向undo log插入一条undo log记录
-
向redo log中插入一条“插入undo log记录”的redo log记录
-
插入数据
-
向redo log插入一条“insert”的redo log记录
在一个事务中插入数据的时候:
假设对两个字段A,B分别进行更新,初始值分别为1,3 begin 在undo log中记录A为1 更新A为2 记录A=2到redo log 在undo log中记录B为3 更新B为4 记录B=4到redo log 将redo log写入到磁盘 commit
redo log的io性能
为了保证redo log能够有很好的io性能,innodb的redo log的设计有以下几个特点:
-
尽量保持redo log存储在一段连续的空间上。因此在系统第一次启动时就会将日志文件的空间完全分配。以顺序追加的方式记录redo log
-
批量写入日志。日志并不是直接写入到文件,而是先写入redo log buffer,然后每秒钟将buffer中数据一并写入磁盘
-
并发的事务共享redo log的存储空间,他们的redo log按语句的执行顺序,依次交替的记录在一起,以减少日志占用的空间
-
redo log上只进行顺序追加的操作,当一个事务需要回滚时,它的redo log记录也不会从redo log中删除
undo log
为了满足事务的原子性,在操作任何数据之前,首先将数据备份到undo log,然后进行数据的修改。如果出现了错误或者用户手动执行了 rollback
,系统可以利用undo log中的备份将数据恢复到事务开始之前的状态。与redo log不同的是,磁盘上不存在单独的undo log 文件,他存放在数据库内部的特殊段(segment)中,这称之为undo段(undo segment),undo段位于共享表空间内
Innodb为每行undo log记录都实现了三个隐藏字段:
-
6字节的事务ID(DB_TRX_ID)
-
7字节的回滚指针(DB_ROLL_PTR)
-
隐藏的ID
redo log和undo log
-
数据持久化
-
pool中维护一个按脏页修改先后顺序排列的链表,叫
flush_list。根据flush_list中页的顺序刷数据到持久化存储。按页面最早一次被修改的顺序排列。正常情况下,dirty page刷新数据的时机为:-
当redo空间占满时,将会将部分dirty page flush到disk上,然后释放部分redo log内容
-
当需要buffer pool分配一个page,但是已经满了,这时候必须flush dirty pages to disk。
-
检测到系统空闲的时候
-
-
数据恢复
随着时间积累,redo log会变得很大。如果每次都从第一条记录开始恢复,恢复过程会十分缓慢,从而无法被容忍。为了减少恢复的时间,就引入了checkpoint机制:假设在某个时间点,所有的脏页都被刷新到了磁盘上。这个时间点之前的所有redo log就不需要重做了。系统记录下这个时间点时redo log的结尾位置作为checkoutpoint。在进行恢复时,从这个checkpoint的位置开始即可。checkpoint点之前的日志就不再需要了,可以被删除掉
以上所述就是小编给大家介绍的《Innodb中的buffer poll和redo undo log》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Just My Type
Simon Garfield / Profile Books / 2010-10-21 / GBP 14.99
What's your type? Suddenly everyone's obsessed with fonts. Whether you're enraged by Ikea's Verdanagate, want to know what the Beach Boys have in common with easy Jet or why it's okay to like Comic Sa......一起来看看 《Just My Type》 这本书的介绍吧!