我的 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,这可能会有很大帮助。