当前位置: 首页 > 编程日记 > 正文

数据库分享一: MySQL的Innodb缓存相关优化

无论是对于哪一种数据库来说,缓存技术都是提高数据库性能的关键技术,物理磁盘的访问速度永 远都会与内存的访问速度永远都不是一个数量级的。通过缓存技术无论是在读还是写方面都可以大大提 高数据库整体性能。

Innodb_buffer_pool_size 的合理设置

Innodb 存储引擎的缓存机制和 MyISAM 的最大区别就在于 Innodb 不仅仅缓存索引,同时还会缓存实 际的数据。所以,完全相同的数据库,使用 Innodb 存储引擎可以使用更多的内存来缓存数据库相关的信 息,当然前提是要有足够的物理内存。这对于在现在这个内存价格不断降低的时代,无疑是个很吸引人 的特性。

innodb_buffer_pool_size 参数用来设置 Innodb 最主要的 Buffer(Innodb_Buffer_Pool)的大小,也 就是缓存用户表及索引数据的最主要缓存空间,对 Innodb 整体性能影响也最大。无论是 MySQL 官方手册 还是网络上很多人所分享的 Innodb 优化建议,都简单的建议将 Innodb 的 Buffer  Pool 设置为整个系统 物理内存的 50%  ~ 80%  之间。如此轻率的给出此类建议,我个人觉得实在是有些不妥。

不管是多么简单的参数,都可能与实际运行场景有很大 的关系。完全相同的设置,不同的场景下的 表现可能相差很大。就从 Innodb 的 Buffer  Pool 到底该设置多大这个问题来看,我们首先需要确定的是 这台主机是不是就只提供 MySQL 服务?MySQL 需要提供的的最大连接数是多少?MySQL 中是否还有 MyISAM 等其他存储引擎提供服务?如果有,其他存储引擎所需要使用的 Cache 需要多大?

假设是一台单独给 MySQL 使用的主机,物理内存总大小为 8G,MySQL 最大连接数为 500,同时还使用 了 MyISAM 存储引擎,这时候我们的整体内存该如何分配呢?
内存分配为如下几大部分:
a)     系统使用,假设预留 800M;
b)     线程独享,约 2GB  = 500  * (1MB  + 1MB  + 1MB  + 512KB  + 512KB),组成大概如下:sort_buffer_size:1MB join_buffer_size:1MB read_buffer_size:1MB read_rnd_buffer_size:512KB thread_statck:512KB
c)    MyISAM  Key Cache,假设大概为 1.5GB;
d)     Innodb Buffer  Pool 最大可用量:8GB  - 800MB  - 2GB  - 1.5GB = 3.7GB;

假设这个时候我们还按照 50%~80%的建议来设置,最小也是 4GB,而通过上面的估算,最大可用值 在 3.7GB 左右,那么很可能在系统负载很高当线程独享内存差不多出现极限情况的时候,系统很可能就 会出现内存不足的问题了。而且上面还仅仅只是列出了一些使用内存较大的地方,如果进一步细化,很 可能可用内存会更少。上面只是一个简单的示例分析,实际情况并不一定是这样的,这里只是希望大家了解,在设置一些 参数的时候,千万不要想当然,一定要详细的分析可能出现的情况,然后再通过不断测试调整来达到自 己所处环境的最优配置。就我个人而言,正式环境上线之初,我一般都会采取相对保守的参数配置策 略。上线之后,再根据实际情况和收集到的各种性能数据进行针对性的调整。

当系统上线之后,我们可以通过 Innodb 存储引擎提供给我们的关于 Buffer  Pool 的实时状态信息作 出进一步分析,来确定系统中 Innodb 的 Buffer  Pool 使用情况是否正常高效:
sky@localhost  : example 08:47:54> show status like  'Innodb_buffer_pool_%';
+-----------------------------------+-------+
| Variable_name    | Value |
+-----------------------------------+-------+
| Innodb_buffer_pool_pages_data     | 70    |
| Innodb_buffer_pool_pages_dirty    | 0    |
| Innodb_buffer_pool_pages_flushed | 0    |
| Innodb_buffer_pool_pages_free    | 1978    |
| Innodb_buffer_pool_pages_latched | 0    |
| Innodb_buffer_pool_pages_misc     | 0    |
| Innodb_buffer_pool_pages_total    | 2048    |
| Innodb_buffer_pool_read_ahead_rnd  | 1    |
| Innodb_buffer_pool_read_ahead_seq  | 0    |
| Innodb_buffer_pool_read_requests | 329    |
| Innodb_buffer_pool_reads    | 19    |
| Innodb_buffer_pool_wait_free    | 0    |
| Innodb_buffer_pool_write_requests | 0    |
+-----------------------------------+-------+

从上面的值我们可以看出总共 2048  pages,还有 1978 是 Free 状态的仅仅只有 70 个 page 有数据, read 请求 329 次,其中有 19 次所请求的数据在 buffer  pool 中没有,也就是说有 19 次是通过读取物理 磁盘来读取数据的,所以很容易也就得出了 Innodb Buffer  Pool 的 Read 命中率大概在为:(329 - 19)/ 329  * 100%  = 94.22%。

当然,通过上面的数据,我们还可以分析出 write 命中率,可以得到发生了多少次 read_ahead_rnd,多少次 read_ahead_seq,发生过多少次 latch,多少次因为 Buffer 空间大小不足而产 生 wait_free 等等。

单从这里的数据来看,我们设置的 Buffer  Pool 过大,仅仅使用 70  / 2048  * 100%  = 3.4%。

在 Innodb Buffer  Pool 中,还有一个非常重要的概念,叫做“预读”。一般来说,预读概念主要是 在一些高端存储上面才会有,简单来说就是通过分析数据请求的特点来自动判断出客户在请求当前数据 块之后可能会继续请求的数据快。通过该自动判断之后,存储引擎可能就会一次将当前请求的数据库和 后面可能请求的下一个(或者几个)数据库一次全部读出,以期望通过这种方式减少磁盘 IO 次数提高 IO 性能。在上面列出的状态参数中就有两个专门针对预读:
Innodb_buffer_pool_read_ahead_rnd,记录进行随机读的时候产生的预读次数; Innodb_buffer_pool_read_ahead_seq,记录连续读的时候产生的预读次数;

innodb_log_buffer_size 参数的使用

顾名思义,这个参数就是用来设置 Innodb 的 Log Buffer 大小的,系统默认值为 1MB。Log  Buffer 的主要作用就是缓冲 Log 数据,提高写 Log 的 IO 性能。一般来说,如果你的系统不是写负载非常高且以 大事务居多的话,8MB 以内的大小就完全足够了。

我们也可以通过系统状态参数提供的性能统计数据来分析 Log 的使用情况:

sky@localhost  : example 10:11:05> show status like 'innodb_log%';
+---------------------------+-------+
| Variable_name    | Value |
+---------------------------+-------+
| Innodb_log_waits     | 0    |
| Innodb_log_write_requests | 6    |
| Innodb_log_writes     | 2    |
+---------------------------+-------+
通过这三个状态参数我们可以很清楚的看到 Log Buffer 的等待次数等性能状态。

当然,如果完全从 Log Buffer 本身来说,自然是大一些会减少更多的磁盘 IO。但是由于 Log 本身是 为了保护数据安全而产生的,而 Log 从 Buffer 到磁盘的刷新频率和控制数据安全一致的事务直接相关, 并且也有相关参数来控制(innodb_flush_log_at_trx_commit),所以关于 Log 相关的更详细的实现机 制和优化在后面的“事务优化”中再做更详细的分析,这里就不展开了。

innodb_additional_mem_pool_size 参数理解

innodb_additional_mem_pool_size 所设置的是用于存放 Innodb 的字典信息和其他一些内部结构所 需要的内存空间。所以我们的 Innodb 表越多,所需要的空间自然也就越大,系统默认值仅有 1MB。当 然,如果 Innodb 实际运行过程中出现了实际需要的内存比设置值更大的时候,Innodb 也会继续通过 OS 来申请内存空间,并且会在 MySQL 的错误日志中记录一条相应的警告信息让我们知晓。

从我个人的经验来看,一个常规的几百个 Innodb 表的 MySQL,如果不是每个表都是上百个字段的 话,20MB 内存已经足够了。当然,如果你有足够多的内存,完全可以继续增大这个值的设置。实际上, innodb_additional_mem_pool_size 参数对系统整体性能并无太大的影响,所以只要能存放需要的数据即 可,设置超过实际所需的内存并没有太大意义,只是浪费内存而已。

Double Write Buffer

Double Write Buffer 是 Innodb 所使用的一种较为独特的文件 Flush 实现技术,主要做用是为了通 过减少文件同步次数提高 IO 性能的情况下,提高系统 Crash 或者断电情况下数据的安全性,避免写入的 数据不完整。

一般来说,Innodb 在将数据同步到数据文件进行持久化之前,首先会将需要同步的内容写入存在于表空间中的系统保留的存储空间,也就是被我们称之为 Double Write Buffer 的地方,然后再将数据进 行文件同步。所以实质上,Double Write Buffer 中就是存放了一份需要同步到文件中数据的一个备份, 以便在遇到系统 Crash 或者主机断电的时候,能够校验最后一次文件同步是否准确的完成了,如果未完 成,则可以通过这个备份来继续完成工作,保证数据的正确性。

那这样 Innodb 不是又一次增加了整体 IO 量了吗?这样不是可能会影响系统的性能么?这个完全不用 太担心,因为 Double Write Buffer 是一块连续的磁盘空间,所有写入 Double Write Buffer 的操作都是 连续的顺序写入操作,与整个同步过程相比,这点 IO 消耗所占的比例是非常小的。为了保证数据的准确 性,这样一点点性能损失是完全可以接受的。

实际上,并不是所有的场景都需要使用 Double Write 这样的机制来保证数据的安全准确性,比如当 我们使用某些特别文件系统的时候,如在 Solaris 平台上非常著名的 ZFS 文件系统,他就可以自己保证文 件写入的完整性。而且在我们的 Slave 端,也可以禁用 Double Write 机制。

Adaptive  Hash Index

在 Innodb 中,实现了一个自动监测各表索引的变化情况的机制,然后通过一系列的算法来判定如果 存在一个 Hash Index 是否会对索引搜索带来性能改善。如果 Innodb 认为可以通过 Hash Index 来提高检 索效率,他就会在内部自己建立一个基于某个 B-Tree 索引的 Hash Index,而且会根据该 B-Tree 索引的 变化自行调整,这就是我们常说的 Adaptive  Hash Index。当然,Innodb 并不一定会将整个 B-Tree 索引 完全的转换为 Hash Index,可能仅仅只是取用该 B-Tree 索引键一定长度的前缀来构造一个 Hash Index。

Adaptive  Hash Index 并不会进行持久化存放在磁盘上面,仅仅存在于 Buffer  Pool 中。所以,在每 次 MySQL 刚启动之后是并不存在 Adaptive  Hash Index 的,只有在停工服务之后,Innodb 才会根据相应 的请求来构建。

Adaptive  Hash Index 的目的并不是为了改善磁盘 IO 的性能,而是为了提高 Buffer  Pool 中的数据 的访问效率,说的更浅显一点就是给 Buffer  Pool 中的数据做的索引。所以,Innodb 在具有大容量内存
(可以设置大的 Buffer  Pool)的主机上,对于其他存储引擎来说,会存在一定的性能优势。

InnoDB的内存使用情况

关于InnoDB如何分配内存的问题有很多。在此,我会给出一些关于数据库启动时内存分配的解释。

下面是一些重要的常量:
1. NBLOCKS:等于innodb_buffer_pool中的块总数,也就是innodb_buffer_pool_size / 16384
2. OS_THREADS:如 果innodb_buffer_pool_size >= 1000MB,那么等于50000;如果innodb_buffer_pool_size >= 8MB,那么等于10000;否则,等于1000(这种计算方法适用于Linux/Unix系统,Windows有另外一种计算OS_THREADS的方 法)。

因此,InnoDB会使用:
1. innodb_buffer_pool
2. innodb_additional_mem_pool_size
3. innodb_log_buffer_size
4. 自适应的索引哈希,大小为innodb_buffer_pool / 64
5. 系统字典哈希,大小为6 * innodb_buffer_pool_size / 512
6. sync_array使用的内存,可用于同步原语,大小为OS_THREADS * 152
7. os_events使用的内存,同样可用于同步原语,大小为OS_THREADS * 216
8. 锁定系统使用的内存,大小为5 * 4 * NBLOCKS

因此,计算InnoDB使用内存的最终公式如下:
innodb_buffer_pool_size + innodb_log_buffer_size + innodb_additional_mem_pool_size + 812 / 16384 * innodb_buffer_pool_size + OS_THREADS * 368

为了简化上述公式,我们可以使用:
812 / 16384 * innodb_buffer_pool_size ~~ innodb_buffer_pool_size / 20
并且,如果innodb_buffer_pool > 1000MB,则OS_THREADS * 368 = 17.5MB;如果innodb_buffer_pool > 8MB,则OS_THREADS * 368 = 3.5MB。

例如,如果你设置的 innodb_buffer_pool_size=1500M,innodb_additional_mem_pool_size = 20M,innodb_log_buffer_size = 8M,那么InnoDB将会分配的内存大小为1500M + 20M + 8M + 1500/20M + 17.5M,也就是1620.5M。

当你规划服务器的内存使用时,请慎重考虑额外使用的内存。

转载于:https://www.cnblogs.com/Alight/p/4900749.html

相关文章:

用过美德乐吸奶器的宝妈们感觉比国产吸奶器怎么样啊?

药效好不好,看疗效就知道。吸奶器好不好看评价就知道。我们来看看美德乐吸奶器 天猫旗舰店 : http://medela.wang 的宝妈们的评价如可 拔奶神器,绝对好过贝亲!最初一次七八十,后来一百多,现在可以翻个倍。结合宝宝吮吸…

小程序地图多个 circles 使用demo

效果图: 代码: var that; const app getApp() const util require("../../utils/util.js") const data require("../../utils/map.js") Page({data: {pageShow: false,scale: 15,obj: {},longitude: 116.34665554470486,latitud…

编写文档_如何通过编写优质文档来使自己的未来快乐

编写文档by Gabriele Cimato加布里埃莱西马托(Gabriele Cimato) 如何通过编写优质文档来使自己的未来快乐 (How to make your future self happy by writing good docs) 或者,在清除旧代码库时如何减少痛苦 (Or how to be less miserable when dusting off an old …

(转载)人人都会OSGI--实例讲解OSGI开发

http://longdick.iteye.com/blog/457310转载于:https://www.cnblogs.com/eecs2016/articles/7422310.html

小程序json字符串转 json对象 { name :你好} 转成 { name :你好}

解决后端接口返回 var obj "{ name :"你好"}" 类似这样的数据,对象或者数组外面包了一层引号, 把这种数据转成 var obj { name :"你好"}; 直接上代码: // pages/test/test.js Page({jsonStrToJ…

每天写的叫工作日志,每周写的总结叫周报,每月写的叫月报

有些时候,老板会突发让您求每天都要写工作周报,什么项目什么任务,完成情况,完成花费的时间等,然后汇总部门周报;也不是写不出,只是不知道有时候重复做一个项目,到底每天有什么好写&a…

为什么分散刷新没有死时间_分散项目为何失败(以及如何处理)

为什么分散刷新没有死时间The most exciting thing about working in the decentralized economy is the fact that no one has any idea as to where it’ll all end up!在去中心decentralized economy工作最令人振奋的事情是,没有人知道最终的结果! T…

.NET Core 常用加密和Hash工具NETCore.Encrypt

前言 在日常开发过程中,不可避免的涉及到数据加密解密(Hash)操作,所以就有想法开发通用工具,NETCore.Encrypt就诞生了。目前NETCore.Encrypt只支持.NET Core ,工具包含了AES,DES,RSA加密解密,MD5&#xff0…

url 通配符解析成参数

需求:url 参数是通配符,需要把通配符解析成参数并且拼接到 url 中 例如:https://xxx.cn/index.html$a1$b2; 解析成 https://xxx.cn/index.html?a1&b2; 时间关系,直接上代码,有时间再补上注释 下面是小程序页…

性能测试分享:系统架构

性能测试分享:系统架构 转载于:https://www.cnblogs.com/poptest/p/4904584.html

graphql是什么_为什么GraphQL是避免技术债务的关键

graphql是什么GraphQL (not to be confused with GraphDB or Open Graph or even an actual graph) is a remarkably creative solution to a relatively common problem: How do you enable front end developers to access backend data in exactly the way they need it?Gr…

JS如何判断json是否为空

1、判断json是否为空 jQuery.isEmptyObject(); 2、遍历json function getHsonLength(json{var jsonLength0;for (var i in json){jsonLength;}return jsonLength;}转载于:https://www.cnblogs.com/donaldworld/p/7423811.html

微软算法100题11 求二叉树中两节点之间的最大距离

第11 题求二叉树中节点的最大距离...如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两节点之间边的个数。写一个程序,求一棵二叉树中相距最远的两个节点之间的距离 思路: 一棵树中节点的最大距…

小程序订阅消息 订阅消息开发

微信小程序交流QQ群: 173683895 173683866 526474645 。 群内打广告或者脏话一律飞机票 订阅消息 当用户勾选了订阅面板中的“总是保持以上选择,不再询问”时,模板消息会被添加到用户的小程序设置页,通过 wx.getSetting…

meetup_如何使用标准库和Node.js构建Meetup Slack机器人

meetupby Janeth Ledezma简妮丝莱德兹玛(Janeth Ledezma) 如何使用标准库和Node.js构建Meetup Slack机器人 (How to build a Meetup Slack bot with Standard Library and Node.js) In this guide, you will learn how to set up a Slack application that will display infor…

.NET使用OpenSSL生成的pem密钥文件[1024位]

using System; using System.Text; using System.Security.Cryptography; using System.Web; using System.IO;namespace Thinhunan.Cnblogs.Com.RSAUtility {public class PemConverter{/// <summary>/// 将pem格式公钥转换为RSAParameters/// </summary>/// <…

[2014百度之星资格赛]

第一个问题&#xff1a; Energy Conversion Problem Description魔法师百小度也有遇到难题的时候——如今。百小度正在一个古老的石门面前&#xff0c;石门上有一段古老的魔法文字&#xff0c;读懂这样的魔法文字须要耗费大量的能量和大量的脑力。过了许久。百小度最终读懂魔法…

视频录制,压缩实现源码

实现代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><meta name"viewport" content"widthdevice-width, initial-scale1.0"><!-- <script src"./js…

alexa技能个数_如何在您的技能中使用Alexa演示语言

alexa技能个数by Garrett Vargas通过Garrett Vargas 如何在您的技能中使用Alexa演示语言 (How to use Alexa Presentation Language in your skill) Amazon recently released the Alexa Presentation Language (APL). APL provides a richer display for multimodal skills. …

HTML与XML总结

阅览《孙欣HTML》和《刘炜XML》过了一段时间&#xff0c;在这里学到的内容用思维导图来概括。HTML与XML都是标记语言。 同样点&#xff1a; HTML文档与XML文档有类似的结构。前者是&#xff08;head和body&#xff09;后者是&#xff08;声明和主体&#xff09;&#xff0c;大致…

ant PageHeaderWrapper 返回上一页

PageHeaderWrapper 返回上一页实现代码&#xff1a; <PageHeaderWrappertitle{false}content{<a onClick{() > router.goBack()}><Icon type"left" />返回</a>}breadcrumb{{routes: [{ path: /, breadcrumbName: 首页 },{ path: /pay_orde…

ruby 新建对象_Ruby面向对象编程的简介

ruby 新建对象by Saul Costa由Saul Costa Object-oriented programming (OOP) is a programming paradigm organized around objects. At a high level, OOP is all about being able to structure code so that its functionality can be shared throughout the application.…

ASP.NET导出文件FileResult的使用

本文给大家讲一下ASP.NET MVC中如何使用FileResult来导出文件&#xff0c;首先网上相关例子有很多大神都有讲&#xff0c;我在这只是稍微说一点不同——为什么我的导出没有反应呢&#xff1f; 这个问题&#xff0c;我找了半天也没有找到&#xff0c;最后是在一个网友的评论中体…

【AHOI 2016初中组】 自行车比赛 - 贪心

题目描述 小雪非常关注自行车比赛&#xff0c;尤其是环滨湖自行车赛。一年一度的环滨湖自行车赛&#xff0c;需要选手们连续比赛数日&#xff0c;最终按照累计得分决出冠军。今年一共有 N 位参赛选手。每一天的比赛总会决出当日的排名&#xff0c;第一名的选手会获得 N 点得分&…

【Ant Design Pro 三】样式动态绑定 react样式绑定

第一步&#xff0c;创建样式文件&#xff0c;在页面目录下根据自己习惯创建一个less文件&#xff0c;用来写样式类 第二部&#xff0c;引用该文件 import styles from ./details.less; //details.less 代码&#xff1a; .menu {width: 95%; } .navigation-menu{width: 90%; …

react hooks使用_如何使用React和Hooks检测外部点击

react hooks使用by Andrei Cacio通过安德烈卡西奥(Andrei Cacio) 如何使用React和Hooks检测外部点击 (How to detect an outside click with React and Hooks) “外部点击”是什么意思&#xff1f; (What does “Outside Click” mean?) You can think of it as the “anti-b…

正则表达式(1)

正则表达式的概念 正则表达式是一个字符串&#xff0c;使用单个字符串来描述、用来定义匹配规则&#xff0c;匹配一系列符合某个句法规则的字符串。在开发中&#xff0c;正则表达式通常被用来检索、替换那些符合某个规则的文本。 正则表达式的匹配规则 字符类&#xff1a;[abc]…

Android 曲线动画animation,类似加入购物车动画

按照惯例先放效果图&#xff1a;图中小球做抛物线运动 资源图片 1.首先布局文件activity_main.xml&#xff0c;布局很简单&#xff0c;就一个测试按钮 1 <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"2 xmlns:tools"http:…

小程序音频播放报10001 解决方案 errCode:10001, errMsg:errCode:602,err:error,not found param

音频播放有两种方式&#xff1a; 第一种&#xff1a; innerAudioContext.src audioSrc;innerAudioContext.play(); 第二种&#xff1a; innerAudioContext.autoplay true;innerAudioContext.src audioSrc; 之前使用第一种&#xff0c;华为手机不能正常播放&#xff0c;…

在线学位课程_您在四年制计算机科学学位课程中学到的知识

在线学位课程by Colin Smith通过科林史密斯 您在四年制计算机科学学位课程中学到的知识 (What you learn in a 4 year Computer Science degree) I recently wrote an article on whether you need a computer science degree to get a job in tech. I thought that going ove…