mysql文件理解

mysql_Innodb的undo_log和redo_log

原创 2014年10月28日 11:26:34

众所周知,mysql支持多种存储引擎,现在常用的是MyISAM和InnoDB。MyISAM相对简单,但不支持事务,而InnoDB是事务安全型的。而InnoDB的事务处理离不开undo_log和redo_Log。

mysql innodb存储引擎

下面简单的介绍一下innodb的存储引擎

内存缓冲池

如果mysql不用内存缓冲池,每次读写数据时,都需要访问磁盘,必定会大大增加I/O请求,导致效率低下。所以Innodb引擎在读写数据时,把相应的数据和索引载入到内存中的缓冲池(buffer pool)中,一定程度的提高了数据读写的速度。

buffer pool:占最大块内存,用来存放各种数据的缓存包括有索引页、数据页、undo页、插入缓冲、自适应哈希索引、innodb存储的锁信息、数据字典信息 等。工作方式总是将数据库文件按页(每页16k)读取到缓冲池,然后按最近最少使用(lru)的算法来保留在缓冲池中的缓存数据。如果数据库文件需要修 改,总是首先修改在缓存池中的页(发生修改后即为脏页dirty page),然后再按照一定的频率将缓冲池的脏页刷新到文件。

表空间

表空间可看做是InnoDB存储引擎逻辑结构的最高层。 表空间文件:InnoDB默认的表空间文件为ibdata1。

  • 段:表空间由各个段组成,常见的段有数据段、索引段、回滚段(undo log段)等。
  • 区:由64个连续的页组成,每个页大小为16kb,即每个区大小为1MB。
  • 页:每页16kb,且不能更改。常见的页类型有:数据页、Undo页、系统页、事务数据页、插入缓冲位图页、插入缓冲空闲列表页、未压缩的二进制大对象页、压缩的二进制大对象页。

    redo log 和undo log

    为了满足事务的持久性,防止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_log_file_size指定了redo log的大小;innodb_log_file_in_group指定了redo log的数量,默认为2; innodb_log_group_home_dir指定了redo log所在路径。

  1. innodb_additional_mem_pool_size = 100M
  2. innodb_buffer_pool_size = 128M
  3. innodb_data_home_dir = /home/mysql/local/mysql/var
  4. innodb_data_file_path = ibdata1:1G:autoextend
  5. innodb_file_io_threads = 4
  6. innodb_thread_concurrency = 16
  7. innodb_flush_log_at_trx_commit = 1
  8. innodb_log_buffer_size = 8M
  9. innodb_log_file_size = 128M
  10. innodb_log_file_in_group = 2
  11. innodb_log_group_home_dir = /home/mysql/local/mysql/var

undo log

为了满足事务的原子性,在操作任何数据之前,首先将数据备份到Undo Log,然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。与redo log不同的是,磁盘上不存在单独的undo log文件,它存放在数据库内部的一个特殊段(segment)中,这称为undo段(undo segment),undo段位于共享表空间内。

Innodb为每行记录都实现了三个隐藏字段:

  • 6字节的事务ID(DB_TRX_ID)
  • 7字节的回滚指针(DB_ROLL_PTR)
  • 隐藏的ID

redo log的记录内容

undo log和 redo log本身是分开的。innodb的undo log是记录在数据文件(ibd)中的,而且innodb将undo log的内容看作是数据,因此对undo log本身的操作(如向undo log中插入一条undo记录等),都会记录redo log。undo log可以不必立即持久化到磁盘上。即便丢失了,也可以通过redo log将其恢复。因此当插入一条记录时:

  1. 向undo log中插入一条undo log记录。
  2. 向redo log中插入一条”插入undo log记录“的redo log记录。
  3. 插入数据。
  4. 向redo log中插入一条”insert”的redo log记录。

redo log的io性能

为了保证Redo Log能够有比较好的IO性能,InnoDB 的 Redo Log的设计有以下几个特点:

  1. 尽量保持Redo Log存储在一段连续的空间上。因此在系统第一次启动时就会将日志文件的空间完全分配。以顺序追加的方式记录Redo Log。
  2. 批量写入日志。日志并不是直接写入文件,而是先写入redo log buffer,然后每秒钟将buffer中数据一并写入磁盘
  3. 并发的事务共享Redo Log的存储空间,它们的Redo Log按语句的执行顺序,依次交替的记录在一起,以减少日志占用的空间。
  4. Redo Log上只进行顺序追加的操作,当一个事务需要回滚时,它的Redo Log记录也不会从Redo Log中删除掉

redo & undo log的作用

  • 数据持久化

    buffer pool中维护一个按脏页修改先后顺序排列的链表,叫flush_list。根据flush_list中页的顺序刷数据到持久存储。按页面最早一次被修改的顺序排列。正常情况下,dirty page什么时候flush到磁盘上呢?

    1. 当redo空间占满时,将会将部分dirty page flush到disk上,然后释放部分redo log。
    2. 当需要在 Buffer pool分配一个page,但是已经满了,这时候必须 flush dirty pages to disk。一般地,可以通过启动参数 innodb_max_dirty_pages_pct控制这种情况,当buffer pool中的dirty page到达这个比例的时候,把dirty page flush到disk中。
    3. 检测到系统空闲的时候,会flush。
  • 数据恢复

    随着时间的积累,Redo Log会变的很大。如果每次都从第一条记录开始恢复,恢复的过程就会很慢,从而无法被容忍。为了减少恢复的时间,就引入了Checkpoint机制。假设 在某个时间点,所有的脏页都被刷新到了磁盘上。这个时间点之前的所有Redo Log就不需要重做了。系统记录下这个时间点时redo log的结尾位置作为checkpoint。在进行恢复时,从这个checkpoint的位置开始即可。Checkpoint点之前的日志也就不再需要 了,可以被删除掉。
  • 事务回滚

    F1~F6是某行列的名字,1~6是其对应的数据。后面三个隐含字段分别对应该行的事务号和回滚指针。假如这条数据是刚INSERT的,可以认为ID为1,其他两个字段为空。

    举例说明数据行更新以及回滚的过程:

    事务1:更改某行数据的值

    当事务1更改该行的值时,会进行如下操作:

    1. 用排他锁锁定该行
    2. 把该行修改前的值Copy到undo log,即下图中下面的行
    3. 修改当前行的值,填写事务编号,使回滚指针指向undo log中的修改前的行
    4. 记录redo log

    事务2:再次更改该行数据的值

    与事务1相同,此时undo log中有两行记录,并且通过回滚指针连在一起。因此,如果undo log一直不删除,则会通过当前记录的回滚指针回溯到该行创建时的初始内容。在Innodb中存在purge线程,它会查询那些比现在最老的活动事务还早 的undo log,并删除它们,从而保证undo log文件不至于无限增长。

    回滚过程

    根据当前回滚指针从undo log中找出事务修改前的版本,并恢复。如果事务影响的行非常多,回滚则可能会变的效率不高。当事务行数在1000~10000之 间,Innodb效率还是非常高的。

    Innodb也会将事务回滚时的操作也记录到redo log中。回滚操作本质上也是对数据进行修改,因此回滚时对数据的操作也会记录到Redo Log中。

    一个回滚过程的redo log 看起来是这样的:

    • 记录1: <trx1, Undo log insert >
    • 记录2: <trx1, insert A…>
    • 记录3: <trx1, Undo log insert >
    • 记录4: <trx1, update B…>
    • 记录5: <trx1, Undo log insert >
    • 记录6: <trx1, delete C…>
    • 记录7: <trx1, insert C>
    • 记录8: <trx1, update B to old value>
    • 记录9: <trx1, delete A>
时间: 2024-10-31 15:59:34

mysql文件理解的相关文章

MySQL深层理解

MySQL是一个关系型数据库,关联的数据保存在不同的表中,增加了数据操作的灵活性. 执行流程 MySQL是一个单进程服务,每一个请求用线程来响应, 流程: 1,客户请求,服务器开辟一个线程响应用户. 2,用户发起SQL请求, 3,查询缓存,并记录用户SQL,如果再次查询,直接查缓存. 4,没有缓存,进入分析器, 语法分析器:检查语法 词法分析器:将命令切片,按空格隔开,获取表,内容和用户权限. 5,优化执行路径选择,生产执行树. 6,存储引擎:用于管理存储文件系统,给上层应用提供不同管理. 那么

cmd导入mysql文件

之所以要使用CMD(命令行)导入Mysql文件(.sql文件形式)也许是你还没遇到过 Mysql图形管理工具都无法正常导入sql文件.在网上找了很多的网友提供的资料来看几乎都是显示 所用工具限制,这里我就不多说了. 如下: 1.连接数据库 (注意:前提是Mysql 环境变量设定好的情况) 2.找到需要导入的数据库(这里以my_table为例) 3.导入数据库(注:文件是放在D盘根目录位置) 总结: 写代码前先不用太着急,不管是实现什么样的功能先把思路推理一遍,再有就是一定要不动手去写代码 .如以

linux备份mysql文件并恢复的脚本,以及其中出现的错误:ERROR: ASCII &#39;\0&#39; appeared in the statement

首先是在网上找了一下教程,代码很简单 #!/bin/bash folder=~/test time=`date +%Y%m%d` mysqldump -u user -p pwd -hlocalhost databasename | gzip > $folder/databasename_$time.sql.gz # find $folder -name 'databasename_*.sql.gz' -type f -mtime +7 -exec rm {} \; # gunzip < $f

mysql体系结构理解与分析

接触mysql有一年多了,但是始终是一个偶尔用用的状态,对其原理性的东西研究不够,在不少mysql相关的暑假中提到mysql体系结构,很清楚解析了mysql的各个模块分层和主要功能特性,在理解此功能特性后,会刚好的帮助我们学习mysql数据库. 一 Mysql体系结构总览 在上面的体系结构图中,我们可以对其进行分层研究,类似于系统架构分析,按层刚好的理解整个体系架构. Connectors: 从图中我们可以看出是包含Python.Perl.Ruby.PHP..NET.JDBC等和数据库交互的编程

mysql文件导入到数据库load data infile into table 的使用例子

load data infile "C:/Users/Administrator/Desktop/1.txt"into table 要一个已经存的表名 字段默认用制表符隔开 文件 我爱你 20 相貌平常李奎 21 相貌1平常王二米 210 相貌3平常老三 24 很强老四 34 XXXXX 常用如下: Load Data InFile 'C:/Data.txt' Into Table `TableTest` Lines Terminated By '\r\n';这个语句,字段默认用制表符

mysql 文件导入方法总结

数据导入3三种方法 一.phpMyAdmin 限制大小:2M 1.创建数据库 2.导入.sql或.sql.zip文件 大数据导入方法一:http://jingyan.baidu.com/article/9113f81bcdf3a32b3214c7e7.html大数据导入方法二:http://jingyan.baidu.com/article/60ccbceb21966d64cab1979e.html 参考文档http://www.sjyhome.com/php/phpmyadmin-limit.

MySQL初步理解,简易单表增删改查

什么是数据库? 存储数据的仓库,本质是一个文件系统,封装了算法和文件之前数据的存储模式 阶段1:集合 数组 变量 缺点:数据存储在内存中,不能实现数据的持久化存储 阶段2:IO流 结合文件 .txt .xml.... 优点:数据存储在磁盘上,数据可以实现持久化存储 缺点:数据操作时,算法必须自己实现,但是相当一部分算法实现重复 阶段3:数据库 优点:使用专门的程序封装了算法部分 数据库与IO比较:算法 + 文件存储数据数据库结构: 算法部分:.exe程序 lib文件夹下 文件存储部分:以文件和文

linux下mysql 文件导入导出

最近在做mysql的数据导入导出得到的一些经验,记录下. 1.首先要开通导入导出的功能,需要设置一个mysql的配置 可以在 my.conf 文件的最后增加配置项 secure-file-priv='' 用这个命令查到当前的设置 SHOW VARIABLES LIKE '%secure_file_priv%'; 如果为 NULL 表示禁止导入导出,如果指定了具体路径,则导入导出必须在这个路径下,如果为空字符串,则可以导出到任意路径(必须要有足够权限写任意的路径权限) 如果权限不够则可以默认到my

linux系统下导出MySQL文件

1.配置:从centOS6.5系统,MySQL数据库 2.导出.sql文件的命令: mysqldump -uroot -h116.228.90.147 -P18006 -p aimo > /home/aimo.sql 3.解释: I.mysqldump是mysql用于转存储数据库的实用程序.它主要产生一个SQL脚本,其中包含从头重新创建数据库所必需的命令CREATE TABLE INSERT等. II.-uroot -u后面紧跟用户名 III.-h116.228.90.147 -h后面紧跟IP地