MySQL DB 导致运行 Zabbix 服务器时出现高 IO

MySQL DB 导致运行 Zabbix 服务器时出现高 IO

我的 VPS 主机抱怨说我使用了主机上迄今为止最高的 IO。我正在运行带有 MySQL innodb 数据库的 Zabbix 监控服务器。VPS 有 512MB 内存。我不明白为什么 mysqltuner.pl 脚本建议 innodb_buffer_pool_size > 1G,而我只有 512MB。任何关于我应该从哪里开始的建议都将不胜感激。我联系了一位 Zabbix 专家,他告诉我“tmp 表不应该在磁盘上结束,并且 innodb 缓冲池在大多数情况下应该尽可能大”,但我不确定如何在数字方面实现这一点。

这是 mysqltuner.pl 脚本的输出。

-------- 一般统计数据 --------------------------------------------------
[--] 跳过 MySQLTuner 脚本的版本检查
[确定] 当前正在运行支持的 MySQL 版本 5.0.77
[OK] 在 64 位架构上运行

-------- 存储引擎统计 ----------------------------------------------------------
[--] 状态:-Archive +BDB-Federated +InnoDB-ISAM-NDBCluster
[--] InnoDB 表中的数据:1G(表:144)
[!!] BDB 已启用但未被使用
[确定] 碎片表总数:0

-  -  -  -  性能指标  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - -
[--] 上传时间:129 天 6 小时 54 分 3 秒(342M q [30.677 qps],1M conn,TX:112B,RX:46B)
[--] 读取/写入:57%/43%
[--] 总缓冲区:全局 34.0M + 每个线程 2.7M(最多 100 个线程)
[确定] 可能的最大内存使用量:309.0M(已安装 RAM 的 62%)
[确定] 慢速查询:0% (134/342M)
[OK] 可用连接的最高使用率:33% (33/100)
[OK] 键缓冲区大小/总 MyISAM 索引:8.0M/67.0K
[OK] 密钥缓冲区命中率:96.3% (31M 缓存/1M 读取)
[!!] 查询缓存已禁用
[OK] 需要临时表的排序:0%(0 个临时排序/5M 个排序)
[确定] 磁盘上创建的临时表:13%(磁盘上 1M/总共 10M)
[!!] 线程缓存已禁用
[!!] 表缓存命中率:0%(64 打开/46K 打开)
[确定] 已使用的打开文件限制:0% (0/1K)
[OK] 立即获取表锁:100%(406M 立即/406M 锁)
[!!] InnoDB数据大小/缓冲池:1.8G/8.0M


-------- 建议 -----------------------------------------------------------------
一般建议:
    将 skip-bdb 添加到 MySQL 配置以禁用 BDB
    启用慢查询日志来排除错误查询故障
    将 thread_cache_size 设置为 4 作为起始值
    逐渐增加 table_cache 以避免文件描述符限制
需要调整的变量:
    查询缓存大小 (>= 8M)
    thread_cache_size (从 4 开始)
    表缓存 (> 64)
    innodb_buffer_pool_size(>= 1G)

这是我当前的 my.cnf

[mysqld]
数据目录=/var/lib/mysql
套接字=/var/lib/mysql/mysql.sock
用户=mysql
# 默认使用旧密码格式以兼容 mysql 3.x
# 客户端(使用 mysqlclient10 兼容包的客户端)。
旧密码=1

# 建议禁用符号链接以防止各种安全风险;
# 为此,请取消注释此行:
#符号链接=0

[mysqld_safe]
日志错误=/var/log/mysqld.log
pid 文件=/var/run/mysqld/mysqld.pid

free -m 的输出

             已使用的、可用的、缓存的共享缓冲区总数
内存:492 486 6 0 2 44
-/+ 缓冲区/缓存:439 53
交换:255 112 143

iostat 的输出

平均 CPU:%用户%nice%系统%iowait%steal%idle
           0.24 0.03 0.12 0.57 0.01 99.03

设备:tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
24.47 36.26 748.69 405085498 8365183264
xvdb 1.16 9.50 6.87 106190600 76708192
xvdc 0.00 0.00 0.00 5961 1416

答案1

innodb_buffer_pool_size > 1G,因为您的数据集大小为 1.8GB。

要减少读取次数,您需要增加innodb_buffer_pool_size。要减少写入次数,您需要编辑 zabbix 模板(禁用一些不必要的项目,如空闲 inode,增加检查间隔)。

您的读/写比率为 57% / 43%,因此启用查询缓存不会有帮助(它可能会使情况变得更糟,因为写入表会使缓存无效)。

考虑增加 tmp_table_size 和 max_heap_table_size 以避免在磁盘上创建临时表(占临时表的 13%)。临时表以 MB 为单位?是计数吗?如果是计数器,则太高了。

将连接数减少到 50(最高数量为 33)。

innodb_support_xa = false
innodb_buffer_pool_size = 256M # It depends how many memory is available to MySQL, more is better.
innodb_flush_log_at_trx_commit = 0 # disable writing to logs on every commit and disable fsync on each write
innodb_max_dirty_pages_pct = 90 # avoid flushing dirty pages to disk
innodb_flush_method = O_DIRECT # direct access to disk without OS cache
thread_cache_size = 4
query_cache_size = 0
table_cache = 80? # a little more than number_of_tables_in_zabbix_database

有用关联关于InnoDB优化。

答案2

InnoDB 缓冲池确实太小了(至少尝试 64M 或 128M)。考虑启用线程缓存、查询缓存并获得更大的 table_cache,这可能会有很大帮助。

相关内容