扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
捕获诊断数据( )
创新互联是专业的南京网站建设公司,南京接单;提供做网站、成都网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行南京网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
堆栈需要自下而上来看 也就是说 线程当前正在执行的是pthread_cond_wait 函数 这是由os_event_wait_low 调用的 继续往下 看起来是线程试图进入到InnoDB 内核(srv_conc_enter_innodb) 但被放入了一个内部队列中(os_event_wait_low) 原因应该是内核中的线程数已经超过innodb_thread_concurrency 的限制 当然 要真正地发挥堆栈跟踪的价值需要将很多的信息聚合在一起来看 这种技术是由Domas Mituzas推广的 他以前是MySQL 的支持工程师 开发了著名的穷人剖析器 poor man sprofiler 他目前在Facebook 工作 和其他人一起开发了更多的收集和分析堆栈跟踪的工具 可以从他的这个网站发现更多的信息 // poormansprofiler
在Percona Toolkit 中我们也开发了一个类似的穷人剖析器 叫做pt pmp 这是一个用shell 和awk 脚本编写的工具 可以将类似的堆栈跟踪输出合并到一起 然后通过sort|uniq|sort 将最常见的条目在最前面输出 下面是一个堆栈跟踪的完整例子 通过此工具将重要的信息展示了出来 使用了 l 选项指定了堆栈跟踪不超过 层 以免因太多前面部分相同而后面部分不同的跟踪信息而导致无法聚合到一起的情况 这样才能更好地显示到底在哪里产生了等待
$ pt pmp l stacktraces txt
pthread_cond_wait one_thread_per_connection_end handle_one_connection
start_thread clone
pthread_cond_wait os_event_wait_low srv_conc_enter_innodb
innodb_srv_conc_enter_innodb ha_innodb::index_read
pthread_cond_wait os_event_wait_low sync_array_wait_event mutex_spin_wait
mutex_enter_func
pthread_cond_wait os_event_wait_low os_aio_simulated_handle fil_aio_wait
io_handler_thread
pthread_cond_wait os_event_wait_low srv_conc_enter_innodb
innodb_srv_conc_enter_innodb ha_innodb::general_fetch
pthread_cond_wait os_event_wait_low sync_array_wait_event rw_lock_s_lock_spin
rw_lock_s_lock_func
sigwait signal_hand start_thread clone ??
select os_thread_sleep srv_lock_timeout_and_monitor_thread start_thread clone
select os_thread_sleep srv_error_monitor_thread start_thread clone
select handle_connections_sockets main
read vio_read_buff ::?? my_net_read cli_safe_read
pthread_cond_wait os_event_wait_low sync_array_wait_event rw_lock_x_lock_low
rw_lock_x_lock_func
pthread_cond_wait MYSQL_BIN_LOG::wait_for_update mysql_binlog_send
dispatch_mand do_mand
fsync os_file_fsync os_file_flush fil_flush log_write_up_to
第一行是MySQL 中非常典型的空闲线程的一种特征 所以可以忽略 第二行才是最有意思的地方 看起来大量的线程正在准备进入到InnoDB 内核中 但都被阻塞了 从第三行则可以看到许多线程都在等待某些互斥锁 但具体的是什么锁不清楚 因为堆栈跟踪更深的层次被截断了 如果需要确切地知道是什么互斥锁 则需要使用更大的 l 选项重跑一次 一般来说 这个堆栈跟踪显示很多线程都在等待进入到InnoDB 这是为什么呢?这个工具并不清楚 需要从其他的地方来入手
从前面的堆栈跟踪和oprofile 报表来看 如果不是MySQL 和InnoDB 源码方面的专家 这种类型的分析很难进行 如果用户在进行此类分析时碰到问题 通常需要求助于这样的专家才行
在下面的例子中 通过剖析和等待分析都无法发现服务器的问题 需要使用另外一种不同的诊断技术
返回目录 高性能MySQL
编辑推荐
ASP NET开发培训视频教程
数据仓库与数据挖掘培训视频教程
lishixinzhi/Article/program/MySQL/201311/29698
一个诊断案例( )
我们看到了两种可能性 要么是数据库导致了I/O(如果能找到源头的话 那么可能就找到了问题的原因) 要么不是数据库导致了所有的I/O 而是其他什么导致的 而系统因为缺少I/O 资源影响了数据库性能 我们也很小心地尽力避免引入另外一个隐式的假设 磁盘很忙并不一定意味着MySQL 会有问题 要记住 这个服务器主要的压力是内存读取 所以也很可能出现磁盘长时间无法响应但没有造成严重问题的现象
如果你一直跟随我们的推理逻辑 就可以发现还需要回头检查一下另外一个假设 我们已经知道磁盘设备很忙 因为其等待时间很高 对于固态硬盘来说 其I/O 平均等待时间一般不会超过 / 秒 实际上 从iostat 的输出结果也可以发现磁盘本身的响应还是很快的 但请求在块设备队列中等待很长的时间才能进入到磁盘设备 但要记住 这只是iostat 的输出结果 也可能是错误的信息
究竟是什么导致了性能低下?
当一个资源变得效率低下时 应该了解一下为什么会这样 有如下可能的原因
资源被过度使用 余量已经不足以正常工作
资源没有被正确配置
资源已经损坏或者失灵
回到上面的例子中 iostat 的输出显示可能是磁盘的工作负载太大 也可能是配置不正确(在磁盘响应很快的情况下 为什么I/O 请求需要排队这么长时间才能进入到磁盘?) 然而 比较系统的需求和现有容量对于确定问题在哪里是很重要的一部分 大量的基准测试证明这个客户使用的这种SSD 是无法支撑几百MB/s 的写操作的 所以 尽管iostat 的结果表明磁盘的响应是正常的 也不一定是完全正确的 在这个案例中 我们没有办法证明磁盘的响应比iostat 的结果中所说的要慢 但这种情况还是有可能的 所以这不能改变我们的看法 可能是磁盘被滥用注 或者是错误的配置 或者两者兼而有之 是性能低下的罪魁祸首
在检查过所有诊断数据之后 接下来的任务就很明显了 测量出什么导致了I/O 消耗 不幸的是 客户当前使用的GNU/Linux 版本对此的支持不力 通过一些工作我们可以做一些相对准确的猜测 但首先还是需要探索一下其他的可能性 我们可以测量有多少I/O来自MySQL 但客户使用的MySQL 版本较低以致缺乏一些诊断功能 所以也无法提供确切有利的支持
作为替代 基于我们已经知道MySQL 如何使用磁盘 我们来观察MySQL 的I/O 情况 通常来说 MySQL 只会写数据 日志 排序文件和临时表到磁盘 从前面的状态计数器和其他信息来看 首先可以排除数据和日志的写入问题 那么 只能假设MySQL 突然写入大量数据到临时表或者排序文件 如何来观察这种情况呢?有两个简单的方法 一是观察磁盘的可用空间 二是通过lsof 命令观察服务器打开的文件句柄 这两个方法我们都采用了 结果也足以满足我们的需求 下面是问题期间每秒运行df–h 的结果
下面则是lsof 的数据 因为某些原因我们每五秒才收集一次 我们简单地将mysqld 在/tmp 中打开的文件大小做了加总 并且把总大小和采样时的时间戳一起输出到结果文件中
$ awk
/mysqld *tmp/ {
total += $ ;
}
/^Sun Mar / total {
printf %s % f MB\n $ total/ / ;
total = ;
} lsof txt
: : MB
: : MB
: : MB
: : MB
: : MB
从这个数据可以看出 在问题之初MySQL 大约写了 GB 的数据到临时表 这和之前在SHOW PROCESSLIST 中有大量的 Copying to tmp table 相吻合 这个证据表明可能是某些效率低下的查询风暴耗尽了磁盘资源 根据我们的工作直觉 出现这种情况比较普遍的一个原因是缓存失效 当memcached 中所有缓存的条目同时失效 而又有很多应用需要同时访问的时候 就会出现这种情况 我们给开发人员出示了部分采样到的查询 并讨论这些查询的作用 实际情况是 缓存同时失效就是罪魁祸首(这验证了我们的直觉) 一方面开发人员在应用层面解决缓存失效的问题 另一方面我们也修改了查询 避免使用磁盘临时表 这两个方法的任何一个都可以解决问题 当然最好是两个都实施
返回目录 高性能MySQL
编辑推荐
ASP NET开发培训视频教程
数据仓库与数据挖掘培训视频教程
lishixinzhi/Article/program/MySQL/201311/29695
测试何种指标
在开始执行甚至是在设计基准测试之前 需要先明确测试的目标 测试目标决定了选择什么样的测试工具和技术 以获得精确而有意义的测试结果 可以将测试目标细化为一系列的问题 比如 这种CPU 是否比另外一种要快? 或 新索引是否比当前索引性能更好?
有时候需要用不同的方法测试不同的指标 比如 针对延迟(latency)和吞吐量(throughput)就需要采用不同的测试方法
请考虑以下指标 看看如何满足测试的需求
吞吐量
吞吐量指的是单位时间内的事务处理数 这一直是经典的数据库应用测试指标 一些标准的基准测试被广泛地引用 如TPC C(参考// tpc ) 而且很多数据库厂商都努力争取在这些测试中取得好成绩 这类基准测试主要针对在线事务处理(OLTP)的吞吐量 非常适用于多用户的交互式应用 常用的测试单位是每秒事务数(TPS) 有些也采用每分钟事务数(TPM)
响应时间或者延迟
这个指标用于测试任务所需的整体时间 根据具体的应用 测试的时间单位可能是微秒 毫秒 秒或者分钟 根据不同的时间单位可以计算出平均响应时间 最小响应时间 最大响应时间和所占百分比 最大响应时间通常意义不大 因为测试时间越长 最大响应时间也可能越大 而且其结果通常不可重复 每次测试都可能得到不同的最大响应时间 因此 通常可以使用百分比响应时间(percentile responsetime)来替代最大响应时间 例如 如果 % 的响应时间都是 毫秒 则表示任务在 % 的时间段内都可以在 毫秒之内完成
使用图表有助于理解测试结果 可以将测试结果绘制成折线图(比如平均值折线或者 % 百分比折线)或者散点图 直观地表现数据结果集的分布情况 通过这些图可以发现长时间测试的趋势 本章后面将更详细地讨论这一点
并发性
并发性是一个非常重要又经常被误解和误用的指标 例如 它经常被表示成多少用户在同一时间浏览一个Web 站点 经常使用的指标是有多少个会话注 然而 HTTP协议是无状态的 大多数用户只是简单地读取浏览器上显示的信息 这并不等同于Web 服务器的并发性 而且 Web 服务器的并发性也不等同于数据库的并发性 而仅仅只表示会话存储机制可以处理多少数据的能力 Web 服务器的并发性更准确的度量指标 应该是在任意时间有多少同时发生的并发请求
在应用的不同环节都可以测量相应的并发性 Web 服务器的高并发 一般也会导致数据库的高并发 但服务器采用的语言和工具集对此都会有影响 注意不要将创建数据库连接和并发性搞混淆 一个设计良好的应用 同时可以打开成百上千个MySQL 数据库服务器连接 但可能同时只有少数连接在执行查询 所以说 一个Web 站点 同时有 个用户 访问 却可能只有 ~ 个并发请求到MySQL 数据库
换句话说 并发性基准测试需要关注的是正在工作中的并发操作 或者是同时工作中的线程数或者连接数 当并发性增加时 需要测量吞吐量是否下降 响应时间是否变长 如果是这样 应用可能就无法处理峰值压力
并发性的测量完全不同于响应时间和吞吐量 它不像是一个结果 而更像是设置基准测试的一种属性 并发性测试通常不是为了测试应用能达到的并发度 而是为了测试应用在不同并发下的性能 当然 数据库的并发性还是需要测量的 可以通过sy *** ench 指定 或者 个线程的测试 然后在测试期间记录MySQL 数据库的Threads_running 状态值 在第 章将讨论这个指标对容量规划的影响
可扩展性
在系统的业务压力可能发生变化的情况下 测试可扩展性就非常必要了 第 章将更进一步讨论可扩展性的话题 简单地说 可扩展性指的是 给系统增加一倍的工作 在理想情况下就能获得两倍的结果(即吞吐量增加一倍) 或者说 给系统增加一倍的资源(比如两倍的CPU 数) 就可以获得两倍的吞吐量 当然 同时性能(响应时间)也必须在可以接受的范围内 大多数系统是无法做到如此理想的线性扩展的 随着压力的变化 吞吐量和性能都可能越来越差
可扩展性指标对于容量规范非常有用 它可以提供其他测试无法提供的信息 来帮助发现应用的瓶颈 比如 如果系统是基于单个用户的响应时间测试(这是一个很糟糕的测试策略)设计的 虽然测试的结果很好 但当并发度增加时 系统的性能有可能变得非常糟糕 而一个基于不断增加用户连接的情况下的响应时间测试则可以发现这个问题
一些任务 比如从细粒度数据创建汇总表的批量工作 需要的是周期性的快速响应时间 当然也可以测试这些任务纯粹的响应时间 但要注意考虑这些任务之间的相互影响 批量工作可能导致相互之间有影响的查询性能变差 反之亦然
归根结底 应该测试那些对用户来说最重要的指标 因此应该尽可能地去收集一些需求 比如 什么样的响应时间是可以接受的 期待多少的并发性 等等 然后基于这些需求来设计基准测试 避免目光短浅地只关注部分指标 而忽略其他指标
返回目录 高性能MySQL
编辑推荐
ASP NET开发培训视频教程
数据仓库与数据挖掘培训视频教程
lishixinzhi/Article/program/MySQL/201311/29741
字符串类型( )
MySQL 支持多种字符串类型 每种类型还有很多变种 这些数据类型在 和 版本发生了很大的变化 使得情况更加复杂 从MySQL 开始 每个字符串列可以定义自己的字符集和排序规则 或者说校对规则(collation)(更多关于这个主题的信息请参考第 章) 这些东西会很大程度上影响性能
VARCHAR 和CHAR 类型
VARCHAR 和CHAR 是两种最主要的字符串类型 不幸的是 很难精确地解释这些值是怎么存储在磁盘和内存中的 因为这跟存储引擎的具体实现有关 下面的描述假设使用的存储引擎是InnoDB 和/ 或者MyISAM 如果使用的不是这两种存储引擎 请参考所使用的存储引擎的文档
先看看VARCHAR 和CHAR 值通常在磁盘上怎么存储 请注意 存储引擎存储CHAR 或者VARCHAR 值的方式在内存中和在磁盘上可能不一样 所以MySQL 服务器从存储引擎读出的值可能需要转换为另一种存储格式 下面是关于两种类型的一些比较
VARCHAR
VARCHAR 类型用于存储可变长字符串 是最常见的字符串数据类型 它比定长类型更节省空间 因为它仅使用必要的空间(例如 越短的字符串使用越少的空间) 有一种情况例外 如果MySQL 表使用ROW_FORMAT=FIXED 创建的话 每一行都会使用定长存储 这会很浪费空间
VARCHAR 需要使用 或 个额外字节记录字符串的长度 如果列的最大长度小于或等于 字节 则只使用 个字节表示 否则使用 个字节 假设采用latin 字符集 一个VARCHAR( ) 的列需要 个字节的存储空间 VARCHAR( ) 的列则需要 个字节 因为需要 个字节存储长度信息
VARCHAR 节省了存储空间 所以对性能也有帮助 但是 由于行是变长的 在UPDATE 时可能使行变得比原来更长 这就导致需要做额外的工作 如果一个行占用的空间增长 并且在页内没有更多的空间可以存储 在这种情况下 不同的存储引擎的处理方式是不一样的 例如 MyISAM 会将行拆成不同的片段存储 InnoDB则需要分裂页来使行可以放进页内 其他一些存储引擎也许从不在原数据位置更新数据
下面这些情况下使用VARCHAR 是合适的 字符串列的最大长度比平均长度大很多 列的更新很少 所以碎片不是问题 使用了像UTF 这样复杂的字符集 每个字符都使用不同的字节数进行存储
在 或者更高版本 MySQL 在存储和检索时会保留末尾空格 但在 或更老的版本 MySQL 会剔除末尾空格
InnoDB 则更灵活 它可以把过长的VARCHAR 存储为BLOB 我们稍后讨论这个问题
CHAR
CHAR 类型是定长的 MySQL 总是根据定义的字符串长度分配足够的空间 当存储CHAR 值时 MySQL 会删除所有的末尾空格(在MySQL 和更老版本中VARCHAR也是这样实现的 也就是说这些版本中CHAR 和VARCHAR 在逻辑上是一样的 区别只是在存储格式上) CHAR 值会根据需要采用空格进行填充以方便比较
CHAR 适合存储很短的字符串 或者所有值都接近同一个长度 例如 CHAR 非常适合存储密码的MD 值 因为这是一个定长的值 对于经常变更的数据 CHAR 也比VARCHAR 更好 因为定长的CHAR 类型不容易产生碎片 对于非常短的列 CHAR 比VARCHAR 在存储空间上也更有效率 例如用CHAR( ) 来存储只有Y 和N 的值 如果采用单字节字符集注 只需要一个字节 但是VARCHAR( ) 却需要两个字节 因为还有一个记录长度的额外字节
CHAR 类型的这些行为可能有一点难以理解 下面通过一个具体的例子来说明 首先 我们创建一张只有一个CHAR( ) 字段的表并且往里面插入一些值
当检索这些值的时候 会发现string 末尾的空格被截断了
如果用VARCHAR( ) 字段存储相同的值 可以得到如下结果
数据如何存储取决于存储引擎 并非所有的存储引擎都会按照相同的方式处理定长和变长的字符串 Memory 引擎只支持定长的行 即使有变长字段也会根据最大长度分配最大空间 不过 填充和截取空格的行为在不同存储引擎都是一样的 因为这是在MySQL 服务器层进行处理的
返回目录 高性能MySQL
编辑推荐
ASP NET MVC 框架揭秘
Oracle索引技术
ASP NET开发培训视频教程
lishixinzhi/Article/program/MySQL/201311/29687
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流