IT技术博客大学习 共学习 共进步

Innodb Log写入方式分析

MySQL支持 2010-08-19 00:11:23 浏览 3,062 次

原文URL:http://www.mysqlperformanceblog.com/2010/07/16/analyzing-the-distribution-of-innodb-log-file-writes/

    最近我分析了一下Innodb是如何写多个日志的。我这里有个流量比较高的MySQL系统,使用的是Percona XtraDB存储引擎,

我使用strace命令分别跟踪了innodb如何去日志文件的。通常来说,innodb是以512bytes的大小来写入日志的。

关于这个可以参考:Mark Callaghan explained this and some of its performance implications 。那么innodb什么时候情况下会以大于512bytes者小于512bytes的请求写到日志里呢?

首先,我通过lsof命令找出日志的文件描述符(handle).

# lsof -p $(pidof mysqld) | grep ib_log
mysqld  29772 mysql    8uW  REG                8,2   268435456   7143989 /var/lib/mysql/ib_logfile0
mysqld  29772 mysql    9uW  REG                8,2   268435456   7143993 /var/lib/mysql/ib_logfile1

我们可以看到2个日志的handle为8和9,现在我们需要捕获innodb是如何写这2个日志的相关信息。Innodb轮循写日志就是通过这个文件描述符.

The following grabs the write sizes out of 100k calls to pwrite() and aggregates them:

# strace -f -p $(pidof mysqld) -e pwrite -s1 -xx 2>&1 \

   | grep ‘pwrite([89],’ |head -n 100000 \

   | awk ‘{writes[$5]++}END{for(w in writes){print w, ” “, writes[w]}}’

本来我可以写一个更好的脚本来捕获信息,但是下面的信息对我来说已经足够了。

<strong>bytes        count</strong>
512           44067
1024         30740
1536         15221
2048         7094
2560         1810
3072         570
3584         219
4096         112
4608         39
5120         23
5632         16
6144         15
6656         5
7168         3
7680         8
8192         2
8704         2
9216         1
9728         2
10240       1
10752       2
11264       1
11776       1
14848       1
15360       1
15872       2
16384       4
16896       4
17408       2
17920       2
18432       2
18944       8
19456       7
19968       4
20480       4
21504       1
22016       2
24064       1
40960       1

总的来说,大致有3/4是以512和1024字节写入的。那么这到底什么意思呢?这里有很多有趣的而且复杂的东西需要我们去研究。

 1. 我们可以看到,大部分的写入都小于4K。但是我们知道操作系统的page大小是4K的。如果要写入的page不在cache中,那么这个page最开始需要读出,然后再修改,最后再写回到磁盘。vadim曾经过做做一些测试,如果要性能最好,那么日志要在OS的cache中。

 2.这台MySQL的innodb_flush_log_at_trx_commit设置是2.这就说明每个事务都会有一个日志写入请求,这个和设置为1是一样的。但是如果设置成0,那么写入的方法就大不相同―这个时候写入请求会累计到一定程度,然后一起写入。

 3.那么如果说log buffer小于一个事务要写的日志大小怎么办?这是另外一个需要研究的主题了。目前我还不清楚。

4.从上面的信息来看,是否可以很容易知道log buffer大小应该给多少呢?最大的写入小于40K,这好像可以说明分配64K给log buffer就已经足够了。这是真的吗?我们需要去测试才可以知道。peter以前和我谈过这个问题,log buffer背后的机制其实是很复杂的,到底log buffer需要保留多少空间给写操作。这些都需要更深入的研究。但是有一点可以确认,即使最大的写入操作不是很大的情况下,如果log buffer设置太小,性能肯定是不好的,而且会造成而外的锁。这个问题或许我们同样需要去研究。

最后,研究innodb是如何写日志的很容易,但是事实上innodb redo log机制是很复杂的,有时候我们很难说去猜想应该是什么样的,而应该去更深入的研究才可以知道的更多。也许我们可以按照上面这种步骤去研究不同LOG buufer大小,不同的日志参数设置,以及不同的服务器负载的情况下innodb到底是如何来写入日志的。

参考地址:http://mysqlha.blogspot.com/2009/06/buffered-versus-direct-io-for-innodb.html

建议继续学习

  1. Innodb IO优化-配置优化 (阅读 7,603)
  2. Innodb分表太多或者表分区太多,会导致内存耗尽而宕机 (阅读 7,565)
  3. Innodb 表和索引结构 (阅读 6,041)
  4. InnoDB线程并发检查机制 (阅读 5,601)
  5. Innodb如何使用内存 (阅读 5,101)
  6. Innodb文件表空间结构 (阅读 5,063)
  7. 快速预热Innodb Buffer Pool的方法 (阅读 4,982)
  8. InnoDB的缓存替换策略及其效果 (阅读 4,781)
  9. 多版本并发控制:PostgreSQL vs InnoDB (阅读 4,561)
  10. InnoDB之Dirty Page、Redo log (阅读 4,481)