在 Ubuntu 20.04 中无法增加 MySQL table_open_cache

在 Ubuntu 20.04 中无法增加 MySQL table_open_cache

我已经阅读了这两个相关问题但仍然卡住:

MySQL table_open_cache 设置为8000in,/etc/mysql/mysql.conf.d/mysqld.cnf并且该值未在任何其他加载的 cnf 文件中定义:

table_open_cache = 8000

另外,/lib/systemd/system/mysql.service我有默认条目:

LimitNOFILE=10000

当我从 cli 查询变量时,我仍然得到以下信息:

mysql> show variables like 'table_open_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| table_open_cache | 4745  |
+------------------+-------+

还有这个:

$ ulimit -n
1024

这很令人困惑,因为如果系统限制了打开文件数,那么上限难道不应该是 1024 而不是 4745 吗?我不明白 4745 是从哪里来的。

有人能解释一下这是怎么回事吗?这是 MySQL 配置问题还是操作系统施加的限制?我刚刚从 Ubuntu 16.04 迁移过来,配置几乎相同,以前这不是问题。

操作系统是 Ubuntu 20.04。MySQL 版本是 8.0.20。

答案1

我发现了一些至少可以部分回答我的问题的东西。LimitNOFILE里面的设置/lib/systemd/system/mysql.service 在这里发挥作用但与我工作过的其他环境不同,这里的环境不是 1:1 的关系并且需要远高于你的目标table_open_cache限制。

通过反复试验,我发现增加LimitNOFILE只会导致部分价值被委托给限制table_open_cache,所以我做了一些实验并得出了以下结论:

  • LimitNOFILE获得1310400一个table_open_cache
  • 以上1310table_open_cache每增加 50%LimitNOFILE
  • 奇怪的是,如果LimitNOFILE低于510table_open_cachesystemd 似乎没有限制。

利用上述公式我得到了以下等式:

(($table_open_cache - 400) * 2) + 1310 = $LimitNOFILE

因此如果您想要table_open_cache8000您需要设置LimitNOFILE16510

((8000 - 400) * 2) + 1310 = 16510

我不明白这里发生了什么,但我能够在具有不同数据库和 mysqld 配置的不同主机上重现完全相同的行为。

如果有人能对这背后的原因提供权威的解释,我会很乐意接受答案并颁发第二轮赏金。

答案2

这个问题已经过时了,可能已经回答了大多数读者的问题。但我想补充两点:@eaten-by-a-grue 想知道为什么打开文件的限制LimitNOFILE需要比table_open_cache.

答案很简单,取决于您的存储引擎,一个表由多个文件组成。table.frm例如table.ibd,对于 MyISAM。

另外,我发现了这个非常好的指南,如何增加table_open_cachehttps://www.basezap.com/guide-to-raise-ulimit-open-files-and-mysql-open-files-limit/

奖金信息

与更改相比,/lib/systemd/system/mysql.service添加文件/etc/systemd/system/mysql.service.d/override.conf并将更新的配置放在那里可能更有意义,如所述堆栈溢出。否则,您的配置更改可能会被更新覆盖。

我希望这有帮助。

答案3

open_files_limittable_open_cache 和之间存在某种约束max_connections

对于每个连接,您需要一个文件描述符;对于缓存中的每个表,您需要 1 或 2 个文件描述符。

如果你不低于或高于某些界限,公式将是

table_cache_size = (requested_open_files - 10 - max_connections) / 2

所有这些参数都是在这 3 个函数中计算的。

功能adjust_table_cache_size

https://github.com/mysql/mysql-server/blob/7d10c82196c8e45554f27c00681474a9fb86d137/sql/mysqld.cc#L7717

功能adjust_max_connections

https://github.com/mysql/mysql-server/blob/7d10c82196c8e45554f27c00681474a9fb86d137/sql/mysqld.cc#L7704

功能adjust_open_files_limit

https://github.com/mysql/mysql-server/blob/7d10c82196c8e45554f27c00681474a9fb86d137/sql/mysqld.cc#L7663


在这种情况下,您需要将最大值增加到open_files更大的值。

systemctl edit mysql1)运行命令

[Service]
LimitNOFILE=20000

2)systemctl停止mysql

3)systemctl启动mysql

检查最大打开文件数的新值

  1. MYSQL 检查方法

在 Ubntu 20.4 上安装 mysql-server-8.0 时的默认值

mysql> show global variables like '%open_files_limit%'  ;
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| open_files_limit | 20000 |
+------------------+-------+
1 row in set (0.00 sec)

在本文档中,您将找到一个公式来计算设置该值的正确方法。

https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_open_files_limit

  1. 通用检查方法

    • 识别 mysql 守护进程的进程 ID
    • /proc/THE_PID/limits通过运行检查输出

    cat /proc/THE_PID/limits | grep -e '^Limit' -e open


检查完你的opencache

mysql> show variables like '%open_cache%'  ;
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| table_open_cache           | 8000  |
| table_open_cache_instances | 16    |
+----------------------------+-------+
2 rows in set (0.01 sec)

相关内容