《MySQL排错指南》——4.1 物理硬件限制

4.1 物理硬件限制

对性能有不切实际的期望是通常会犯的错。我们要求MySQL服务器在忽略硬件组件延迟的情况下进行优化。因此,理解什么导致了延迟很重要。

下面列出了影响MySQL服务器的硬件资源:

内存
CPU
内核数量
磁盘I/O
网络带宽
我们依次讨论每个细节。

4.1.1 内存

内存对于MySQL是非常宝贵的资源。服务器在没有磁盘交换的情况下运行很快。理想情况是数据驻留在内存中。因此,在物理内存的限制内合理配置缓冲区是非常重要的。关于这一点,1.6.4小节和3.9.3小节提供了更多详细的介绍和指导。

提示 提示

在Linux/UNIX上可以通过vmstat,或者Windows上的任务管理器来查看mysqld是否有大量磁盘交换。

这里列出Linux上一个磁盘交换的例子。重要的部分加粗显示。对于没有磁盘交换的服务器,这些值应该为0:

相关章节讨论了影响内存使用的配置变量。首先计算出MySQL服务器需要用到的最大内存量,基本原则是要保证它小于你的物理内存。当缓冲区大于实际内存时会增加MySQL服务器因为“内存不足”错误而崩溃的风险。

前面的观点可以换一种陈述方式:如果你需要更大的缓冲区,则需要购买更多内存。扩展应用程序时这始终是一个很好的做法。
使用的内存模块支持扩展错误校正(EEC),这样即使内存有一些损坏,MySQL服务器也不会因此崩溃。
关于内存使用的更多内容,可以参考MySQL参考手册中的“MySQL如何使用内存”章节。我就不在此处重复,因为它不涉及任何新排错技巧。

很重要的一点是,当查询的行包含BLOB字段时,内部缓冲区会增长到能存储该值的点,并且存储引擎在查询结束后不会释放内存。需要执行FLUSH TABLE来释放内存。

另一个要点涉及32位和64位架构的不同。虽然32位使用较小的指针大小可以节约内存,但由于操作系统的寻址受限,它在缓冲区大小设置上存在固有的约束。理论上,每个进程在32位系统上的最大可用内存为4GB,实际上在很多系统上这个数值很小。所以如果你想使用的缓冲区在32位系统上超过了这个值,考虑转换到64位架构下。

4.1.2 处理器与内核

MySQL的性能不会随着CPU的速度线性增长。这并不意味着你不能使用一块快的CPU,但不要期望提高CPU速度能像增加内存那样性能会有大幅提升。

然而,当设置一些影响内部线程并发的选项时,内核的数量很重要。如果你没有足够的内核数增加这些值是没有任何意义的。通过使用一款名叫sysbench[1]的基准工具能够轻松说明问题。表4-1显示了在四核机器上的一个测试结果。我使用具有16个线程的OLTP sysbench测试。

表4-1 不同innodb_thread_concurrency值下执行事件消耗的时间(s)

如你所见,在启动8个线程之前测试越运行越快,但随着数值的增加停止了增长。

4.1.3 磁盘I/O

快速磁盘对MySQL性能很重要。磁盘越快,I/O性能越好。

关于磁盘,你需要关注磁盘读延迟(每次读访问需要多长时间)和fsync延迟(每个fsync耗时多少)。

近来固态硬盘(SSD)的性能很好,但不要指望在上面出现奇迹,因为大多数存储引擎是针对硬盘读写优化的。

同样网络存储也是。可以将数据和日志文件放在网络文件系统或者存储上,但这些装置可能会慢于本地磁盘。你需要检查存储是否快速并且可靠,否则,如果由于网络故障引起数据丢失请不要感到意外。

在Linux/UNIX上使用iostat来判断磁盘I/O是否过载。向设备发起的请求平均队列长度正常情况下不会很高。出于同样的目的,你可以在Windows平台上使用perfmon。下面给出iostat的一个输出例子:

以上输出取自mysqld空闲并随后启动一个活跃的I/O作业时。你可以看到avgqu-sz是如何增长的。虽然还不至于带来问题,但我决定在这里通过这个例子来说明当mysqld正在处理它的作业时磁盘I/O活动是如何发生变化的。

除了速度之外,要牢记的是,存储也可能会丢失数据,可能出现只写入一部分页的情况。如果使用InnoDB,为了数据安全通过设置innodb_double_write使用双写缓冲区。同样,为磁盘准备备用电池是很重要的,它可能防止因为电源故障导致的数据丢失。

4.1.4 网络带宽

客户端几乎总是通过网络连接MySQL到服务器的,所以MySQL服务器运行在一个快速的网络环境下是很重要的。

除了网络带宽之外,往返时间(RTT)和往返次数也很重要。RTT指的是客户端发送网络包到服务端返回应答所消耗的时间。主机间隔的距离越长,RTT越高。

也正是因为存在网络带宽和RTT这些原因,如果可以,推荐将客户端和服务器放在同一个本地网络中。

复制也推荐在本地网络中进行。连接到从服务器时可以使用因特网来替代本地内联网,但预期会出现延迟,甚至中继日志数据损坏带来的报错。上面的错误应该在bug #26489 bug修复之后会自动修复,前提是你在5.5版本中配置了relay-log-recovery选项,或者从5.6版本开始使用二进制日志校验和。但由于网络故障主从服务器之间仍然会在重发包上消耗时间。

4.1.5 延迟效应的例子

为了结束本章内容,我用一个小例子来说明硬件延迟是如何影响一条普通的UPDATE查询的。我们使用InnoDB表并将自动提交打开,同时打开二进制日志文件。

这个简单的查询会在下面的情况下遭遇延迟:

  客户端发送命令到服务端历经半个RTT。

  执行UPDATE的WHERE子句,mysqld读磁盘。

  由于自动提交开启mysqld会对此事务做一个fsync调用。

  为写入二进制日志文件Mysqld做一次fsync调用。

  为提交改变mysqld做一次fsync调用。

  客户端收到来自服务器的结果,这是RTT的另一半。

时间: 2024-10-17 05:07:51

《MySQL排错指南》——4.1 物理硬件限制的相关文章

《MySQL排错指南》导读

前言 MySQL排错指南我从2006年5月开始,作为首席技术支持工程师在MySQL AB公司MySQL支持团队的bug校验组工作,然后我到了Sun公司,最后是在Oracle公司.在日常工作中,我经常遇到用户受困于某个问题而不知所措的情况.虽然有已经被证实可用的方法去定位并快速修复问题,但是用户往往很难从大量的信息中筛选出这些可用的信息.尽管有数以千百计的著名书籍.博文和网页都详细介绍了MySQL服务器方方面面的问题,但这正是我感觉困难的地方:这些信息都关注于如何让MySQL服务器正常地工作,而忽

《MySQL排错指南》——第4章 MySQL环境

第4章 MySQL环境 MySQL排错指南MySQL服务器在运行环境中不是孤立的.即使它运行在专用服务器环境中,你依然需要考虑硬件资源和操作系统限制.在共享环境中,MySQL服务器仍然会受到其他进程的影响.关于MySQL操作系统层面的调优,这个主题可以另写一本书了.所以本章不深入讨论,只是从排错角度切入并展开.MySQL的其中一个优势就是能运行在不同环境中,但这也导致了本章很难将其细化说明.最终我决定写下你需要关心的部分,剩下的留给你去查找操作系统对应的手册来决定如何调优.

《MySQL排错指南》——第1章 基础

第1章 基础 MySQL排错指南当解决疑难问题的时候,为了节约时间,你可以从最简单的情况开始,然后一步步从简入繁.在MySQL支持团队工作的时候,我每个月解决成百上千的问题.其中的大部分都是从零散的请求信息开始的,最终的解决方案可能也很基础,我们将会从一些示例中看到这点.不过有些时候,我们确实会遭遇很大的挑战.所以,我们应时刻牢记从最基础的开始. 典型的基础类问题不外乎执行一个查询但是返回非预期的结果.这类问题的表现形式可能是很明显的错误,也可能是在你明知有匹配记录的情况下却没有返回结果,或者其

《MySQL排错指南》——1.7 当服务器无响应的时候

1.7 当服务器无响应的时候 有时候,MySQL客户端会收到严重的错误消息"在请求中丢失与服务器的连接"或者"服务器已停止".尽管我希望你永远不会遇到这个错误,但是有所准备总是有好处的.由MySQL安装本身引起的这个问题主要有两个原因:服务器问题(最有可能是崩溃)或者滥用连接选项(通常是超时选项或者max_allowed_packet). 第3章将讨论连接相关的配置.第4章会讨论硬件问题和第三方软件相关的问题.这里简短地介绍一下如果遇到服务器崩溃该做些什么. 首先,

《MySQL排错指南》——1.1 语法错误

1.1 语法错误 这个错误听起来十分简单,但仍可能很难发现.我建议你像处理其他问题一样,非常细心地查找可能出现的SQL语法错误. 类似如下错误,很容易被发现: 在这个示例中,很显然用户少转入了个"m",错误消息也很清楚(输出结果根据页面设置进行宽度调整): 遗憾的是,不是所有的语法错误都这么显而易见.我曾经处理过一个问题,它的查询语句是这样的: 这是一个版本迁移导致的问题:该语句在5.0版本中运行正常,但是在5.1版本中出现错误.问题的原因在于,在5.1版本中,"access

《MySQL排错指南》——1.3 当错误可能由之前的更新引起时

1.3 当错误可能由之前的更新引起时 如果SELECT查询返回了非预期的结果集,这并不总是意味着查询语句本身有错误,也有可能是因为你以为已经进行了插入.更新或者删除等操作,而事实上它们并未生效. 在你调查这种可能之前,你应该先完全仔细检查前一节讨论的SELECT语句编写错误的问题.在SELECT语句编写正确并且能够返回你想要的值的情况下,现在我开始调查由数据本身的问题导致错误的可能性.为了确认问题是由数据本身而非SELECT语句产生的,我尝试精简语句,使其变成某个独立表的简单查询.如果是小表,那

《MySQL排错指南》——1.9 许可问题

1.9 许可问题 MySQL有复杂的权限方案,这使得你可以精确地设置哪些用户和主机可以或不可以执行这个或那个操作.从5.5版本开始,MySQL也有了可插拔式的身份验证模式. 尽管它有很多优势,但是这个方案很复杂.例如,让user1@hostA.user2@hostA和user1@hostB不同会很容易混淆它们的权限.当用户名相同而主机名变化的时候更是如此. MySQL允许在对象和连接层面设置访问规则.可以限制某个用户对于特定的表.列等的访问权限. 用户通常会遇到两类权限问题: 应该有权限连接到服

《MySQL排错指南》——1.2 SELECT返回错误结果

1.2 SELECT返回错误结果 这是用户反馈的另一个非常常见的问题,主要的现象有:用户看不到更新的结果.展示的顺序错误或者查询到了非预期的结果. 这个问题主要有两方面的原因:一方面是你的SELECT查询有误:另一方面是数据库中的数据和你想象的不同.我先介绍第一种情况. 在我规划本节示例的时候,我考虑要么使用真实的示例,要么使用我自己设计的小场景.真实的示例可能占用大量篇幅,但是我自己设计的示例可能对你没有什么帮助,因为没有人会写出那样的代码.因此,我选择使用典型的真实示例作为示例,只是大幅简化

《MySQL排错指南》——1.4 获取查询信息

1.4 获取查询信息 正如前一节看到的一样,数据库会返回一些关于每个查询的重要信息,有些信息直接展现在MySQL的访问客户端中,而有些信息则需要通过如SHOW WARNINGS等命令才能得到.当从应用程序中调用SQL语句的时候,获取这些返回信息并确认没有异常情况发生同样重要.所有语言的MySQL API都提供了获取服务器返回信息的接口.本节将讨论这些接口.这里仅涉及C的API,因为我必须选择一种语言的API,并且大部分其他语言的API都是基于C的API的[2]. 受影响的行数我们从之前见过的输出