Heim >Datenbank >MySQL-Tutorial >MySQL如何计算打开文件数_MySQL

MySQL如何计算打开文件数_MySQL

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOriginal
2016-06-01 14:00:441172Durchsuche

每打开一个MyISAM表,就需要使用2个文件描述符,咱们来验证一下MySQL如何计算打开文件数。


  一、试验

  从手册的"6.4.8. How MySQL Opens and Closes Tables"可以了解到,每打开一个MyISAM表,就需要使用2个文件描述符,咱们来验证一下。

  1. 重启mysqld

  /etc/init.d/mysql restart

  2. 看看打开了几个文件

  lsof | grep /home/mysql
  ...
  mysqld 24349 mysql 5u unix 0x000001041e8de040 4244009 /home/mysql/mysql.sock
  mysqld 24349 mysql 6u REG 8,33 2048 30425188 /home/mysql/mysql/host.MYI
  mysqld 24349 mysql 7u REG 8,33 0 30425189 /home/mysql/mysql/host.MYD
  mysqld 24349 mysql 8u REG 8,33 2048 30425153 /home/mysql/mysql/user.MYI
  mysqld 24349 mysql 9u REG 8,33 892 30425155 /home/mysql/mysql/user.MYD
  mysqld 24349 mysql 10u REG 8,33 5120 30425126 /home/mysql/mysql/db.MYI
  mysqld 24349 mysql 11u REG 8,33 3080 30425148 /home/mysql/mysql/db.MYD
  mysqld 24349 mysql 12u REG 8,33 4096 30425154 /home/mysql/mysql/tables_priv.MYI
  mysqld 24349 mysql 13u REG 8,33 0 30425157 /home/mysql/mysql/tables_priv.MYD
  mysqld 24349 mysql 14u REG 8,33 4096 30425143 /home/mysql/mysql/columns_priv.MYI
  mysqld 24349 mysql 15u REG 8,33 0 30425156 /home/mysql/mysql/columns_priv.MYD
  mysqld 24349 mysql 16u REG 8,33 4096 30425127 /home/mysql/mysql/procs_priv.MYI
  mysqld 24349 mysql 17u REG 8,33 0 30425136 /home/mysql/mysql/procs_priv.MYD
  mysqld 24349 mysql 18u REG 8,33 1024 30425173 /home/mysql/mysql/servers.MYI
  mysqld 24349 mysql 19u REG 8,33 0 30425174 /home/mysql/mysql/servers.MYD
  mysqld 24349 mysql 20u REG 8,33 2048 30425182 /home/mysql/mysql/event.MYI
  mysqld 24349 mysql 21u REG 8,33 0 30425183 /home/mysql/mysql/event.MYD
  ...   


  可以看到,总共打开了8个表,每个表分别有2个文件描述符,看来没错。

 3. 再来看 status 结果
  mysql>show global status like 'open_%';
  +------------------------+-------+
  | Variable_name | Value |
  +------------------------+-------+
  | Open_files | 17 |
  | Open_streams | 0 |
  | Open_table_definitions | 15 |
  | Open_tables | 8 |
  | Opened_files | 52 |
  | Opened_tables | 15 |
  +------------------------+-------+


  4. flush tables 后再看看

  mysql>flush tables;
  mysql> show global status like 'open_%';
  +------------------------+-------+
  | Variable_name | Value |
  +------------------------+-------+
  | Open_files | 1 |
  | Open_streams | 0 |
  | Open_table_definitions | 0 |
  | Open_tables | 0 |
  | Opened_files | 52 |
  | Opened_tables | 15 |
  +------------------------+-------+
  lsof | grep /home/mysql
  ...
  mysqld 24349 mysql 5u unix 0x000001041e8de040 4244009 /home/mysql/mysql.sock
  mysqld 24349 mysql 22u unix 0x00000102378ff980 4244128 /home/mysql/mysql.sock
  ...


  可以看到,flush 之后,所有的文件描述符都释放了。

  通过测试可以得知,另一个打开的文件描述符是 slow query log所用。

  如果是有大量的 MyISAM 表,那么就需要特别注意打开文件数是否会超出限制了。

  二、原理

  接下来仔细了解下这个最大文件数相关的参数:

  table_cache (新版本改成了 table_open_cache) The number of cached open tables.

  open_files_limit If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit().

  If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger)

  number of files.

  如果 open_files_limit 不是设置为 0,则以 setrlimit() 函数计算后的结果为准,如果设置为 0,则实际值是 max_connections*5 或 max_connections + table_cache*2 中的最大者。

  因此,想要解决打开文件数超限的问题,还需要综合系统内核限制(ulimit -n),mysqld自身限制(open_files_limit),以及表缓存数(table_open_cache)等多方面因素。

  不过,实际测试中,发现却不是这样的,open_files_limit采用了内核的最大限制,而非上面的计算结果。

  1. 查看内核限制

  ulimit -n

  65535

  2. 修改 my.cnf 限制

  vi /etc/my.cnf
  ...
  open_files_limit = 10000
  ...


  3. 重启 mysqld

  /etc/init.d/mysql restart

  4. 查看结果

  mysql>show global variables like '%open%';
  | open_files_limit | 65535 |
  | table_open_cache | 1000 |


  5. 不设置 open_files_limit 看看

  vi /etc/my.cnf
  ...
  #open_files_limit = 10000
  ...
  重启
  /etc/init.d/mysql restart
  查看
  mysql>show global variables like '%open%';
  | open_files_limit | 65535 |
  | table_open_cache | 1000 |


  而这个时候,按计算公式结果如下:

  | max_connections | 100 |

  | table_open_cache | 1000 |

  来计算一下:

  max_open_files_1 = max_connections + table_cache * 2 = 100 + 1000 * 2 = 2100

  max_open_files_2 = max_connections*5 = 100 * 5 = 500

  6. 修改 ulimit 试试看:

  unlimit -n 5000
  vi /etc/my.cnf
  ...
  open_files_limit = 10000
  ...
  /etc/init.d/mysql restart
  mysql>show global variables like '%open%';
  | open_files_limit | 10000 |
  | table_open_cache | 1000 |


  open_files_limit 比内核最大限制数还大,因此以 open_files_limit 为准。

  vi /etc/my.cnf
  ...
  #open_files_limit = 10000
  ...
  /etc/init.d/mysql restart
  mysql>show global variables like '%open%';
  | open_files_limit | 5000 |
  | table_open_cache | 1000 |


  看到了,变成了新的内核最大限制

  看到了吧,结果完全跟文档描述的以及mysql源码中写的不一样,看来预编译版本有些地方不太可靠啊 :(

  以上测试在mysql 5.1.23-rc(预编译), mysql-5.1.24-rc(自编译) 以及 5.0.45(预编译) 均一样。

  uname -a
  Linux s1.yejr.com 2.6.9-55.ELsmp #1 SMP Fri Apr 20 16:36:54 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux
  mysql> select version();
  +---------------+
  | version() |
  +---------------+
  | 5.1.23-rc-log |
  +---------------+

 

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn