MySQL数据库共享内存和缓存介绍

转载至 http://www.server110.com/mysql/201311/2991.html

全局共享内存主要是 MySQL Instance(mysqld进程)以及底层存储引擎用来暂存各种全局运算及可共享的暂存信息,如存储查询缓存的 Query Cache,缓存连接线程的 Thread Cache,缓存表文件句柄信息的 Table Cache,缓存二进制日志的 BinLog Buffer, 缓存 MyISAM 存储引擎索引键的 Key Buffer以及存储 InnoDB 数据和索引的 InnoDB Buffer Pool 等等。下面针对 MySQL 主要的共享内存进行一个简单的分析。

查询缓存(Query Cache):
查询缓存是 MySQL
比较独特的一个缓存区域,用来缓存特定 Query 的结果集(Result Set)信息,且共享给所有客户端。通过对 Query
语句进行特定的 Hash 计算之后与结果集对应存放在 Query Cache 中,以提高完全相同的 Query
语句的相应速度。当我们打开 MySQL 的 Query Cache 之后,MySQL 接收到每一个 SELECT 类型的 Query
之后都会首先通过固定的 Hash 算法得到该 Query 的 Hash 值,然后到 Query Cache 中查找是否有对应的
Query Cache。如果有,则直接将 Cache
的结果集返回给客户端。如果没有,再进行后续操作,得到对应的结果集之后将该结果集缓存到 Query Cache
中,再返回给客户端。当任何一个表的数据发生任何变化之后,与该表相关的所有 Query Cache 全部会失效,所以 Query
Cache
对变更比较频繁的表并不是非常适用,但对那些变更较少的表是非常合适的,可以极大程度的提高查询效率,如那些静态资源表,配置表等等。为了尽可能高效的利用
Query Cache,MySQL 针对 Query Cache 设计了多个 query_cache_type 值和两个 Query
Hint:SQL_CACHE 和 SQL_NO_CACHE。当 query_cache_type 设置为0(或者 OFF)的时候不使用
Query Cache,当设置为1(或者 ON)的时候,当且仅当 Query 中使用了 SQL_NO_CACHE 的时候 MySQL
会忽略 Query Cache,当 query_cache_type 设置为2(或者DEMAND)的时候,当且仅当Query 中使用了
SQL_CACHE 提示之后,MySQL 才会针对该 Query 使用 Query Cache。可以通过
query_cache_size 来设置可以使用的最大内存空间。

连接线程缓存(Thread Cache):
连接线程是 MySQL
为了提高创建连接线程的效率,将部分空闲的连接线程保持在一个缓存区以备新进连接请求的时候使用,这尤其对那些使用短连接的应用程序来说可以极大的提高创建连接的效率。当我们通过
thread_cache_size 设置了连接线程缓存池可以缓存的连接线程的大小之后,可以通过(Connections -
Threads_created) / Connections * 100%
计算出连接线程缓存的命中率。注意,这里设置的是可以缓存的连接线程的数目,而不是内存空间的大小。

表缓存(Table Cache):
表缓存区主要用来缓存表文件的文件句柄信息,在
MySQL5.1.3之前的版本通过 table_cache 参数设置,但从MySQL5.1.3开始改为
table_open_cache 来设置其大小。当我们的客户端程序提交 Query 给 MySQL 的时候,MySQL 需要对
Query 所涉及到的每一个表都取得一个表文件句柄信息,如果没有 Table Cache,那么 MySQL
就不得不频繁的进行打开关闭文件操作,无疑会对系统性能产生一定的影响,Table Cache 正是为了解决这一问题而产生的。在有了
Table Cache 之后,MySQL 每次需要获取某个表文件的句柄信息的时候,首先会到 Table Cache
中查找是否存在空闲状态的表文件句柄。如果有,则取出直接使用,没有的话就只能进行打开文件操作获得文件句柄信息。在使用完之后,MySQL
会将该文件句柄信息再放回 Table Cache
池中,以供其他线程使用。注意,这里设置的是可以缓存的表文件句柄信息的数目,而不是内存空间的大小。

表定义信息缓存(Table definition Cache):
表定义信息缓存是从
MySQL5.1.3 版本才开始引入的一个新的缓存区,用来存放表定义信息。当我们的 MySQL
中使用了较多的表的时候,此缓存无疑会提高对表定义信息的访问效率。MySQL 提供了 table_definition_cache
参数给我们设置可以缓存的表的数量。在 MySQL5.1.25 之前的版本中,默认值为128,从 MySQL5.1.25
版本开始,则将默认值调整为 256
了,最大设置值为524288。注意,这里设置的是可以缓存的表定义信息的数目,而不是内存空间的大小。

二进制日志缓冲区(Binlog
Buffer):
二进制日志缓冲区主要用来缓存由于各种数据变更操做所产生的 Binary Log
信息。为了提高系统的性能,MySQL 并不是每次都是将二进制日志直接写入 Log File,而是先将信息写入 Binlog
Buffer 中,当满足某些特定的条件(如 sync_binlog参数设置)之后再一次写入 Log File 中。我们可以通过
binlog_cache_size 来设置其可以使用的内存大小,同时通过 max_binlog_cache_size
限制其最大大小(当单个事务过大的时候 MySQL 会申请更多的内存)。当所需内存大于 max_binlog_cache_size
参数设置的时候,MySQL 会报错:“Multi-statement transaction required more than
‘max_binlog_cache_size’ bytes of storage”。

MyISAM索引缓存(Key Buffer):
MyISAM 索引缓存将 MyISAM
表的索引信息缓存在内存中,以提高其访问性能。这个缓存可以说是影响 MyISAM 存储引擎性能的最重要因素之一了,通过
key_buffere_size 设置可以使用的最大内存空间。

InnoDB 日志缓冲区(InnoDB Log Buffer):
这是 InnoDB
存储引擎的事务日志所使用的缓冲区。类似于 Binlog Buffer,InnoDB 在写事务日志的时候,为了提高性能,也是先将信息写入
Innofb Log Buffer 中,当满足 innodb_flush_log_trx_commit
参数所设置的相应条件(或者日志缓冲区写满)之后,才会将日志写到文件(或者同步到磁盘)中。可以通过
innodb_log_buffer_size 参数设置其可以使用的最大内存空间。
注:innodb_flush_log_trx_commit 参数对 InnoDB Log
的写入性能有非常关键的影响。该参数可以设置为0,1,2,解释如下:
0:log buffer中的数据将以每秒一次的频率写入到log
file中,且同时会进行文件系统到磁盘的同步操作,但是每个事务的commit并不会触发任何log buffer 到log
file的刷新或者文件系统到磁盘的刷新操作。
1:在每次事务提交的时候将log buffer 中的数据都会写入到log file,同时也会触发文件系统到磁盘的同步;
2:事务提交会触发log buffer 到log
file的刷新,但并不会触发磁盘文件系统到磁盘的同步。此外,每秒会有一次文件系统到磁盘同步操作。
此外,MySQL文档中还提到,这几种设置中的每秒同步一次的机制,可能并不会完全确保非常准确的每秒就一定会发生同步,还取决于进程调度的问题。实际上,InnoDB
能否真正满足此参数所设置值代表的意义正常 Recovery 还是受到了不同 OS
下文件系统以及磁盘本身的限制,可能有些时候在并没有真正完成磁盘同步的情况下也会告诉 mysqld 已经完成了磁盘同步。

InnoDB 数据和索引缓存(InnoDB Buffer Pool):
InnoDB
Buffer Pool 对 InnoDB 存储引擎的作用类似于 Key Buffer Cache 对 MyISAM
存储引擎的影响,主要的不同在于 InnoDB Buffer Pool
不仅仅缓存索引数据,还会缓存表的数据,而且完全按照数据文件中的数据快结构信息来缓存,这一点和 Oracle SGA 中的
database buffer cache 非常类似。所以,InnoDB Buffer Pool 对 InnoDB
存储引擎的性能影响之大就可想而知了。可以通过 (Innodb_buffer_pool_read_requests -
Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100%
计算得到 InnoDB Buffer Pool 的命中率。

InnoDB 字典信息缓存(InnoDB Additional Memory
Pool):
InnoDB 字典信息缓存主要用来存放 InnoDB 存储引擎的字典信息以及一些 internal
的共享数据结构信息。所以其大小也与系统中所使用的 InnoDB 存储引擎表的数量有较大关系。不过,如果我们通过
innodb_additional_mem_pool_size 参数所设置的内存大小不够,InnoDB 会自动申请更多的内存,并在
MySQL 的 Error Log 中记录警告信息。
这里所列举的各种共享内存,是我个人认为对 MySQL
性能有较大影响的集中主要的共享内存。实际上,除了这些共享内存之外,MySQL
还存在很多其他的共享内存信息,如当同时请求连接过多的时候用来存放连接请求信息的back_log队列等。

时间: 2024-08-29 23:08:11

MySQL数据库共享内存和缓存介绍的相关文章

Oracle数据库共享内存分配不足问题的解决

问题: ORA-04031: unable to allocate 19204 bytes of shared memory ("shared pool","unknown object","sga heap(1,0)","session param values") 错误原因: 共享内存太小,分配给共享池的内存不足以满足用户请求,或者存在一定碎片,没有有 效的利用保留区,造成无法分配合适的共享区.一个ORACLE例程的系统全

Linux环境编程之共享内存区(一):共享内存区简单介绍

共享内存区是可用IPC形式中最快的.一旦内存区映射到共享它的进程的地址空间,进程间数据的传递就不再涉及内核.然而往该共享内存区存放信息或从中取走信息的进程间通常须要某种形式的同步.不再涉及内核是指:进程不再通过运行不论什么进入内核的系统调用来彼此传递数据.内核必须建立同意各个进程共享该内存区的内存映射关系.然后一直管理内存区. 默认情况下通过fork派生的子进程并不与其父进程共享内存区. mmap函数把一个文件或一个Posix共享内存区对象映射到调用进程的地址空间.使用该函数的目的有: 1.使用

mysql数据库性能优化 - 查询缓存

查询缓存       缓存机制简单的说就是缓存sql文本和查询结果,如果运行相同的sql,服务器直接从缓存中取到结果,而不需要去解析和执行sql,如果表更改了,那么使用这个表的所有缓存查询将不再有效,查询缓存值的相关条目被清空.更改指的是表中任何数据或是结构的改变,包括insert.update.delete.truncate.alter table.drop table或drop database等.这对频繁更新的表,查询缓存是不适合的,而对一些不常改变数据且大量相同的sql查询的表,查询缓存

mysql数据库性能优化(包括SQL,表结构,索引,缓存)

优化目标减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当然,也是收效最明显的优化手段.降低 CPU 计算除了 IO 瓶颈之外,SQL优化中需要考虑的就是 CPU 运算量的优化了.order by, group by,distinct … 都是消耗 CPU 的大户(这些操作基本上都是 CPU 处理内存中的数据比较运算).当我们的 IO 优化做到一定阶段之后

Memcached 内存级缓存

Memcached在大型网站中应用    memcached是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像.视 频.文件以及数据库检索的结果等.最初为了加速 LiveJournal 访问速度而开发的,后来被很多大型的网站采用.起初作者编写它可能是为了提高动态网页应用,为了减轻数据库检索的压力,来做的这个缓存系统.它的缓存是一 种分布式的,也就是可以允许不同主机上的多个用户同时访问这个缓存系统, 这种方法不仅解决了共享内存

MYSQL数据库自动本地/异地双备份/MYSQL增量备份

构建高安全电子商务网站之(网站文件及数据库自动本地/异地双备份)架构图 继续介绍Linux服务器文件备份,数据库备份,数据安全存储相关的电子商务系统架构.针对安全性有多种多样的解决方案,其中数据备份是重中之重的首要工作.电 子商务网站更加注重考虑数据安全,数据备份方案,包括本地备份.异地备份架构.其中Linux服务器的备份方案非常多,本文介绍一个大众化适用的解决方 案,通过编写Shell脚本来完成自动备份.本架构包括备份网站文件.数据库,自动本地备份并FTP上传备份脚本,完成相应本地备份.异地备

MySQL数据库远程连接开启方法

第一中方法:比较详细以下的文章主要介绍的是MySQL 数据库开启远程连接的时机操作流程,其实开启MySQL 数据库远程连接的实际操作步骤并不难,知识方法对错而已,今天我们要向大家描述的是MySQL 数据库开启远程连接的时机操作流程. 1.d:\MySQL\bin\>MySQL -h localhost -u root 这样应该可以进入MySQL服务器 复制代码代码如下: MySQL>update user set host = '%' where user = 'root'; MySQL>

Linux进程间通信 共享内存+信号量+简单例子

每一个进程都有着自己独立的地址空间,比如程序之前申请了一块内存,当调用fork函数之后,父进程和子进程所使用的是不同的内存.因此进程间的通信,不像线程间通信那么简单.但是共享内存编程接口可以让一个进程使用一个公共的内存区段,这样我们便能轻易的实现进程间的通信了(当然对于此内存区段的访问还是要控制好的). 共享内存实现进程通信的优点: 共享内存是进程通信方式中最快速的方式之一,它的快速体现在,为数据共享而进行的复制非常少.这里举例来说,使用消息队列时,一个进程向消息队列写入消息时,这里有一次数据的

.net连mysql数据库汇总

另外MySql官方出了一个在csharp里面连接MySql的Connector,可以试试 http://dev.mysql.com/downloads/#connector-net <add name="mysql" connectionString="server=125.46.37.170;uid=root;pwd=;"/> 报错:Unable to connect to any of the specified MySQL hosts. 今天做项目