PUB:20150626 15 Useful MySQL or MariaDB Performance Tuning and Optimization Tips

@strugglingyouth @ictlyh
This commit is contained in:
wxy 2015-06-30 23:38:55 +08:00
parent 4943523c0b
commit d293d68f5d

View File

@ -1,16 +1,16 @@
15 个有用的 MySQL/MariaDB 性能调整和优化技巧
================================================================================
MySQL 是一个强大的开源关系数据库管理系统或简称 RDBMS。它于 1995 年发布20年前。它采用结构化查询语言这可能是数据库内容管理中最流行的选择。最新的 MySQL 版本是5.6.25,于 2015 年 5 月 29 日发行
MySQL 是一个强大的开源关系数据库管理系统(简称 RDBMS。它发布于 1995 年20年前。它采用结构化查询语言SQL这可能是数据库内容管理中最流行的选择。最新的 MySQL 版本是 5.6.25,于 2015 年 5 月 29 日发布
关于 MySQL 一个有趣的事实是它的名字来自于 Michael WideniusMySQL 的创始人)的女儿。尽管有许多关于 MySQL 有趣的传闻,本文旨在向你展示一些有用的实践,以帮助你管理你的 MySQL 服务器。
关于 MySQL 一个有趣的事实是它的名字来自于 Michael WideniusMySQL 的创始人)的女儿“ My”。尽管有许多关于 MySQL 有趣的传闻,不过本文主要是向你展示一些有用的实践,以帮助你管理你的 MySQL 服务器。
![MySQL 性能优化](http://www.tecmint.com/wp-content/uploads/2015/06/MySQL-Performance-Tuning1.png)
MySQL 性能优化
*MySQL 性能优化*
2009 年 4 月MySQL 被 Oracle 收购。其结果是成立了一个叫 MariaDB 的 MySQL 社区。创建的主要原因是为了保持 MySQL 项目在通用公共许可证下自由。
2009 年 4 月MySQL 被 Oracle 收购。其结果是MySQL 社区分裂,创建了一个叫 MariaDB 的分支 。创建该分支的主要原因是为了保持这个项目可以在 GPL 下的自由。
今天MySQL 和 MariaDB 是用于类似 WordPress、Joomla、Magento 和其他 web 应用程序最广泛的 RDMS 之一(如果不是最多的)。
今天MySQL 和 MariaDB 是用于类似 WordPress、Joomla、Magento 和其他 web 应用程序的最流行的 RDMS 之一(如果不是最多的)。
这篇文章将告诉你一些基本的,但非常有用的关于如何优化 MySQL/MariaDB 性能的技巧。注意,本文假定您已经安装了 MySQL 或 MariaDB。如果你仍然不知道如何在系统上安装它们你可以按照以下说明去安装
@ -21,34 +21,34 @@ MySQL 性能优化
- [在 Gentoo Linux 上安装 MariaDB][5]
- [在 Arch Linux 上安装 MariaDB][6]
**重要** 在开始之前,不要盲目的接受这些建议。每个 MySQL 设置都是不同的,在进行任何更改之前需要慎重考虑。
**重要提示** 在开始之前,不要盲目的接受这些建议。每个 MySQL 设置都是不同的,在进行任何更改之前需要慎重考虑。
你需要明白这些:
- MySQL/MariaDB 配置文件位于 `/etc/my.cnf`。 每次更改此文件后你需要重启 MySQL 服务,以使更改生效。
- 这篇文章使用 MySQL 5.6 版本。
### 1. 启用 InnoDB 的 file-per-table ###
### 1. 启用 InnoDB 的每张表一个数据文件设置 ###
首先,解释清楚 InnoDB 是一个存储引擎很重要。MySQL 和 MariaDB 使用 InnoDB 作为默认存储引擎。以前MySQL 使用系统表空间来保存数据库中的表和索引。这意味着服务器唯一的目的就是数据库处理,它们的存储盘不用于其它目的。
首先,有一个重要的解释, InnoDB 是一个存储引擎。MySQL 和 MariaDB 使用 InnoDB 作为默认存储引擎。以前MySQL 使用系统表空间来保存数据库中的表和索引。这意味着服务器唯一的目的就是数据库处理,它们的存储盘不用于其它目的。
InnoDB 提供了更灵活的方式,它把每个数据库的信息保存在一个 `.ibd` 数据文件中。每个 .idb 文件表它自己的表空间。通过这样的方式可以更快地完成类似 “TRUNCATE” 的数据库操作,当删除或截断一个数据库表时,你也可以回收未使用的空间。
InnoDB 提供了更灵活的方式,它把每个数据库的信息保存在一个 `.ibd` 数据文件中。每个 .idb 文件表它自己的表空间。通过这样的方式可以更快地完成类似 “TRUNCATE” 的数据库操作,当删除或截断一个数据库表时,你也可以回收未使用的空间。
这样配置的另一个好处是你可以在一个单独的存储设备保留某些数据库表。这可以大大提高你磁盘的 I/O 负载。
这样配置的另一个好处是你可以将某些数据库表放在一个单独的存储设备。这可以大大提升你磁盘的 I/O 负载。
MySQL 5.6及以上的版本默认启用 `innodb_file_per_table`。你可以在 /etc/my.cnf 文件中看到。该指令看起来是这样的:
innodb_file_per_table=1
### 2. 在独立分区上保存 MySQL 数据库数据 ###
### 2. 将 MySQL 数据库数据存储到独立分区上 ###
**注意**:此设置只在 MySQL 上有效, 在 MariaDB 上无效。
有时候操作系统的读/写会降低你 MySQL 服务器的性能,尤其是如果位于同一块磁盘上。因此,我建议你使用单独的磁盘(最好是 SSD用于 MySQL 服务。
有时候操作系统的读/写会降低你 MySQL 服务器的性能,尤其是如果操作系统和数据库的数据位于同一块磁盘上。因此,我建议你使用单独的磁盘(最好是 SSD用于 MySQL 服务。
要完成这步,你需要将新的磁盘连接到你的计算机/服务器上。对于这篇文章,我假定磁盘挂在到 /dev/sdb。
下一步是准备新的分区:
####下一步是准备新的分区:
# fdisk /dev/sdb
@ -70,7 +70,9 @@ MySQL 5.6及以上的版本默认启用 `innodb_file_per_table`。你可以在 /
/dev/sdb1 /ssd ext3 defaults 0 0
现在我们移动 MySQL 到新磁盘中。首先停止 MySQL 服务:
####现在我们将 MySQL 移动到新磁盘中
首先停止 MySQL 服务:
# service mysqld stop
@ -101,12 +103,12 @@ MySQL 5.6及以上的版本默认启用 `innodb_file_per_table`。你可以在 /
### 3. 优化使用 InnoDB 的缓冲池 ###
InnoDB 引擎在内存中有一个缓冲池用于缓存数据和索引。这当然有助于你更快地执行 MySQL/MariaDB 查询语句。选择合适的内存大小需要一些重要的决策并对系统的内存消耗有很好的认识。
InnoDB 引擎在内存中有一个缓冲池用于缓存数据和索引。这当然有助于你更快地执行 MySQL/MariaDB 查询语句。选择合适的内存大小需要一些重要的决策并对系统的内存消耗有较多的认识。
下面是你需要考虑的:
- 其它的进程需要消耗多少内存。这包括你的系统进程,页表,套接字缓冲。
- 你的服务器是否专门用于 MySQL 还是你运行其它非常消耗内存的服务。
- 你的服务器是否专门用于 MySQL 还是你运行其它非常消耗内存的服务。
在一个专用的机器上,你可能会把 60-70 的内存分配给 `innodb_buffer_pool_size`。如果你打算在一个机器上运行更多的服务,你应该重新考虑专门用于 `innodb_buffer_pool_size` 的内存大小。
@ -116,9 +118,9 @@ InnoDB 引擎在内存中有一个缓冲池用于缓存数据和索引。这当
### 4. 在 MySQL 中避免使用 Swappiness ###
Swapping 是一个当系统移动部分内存到一个称为 “swap” 的特殊磁盘空间时运行的进程。通常当你的系统用完物理内存后就会出现这种情况,系统将信息写入磁盘而不是释放一些 RAM。正如你猜测的磁盘比你的 RAM 要慢得多。
“交换”是一个当系统移动部分内存到一个称为 “交换空间” 的特殊磁盘空间时的过程。通常当你的系统用完物理内存后就会出现这种情况,系统将信息写入磁盘而不是释放一些内存。正如你猜测的磁盘比你的内存要慢得多。
默认启用了该选项
该选项默认情况下是启用的
# sysctl vm.swappiness
@ -130,18 +132,18 @@ Swapping 是一个当系统移动部分内存到一个称为 “swap” 的特
### 5. 设置 MySQL 的最大连接数 ###
`max_connections` 指令告诉你当前你的服务器允许多少并发连接。MySQL/ MariaDB 服务器允许有特级权限的用户 max_connections + 1 的连接数。只有当执行 MySQL 查询的时候才会建立连接,执行完成后会关闭连接并被新的连接取代。
`max_connections` 指令告诉你当前你的服务器允许多少并发连接。MySQL/MariaDB 服务器允许有 SUPER 权限的用户在最大连接之外再建立一个连接。只有当执行 MySQL 请求的时候才会建立连接,执行完成后会关闭连接并被新的连接取代。
请记住,太多的连接会导致 RAM 的使用量过高并且会锁住你的 MySQL 服务器。一般小网站需要 100-200 的连接数而较大可能需要 500-800 甚至更多。这里的值很大程度上取决于你 MySQL/MariaDB 的使用情况。
请记住,太多的连接会导致内存的使用量过高并且会锁住你的 MySQL 服务器。一般小网站需要 100-200 的连接数而较大可能需要 500-800 甚至更多。这里的值很大程度上取决于你 MySQL/MariaDB 的使用情况。
你可以动态地改变 `max_connections` 的值而无需重启MySQL服务器
# mysql -u root -p
mysql> set global max_connections := 300;
mysql> set global max_connections = 300;
### 6. 配置 MySQL `thread_cache_size` ###
### 6. 配置 MySQL 的线程缓存数量 ###
`thread_cache_size` 指令用来设置你服务器缓存的线程数量。当客户端断开连接时,如果当前线程数小于thread_cache_size的线程将被放入缓存中。下一个请求通过使用缓存池中的线程来完成。
`thread_cache_size` 指令用来设置你服务器缓存的线程数量。当客户端断开连接时,如果当前线程数小于 `thread_cache_size`,它的线程将被放入缓存中。下一个请求通过使用缓存池中的线程来完成。
要提高服务器的性能,你可以设置 `thread_cache_size` 的值相对高一些。你可以通过以下方法来查看线程缓存命中率:
@ -152,7 +154,7 @@ Swapping 是一个当系统移动部分内存到一个称为 “swap” 的特
100 - ((Threads_created / Connections) * 100)
如果你得到一个较低的数字,这意味着大多数 mysql 连接请求使用新的线程,而不是从缓存加载。在这种情况下,你需要增加 `thread_cache_size`
如果你得到一个较低的数字,这意味着大多数 mysql 连接使用新的线程,而不是从缓存加载。在这种情况下,你需要增加 `thread_cache_size`
这里有一个好处是可以动态地改变 `thread_cache_size` 而无需重启 MySQL 服务。你可以通过以下方式来实现:
@ -170,9 +172,9 @@ Swapping 是一个当系统移动部分内存到一个称为 “swap” 的特
更改后你需要重启 MySQL 服务。
### 8. 配置 MySQL `query_cache_size` ###
### 8. 配置 MySQL 的查询缓存容量 ###
如果你有很多重复的查询并且数据不经常改变 请使用缓存查询。 人们常常不理解 `query_cache_size` 的实际含义而将此值设置为 GB这实际上会降低服务器的性能。
如果你有很多重复的查询并且数据不经常改变 请使用缓存查询。 人们常常不理解 `query_cache_size` 的实际含义而将此值设置为 GB,这实际上会降低服务器的性能。
背后的原因是,在更新过程中线程需要锁定缓存。通常设置为 200-300 MB应该足够了。如果你的网站比较小的你可以尝试给 64M 并在以后及时去增加。
@ -183,11 +185,11 @@ Swapping 是一个当系统移动部分内存到一个称为 “swap” 的特
query_cache_min_res_unit = 2k
query_cache_size = 80M
### 9. 配置 `tmp_table_size``max_heap_table_size` ###
### 9. 配置临时表容量和内存表最大容量 ###
这两个变量的大小应该相同并帮助你避免将数据直接写入到磁盘中去。`tmp_table_size` 是内置内存表的最大空间。如果表的大小超出限值将会被转换为磁盘上的 MyISAM 表。
`tmp_table_size``max_heap_table_size` 这两个变量的大小应该相同,它们可以让你避免磁盘写入。`tmp_table_size` 是内置内存表的最大空间。如果表的大小超出限值将会被转换为磁盘上的 MyISAM 表。
这会影响数据库的性能。管理员通常建议在服务器上设置这两个值为每 GB RAM 64M。
这会影响数据库的性能。管理员通常建议在服务器上设置这两个值为每 GB 内存给 64M。
[mysqld]
tmp_table_size= 64M
@ -201,17 +203,17 @@ Swapping 是一个当系统移动部分内存到一个称为 “swap” 的特
slow-query-log-file = /var/lib/mysql/mysql-slow.log
long_query_time = 1
第一个变量启用慢查询日志,第二个告诉 MySQL 实际的日志文件存储位置。使用 `long_query_time` 来定义完成 MySQL 查询用时多少认为是长查询
第一个变量启用慢查询日志,第二个告诉 MySQL 实际的日志文件存储位置。使用 `long_query_time` 来定义完成 MySQL 查询多少用时算长
### 11. 检查 MySQL 的空闲连接 ###
空闲连接会消耗资源,可以的话应该被中断或者刷新。空闲连接是指处于 “sleep” 状态并且保持很长一段时间。你可以通过运行以下命令查看空闲连接:
空闲连接会消耗资源,可以的话应该被终止或者刷新。空闲连接是指处于 “sleep” 状态并且保持很长一段时间的连接。你可以通过运行以下命令查看空闲连接:
# mysqladmin processlist -u root -p | grep “Sleep”
这会显示处于睡眠状态的进程列表。当代码使用持久连接到数据库时会出现以下情况。使用 PHP 调用 mysql_pconnect 可以打开这个连接,执行完查询之后,删除认证并保持连接为打开状态。这会导致每个线程的缓冲被保存在内存中,直到该线程死亡
这会显示处于睡眠状态的进程列表。当代码使用持久连接到数据库时会出现这种情况。使用 PHP 调用 mysql_pconnect 可以打开这个连接,执行完查询之后,删除认证信息并保持连接为打开状态。这会导致每个线程的缓冲都被保存在内存中,直到该线程结束
首先你要做的就是检查代码并修复它。如果你不能访问正在运行的代码,你可以修改 `wait_timeout` 变量。默认值是 28800 秒,而你可以安全地将其降低到 60
首先你要做的就是检查代码问题并修复它。如果你不能访问正在运行的代码,你可以修改 `wait_timeout` 变量。默认值是 28800 秒,而你可以安全地将其降低到 60
wait_timeout=60
@ -219,43 +221,21 @@ Swapping 是一个当系统移动部分内存到一个称为 “swap” 的特
选择正确的文件系统对数据库至关重要。在这里你需要考虑的最重要的事情是 - 数据的完整性,性能和易管理性。
按照 MariaDB 的建议最好的文件系统是XFS、ext4 和 Btrfs。它们都是可以使用超大文件和大容量存储卷的企业级日志文件系统。
按照 MariaDB 的建议最好的文件系统是XFS、ext4 和 Btrfs。它们都是可以使用超大文件和大容量存储卷的企业级日志文件系统。
下面你可以找到一些关于这三个文件系统的有用信息:
注:表格
<table cellspacing="0" border="0">
<colgroup width="179"></colgroup>
<colgroup width="85" span="3"></colgroup>
<tbody>
<tr>
<td align="center" height="18" style="border: 1px solid #000000;"><b><span style="color: black; font-family: Arial;">Filesystems</span></b></td>
<td align="center" style="border: 1px solid #000000;"><b><span style="color: black; font-family: Arial;">XFS</span></b></td>
<td align="center" style="border: 1px solid #000000;"><b><span style="color: black; font-family: Arial;">Ext4</span></b></td>
<td align="center" style="border: 1px solid #000000;"><b><span style="color: black; font-family: Arial;">Btrfs</span></b></td>
</tr>
<tr class="alt">
<td align="center" height="18" style="border: 1px solid #000000;"><span style="color: black; font-family: Arial;">Maximum filesystem size</span></td>
<td align="center" style="border: 1px solid #000000;"><span style="color: black; font-family: Arial;">8EB</span></td>
<td align="center" style="border: 1px solid #000000;"><span style="color: black; font-family: Arial;">1EB</span></td>
<td align="center" style="border: 1px solid #000000;"><span style="color: black; font-family: Arial;">16EB</span></td>
</tr>
<tr>
<td align="center" height="18" style="border: 1px solid #000000;"><span style="color: black; font-family: Arial;">Maximum file size</span></td>
<td align="center" style="border: 1px solid #000000;"><span style="color: black; font-family: Arial;">8EB</span></td>
<td align="center" style="border: 1px solid #000000;"><span style="color: black; font-family: Arial;">16TB</span></td>
<td align="center" style="border: 1px solid #000000;"><span style="color: black; font-family: Arial;">16EB</span></td>
</tr>
</tbody>
</table>
| 文件系统 | XFS | Ext4 | Btrfs |
|---------------|-----|------|-------|
| 文件系统最大容量 | 8EB | 1EB | 16EB |
| 最大文件大小 | 8EB | 16TB | 16EB |
我们的这篇文章详细介绍了 Linux 文件系统的利与弊:
- [Linux 文件系统解析][7]
我们的这篇文章详细介绍了 Linux 文件系统的利与弊: [Linux 文件系统解析][7]。
### 13. 设置 MySQL `max_allowed_packet` ###
### 13. 设置 MySQL 允许的最大数据包 ###
MySQL 把数据拆分成包。通常发送到客户端的一行作为一个包。`max_allowed_packet` 变量定义了可以被发送的最大的包。
MySQL 把数据拆分成包。通常一个包就是发送到客户端的一行数据。`max_allowed_packet` 变量定义了可以被发送的最大的包。
此值设置得过低可能会导致查询速度变得非常慢,然后你会在 MySQL 的错误日志看到一个错误。建议将该值设置为最大包的大小。