MySQL内存及虚拟内存优化设置

mysql 优化调试命令html

一、mysqld --verbose --helpmysql

这个命令生成全部mysqld选项和可配置变量的列表算法

二、经过链接它并执行这个命令,能够看到实际上使用的变量的值:sql

mysql> SHOW VARIABLES;

还能够经过下面的语句看到运行服务器的统计和状态指标:shell

mysql>SHOW STATUS;

使用mysqladmin还能够得到系统变量和状态信息:数据库

shell> mysqladmin variables
shell> mysqladmin extended-status

shell> mysqladmin flush-table 命令能够当即关闭全部不使用的表并将全部使用中的表标记为已经关闭,这样能够有效释放大多数使用中的内存。FLUSH TABLE在关闭全部表以前不返回结果。缓存

swap -s检查可用交换区安全

mysql内存计算公式服务器

mysql used mem = key_buffer_size + query_cache_size + tmp_table_size
+ innodb_buffer_pool_size + innodb_additional_mem_pool_size
+ innodb_log_buffer_size
+ max_connections * (
read_buffer_size + read_rnd_buffer_size
+ sort_buffer_size+ join_buffer_size
+ binlog_cache_size + thread_stack
)数据结构

在mysql 中输入以下命令,可自动计算本身的当前配置最大的内存消耗

SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'innodb_additional_mem_pool_size';
SHOW VARIABLES LIKE 'innodb_log_buffer_size';
SHOW VARIABLES LIKE 'thread_stack';
SET @kilo_bytes = 1024;
SET @mega_bytes = @kilo_bytes * 1024;
SET @giga_bytes = @mega_bytes * 1024;
SET @innodb_buffer_pool_size = 2 * @giga_bytes;
SET @innodb_additional_mem_pool_size = 16 * @mega_bytes;
SET @innodb_log_buffer_size = 8 * @mega_bytes;
SET @thread_stack = 192 * @kilo_bytes;
SELECT
( @@key_buffer_size + @@query_cache_size + @@tmp_table_size
+ @innodb_buffer_pool_size + @innodb_additional_mem_pool_size
+ @innodb_log_buffer_size
+ @@max_connections * (
@@read_buffer_size + @@read_rnd_buffer_size + @@sort_buffer_size
+ @@join_buffer_size + @@binlog_cache_size + @thread_stack
) ) / @giga_bytes AS MAX_MEMORY_GB;

 

 

mysql关键参数设置

Mysqld 数据库的参数设置有两种类型,

 

一种是全局参数,影响服务器的全局操做;

另外一种是会话级参数,只影响当前的客户端链接的相关操做。

 

服务器启动时,全部全局参数都初始化为默认值。能够在初始化文件或命令行中指定的选项来更改这些默认值。服务器启动后,经过链接服务器并执行 SET GLOBAL var_name 语句能够更改动态全局参数。要想更改全局参数,必须具备 SUPER 权限。全局参数的修改只对新的链接生效,已有的客户端链接并不会生效。

 

服务器还能够为每一个客户端链接维护会话级参数,客户端链接时使用相应全局参数的当前值对客户端会话参数进行初始化。客户能够经过 SET SESSION var_name 语句来更改动态会话参数。设置会话级参数不须要特殊权限,但每一个客户端能够只更改本身的会话级参数,不能更改其它客户的会话级参数。

不指定设置的参数类型时,默认设置的是会话级参数。

 


(1)、max_connections:
容许的同时客户的数量。增长该值增长 mysqld 要求的文件描述符的数量。这个数字应该增长,不然,你将常常看到 too many connections 错误。 默认数值是100,我把它改成1024 。

(2)、record_buffer:
每一个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。若是你作不少顺序扫描,你可能想要增长该值。默认数值是131072(128k),我把它改成16773120 (16m)

(3)、key_buffer_size:

为了最小化磁盘的 I/O , MyISAM 存储引擎的表使用键高速缓存来缓存索引,这个键高速缓存的大小则经过 key-buffer-size 参数来设置。若是应用系统中使用的表以 MyISAM 存储引擎为主,则应该适当增长该参数的值,以便尽量的缓存索引,提升访问的速度。


索引块是缓冲的而且被全部的线程共享。key_buffer_size是用于索引块的缓冲区大小,增长它可获得更好处理的索引(对全部读和多重写),到你能负担得起那样多。若是你使它太大,系统将开始换页而且真的变慢了。默认数值是8388600(8m),个人mysql主机有2gb内存,因此我把它改成 402649088(400mb)。

默认状况下,全部的索引都使用相同的键高速缓存,当访问的索引不在缓存中时,使用 LRU ( Least Recently Used 最近最少使用)算法来替换缓存中最近最少使用的索引块。为了进一步避免对键高速缓存的争用,从 MySQL5.1 开始,能够设置多个键高速缓存,并为不一样的索引键指定使用的键高速缓存。下面的例子演示如何修改高速键缓存的值,如何设置多个键高速缓存,以及如何为不一样的索引指定不一样的缓存:

显示当前的参数大小,为16M:

mysql> show variables like 'key_buffer_size';

+-----------------+-------+

| Variable_name | Value |

+-----------------+-------+

| key_buffer_size | 16384 |

+-----------------+-------+

1 row in set (0.00 sec)

修改参数值到200M:

mysql> set global key_buffer_size=204800;

Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'key_buffer_size';

+-----------------+--------+

| Variable_name | Value |

+-----------------+--------+

| key_buffer_size | 204800 |

+-----------------+--------+

1 row in set (0.00 sec)

上面介绍的是默认的键缓存,下面介绍如何设置多个键缓存:

设置 hot_cache 的键缓存 100M , cold_cache 的键缓存 100M ,另外还有 200M 的默认的键缓存。若是索引不指定键缓存,则会放在默认的键缓存中。

mysql> set global hot_cache.key_buffer_size=102400;

Query OK, 0 rows affected (0.00 sec)

mysql> set global cold_cache.key_buffer_size= 1024 00;

Query OK, 0 rows affected (0.01 sec)

mysql> show variables like 'key_buffer_size';

+-----------------+--------+

| Variable_name | Value |

+-----------------+--------+

| key_buffer_size | 204800 |

+-----------------+--------+

1 row in set (0.00 sec)

若是要显示设置的多键缓存的值,可使用:

mysql> SELECT @@global.hot_cache.key_buffer_size;

+------------------------------------+

| @@global.hot_cache.key_buffer_size |

+------------------------------------+

| 102400 |

+------------------------------------+

1 row in set (0.03 sec)

mysql> SELECT @@global.cold_cache.key_buffer_size;

+-------------------------------------+

| @@global.cold_cache.key_buffer_size |

+-------------------------------------+

| 102400 |

+-------------------------------------+

1 row in set (0.00 sec)

指定不一样的索引使用不一样的键缓存:

mysql> CACHE INDEX test1 in hot_cache;

+------------+--------------------+----------+----------+

| Table | Op | Msg_type | Msg_text |

+------------+--------------------+----------+----------+

| test .test1 | assign_to_keycache | status | OK |

+------------+--------------------+----------+----------+

1 row in set (0.00 sec)

mysql> CACHE INDEX test2 in hot_cache;

+------------+--------------------+----------+----------+

| Table | Op | Msg_type | Msg_text |

+------------+--------------------+----------+----------+

| test .test2 | assign_to_keycache | status | OK |

+------------+--------------------+----------+----------+

1 row in set (0.00 sec)

一般在数据库刚刚启动的时候,须要等待数据库热起来,也就是等待数据被缓存到缓存区中,这段时间数据库会由于 buffer 的命中率低而致使应用的访问效率不高。使用键高速缓存的时候,能够经过命令将索引预加载到缓存区中,大大缩短了数据库预热的时间。具体的操做方式是:

mysql> LOAD INDEX INTO CACHE test1,test2 IGNORE LEAVES;

+------------+--------------+----------+----------+

| Table | Op | Msg_type | Msg_text |

+------------+--------------+----------+----------+

| test .test1 | preload_keys | status | OK |

| test .test2 | preload_keys | status | OK |

+------------+--------------+----------+----------+

2 rows in set (3.89 sec)

若是已经使用 CACHE INDEX 语句为索引分配了一个键高速缓冲,预加载能够将索引块放入该缓存,不然,索引块将被加载到默认的键高速缓冲。

 


4)、back_log:
要求 mysql 能有的链接数量。当主要mysql线程在一个很短期内获得很是多的链接请求,这就起做用,而后主线程花些时间(尽管很短)检查链接而且启动一个新线程。
back_log 值指出在mysql暂时中止回答新请求以前的短期内多少个请求能够被存在堆栈中。只有若是指望在一个短期内有不少链接,你须要增长它,换句话说,这值对到来的tcp/ip链接的侦听队列的大小。你的操做系统在这个队列大小上有它本身的限制。试图设定back_log高于你的操做系统的限制将是无效的。
当你观察你的主机进程列表,发现大量 264084 | unauthenticated user | xxx.xxx.xxx.xxx | null | connect | null | login | null 的待链接进程时,就要加大 back_log 的值了。默认数值是50,我把它改成500。

(5)、interactive_timeout:
服务器在关闭它前在一个交互链接上等待行动的秒数。一个交互的客户被定义为对 mysql_real_connect()使用 client_interactive 选项的客户。 默认数值是28800,我把它改成7200。


(6)、sort_buffer:
每一个须要进行排序的线程分配该大小的一个缓冲区。增长这值加速order by或group by操做。默认数值是2097144(2m),我把它改成 16777208 (16m)。

(7)、table_cache:
为全部线程打开表的数量。增长该值能增长mysqld要求的文件描述符的数量。mysql对每一个惟一打开的表须要2个文件描述符。默认数值是64,我把它改成512。

(8)、thread_cache_size:
能够复用的保存在中的线程的数量。若是有,新的线程从缓存中取得,当断开链接的时候若是有空间,客户的线置在缓存中。若是有不少新的线程,为了提升性能能够这个变量值。经过比较 connections 和 threads_created 状态的变量,能够看到这个变量的做用。我把它设置为 80。

(9)mysql的搜索功能
用mysql进行搜索,目的是能不分大小写,又能用中文进行搜索
只需起动mysqld时指定 --default-character-set=gb2312

(10)、wait_timeout:
服务器在关闭它以前在一个链接上等待行动的秒数。 默认数值是28800,我把它改成7200。

 

(11)、innodb_thread_concurrency:
你的服务器CPU有几个就设置为几,默认为8。

 

(12)、query_cache_size  与 query_cache_limit

QueryCache 以后所带来的负面影响:
a) Query 语句的hash 运算以及hash 查找资源消耗。当咱们使用Query Cache 以后,每条SELECT
类型的Query 在到达MySQL 以后,都须要进行一个hash 运算而后查找是否存在该Query 的
Cache,虽然这个hash 运算的算法可能已经很是高效了,hash 查找的过程也已经足够的优化
了,对于一条Query 来讲消耗的资源确实是很是很是的少,可是当咱们每秒都有上千甚至几千
条Query 的时候,咱们就不能对产生的CPU 的消耗彻底忽视了。
b) Query Cache 的失效问题。若是咱们的表变动比较频繁,则会形成Query Cache 的失效率很是
高。这里的表变动不只仅指表中数据的变动,还包括结构或者索引等的任何变动。也就是说我
们每次缓存到Query Cache 中的Cache 数据可能在刚存入后很快就会由于表中的数据被改变而被
清除,而后新的相同Query 进来以后没法使用到以前的Cache。
c) Query Cache 中缓存的是Result Set ,而不是数据页,也就是说,存在同一条记录被Cache 多
次的可能性存在。从而形成内存资源的过渡消耗。固然,可能有人会说咱们能够限定Query
Cache 的大小啊。是的,咱们确实能够限定Query Cache 的大小,可是这样,Query Cache 就很
容易形成由于内存不足而被换出,形成命中率的降低。

 

QueryCache 的正确使用:

虽然Query Cache 的使用会存在一些负面影响,可是咱们也应该相信其存在是一定有必定价值。我
们彻底不用由于Query Cache 的上面三个负面影响就彻底失去对Query Cache 的信心。只要咱们理解了
Query Cache 的实现原理,那么咱们就彻底能够经过必定的手段在使用Query Cache 的时候扬长避短,重
发发挥其优点,并有效的避开其劣势。
首先,咱们须要根据Query Cache 失效机制来判断哪些表适合使用Query 哪些表不适合。因为Query
Cache 的失效主要是由于Query 所依赖的Table 的数据发生了变化,形成Query 的Result Set 可能已经
有所改变而形成相关的Query Cache 所有失效,那么咱们就应该避免在查询变化频繁的Table 的Query 上
使用,而应该在那些查询变化频率较小的Table 的Query 上面使用。MySQL 中针对Query Cache 有两个专
用的SQL Hint(提示):SQL_NO_CACHE 和SQL_CACHE,分别表明强制不使用Query Cache 和强制使用
Query Cache。咱们彻底能够利用这两个SQL Hint,让MySQL 知道咱们但愿哪些SQL 使用Query Cache 而
哪些SQL 就不要使用了。这样不只可让变化频繁Table 的Query 浪费Query Cache 的内存,同时还能够
减小Query Cache 的检测量。
其次,对于那些变化很是小,大部分时候都是静态的数据,咱们能够添加SQL_CACHE 的SQL Hint,
强制MySQL 使用Query Cache,从而提升该表的查询性能。
最后,有些SQL 的Result Set 很大,若是使用Query Cache 很容易形成Cache 内存的不足,或者将
以前一些老的Cache 冲刷出去。对于这一类Query 咱们有两种方法能够解决,一是使用SQL_NO_CACHE 参
数来强制他不使用Query Cache 而每次都直接从实际数据中去查找, 另外一种方法是经过设定
“query_cache_limit”参数值来控制Query Cache 中所Cache 的最大Result Set ,系统默认为
1M(1048576)。当某个Query 的Result Set 大于“query_cache_limit”所设定的值的时候,Query
Cache 是不会Cache 这个Query 的。

(13)、innodb_buffer_pool_size

innodb_buffer_pool_size 定义了 InnoDB 存储引擎的表数据和索引数据的最大内存缓冲区大小。和 MyISAM 存储引擎不一样, MyISAM 的 key_buffer_size 只能缓存索引键,而 innodb_buffer_pool_size 却能够缓存数据块和索引键。适当的增长这个参数的大小,能够有效的减小 InnoDB 类型的表的磁盘 I/O 。在一个以 InnoDB 为主的专用数据库服务器上,能够考虑把该参数设置为物理内存大小的 60%-80%

 

InnoDB占用的内存,除innodb_buffer_pool_size用于存储页面缓存数据外,另外正常状况下还有大约8%的开销,主要用在每一个缓存页帧的描述、adaptive hash等数据结构,若是不是安全关闭,启动时还要恢复的话,还要另开大约12%的内存用于恢复,二者相加就有差很少21%的开销。

这样,12G的innodb_buffer_pool_size,最多的时候InnoDB就可能占用到14.5G(12G X 21%)的内存,再加上操做系统用的几百M,近千个线程堆栈,就差很少16G了。

 

MAX_QUERIES_PER_HOUR 用来限制用户每小时运行的查询数量:

mysql> grant all on dbname。* to db@localhost identified by “123456” with max_connections_per_hour 5;

(db用户在dbname的数据库上控制用户每小时打开新链接的数量为5个)

 

MAX_USER_CONNECTIONS 限制有多少用户链接MYSQL服务器:

mysql> grant all on dbname。* to db@localhost identified by “123456” with max_user_connections 2;

(db用户在dbname的数据库帐户一次能够同时链接的最大链接数为2个)


MAX_UPDATES_PER_HOUR 用来限制用户每小时的修改数据库数据的数量:

mysql> grant all on dbname。* to db@localhost identified by “123456” with max_updates_per_hour 5;

(db用户在dbname的数据库上控制用户每小时修改更新数据库的次数为5次)

MAX_USER_CONNECTIONS 用来限制用户每小时的修改数据库数据的数量:

mysql> grant all on dbname。* to db@localhost identified by “123456”

With MAX_QUERIES_PER_HOUR 20 ;指mysql单个用户的最大链接数

(db用户在dbname的数据库上控制用户每小时的链接数为20个)

 

调优举例

针对my.cnf文件进行优化:

[mysqld]

skip-locking(取消文件系统的外部锁)

skip-name-resolve(不进行域名反解析,注意由此带来的权限/受权问题)
key_buffer_size = 256M(分配给MyISAM索引缓存的内存总数)对于内存在4GB左右的服务器该参数可设置为256M或384M。
  注意:该参数值设置的过大反而会是服务器总体效率下降!
  max_allowed_packet = 4M(容许最大的包大小)
  thread_stack = 256K(每一个线程的大小)
  table_cache = 128K(缓存可重用的线程数)
  back_log = 384(临时中止响应新请求前在短期内能够堆起多少请求,若是你须要在短期内容许大量链接,能够增长该数值)
  sort_buffer_size = 2M(分配给每一个线程中处理排序)
  read_buffer_size = 2M(读取的索引缓冲区大小)
  join_buffer_size = 2M(分配给每一个线程中处理扫描表链接及索引的内存)
  myisam_sort_buffer_size = 64M(myisam引擎排序缓冲区的大小)
  table_cache = 512(缓存数据表的数量,避免重复打开表的开销)
  thread_cache_size = 64(缓存可重用线程数,见笑建立新线程的开销)
  query_cache_size = 64M(控制分配给查询缓存的内存总量)
  tmp_table_size = 256M(指定mysql缓存的内存大小)
  max_connections = 768(最大链接数)指mysql整个的最大链接数
max_connect_errors = 10000(最大链接错误数据)
  wait_timeout = 10(超时时间,能够避免攻击)
  thread_concurrency = 8(根据cpu数量来设置)
  skip-bdb 禁用没必要要的引擎
  skip-networking(关闭mysql tcp/ip链接方式)
  Log-slow-queries = /var/log/mysqlslowqueries.log
  long_query_time = 4(设定慢查询的时间)
  skip-host-cache(提升mysql速度的)
  open_files_limit = 4096(打开文件数)
interactive_timeout = 10(服务器在关闭它前在一个交互链接上等待行动的秒数)
max_user_connections = 500(最大用户链接数)

 

key_buffer_size                 默认为218       调到128最佳

query_cache_size  

tmp_table_size                  默认为16M        调到64-256最挂

innodb_thread_concurrency=8       你的服务器CPU有几个就设置为几,默认为8

 

table_cache=1024 物理内存越大,设置就越大.默认为2402,调到512-1024最佳
innodb_additional_mem_pool_size=8M   默认为2M
innodb_flush_log_at_trx_commit=0 等到innodb_log_buffer_size列队满后再统一储存,默认为1
innodb_log_buffer_size=4M          默认为1M

read_buffer_size=4M                   默认为64K
read_rnd_buffer_size   随机读 缓存区  默认为256K
sort_buffer_size=32M                   默认为256K
max_connections=1024                 默认为1210

thread_cache_size=120             默认为60

性能测试

一、mysql 自带测试工具

shell> perl -MCPAN -e shell
cpan> install DBI
cpan> install DBD::mysql

shell> cd sql-bench

shell> perl run-all-tests --server=server_name

server_name是一个支持的服务器。要得到全部选项和支持的服务器,调用命令:

shell> perl run-all-tests --help

二、mysqlreport

 http://hackmysql.com/mysqlreport

参考文档

http://dev.mysql.com/doc/refman/5.1/zh/optimization.html

http://hackmysql.com/tools

http://www.imysql.cn/

相关文章
相关标签/搜索