我正在使用 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_insert
为2
。
query_cache_size
以上64MB
就是内存的浪费。
定期运行mysqlcheck -o -A
以改进内部 mysql 查询计划器的索引统计信息。
避免查询那些做的人full_scan
。
如果您有单磁盘存储或简单 RAID,则降低innodb_io_capacity
至100
或。120
使用XFS
以提供优势同一文件中的并发写入。
使用选项挂载你的 fs noatime
。
避免交换。
禁用不必要的日志。