由于 MariaDB 导致 I/O 较高

由于 MariaDB 导致 I/O 较高

我正在使用 nginx、php-fpm 和 mariadb。有时我的页面加载很慢。通过检查 munin,我发现我的平均 I/O 等待时间非常长,长达 8 秒。在 php-slowlog 中,mysql 函数被列为原因,例如 mysql_query()。我尝试调整 mariadb 服务器(例如增加缓存、将 tmp 目录从 hdd 移动到 ramdisk)。但我的 I/O 会随机变高。

在此处输入图片描述

例如图表开头的部分。我以为我解决了这个问题,但随后等待时间却无缘无故地增加了。当我重新启动 mariadb 时,它迅速下降(您可以在最后看到它是如何下降的,我在这里重新启动了 mariadb)。

我实际上并没有使用太多的 I/O,峰值大约是 8MB/s:

在此处输入图片描述

值得注意的是 Table_locks_immediate 与 Table_locks_waited 的比率正在增加。当我重新启动 mariadb 时,该比率为 2.5%。服务器现在已启动约 30 分钟,该比率已增加到 3.5%。我还注意到,当服务器挂起时,正在运行的线程数 (Threads_running) 很高(最多 30 个)。当该数字下降时,服务器停止挂起。

我的my.cnf:

[client]
port        = 3306
socket      = /var/run/mysqld/mysqld.sock

[mysqld_safe]
socket      = /var/run/mysqld/mysqld.sock
nice        = 0

[mysqld]
sync_binlog = 3

user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
#tmpdir     = /tmp
tmpdir      = /var/mysqltmp
lc_messages_dir = /usr/share/mysql
lc_messages = en_US
skip-external-locking
log-bin=/var/mysqltmp/mysql-bin.log
#log=/var/mysqltmp/mysql.log
log-error=/var/mysqltmp/mysql-error.log
log-slow-queries=/var/mysqltmp/mysql-slowquery.log

bind-address        = 127.0.0.1

max_tmp_tables      = 100
max_connections     = 150
connect_timeout     = 5
#wait_timeout            = 600
wait_timeout        = 800
max_allowed_packet  = 16M
thread_cache_size       = 128
#sort_buffer_size        = 4M
sort_buffer_size    = 8M
bulk_insert_buffer_size = 8M
max_heap_table_size     = 128M
tmp_table_size      = 128M
#tmp_table_size          = 64M

# * MyISAM
myisam_recover          = BACKUP
key_buffer_size         = 256M
#open-files-limit   = 2000
table_open_cache    = 1000
myisam_sort_buffer_size = 8M

#concurrent_insert  = 2
#read_buffer_size        = 2M
read_buffer_size    = 4M
#read_rnd_buffer_size    = 1M
read_rnd_buffer_size    = 2M

# * Query Cache Configuration
query_cache_limit       = 256M
query_cache_size        = 256M
# for more write intensive setups, set to DEMAND or OFF
query_cache_type        = ON
#table_cache                    = 400
table_open_cache        = 2000
join_buffer_size        = 4M

# * Logging and Replication
log_warnings        = 2
slow_query_log      = 1
slow_query_log_file = /var/log/mysql/mariadb-slow.log
long_query_time = 1
#log_slow_rate_limit    = 1000
log_slow_verbosity  = query_plan

log_bin         = /var/log/mysql/mariadb-bin
log_bin_index       = /var/log/mysql/mariadb-bin.index
# not fab for performance, but safer
#sync_binlog        = 1
expire_logs_days    = 10
max_binlog_size         = 128M

# * InnoDB
default_storage_engine  = InnoDB
#innodb_log_file_size   = 50M
#innodb_buffer_pool_size    = 256M
innodb_buffer_pool_size = 256M
innodb_log_buffer_size  = 32M
innodb_file_per_table   = 1
innodb_open_files   = 400
innodb_io_capacity  = 400
#innodb_flush_method    = O_DIRECT
innodb_flush_method     = O_DSYNC

[mysqldump]
quick
quote-names
max_allowed_packet  = 16M

[isamchk]
#key_buffer     = 16M
key_buffer             = 32M

!includedir /etc/mysql/conf.d/

答案1

如果你的大多数桌子都是数据库引擎InnoDBinnodb_buffer_pool_size,至少将数据库总数增加到这个数字,或者2GB改为。如果此服务器仅运行数据库服务,则将这些值设置为总内存的 ~60% 或 70%,您的数据库将完全适合内存。

如果你的大多数桌子都是数据库管理系统key_buffer_size,以同样的方式增加。

对于 MyISAM,设置concurrent_insert2

query_cache_size以上64MB就是内存的浪费。

定期运行mysqlcheck -o -A以改进内部 mysql 查询计划器的索引统计信息。

避免查询那些做的人full_scan

如果您有单磁盘存储或简单 RAID,则降低innodb_io_capacity100或。120

使用XFS以提供优势同一文件中的并发写入

使用选项挂载你的 fs noatime

避免交换。

禁用不必要的日志。

相关内容