Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > Mysql中的常用调优参数

Mysql中的常用调优参数用法及解读

作者:诺浅

文章介绍了MySQL数据库的一些关键配置参数,包括InnoDB缓冲池、redolog缓冲区、日志缓冲区等,并解释了这些参数在数据库性能和事务一致性中的作用,文章通过比喻和实际建议帮助读者理解这些配置参数的合理设置

写在开头

以下的每个参数详细拉开来讲都可以开一篇文章,篇幅所限,我这里会给出一些基本的描述以及建议的参数,详细了解的请自行百度

知其然才能知其所以然

如果只是把参数根据当前服务器的配置列出来,自然是最快完成任务的方式,但这种方式我们始终不知道是为什么要这么配置,故以下会先科普一些底层的知识,比如InnoDB 缓冲池,redo log 缓冲区, log buffer,redo log 文件这些东西到底是什么玩意,如果要完全理解可能需要系统的学习mysql底层的知识,因为背后牵扯到 InnoDB 存储引擎的内部机制:数据是怎么存储、怎么读取、怎么保证事务一致性的。

本文会尽可能用一些通俗的比喻来让你理解

内存池相关

innodb_buffer_pool_size
innodb_buffer_pool_instances
innodb_log_buffer_size

innodb_buffer_pool_size

这是 InnoDB 缓冲池大小,作用就是把数据页、索引页、插入缓存、锁信息等都放到内存里,减少磁盘随机 I/O。

**建议:**分配为物理内存的 60%~75% 左右。

如果 buffer pool 太小,查询就频繁读磁盘,性能会雪崩。

  1. 就像一座“大冰箱”,里面放着你常用的菜(数据页、索引页)。
  2. 查询数据时,如果“冰箱”里有(命中缓存),就直接从内存里取,快得飞起。
  3. 如果没有,就得下楼去超市(磁盘),再顺便搬进冰箱,下次就快了。

innodb_buffer_pool_size = 冰箱有多大。

innodb_buffer_pool_instances

这个参数是把大 buffer pool 分片,避免多线程并发访问时锁竞争。

MySQL 8 默认就会根据 innodb_buffer_pool_size 自动调整,一般每个 instance 至少要有 1G~2G。

**建议:**比如innodb_buffer_pool_size=24G,innodb_buffer_pool_instances就要为16左右,这样 24G/16 = 1.5G 每个实例,正好在推荐范围里。

如果实例数太少,大锁竞争严重;太多则浪费管理开销。

innodb_buffer_pool_instances = 冰箱有几个独立的格子,防止大家挤着抢同一个门。

innodb_log_buffer_size

这是 redo log 缓冲区,事务在提交前会先写到 log buffer,然后再刷到 redo log 文件。

**建议:**默认一般是 16M 或 128M。如果太小事务中间就被迫刷盘。如果太大但是业务系统事务都很小(简单的单行 INSERT/UPDATE),太大没意义意义,可能浪费内存。

要讲清楚这个配置,就要科普另一个点

写数据不能直接怼磁盘

Redo Log(重做日志)

Redo Log Buffer(日志缓冲区)

所以:

UPDATE account SET balance = balance - 100 WHERE id = 1;
  1. InnoDB 在 Buffer Pool 找到 account 表里 id=1 的数据页(如果不在,就从磁盘读进来)。
  2. 在内存里修改数据页,balance 减 100。
  3. 把“修改过的数据”记录到 Redo Log Buffer(白板)。
  4. 事务提交时,把 redo log buffer 刷到磁盘上的 Redo Log 文件。
  5. 数据页什么时候刷回磁盘?不一定立刻,可能延迟(后台刷脏页)。

这样做的好处:

  1. 日志先落盘,保证崩溃后还能恢复。
  2. 数据页延迟落盘,提高性能。

所以:innodb_log_buffer_size:白板大小,决定写日志时事务大不大会卡顿。

写日志redo log & 刷盘相关

innodb_redo_log_capacity
innodb_flush_log_at_trx_commit 
innodb_flush_log_at_timeout
sync_binlog

这几个参数都是 “日志系统的节奏控制器”,决定了 MySQL 写日志的安全性 vs 性能 取舍。咱们还是延续“日记本”的类比来解释:

innodb_redo_log_capacity

这相当于 redo log 文件的 总大小(循环写)。Redo log 记录了事务的修改操作,保证崩溃恢复。

它是循环写的,就像一本日记本,写满后会从头覆盖。

建议: 几 GB 到几十 GB 都可以,看磁盘和 workload。我一般配 4G,算比较中等偏大的设置了,OLTP(高并发事务)场景挺合适。普通web系统配置为1-2G就够

innodb_flush_log_at_trx_commit

控制了事务提交时 redo log(重做日志)的刷盘策略,有3个值,

业务类型推荐值理由
金融、支付、订单1数据不丢是底线
普通 Web 应用2性能与安全的折中
日志、监控、分析0可接受数据丢失

这个一秒可以通过参数:innodb_flush_log_at_timeout 来配置,默认值是1

sync_binlog

这是 binlog(归档日志)的同步策略。Binlog 是逻辑日志,用于复制和恢复。

后台 I/O、清理线程和并发限制

innodb_write_io_threads = 16
innodb_read_io_threads = 16
innodb_purge_threads = 4
innodb_thread_concurrency = 0

innodb_write_io_threads

建议: 4-16。在现代服务器 + SSD 场景,比如16 个写线程是比较激进的配置,适合高写入压力的系统,如果是HHD硬盘,设置为4足够,设置多了会增加线程调度开销。

innodb_read_io_threads

建议: 一般 4-8 足够。

innodb_purge_threads

建议: 一般设置为2就够了,高并发场景可以考虑设置为4

临时表全内存

temptable_max_ram
tmp_table_size
max_heap_table_size
internal_tmp_mem_storage_engine

这几个参数都跟 临时表 有关,而临时表就是 MySQL 在执行 SQL 时的“临时工地”,用来放中间结果。

比如:GROUP BY、ORDER BY、DISTINCT、UNION、JOIN 等操作,如果不能直接用索引,就可能生成临时表。

temptable_max_ram

tmp_table_size / max_heap_table_size

内存临时表的大小上限。复杂查询(GROUP BY、JOIN、ORDER BY)结果可能要放临时表。超过大小会落到磁盘 → 性能急剧下降。

这两个值建议设置为一样的,对齐限制,避免临时表因为两个参数不一致导致意外落盘或报错。

最佳配置

普通的web类后台管理系统

这类系统的普遍情况是:很少有高并发,但存在很多复杂,多张表关联查询

# -------------------------
# InnoDB 缓冲池(核心参数)
# -------------------------
innodb_buffer_pool_size = 8G           # 给 InnoDB 分配 50% 内存,留给系统和其他 MySQL 组件
innodb_log_buffer_size = 128M          # 日志缓冲大小,适合复杂查询场景
innodb_max_dirty_pages_pct=50	# 控制 脏页(dirty page)在缓冲池中允许的最大比例。推荐 50~60,平衡刷盘压力和性能。

# -------------------------
# Redo Log & 刷盘策略(安全优先)
# -------------------------
innodb_redo_log_capacity = 1G          # 合理大小,防止频繁刷新
innodb_flush_log_at_trx_commit = 2     # web系统配置为2足够
innodb_flush_log_at_timeout = 1        # 最多延迟 1 秒刷盘
# 默认200,如果SSD,调整为5000~20000
innodb_io_capacity=200

# -------------------------
# 临时表优化(多表关联查询关键)
# -------------------------
temptable_max_ram = 512M
tmp_table_size = 512M
max_heap_table_size = 512M
internal_tmp_mem_storage_engine = TempTable

# -------------------------
# 连接和缓存(低并发适度)
# -------------------------
max_connections = 200
thread_cache_size = 50
table_open_cache = 2000
table_definition_cache = 1000
open_files_limit = 65535

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文