【问题标题】:MariaDB Excessive memory UsageMariaDB 内存使用过多
【发布时间】:2016-11-01 12:15:36
【问题描述】:

我有一个基于四核处理器的 16 GiG RAM 和 4 TB HDD 用于 DB 和 4 TB 用于操作系统。 分配的缓冲池为 6 GB。也尝试了 70% 的内存,但结果是一样的。 内存很快就被填满了。当我重新启动服务时,它会被释放,但在不到 20 分钟的时间内,10-15% 会被填满。

我的 my.conf 配置:

[client]
socket=/db/mysql/mysql.sock

[mysqld]
datadir=/db/mysql
socket=/db/mysql/mysql.sock

innodb_max_dirty_pages_pct = 0
innodb_file_per_table = 1
innodb_buffer_pool_size = 6G
innodb_buffer_pool_instances = 6
thread_cache_size = 4
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
query_cache_type = 0
innodb_fast_shutdown=0

[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid

也附上我的内存使用图。

重要参考:

显示变量 - pastebin.com/wzAhva55 显示全局状态 - pastebin.com/8G1N3g78

【问题讨论】:

  • 更多信息会很有用,例如SHOW ENGINE InnoDB STATUS 中的缓冲池/内存部分。慢查询日志是否包含一些信息,例如使用排序缓冲区的慢查询? SHOW PROCESSLIST 中是否有任何长时间运行的进程?
  • InnoDB Satus - pastebin.com/Hxi6S5f8 Show ProcessList - pastebin.com/ftTiDSrC 输出太长,所以不得不使用 pastebin。
  • 图上Y轴的含义和单位是什么?
  • 其他应用是否在同一台服务器上运行?
  • 请在几个小时后提供(通过 pastebin)SHOW VARIABLES;SHOW GLOBAL STATUS;

标签: mysql mariadb


【解决方案1】:

观察:

Version: **5.5.50-MariaDB**
**16 GB** of RAM
Uptime = **3d 05:16:26**
You are **not** running on Windows.
Running **64-bit** version
You appear to be running entirely (or mostly) **InnoDB**.
20 issues flagged, out of 145 computed Variables/Status/Expressions checked

更重要的问题

  • 既然你有一个“小”的 6G 用于 buffer_pool,那么为什么 RAM 会这么满令人费解。
  • 不涉及复制,对吗?
  • 为什么innodb_max_dirty_pages_pct 设置为零?通常为 75 (%)。我希望您遭受大量 I/O。
  • iblog 的旋转速度非常快。这是因为高活跃度,以及极小的log_file_size = 5M。将其更改为 1G;但请注意:更改它很复杂,需要重新启动。
  • 每秒创建 6K tmp 表。 3K 表扫描/秒。这意味着某些索引或查询调优可能有用。
  • 您的连接周转率似乎非常低,因此下面关于线程和连接的 cmets 可能并不重要。
  • Aborted_connects / Connections = 98.8%。 (最多 20% 是“好的”。)

你有内存盘吗?多大?我通常反对这种做法。但是,如果您有一个 RAM 磁盘,那就可以解释高内存使用率、高查询率以及看似低 I/O 的问题。

细节和其他观察结果

( innodb_buffer_pool_size / _ram ) = 6,442,450,944 / 16384M = 37.5% -- 用于 InnoDB buffer_pool 的 RAM 百分比

( open_files_limit ) = 1,024 -- ulimit -n -- 要允许更多文件,请更改 ulimit 或 /etc/security/limits.conf 或 sysctl.conf (kern.maxfiles & kern.maxfilesperproc) 或其他内容(取决于操作系统)另一方面,Open_table* 值非常低,所以您使用的表似乎很少。

( innodb_max_dirty_pages_pct ) = 0 -- 当 buffer_pool 开始刷新到磁盘时 -- 你在做实验吗?

( Innodb_log_writes ) = 26,966,874 / 278186 = 97 /sec

( Innodb_os_log_written / (Uptime / 3600) / innodb_log_files_in_group / innodb_log_file_size ) = 253,091,451,392 / (278186 / 3600) / 2 / 5M = 312 -- 比率

( Uptime / 60 * innodb_log_file_size / Innodb_os_log_written ) = 278,186 / 60 * 5M / 253091451392 = 0.096 -- InnoDB 日志轮换之间的分钟数从 5.6.8 开始,可以动态更改;请务必同时更改 my.cnf。 --(轮换间隔60分钟的建议有些武断。)调整innodb_log_file_size。

( Questions ) = 889,470,233 / 278186 = 3197 /sec -- 查询(SP 外) -- "qps" -- >2000 可能给服务器带来压力

( Queries ) = 85,684,886,985 / 278186 = 308012 /sec -- 查询(包括 SP 内部) -- >3000 可能给服务器带来压力

( (Queries-Questions)/Queries ) = (85684886985-889470233)/85684886985 = 99.0% -- 存储例程内的查询部分。 --(如果高也不错;但它会影响其他一些结论的有效性。)

( Created_tmp_tables ) = 1,674,262,702 / 278186 = 6018 /sec -- 创建“临时”表作为复杂 SELECT 的一部分的频率。

( Select_scan ) = 837,131,930 / 278186 = 3009 /sec -- 全表扫描 -- 添加索引/优化查询(除非它们是小表)

( Select_scan / Com_select ) = 837,131,930 / 2511393099 = 33.3% -- % 的选择执行全表扫描。 (可能会被存储的例程愚弄。) -- 添加索引/优化查询

( Com_insert + Com_delete + Com_delete_multi + Com_replace + Com_update + Com_update_multi ) = (837130735 + 0 + 0 + 0 + 0 + 0) / 278186 = 3009 /sec -- 写入/秒 -- 50 次写入/秒 + 日志刷新可能会最大化普通驱动器的 I/O 写入容量

( expire_logs_days ) = 0 -- 多久自动清除 binlog(经过这么多天) -- 太大(或为零)= 消耗磁盘空间;太小 = 需要快速响应网络/机器崩溃。 (如果 log_bin = OFF 则不相关)

( long_query_time ) = 10.000000 = 10 -- 定义“慢”查询的截止时间(秒)。 -- 建议2

( Aborted_connects / Connections ) = 11,455 / 11594 = 98.8% -- 可能是黑客试图闯入?

( thread_cache_size ) = 4 -- 要保留多少额外进程(使用线程池时不相关)(自 5.6.8 起自动调整;基于 max_connections)

更多

Select_scan / Com_select 如此接近 1/3,以至于您怀疑您在执行的查询中有很强的模式。也许有可以避免的重复?同样,Com_set_option/Queries 非常接近 1/6。

Handler_read* 的值与查询数量相比非常小。

嗯...Select_scan/sec、Com_call_procedure/sec 和 Com_insert/sec 都非常相似 (3009/sec)。只有一个程序,而且调用很多?

Innodb_rows_inserted = 622 /秒。

抱歉,此分析主要针对性能,而不是内存。我确实想出了一个记忆想法。我猜ramdisk是4-5G?

【讨论】:

  • 当我将缓冲池从 6G 增加到 10G 时,内存使用率上升到 98%。于是又恢复到6G。将 innodb_max_dirty_pages_pct 设为默认值。无法更改 my.cnf 中的 innodb_log_file_size = 1G,因为它给出了错误。
  • 你有内存盘吗?
  • 来自 df -h 的 tmpfs 为 7.7 GB。附上截图和主要问题。但我还没有创建任何这些。默认情况下它就在那里。 (sdc 是我的数据库驱动器)
  • 假设 /dev/shm 是一个 ramdisk,那么 7.7GB 不能用作缓存的 RAM,例如 buffer_pool。因此,6G 大约是 (16 - 7.7)GB 的限制。换句话说:您使用的是 (7.7 + 6 + miscellany) GB,因此是大图。为什么图表下降到接近零?也许 tmpfs 被卸载了?
  • 当我手动重新启动 mariadb 服务时,图表下降到零。如何绕过 RAM 盘的事情?操作系统真的有必要吗?
猜你喜欢
  • 2019-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-12
  • 2018-04-01
  • 2021-12-21
相关资源
最近更新 更多