mysql innodb_log_file_size 和innodb_log_buffer_size参数

今天主要研究下关于mysql的redo log(事务日志)的相关参数的设置问题,其中主要涉及到了三个参数的问题,
一:innodb_log_file_size :该参数决定着mysql事务日志文件(ib_logfile0)的大小;
设置的太小:当一个日志文件写满后,innodb会自动切换到另外一个日志文件,而且会触发数据库的检查点(Checkpoint),这会导致innodb缓存脏页的小批量刷新,会明显降低innodb的性能。由于日志切换更频繁,也就直接导致更多的BUFFER FLUSH,由于日志切换的时候是不能BUFFER FLUSH的, BUFFER写不下去,导致没有多余的buffer 写redo, 那么整个MYSQL就HANG住,还有一种情况是如果有一个大的事务,把所有的日志文件写满了,还没有写完,这样就会导致日志不能切换(因为实例恢复还需要,不能被循环复写)这样mysql就hang住了。可以根据文件修改时间来判断日志文件的旋转频率,旋转频率太频繁,说明日志文件太小了。
设置的太大:设置很大以后减少了checkpoint,并且由于redo log是顺序I/O,大大提高了I/O性能。但是如果数据库意外出现了问题,比如意外宕机,那么需要重放日志并且恢复已经提交的事务(也就是实例恢复中的前滚, 利用redo从演变化来恢复buffer cache中的数据),如果日志很大,那么将会导致恢复时间很长。甚至到我们不能接受的程度。
如果对 Innodb 数据表有大量的写入操作,那么选择合适的 innodb_log_file_size 值对提升MySQL性能很重要,
如何去设置合适的innodb_log_file_size 大小呢?
一般来说,日志文件的全部大小,应该足够容纳服务器一个小时的活动内容。
具体依据如下:我经常设置为 64-512MB
首先在业务高峰期,计算出1分钟写入的redo量,然后评估出一个小时的redo量;
MariaDB [(none)]> pager grep Log ##使用page之后,执行的命令只显示 Log开头的
PAGER set to ‘grep Log’
MariaDB [(none)]> show engine innodb status\G select sleep(60); show engine innodb status\G;
Log sequence number 4578059050533
Log flushed up to 1149269980149
1 row in set (0.00 sec)
1 row in set (1 min 0.00 sec)
Log sequence number 4578062739081
Log flushed up to 1149270019005
1 row in set (0.00 sec)
MariaDB [(none)]> nopager
PAGER set to stdout
MariaDB [(none)]> select (4578062739081-4578059050533)/1024/1024 as MB;
+————+
| MB |
+————+
| 3.51767349 |
+————+
1 row in set (0.00 sec)
注意Log sequence number,这是写入事务日志的总字节数。所以,现在你可以看到每分钟有多少MB日志写入(这里的技术适用于所有版本的MySQL,在5.0及更高版本,你可以从SHOW GLOBAL STATUS的输出看Innodb_os_log_written的值) 。
通过计算后得到每分钟有3.5M的日志写入。
根据经验法则。通常我们设置redo log size足够大,能够容纳1个小时的日志写入量。
1小时日志写入量=3.5M * 60=210M,由于默认有两个日志重做日志文件ib_logfile0和ib_logfile1。在日志组中的每个重做日志文件的大小一致,并以循环的方式写入。innodb存储引擎先写重做日志文件0,当达到文件的最后时,会切换到重做日志1,并checkpoint。以此循环。
所以我们可以大约设置innodb_log_file_size=110M。注意:在innodb1.2.x版本之前,重做日志文件总的大小不得大于等于4G,而1.2.x版本将该限制扩大到了521G。
二:innodb_log_files_in_group
该参数控制日志文件数。默认值为2。mysql 事务日志文件是循环覆写的。
需要注意的是:innodb_log_files_in_group是静态的变量,需要以“干净”的方式更改并重新启动,否则mysql启动不起来。也就是说如果想把原来是2的修改成3,这样的话你需要先关闭mysql服务,把原来的ib_logfile0和ib_logfile1文件删掉,然后启动mysql,否则报错如下所示:
直接修改my.cnf将该参数改为3的时候
重启mysql,报错,innodb引擎无法挂载
110124 14:06:23 InnoDB: Log file ./ib_logfile2 did not exist: new to be created
110124 14:06:23 [ERROR] Plugin ‘InnoDB’ init function returned error.
110124 14:06:23 [ERROR] Plugin ‘InnoDB’ registration as a STORAGE ENGINE failed.
三:innodb_log_buffer_size
该参数确保有足够大的日志缓冲区来保存脏数据在被写入到日志文件之前。
对于比较小的innodb_buffer_pool_size,建议是设置一样大。 但是,对于比较大的innodb_buffer_pool_size,不建议这么设置,这会存在一个潜在的问题,那就是当mysql挂掉时,恢复数据需要很久,造成大量的停机时间,当我们调整innodb_buffer_pool_size大小时,innodb_log_buffer_size和innodb_log_file_size也应该做出相应的调整。
四:innodb_log_group_home_dir
在事务被提交并写入到表空间磁盘文件上之前,事务日志存储在InnoDB的redo日志文件里。这些日志位于innodb_log_group_home_dir参数设置的目录中,通常我们把这个目录设置与innodb_data_home_dir变量相同。为了获得最佳性能,建议分离innodb_data_home_dir和innodb_log_group_home_dir到单独的物理存储阵列上,这样可以保证IO资源不起冲突,利于服务器处理大量高并发连接。
小结:mysql的事务日志相关的参数,基本介绍完毕了,影响日志刷新的性能的参数innodb_flush_log_at_trx_commit
具体分析innodb_flush_log_at_trx_commit=N的意义:
innodb_flush_log_at_trx_commit=0,每次commit时,事务日志写进了innodb log buffer ,然后每秒Log Thread 会将事务日志从innodb log buffer刷新到ib_ogfile(也就刷新到了磁盘)。当innodb_flush_log_at_trx_commit设置为0,mysqld进程的崩溃会导致上一秒钟所有事务数据的丢失,这是因为每次commit,事务日志只是写进了innodb log buffer 中,然后是每秒才将innodb log buffer 中的事务日志刷新到磁盘永久保存,所以mysqld进程的崩溃时,innodb log buffer可能会有一秒的日志没有刷新出来,但是在这种情况下,MySQL性能最好;
innodb_flush_log_at_trx_commit=2,每次commit时,事务日志写进了innodb log buffer,并同时接着写进os cache, 也就是说每次commit,事务日志写进了os cache中, 然后每秒从os cache刷新到ib_logfile(也就是刷新到了磁盘)。当innodb_flush_log_at_trx_commit设置为2,只有在操作系统崩溃或者系统掉电的情况下,上一秒钟所有事务数据才可能丢失,因为每次commit,事务日志已经进入了os cache,所以mysqld崩溃,事务日志是不会丢失的;
当innodb_flush_log_at_trx_commit设置为1,这是最安全的设置,同时由于频繁的io操作,导致效率是最差的,这时候不管是mysqld,还是操作系统崩溃,都不会丢数据,这是因为每次commit,事务日志都刷新到了磁盘永久保存了;

java.net.SocketException: Too many open files解决方法

一、错误现象

tomcat启动后,会出现前台页面无法访问,从日志中看错误:

2011-03-01 02:30:00 [com.asiainfo.aiox.common.rest.RestClient]-[ERROR] java.net.SocketException: Too many open files
Exception in thread “Thread-1168” java.lang.NoClassDefFoundError: org/apache/log4j/spi/ThrowableInformation
at org.apache.log4j.spi.LoggingEvent.<init>(LoggingEvent.java:159)
at org.apache.log4j.Category.forcedLog(Category.java:391)

 

2.错误原因

Linux默认打开文件1024,对于并发量大的无法满足要求;

 

(1)查看系统设置

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 253951
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024

pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 253951
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

通过以上命令,我们可以看到open files 的最大数为1024

对于并发量比较大的网站这个限制是有些捉襟见肘的

 

(2)解决方法

通过这个命令

ulimit -n 4096
把打开文件数的上限设为了4096,这下好了,项目又稳定了

但是,ulimit -n 4096 命令只能临时的改变open files  的值,当重新登陆后又会恢复,所以需要永久设置open files 的值。

 

很多系统上限可以通过修改/etc/security/limits.conf文件改变,这个文件有详细的注释,对如何修改做了说明。如果希望把所有用户的进程打开文件上限改为65536,可以加入下面两行

* soft nofile 65535
* hard nofile 65535

其中,*表示所有用户,soft/hard表示软/硬限制,还可以只真对某个用户或某个组做修改,具体方法参见文件注释。修改后需要重新启动系统才能生效。

 

3.涉及命令

ulimit -a  显示当前所有的 limit 信息

ulimit -n 可以打开最大文件描述符的数量

ulimit – n 4096;限制最大可以使用 4096个文件描述符

用lsof -p [进程ID] 可以看到某ID的打开文件状况。进程ID可能用 ps -ef|grep java列出weblogic的进程ID,然后用此ID套入lsof -p ID号,咳,一大堆的请求哟,这显然是网络请求过多造成了 Too many open files。适当调整后便已消除这种现象。
————————————————
版权声明:本文为CSDN博主「zdwzzu2006」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zdwzzu2006/article/details/7552017

linux之ls -l|grep “^-“|wc -l命令

查看某文件夹下文件的个数

ls -l |grep “^-“|wc -l

find ./company -type f | wc -l

查看某文件夹下文件的个数,包括子文件夹里的。

ls -lR|grep “^-“|wc -l

查看某文件夹下文件夹的个数,包括子文件夹里的。

ls -lR|grep “^d”|wc -l

说明:

ls -l

长列表输出该目录下文件信息(注意这里的文件,不同于一般的文件,可能是目录、链接、设备文件等)

grep “^-”

这里将长列表输出信息过滤一部分,只保留一般文件,如果只保留目录就是 ^d

wc -l

统计输出信息的行数,因为已经过滤得只剩一般文件了,所以统计结果就是一般文件信息的行数,又由于

一行信息对应一个文件,所以也就是文件的个数。