Archive for 一月 2012

MySQL group by with rollup的用法

有一位同学通过askdba来询问with rollup的用法

(2012-02-01 15:08:22):
 mysql中有这种用法select ... from table_name  group by a with rollup
"with rollup"是什么意思呢?


GROUP BY Modifiers  官方手册里面对这个rollup有一个专门的页面介绍 地址在这里,说得非常详细,我这里做一个简单的例子重现

建一个简单的表并插入几条简单的数据

CREATE TABLE `t` (
  `id` int(11) DEFAULT NULL,
  `id2` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk
insert into t valeu(11,11),(12,12),(13,13);

先来做一个查询

root@test 03:44:32>select id,sum(id2),avg(id2) from t group by id with rollup;
+------+----------+----------+
| id   | sum(id2) | avg(id2) |
+------+----------+----------+
|   11 |       11 |  11.0000 |
|   12 |       12 |  12.0000 |
|   13 |       13 |  13.0000 |
| NULL |       36 |  12.0000 |
+------+----------+----------+
4 rows in set (0.00 sec)

我们可以看到,对于group by的列,with rollup将不会做任何的操作,而是返回一个NULL,而没有group by的列,则根据前面的avg函数和sum函数做了处理。

再来看另外一个语句,只对一个列做avg

root@test 03:44:36>select id,avg(id2) from t group by id with rollup;
+------+----------+
| id   | avg(id2) |
+------+----------+
|   11 |  11.0000 |
|   12 |  12.0000 |
|   13 |  13.0000 |
| NULL |  12.0000 |
+------+----------+
4 rows in set (0.00 sec)

以前从没留意到有这种用法,这次长见识了。

redhat5 和redhat6 root用户不同的ulimits

以前一直都是用redhat5,redhat6也处于测试阶段,当然也遇到了很多奇奇怪怪的问题,比如之前写的一篇博客,当时候是用root启动了mysqld_unsafe,在mysql的QPS到1W以上后,会出现ERROR 1135 (HY000): Can’t create a new thread (errno 11); 当时候的解决办法是用mysql用户来启动就解决了问题。但因为在系统重启后,如果用sudo  -u mysql来启动的话,脚本会被卡主。

这个问题今天得到了一个稍微深入一点的结论。

首先我们看看这个错误

ERROR 1135 (HY000): Can’t create a new thread (errno 11);
if you are not out of available memory,
you can consult the manual for a possible OS-dependent bug

google类似Can’t create a new thread的错误后,得到的结论是文件描述符不够用,检查了vim /etc/security/limits.conf   的设置,是正常的

vim /etc/security/limits.conf
得到的结果是
root    soft    nofile  65535
root    hard    nofile  65535
admin   soft    nofile  65535
admin   hard    nofile  65535
# End of file
mysql   soft    nproc   65536
mysql   hard    nproc   65536
mysql   soft    nofile  65535
mysql   hard    nofile  65535
但观察了sudo -u root bash -c " ulimit -a " 后,得到 max user processes   (-u) 1024
core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

scheduling priority             (-e) 0

file size               (blocks, -f) unlimited

pending signals                 (-i) 385957

max locked memory       (kbytes, -l) 64

max memory size         (kbytes, -m) unlimited

open files                      (-n) 65535

pipe size            (512 bytes, -p) 8

POSIX message queues     (bytes, -q) 819200

real-time priority              (-r) 0

stack size              (kbytes, -s) 10240

cpu time               (seconds, -t) unlimited

max user processes              (-u) 1024

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited
max user processes              (-u) 1024 和 sudo -u root bash -c " ulimit -u "  一样,都是得到1024的结果
sudo -u root bash -c " ulimit -u "
1024

而在redhat5里面,只要在/etc/security/limits.conf  设置了root    soft    nofile  65535 和root    hard    nofile  65535,对应的uilmit  -u 就会是65535.

和@维西v @tb天羽 搞了几个小时,依然没法成功修改root用户的 max user processes到65535 。后来发现了一篇文章 Know your limits (ulimits)  ,提及到redhat6新增了/etc/security/limits.d/90-nproc.conf,里面的内容是

# Default limit for number of user's processes to prevent

# accidental fork bombs.

# See rhbz #432903 for reasoning.

*          soft    nproc     1024

redhat6下面,root用户使用ulimit -u没法修改

* soft nproc 1024的意思是任何用户的最大max user processes为1024个,其他用户可以通过ulimit -u来修改 ,但root用户则修改不成功,我们这里看一个例子

[yingyuan.ydh@my031226 ~]$ cat /etc/security/limits.d/90-nproc.conf

# Default limit for number of user's processes to prevent

# accidental fork bombs.

# See rhbz #432903 for reasoning.


*          soft    nproc     1024

[yingyuan.ydh@my031226 ~]$ ulimit -u

1024

[yingyuan.ydh@my031226 ~]$ ulimit -u 65535

[yingyuan.ydh@my031226 ~]$ ulimit -u

65535

[yingyuan.ydh@my031226 ~]$ sudo -uroot bash -c " ulimit -u 65535"

[yingyuan.ydh@my031226 ~]$ sudo -uroot bash -c " ulimit -u "

1024

很明显,在redhat6的/etc/security/limits.d/90-nproc.conf限制下,个人用户可以修改ulimit-u,但root用户没法修改。 解下来,我们把etc/security/limits.d/90-nproc.conf改掉,会看到root的ulimit -u 可以修改成功

[yingyuan.ydh@my031226 ~]$ sudo -uroot bash -c " ulimit -u 65535"

[yingyuan.ydh@my031226 ~]$ sudo -uroot bash -c " ulimit -u "

65535

[yingyuan.ydh@my031226 ~]$ cat /etc/security/limits.d/90-nproc.conf

# Default limit for number of user's processes to prevent

# accidental fork bombs.

# See rhbz #432903 for reasoning.


*          soft    nproc     65535

结果

在成功修改了root用户的max user processes后,继续使用root用户启动mysqld_safe脚本,稳定运行了一个下午,一切正常。

思考

为什么redhat6要做新增一个文件的限制,而不是继续沿用redhat5的方式来管理? 在微博上面发了一条简单的描述,引起很多人的讨论。

http://weibo.com/1642466057/y3jM4cz3q

遭遇Linux进程状态D

在一台flashcache的机器上面跑stap脚本

global some_count
probe process(@1).function("*")
{
  some_count[tid()] = backtrace()
}

function print_top()
{
  foreach (tid+ in some_count)
  {
    print_stack(some_count[tid])
  }
}

probe timer.s(5)
{
  print_top()
  printf("—————————————————-\n")
}

跑了这个脚本,跑了一会就ctrl+c abort掉,但后台还是有一个D进程的程序,用了好几次kill -9也杀不掉

1 15466 15252 14863 ?           -1 D        0   0:00 /usr/libexec/systemtap/stapio -u /tmp/stapzHoiGc/stap_b2dc831605d82ca90db5b550e7dfd16a_24607.ko

在Linux里面,进程状态分为task_running,task_interruptiable,task_uninterruptiable,_task_traced _task_stopped

之前一直对task_uninterruptiable不是很理解,这次亲身经历后,对它的认识更加深入。

进程状态为D的进程,一直滞留在CPU run_queue里面,搞得我的其他进程都不能正常运行,尝试了kill –9 ,没办法杀掉。最后只能reboot解决

之所以命名为D,往往是因为I/O资源得不到满足而引发等待。

我们的备库依赖nas服务器来作为备份盘,今年遇到过好几次因为nas的问题,导致mysql的监控一直告警(监控程序需要连接到MySQL,但由于备份脚本因为在写nas的时候,nas在中途卸载掉了,导致脚本一直在等待nas就绪,必须得重新挂载nas才能解决)

 

image

CPU软中断实践一

最近在对一个MySQL项目进行性能测试 QPS在1.1W到1.5W之间波动,但通过tcprstat观察到,响应时间不是非常稳定,会从0.3ms波动到1.9ms

image

响应时间监控,avg代表的是平均响应时间,单位为微秒,这里可以看到,平均响应时间为0.3ms 到1.7ms之间波动

image

@淘宝褚霸 在帮忙分析的时候,给了三点建议 1.CPU 2.IO 3.内存 这里先从CPU使用优化来总结一下

1.首先定位系统的CPU占用是否正常,可以使用 命令 mpstat –P ALL  1image

我们可以看到第四颗CPU的idle百分比明显比其他CPU要低好多。那这颗CPU到底在忙什么事情?    perf top 工具可以帮我们查看,这颗CPU上面跑的进程的百分比

2. sudo perf top –cpu=4 image

输出的结果和oprofile相似,但perf top可以实时来做cpu采样,这点比oprofile要好使得多。

另外一个工具是 taskset ,例如 taskset -p 03 700  的意思是把pid为700的进程绑定到第四颗CPU上面

ERROR 1135 (HY000): Can’t create a new thread (errno 11)

在一台MySQL测试服务器上面,今天遇到了

ERROR 1135 (HY000): Can’t create a new thread (errno 11); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug

首先使用perror工具看一下 错误代码11代表的意思

perror 11
OS error code 11: Resource temporarily unavailable
资源暂时不可用
google搜索了一下,很多文章说和当前用户的文件描述符ulimit -n有关系
ulimit -n
65535
当时候mysql的服务器load 为0,自然不可能是文件描述符不够导致的问题
第二个检查操作 cat /etc/security/limits.conf
得到的结果是
root soft nofile 65535
root hard nofile 65535
admin soft nofile 65535
admin hard nofile 65535
# End of file
mysql soft nproc 65536
mysql hard nproc 65536
mysql soft nofile 65535
第三个检查操作 查看mysql的错误日志
有一个很奇怪的现象,我的mysql是一直跑着的,但错误日志只有前两天的

这个时候,在ps aux | grep mysql的输出中发现 -log-error=/var/log/mysqld.log ,错误日志输出到/var目录下面是不正常的
mysql     2086 35.1 37.1 51184004 18388068 ?   Sl   20:25   9:01 
/u01/mysql/bin/mysqld –basedir=/u01/mysql –datadir=/u01/mysql/data –plugin-dir=/u01/mysql/lib/plugin
 –user=mysql –log-error=/var/log/mysqld.log –open-files-limit=65535 –pid-file=/u01/mysql/run/mysqld.pid
 –socket=/u01/mysql/run/mysql.sock –port=3306

直觉告诉我mysql用了/etc/my.cnf的内容
/etc/my.cnf的内容
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

最终把mysqld_safe干掉后,用mysqld_safe –defaults-file=xx.cnf 重新指定my.cnf的位置,mysql就正常跑了
最终原因,@维西v 启动mysql的时候没有指定my.cnf的位置,所以导致mysqld_safe使用了/etc/my.cnf这个默认文件
但依然有问题不是很理解
1.为什么读了/etc/my.cnf的时候,mysqld还会继续使用my.cnf配置文件里面的/u01/mysql/data
2.为什么还会继续使用plugin-dir=/u01/mysql/lib/plugin