Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1000394
  • 博文数量: 116
  • 博客积分: 3758
  • 博客等级: 中校
  • 技术积分: 1316
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-17 11:49
个人简介

这家伙很懒。。。

文章分类

全部博文(116)

文章存档

2016年(3)

2015年(2)

2014年(1)

2013年(9)

2012年(25)

2011年(50)

2010年(12)

2009年(14)

分类: Mysql/postgreSQL

2011-03-19 16:30:35

Mysql启动中 InnoDB: Error: log file ./ib_logfile0 is of different size 0 5242880 bytes 的问题

对于使用了默认 my.cnf(一般教程都会教你使用support-files/my-medium.cnf)的Mysql服务来说
如果中间使用了innodb的话,innodb默认的log file大小是56M

如果你的配置文件使用了类似my-innodb-heavy-4G.cnf作为配置文件的话。
Mysql可以正常启动,但innodb的表无法使用
在错误日志里你会看到如下输出:

InnoDB: Error: log file ./ib_logfile0 is of different size 0 5242880 bytes

现在需要做的事情就是把原来的 innodb 的ib_logfile×备份到一个目录下,然后删除掉原来的文件,重启 mysql。
你会看到ib_logfile*大小变成了你配置文件中指定的大小。
my-innodb-heavy-4G.cnf的话(log file 的大小是256M:innodb_log_file_size = 256M)
你会看到很多个268435456大小的文件。



附件是我推荐使用的Mysql(支持Innodb)的


InnoDB的ib_logfile写入策略

ib_logfileInnoDB的事务日志文件。本文简要说明其写入时机、写入策略及如何保证数据安全。

 

 

1、              基本概念

a)        ib_logfile文件个数由innodb_log_files_in_group配置决定,若为2,则在datadir目录下有两个文件,命令从0开始,分别为ib_logfile0ib_logfile.

b)        文件为顺序写入,当达到最后一个文件末尾时,会从第一个文件开始顺序复用。

c)        lsn: Log Sequence Number,是一个递增的整数。 Ib_logfile中的每次写入操作都包含至少1log,每个log都带有一个lsn。在内存page修复过程中,只有大于page_lsnlog才会被使用。

d)        lsn的保存在全局变量log_sys中。递增数值等于每个log的实际内容长度。即如果新增的一个log长度是len,则log_sys->lsn += len.

e)        ib_logfile每次写入以512OS_FILE_LOG_BLOCK_SIZE)字节为单位。实际写入函数 log_group_write_buf (log/log0log.c)

f)         每次写盘后是否flush,由参数innodb_flush_log_at_trx_commit控制。

 

 

2、              log_sys介绍

                  log_sys是一个全局内存结构。以下说明几个成员的意义。

        

lsn

表示已经分配的最后一个lsn的值。

written_to_all_lsn

n表示实际已经写盘的lsn。需要这个值是因为并非每次生成log后就写盘。

flushed_to_disk_lsn

表示刷到磁盘的lsn。需要这个值是因为并非每次写盘后就flush

buf

待写入的内容保存在buf

buf_size

buf的大小。由配置中innodb_log_buffer_size决定,实际大小为innodb_log_buffer_size /16k * 16k

buf_next_to_write

buf中下一个要写入磁盘的位置

buf_free

 

buf中实际内容的最后位置。当buf_free> buf_next_to_write时,说明内存中还有数据未写盘。

 

3、相关更新

用一个简单的更新语句来说明log_sys以及ib_logfile的更新内容的过程。假设我们的更新只涉及到非索引的固定长度字段。

a)        log_sys->buf中写入undo log 对于一个单一的语句,需要先创建一个undolog头。

b)        log_sys->buf中写入undo log的实际内容。

c)        log_sys->buf中写入buffer page的更新内容。此处保存了更新的完整信息。

d)        log_sys->buf中写入启动事务(trx_prepare)的日志

e)        ad的所有log内容写入ib_logfile中。

f)         log_sys->buf中写入事务结束(trx_commit)的日志

g)        f步骤的log内容写入ib_logfile中。

 

4、              说明

a)        完成上述所有操作时,数据文件还没有更新。

b)        每次写入log_sys->buf时同时更新lsnbuf_free 每次写ib_logfile时同时更新written_to_all_lsnbuf_next_to_write

c)        每次写ib_logfile时以512字节为对齐,如需写入600字节,则实际写入1k。写到最后一个文件末尾则从第一个文件重复使用。

d)         从上述流程看到,在ad过程中若出现异常关闭,由于没有写入到磁盘中,因此整个事务放弃;若在e刚完成时出现异常关闭,虽然事务内容已经写盘,但没有提交。在重启恢复的时候,发现这个事务还没有提交,逻辑上整个事务放弃。      (重启日志中会有Found 1 prepared transaction(s) in InnoDB字样)。在g完成后出现异常关闭,则能够在重启恢复中正常提交。

    ef之间会写mysqlbin-log,若bin-log写完前异常关闭,事务无效,bin-log写入成功后,则异常重启后能够根据bin-log恢复事务的修改。

 

e)        若涉及到索引更新,在步骤c之后会增加索引更新的log。由于索引可能有merge过程,因此在merge过程中会另外增加写入一个log。但事务完全提交仍在步骤g中。索引的更新由于已经写盘,并不会因此丢失。




阅读(5841) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~