testing-04

MySQL

  • 使用pt-stalk诊断MySQL问题

    ·

    在MySQL服务器出现短暂(5~30秒)的性能波动的时候,一般的性能监控工具都很难抓住故障现场,也就很难收集对应较细粒度的诊断信息。另外,如果这种波动出现的频率很低,例如几天才一次,我们也很难人为的抓住现场,收集数据。这正是pt-stalk所解决的问题。

    pt-stalk是Percona-Toolkit的一部分(其前身是Aspersa的一部分)。安装Percona-Toolkit后,可以通过man pt-stalk了解如何使用该工具,本文的介绍是man pt-stalk的一个子集,强烈建议直接阅读man pt-stalk。额外的,本文将提供pt-stalk示例命令可供参考。

    1. 使用pt-stalk

    pt-stalk --collect-tcpdump --function status \
    --variable Threads_connected --threshold 2500 \
    --daemonize -- --user=root --password=YOURPASSWORD

    上面的命令表示,让pt-stalk后台运行(–daemonize),并监视SHOW GLOBAL STATUS中的Threads_connected状态值,如果该值超过2500,则触发收集主机和MySQL的性能、状态信息。pt-stalk会每隔一秒检查一次状态值,如果连续5次满足触发条件,则开始收集。

    –collect-tcpdump表示除了收集基本信息外,还将额外使用tcpdump收集当时的网络包,类似的还可以使用–collect-gdb等。

    (more…)
  • MySQL/InnoDB和Group Commit(2)

    ·

    今天发现Percona Release的Percona-Server-5-5-18-23-0已经完成了Group Commit工作,而且是用最优雅的方式(移植了MariaDB的实现,而不是workaround),心里难掩激动。

    这篇文章接前篇继续介绍一下问题的背景:什么是Group Commit,现在的官方版本Group Commit做到了什么程度?

    1. 什么是Group Commit

    MySQL/InnoDB在做事务的时候使用的日志先行(Write-ahead logging)的方式保证事务的快速和持久,所以每次事务完成都要求日志必须持久化到磁盘,在Linux上对应的操作就是“write and fsync”,write速度是很快的,一般对应的写Page Cache,而fsync则要求文件系统把对应文件的哦Page Cache必须持久化到磁盘上,而对于传统磁盘一次写操作大约需要1~3ms(不说BBU),这意味着对于传统磁盘1秒钟最多最多做333~1000个事务,这是不理想的,对硬件的利用率(吞吐量)也是非常低。

    所以,这里就有了Group操作的概念,即当好几个线程都要fsync同一个日志文件时,我们将这些fsync合并到一次来做。简单举例:我们让系统每2ms做一次fsync,这样如果这2ms内有100个线程都需要做fsync,那就赚到了,原本100个fsync都独立来做那耗时会非常多的。

    你肯定会说,难道这不是很简单的想法吗?是的,这就是原本是很简单、也很自然的想法。

    但对MySQL来说却变成了一种奢求(看看这个Bug讨论)。

    2. 为啥MySQL一直没有实现?

    MySQL是不是太弱了,这么简单的事情都搞不定?不是的。

    MySQL从开源到现在,成功的一个非常重要的原因,就是MySQL的插件式架构。如果MySQL只是MyISAM估计不会有现在的流行程度,插件式的架构让诸如Heikki Tuuri有了发挥空间,在InnoDB和MySQL一起时,MySQL才能算是一个真正的DBMS。再到后来,有Infobright、 FEDERATED、PBXT等等。

    插件式的架构给MySQL带来了活力,做出牺牲便是在上层(MySQL)和下层(存储引擎)交互时带来的额外消耗,有时甚至上层和下层需要做一些重复工作。无法做Group Commit就是这其中的牺牲之一。

    (more…)

  • 在Percona的5.1.53和5.5.8版本,开始将RT的统计内置到MySQL Server端。Thanks, Percona.

    Percona在提供了tcprstat工具统计RT时间之后,很快就在Percona Server中集成了响应时间统计的功能。这里介绍一下该功能,各位看官如果在犹豫选择Percona Server还是MySQL Community Server,这里给Percona Server加一个筹码。

    “响应时间”(Response time,后面简称RT)在数据库应用中,特别是OLTP的场景,可以说非常重要,不过,MySQL官方版本中一直没有加上这个统计功能。最早,社区开始尝试tcmdump+perl脚本的方式查看RT,后来告警一点用tcpdump+mk-query-digest,再后来Ignacio Nin和Baron Schwartz完成了tcprstat。

    在Percona的5.1.53和5.5.8版本,开始将RT的统计内置到MySQL Server端。

    1. 配置该功能

    这个是功能默认是关闭的,可以通过设置参数query_response_time_stats=1打开这个功能,这是一个动态参数,所以在服务器上可以很方便的打开或者关闭这个功能。可以通过命令SHOW QUERY_RESPONSE_TIME查看响应时间统计。 (more…)

  • 偶尔我们需要这样做。

    在一台主机上如果复制多个主库,可以很简单:在备库主机上启动多个MySQL实例(mysqld_muilt),每个实例使用一个端口,复制多台主库就可以了。但是如果希望复制过来的数据都在同一个实例中,事情就复杂了。

    1. 问题以及开源社区的尝试

    需求:多个主库都复制到一个备库,复制过来的数据都在一个实例中,这样实现对应用层的透明。目前,MySQL本身不提供这样的功能(考虑过,但一直未实现)。

    1.1 开源社区也有很多方案和想法,例如Tungsten replicator:可以支持异构数据复制,JAVA实现,数据量较大时,性能较差,而且MySQL版本更新较快,而该软件支持较慢;

    1.2 再如P.Linux的尝试:通过拉取多个主库上的Binlog在单个备库上应用的方式,对MySQL没有入侵,实现也较为简单。

    1.3 High Performance MySQL还可以通过多级复制的方式实现:例如有主库DB1、DB2,都需要复制到S1上,则先配置D2复制D1的全部数据,然后再从S1上复制D2的全部数据就可以了。整理需要注意D2上的log-slave-update需要打开,为了减少D2的压力,DB上复制过来的表可以全部使用Blackhole引擎

    1.4 另外,还有一些欠成熟的Patch实现。

    2. MySQL Federated引擎的“软链接”特性

    Federated引擎可以在本地数据库中创建一个远端数据表的“软链接”。这样,访问远端数据表就如同访问本地数据表。(这里远端可以是不同主机上的不同实例)

    se-federated-structure

    3. 使用Federated数据表实现多主一备

    例如,主库DB1,DB2,都需要复制到S1上,这里DB1,DB2,S1分别在主机H1,H2,H3上。首先,在主机H3(S1所在的主机)上其另外起两个MySQL实例S2、S3,分别复制主库DB1和DB2,然后在实例S1上建立多个Federated表关联S2、S3中的数据表(相当于在S1中建立到S2、S3的软连接)。

    Federated-Muilt-master

    这时应用,连接到S1,就可以同时透明的访问到DB1、DB2中的实时数据表了。

    4. 一些说明

    4.1 上面描述的方法,也可以直接在S1上建立到DB1、DB2各个表的软连接,但是为了最大程度的减少对主库的影响,最好如上多配一层备库。

    4.2 最简单的可以直接在备库上配置多个实例,让应用连接多个实例就好了,无需上面这么复制的配置。

    参考文献:

    1. MySQL Manual: The FEDERATED Storage Engine

    2. Post of MySQL Forums : Multiple masters to single slave

    3. 通过tungsten replicator实现mysql多主一从的备份架构

    4. Is it possible to do N-master => 1-slave replication with MySQL

    5. MySQL Multi-Master – Single-Slave – Replication

  • MySQL: Too many connections

    ·

    $mysql -uroot
    ERROR 1040 (00000): Too many connections

    上面的错误,估计很多人都遇到过,Aurimas Mikalauskas在MySQL Performance Blog已经提到了一个解决办法(生产环境慎用之):

    $gdb -p $(cat data/mysql_sandbox5087.pid) \
    -ex “set max_connections=5000” -batch

    上面提到的只是一个救火的办法,MySQL提供了另一个办法,可以一定程度上避免上述问题。

    MySQL提供了参数max_connections控制最大连接数,这包括所有用户的连接数。MySQL还提供了另一个参数max_user_connections,用来控制某个用户的最大连接数。例如,将该参数设置为50,那么对于任何一个用户(包括super权限的用户),最多只能创建50个连接。 (more…)

  • MySQL/InnoDB和Group Commit(1)

    ·

    估计相关的东西一篇文章是讲不清楚的。

    这个问题由来已久,Kristian Nielsen连续写了四篇文章《Fixing MySQL group commit》(part 1 | part 2 | part 3 | part 4 )深入细致的分析了“故事”的前因后果。本文完全没有任何新意,仅做一个小的总结。这里会先介绍一下什么是“Group Commit”,MySQL/InnoDB里面的Group Commit为什么引起如此大的关注,现在是怎么解决问题的。 (more…)