mysql 原理 ~ LRU 算法与buffer_pool

本文详细探讨了MySQL中LRU算法的工作原理及其对页缓存的影响,包括普通LRU算法与mysql_lru改进算法的区别,以及如何通过调整相关参数优化内存使用效率,提高事务命中率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 简介:针对查询和事务的页在内存中的处理,是如何进行的

二 LRU算法

    普通 : 实现的是末尾淘汰法,当整个链表已满时,淘汰尾部,将新的数据页加入头部

    mysql_lru改进 : 分为两部分 1分为 yang和old,并不从LRU列表头部进行插入,而是从中间部位.对过期页实行末尾淘汰没有问题,

                                               2 针对新插入的数据页需要做二次判断 

                                                                     1 如果数据页保持1S以上时间,则推进到yang头部

                                                                     2 如果数据页不能保持1S,则依然保留到old区,等待被淘汰

    改进优点:防止一次性的大查询读取的数据页污染整个LRU列表,影响整体的事务命中率

三 相关参数

  1 innodb_old_blocks_time 控制着判断数据页保持时间,是加入yang还是保留在old区,默认1s,防止单次大量的全表扫描污染整个LRU

  2 innodb_max_dirty_pages_pct 控制着页插入的位置,默认为50%, yang和old区的百分比

四 计算公式
  innodb buffer pool命中率

        1  Innodb_buffer_pool_read_requests表示read请求的次数
        2  Innodb_buffer_pool_reads表示从物理磁盘中读取数据的请求次数
     innodb buffer的read命中率就可以这样得到:(Innodb_buffer_pool_read_requests - Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100%。一般来讲这个命中率不会低于99%,如果低于这个值的话就要考虑加大innodb buffer pool。

     通过 innodb_buffer_pool_stats 可以直接查看命中率,并不需要计算

五 相关补充       

   Free List 数据库刚启动的时候,LRU 列表为空,此时需要用到的时候直接将Free列表中的页删除,在LRU列表中增加相应的页,维持页数守恒。

   Flush List 当LRU列表中的页被修改后,称该页为脏页(dirty page),即缓冲池中的页和磁盘上的页数据产生了不一致。这时候数据库会通过checkpoint机制将脏页刷新回磁盘,而Flush 列表中的页即为脏页列表。注意脏页也存在于LRU列表中。

   INNODB_BUFFER_POOL 构成  1 数据页 2 索引页 3 字典 4 锁信息 5 AHI 6 插入缓冲

六 相关监控

    命令  show engine innodb status

    相关参数

     1 BUFFE POOL SIZE    整个innodb_buffer_pool 页的总数大小  计算总量X16K即可

     2 Free  buffers              当前Free列表中页的数量

     3 Datebase pages         LRU列表中数据页的个数

    这里注意 通常 Datebase pages+Free buffers 并不等于 整个buffer_pool页的数量。因为还有其他需要页 (数据字典,锁)等,这部分是不归LRU列表进行维护的

    4 Modified  db pages   脏页的大小

 

           

 

转载于:https://www.cnblogs.com/danhuangpai/p/10329488.html

<think>我们正在分析MySQL配置参数,需要涵盖原理、建议值、修改影响和性能调优。根据引用,我们可以参考一些实战配置,特别是针对特定硬件(如64核CPU,128GB内存)的配置,并且内存参数可以扩展到256GB~512GB(引用[1])。同时,引用[2]提到可以参考专业DBA的配置,引用[3]至[5]则提供了一些SQL优化的背景知识。 由于MySQL参数众多,我们将重点选取一些关键参数进行详细分析。这些参数通常对性能影响较大,包括内存相关参数、连接相关参数、InnoDB相关参数等。 ### 一、内存相关参数 内存参数是MySQL性能调优的核心,合理配置可以大幅减少磁盘I/O。 1. **innodb_buffer_pool_size** - **原理**:InnoDB存储引擎的缓冲池,用于缓存索引和数据页。通过减少磁盘访问提升性能。 - **建议值**: - 对于专用数据库服务器,通常设置为物理内存的60%~80%[^1]。 - 128GB内存服务器:建议80~100GB - 256GB~512GB内存:可设置为200~400GB - **修改影响**: - 过小:导致频繁磁盘读写,性能下降。 - 过大:可能引发OOM或系统不稳定。 - **调优建议**:使用`SHOW ENGINE INNODB STATUS`观察缓冲池命中率(一般应>99%): $$ \text{命中率} = 1 - \frac{\text{磁盘读取}}{\text{缓冲池读取}} $$ 2. **key_buffer_size** - **原理**:MyISAM存储引擎的索引缓存(若仅使用InnoDB可调低)[^1]。 - **建议值**: - 纯InnoDB环境:10~50MB - 混合环境:根据MyISAM表大小调整 - **修改影响**: - 过小:MyISAM索引查询效率降低。 - 过大:浪费内存资源。 3. **query_cache_size** - **原理**:缓存SELECT查询结果(MySQL 8.0已移除)[^1]。 - **建议值**: - MySQL 5.7及以下:建议关闭(设置为0) - **修改影响**: - 高并发写场景下,缓存失效机制会导致锁竞争,降低性能。 ### 二、连接线程参数 控制并发连接和线程资源分配。 1. **max_connections** - **原理**:允许的最大客户端连接数。 - **建议值**: - 根据业务需求设定,通常500~3000[^2]。 - 需监控`Threads_connected`和`Threads_running`(`SHOW STATUS`) - **修改影响**: - 过小:导致连接被拒绝(`Too many connections`错误)。 - 过大:内存和线程切换开销增加(每个连接约需4~12MB内存)。 2. **thread_cache_size** - **原理**:缓存空闲线程以供复用,减少线程创建销毁开销。 - **建议值**: - 根据`Threads_created`状态调整,公式: $$ \text{建议值} = \frac{\text{高峰Threads_created}}{\text{运行时间}} \times 1.5 $$ - 通常设置50~200。 - **修改影响**: - 过小:线程频繁创建销毁,增加CPU负载。 - 过大:浪费内存。 ### 三、InnoDB引擎参数 优化事务处理和写入性能。 1. **innodb_log_file_size** 和 **innodb_log_files_in_group** - **原理**:重做日志(Redo Log)大小和文件数量,影响事务提交速度和崩溃恢复时间[^5]。 - **建议值**: - 单个日志文件:1~4GB(如设置`innodb_log_file_size=2G`,`innodb_log_files_in_group=2`) - 总日志大小建议能容纳1~2小时的事务量。 - **修改影响**: - 过小:日志切换频繁,增加I/O压力;大事务可能因日志满而失败。 - 过大:崩溃恢复时间延长。 2. **innodb_flush_log_at_trx_commit** - **原理**:控制Redo Log刷盘策略,平衡安全性性能。 - **建议值**: - 安全性优先(如金融系统):设置为1(每次事务提交刷盘)。 - 性能优先:设置为2(每秒刷盘,操作系统崩溃可能丢失1秒数据)。 - 折中方案:设置为0(每秒刷盘,MySQL进程崩溃可能丢失1秒数据)。 - **修改影响**: - 设置为1时I/O压力最大,但数据最安全。 ### 四、查询优化参数 提升SQL执行效率。 1. **optimizer_switch** - **原理**:控制查询优化器的行为(如是否启用MRR、ICP等特性)[^5]。 - **建议值**: - 启用关键优化: ```ini optimizer_switch='mrr=on,mrr_cost_based=off,batched_key_access=on,index_condition_pushdown=on' ``` - **修改影响**: - 错误配置可能导致执行计划退化(需通过`EXPLAIN`验证)。 2. **max_allowed_packet** - **原理**:限制单个网络包大小,影响大字段操作(如BLOB)。 - **建议值**: - 根据业务需求设置,通常64M~256M。 - **修改影响**: - 过小:导致大查询或大字段插入失败。 ### 五、性能调优流程 1. **基准监控**: - 使用`SHOW GLOBAL STATUS`和`SHOW ENGINE INNODB STATUS`获取初始指标。 2. **参数调整**: - 优先调整内存参数(如`innodb_buffer_pool_size`)。 3. **压力测试**: - 使用`sysbench`或`mysqlslap`模拟业务负载。 4. **问题诊断**: - 慢查询日志(`slow_query_log=ON`)分析。 - 执行计划分析(`EXPLAIN FORMAT=JSON`)。 > **关键公式**:缓冲池命中率计算 > $$ \text{Hit Rate} = \left(1 - \frac{\text{Innodb_buffer_pool_reads}}{\text{Innodb_buffer_pool_read_requests}}\right) \times 100\% $$ > 目标值:>99%[^1] ### 六、配置修改示例 ```ini # 内存配置(128GB服务器) innodb_buffer_pool_size = 100G key_buffer_size = 20M query_cache_size = 0 # 连接配置 max_connections = 2000 thread_cache_size = 100 # InnoDB日志 innodb_log_file_size = 2G innodb_log_files_in_group = 2 innodb_flush_log_at_trx_commit = 1 # 查询优化 optimizer_switch = 'mrr=on,mrr_cost_based=off' max_allowed_packet = 64M ``` ### 七、参数修改风险控制 - **灰度调整**:分阶段修改参数,避免一次性大规模变更。 - **监控指标**: - `QPS`(每秒查询数)和`TPS`(每秒事务数) - 线程状态:`Threads_connected`、`Threads_running` - 缓冲池命中率 §§相关问题§§ 1. 如何监控`innodb_buffer_pool_size`是否足够? 2. 为什么MySQL 8.0移除了查询缓存(Query Cache)? 3. 如何根据业务负载调整InnoDB日志文件大小? 4. 在高并发场景下,`max_connections`设置过高会引发什么问题? [^1]: MySQL参数配置实战参考 [^2]: 专业DBA配置经验 [^5]: InnoDB引擎优化措施</think>### MySQL 配置参数深度分析:原理、建议值性能调优 以下针对关键参数进行原理剖析,结合 **64核CPU/128GB内存** 的典型服务器配置给出建议值(可扩展至256~512GB内存场景),并说明修改影响。核心参数分类如下: --- #### 一、内存管理参数(核心优化区) 1. **`innodb_buffer_pool_size`** - **原理**: 缓存InnoDB数据页和索引的全局内存池,减少磁盘I/O。通过 **LRU算法** 管理页面置换,其大小直接影响 **缓冲池命中率**(计算公式): $$ \text{命中率} = 1 - \frac{\text{Innodb\_buffer\_pool\_reads}}{\text{Innodb\_buffer\_pool\_read\_requests}} $$ - **建议值**: - 128GB内存服务器:80~100GB(占物理内存60%~75%) - 256~512GB内存:200~400GB(避免超过80%以防OOM)[^1] - **修改影响**: - ✅ 提升:减少磁盘访问,加速查询(TPC-C测试中提升可达300%) - ❌ 过度:可能引发Swap或OOM崩溃 2. **`innodb_log_buffer_size`** - **原理**: 缓存未写入Redo Log的事务数据,通过 **批量刷盘机制** 减少I/O次数(结合`innodb_flush_log_at_trx_commit`控制)。 - **建议值**: - OLTP场景:256~512MB - 大事务系统:1~2GB - **修改影响**: - ✅ 提升:降低事务提交延迟(尤其批量插入) - ❌ 过度:事务崩溃时可能丢失更多数据 --- #### 二、连接线程参数(高并发优化) 1. **`max_connections`** - **原理**: 限制同时连接的客户端数量,每个连接占用独立内存(约4~12MB)。 - **建议值**: - 通用配置:`1000 + (max_connections * 0.1)` - 128GB内存:建议2000~3000(需监控`Threads_connected`)[^2] - **修改影响**: - ✅ 提升:支持更高并发 - ❌ 过度:内存耗尽导致服务雪崩 2. **`thread_cache_size`** - **原理**: 缓存空闲线程,避免频繁创建/销毁开销(通过`Threads_created`监控)。 - **建议值**: $$ \text{建议值} = \frac{\text{峰值QPS}}{\text{平均查询时间}} \times 1.5 $$ 通常设置50~200 - **修改影响**: - ✅ 提升:降低CPU线程调度开销 --- #### 三、InnoDB引擎关键参数 1. **`innodb_io_capacity` & `innodb_io_capacity_max`** - **原理**: 控制InnoDB后台线程(如Purge、Flush)的I/O吞吐量上限,需匹配存储设备性能。 - **建议值**: | 存储类型 | `innodb_io_capacity` | `innodb_io_capacity_max` | |----------------|----------------------|--------------------------| | SATA SSD | 2000~5000 | 4000~10000 | | NVMe SSD | 10000~20000 | 20000~40000 | - **修改影响**: - ✅ 合理值:避免Checkpoint堆积,稳定写入性能 - ❌ 过低:脏页刷新不及时导致写入尖峰 2. **`innodb_flush_method`** - **原理**: 控制Redo Log和数据文件的刷盘方式(文件系统交互)。 - **建议值**: ```ini # Linux最佳实践 innodb_flush_method = O_DIRECT_NO_FSYNC ``` - **修改影响**: - ✅ `O_DIRECT`:绕过OS缓存,减少双缓冲开销 - ❌ `fsync`:安全但性能下降30%~50% --- #### 四、查询优化参数 1. **`optimizer_switch`** - **原理**: 控制查询优化器行为(如MRR多范围读、ICP索引条件下推)[^5]。 - **建议值**: ```ini optimizer_switch = 'mrr=on,mrr_cost_based=off,index_condition_pushdown=on' ``` - **修改影响**: - ✅ MRR:将随机I/O转为顺序I/O,提升范围查询性能 - ❌ 错误配置:可能导致索引失效(如字符集不一致问题)[^4] 2. **`join_buffer_size`** - **原理**: 为无法使用索引的JOIN操作分配缓存(如全表扫描JOIN)。 - **建议值**: - 默认值过低(256KB),建议:16~64MB - 注意:每个JOIN分配独立buffer,不宜过大 --- #### 五、性能调优操作清单 | 优化方向 | 操作步骤 | 验证命令 | |------------------|--------------------------------------------------------------------------|-----------------------------------| | 内存瓶颈 | 1. 调整`innodb_buffer_pool_size`<br>2. 监控命中率(目标>99%) | `SHOW ENGINE INNODB STATUS` | | 连接风暴 | 1. 设置`max_connections`<br>2. 配置连接池(如ProxySQL) | `SHOW STATUS LIKE 'Threads_%'` | | I/O性能优化 | 1. 匹配`innodb_io_capacity`磁盘性能<br>2. 启用O_DIRECT | `iostat -dx 1` | | 查询加速 | 1. 启用MRR/ICP<br>2. 检查字符集一致性 | `EXPLAIN FORMAT=JSON SELECT ...` | > **关键公式**:缓冲池大小估算 > $$ \text{Buffer Pool Size} = \text{Total Data Size} \times 1.2 + \text{Index Size} $$ > 若数据量100GB,索引30GB,则建议设置 ≈ 156GB --- #### 六、参数修改风险控制 1. **灰度变更**: ```sql SET GLOBAL innodb_buffer_pool_size=107374182400; -- 动态调整(仅支持部分参数) ``` 2. **监控指标**: - 内存压力:`SHOW STATUS LIKE 'Innodb_buffer_pool_wait%'` - I/O负载:`SHOW STATUS LIKE 'Innodb_%io%'` 3. **回滚方案**: - 备份配置文件:`cp /etc/my.cnf /etc/my.cnf.bak_$(date +%F)`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值