Author Archive

遭遇MySQL server has gone away

一个开发MM的项目(PHP+MySQL)的PHP项目今天出现了MySQL server has gone away的错误,MySQL服务器端表示毫无压力。

而通过mysql客户端的连接方式mysql -hxx -uxx -pxx databasename -e xxx则毫无问题

而App服务器的netstat -a | grep 3306  | grep TIME_WAIT个数非常小,只有2个。

MySQL在连接超时这块的参数如下

root@(none) 09:24:51>show variables like '%out%';
+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| connect_timeout              | 10       |
| delayed_insert_timeout       | 300      |
| handlersocket_timeout        | 300      |
| handlersocket_wrlock_timeout | 12       |
| innodb_lock_wait_timeout     | 100      |
| innodb_rollback_on_timeout   | OFF      |
| interactive_timeout          | 28800    |
| lock_wait_timeout            | 31536000 |
| log_output                   | FILE     |
| net_read_timeout             | 30       |
| net_write_timeout            | 60       |
| slave_net_timeout            | 3600     |
| wait_timeout                 | 28800    |
+------------------------------+----------+

最终MM把PHP连接MySQL的连接方式从长连接改成了短连接,就再没出现了。

后来查了下资料,总结如下

1.MySQL服务器的wait_timeout参数为默认的28800秒,即8小时。该参数的意思是MySQL等待睡眠的连接的持续时间,如果超过8小时不活动,MySQL就会关闭这个连接。这个参数可以动态修改,但这个参数是session级别的,需要应用重新建立连接获取这个变量值才会生效。

2.PHP的默认php.ini里面,default_socket_timeout参数是默认60s.default_socket_timeout参数的意思是socket超时为60s。 官方解释

3.在MySQL的官方文档里面,有专门的章节介绍MySQL Server has gone away。但并没有提及到客户端本身也会有超时机制,以前曾经试过把wait_timeout设置为1年,但App还是继续出现MySQL server has gone away的错误。

4.在PHP程序里面,如果php.ini修改起来不方便,可以以下代码来尝试解决。

ini_set('mysql.connect_timeout', 300);
ini_set('default_socket_timeout', 300);

在ini_set后,可以用ini_get来验证参数设置适合符合预期。

 

参考资料

1. MySQL server has gone away – in exactly 60 seconds

2.MySQL server has gone away

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

编译Percona MySQL 5.5 +Handler Socket

安装准备 Cmake wget http://service-spi.web.cern.ch/service-spi/external/tarFiles/cmake-2.6.4.tar.gz

Percona-Server-5.5.16-rel22.0  get http://www.percona.com/redir/downloads/Percona-Server-5.5/Percona-Server-5.5.16-22.0/source/Percona-Server-5.5.16-rel22.0.tar.gz

$tar zxf cmake-2.6.4.tar.gz
$cd cmake-2.6.4
$./bootstrap
$make
$sudo make install

tar zxvf  Percona-Server-5.5.15-rel22.0.tar.gz

cd  Percona-Server-5.5.15-rel22.0

执行 CFLAGS=”-O3″ CXX=gcc CXXFLAGS=”-O3 -felide-constructors -fno-exceptions -fno-rtti”

 

cmake . \
  -DCMAKE_BUILD_TYPE:STRING=Release             \
  -DSYSCONFDIR:PATH=/u01/mysql            \
  -DCMAKE_INSTALL_PREFIX:PATH=/u01/mysql  \
  -DENABLED_PROFILING:BOOL=ON                   \
  -DENABLE_DEBUG_SYNC:BOOL=OFF                  \
  -DMYSQL_DATADIR:PATH=/u01/mysql/data    \
  -DMYSQL_MAINTAINER_MODE:BOOL=OFF              \
  -DWITH_EXTRA_CHARSETS:STRING=utf8,gbk,gb2312  \
  -DWITH_BIG_TABLES:BOOL=ON \
  -DWITH_FAST_MUTEXES:BOOL=ON \
  -DENABLE-PROFILING:BOOL=ON \
  -DWITH_SSL:STRING=bundled                     \
  -DWITH_UNIT_TESTS:BOOL=OFF                    \
  -DWITH_ZLIB:STRING=bundled                    \
  -DWITH_PARTITION_STORAGE_ENGINE:BOOL=ON       \
  -DWITH_SERVER_SUFFIX=hxsw                        \
  -DWITH_PLUGINS=heap,csv,partition,innodb_plugin,myisam \
  -DDEFAULT_CHARSET=gbk -DDEFAULT_COLLATION=gbk_chinese_ci -DWITH_EXTRA_CHARSETS=ALL \
  -DENABLED_ASSEMBLER:BOOL=ON                   \
  -DENABLED_LOCAL_INFILE:BOOL=ON                \
  -DENABLED_THREAD_SAFE_CLIENT:BOOL=ON          \
  -DENABLED_EMBEDDED_SERVER:BOOL=OFF             \
  -DWITH_CLIENT_LDFLAGS:STRING=all-static                 \
  -DINSTALL_LAYOUT:STRING=STANDALONE            \
  -DCOMMUNITY_BUILD:BOOL=ON;
 make -j `cat /proc/cpuinfo  | grep processor | wc -l`
make install

执行/u01/mysql/scripts/mysql_install_db –basedir=/u01/mysql/

(安装mysql,test数据库,初始化权限)

启动MySQL /u01/mysql/bin/mysqld_safe –defaults-file=my.cnf &

(my.cnf 请参考/u01/pmysql/support-files 下面的 my-innodb-heavy-4G.cnf文件 )

启动MySQL后,登录后

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.16-log MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.00 sec)

恭喜你,已经安装成功了!

编译Handler Socket

cd Percona-Server-5.5.16-rel22.0/storage/HandlerSocket-Plugin-for-MySQL

./configure  –with-mysql-source=/home/xxx/Percona-Server-5.5.15-rel21.0 \

–with-mysql-bindir=/u01/mysql/bin/ –with-mysql-plugindir=/u01/mysql/lib/plugin

 

make -j `cat /proc/cpuinfo  | grep processor | wc -l`

make install

登录到MySQL

mysql>  INSTALL PLUGIN handlersocket SONAME ‘handlersocket.so’;

mysql> show plugins;

+--------------------------------+----------+--------------------+------------------+---------+
| Name                           | Status   | Type               | Library          | License |
+--------------------------------+----------+--------------------+------------------+---------+
| binlog                         | ACTIVE   | STORAGE ENGINE     | NULL             | GPL     |
| mysql_native_password          | ACTIVE   | AUTHENTICATION     | NULL             | GPL     |
| mysql_old_password             | ACTIVE   | AUTHENTICATION     | NULL             | GPL     |
| MRG_MYISAM                     | ACTIVE   | STORAGE ENGINE     | NULL             | GPL     |
| MEMORY                         | ACTIVE   | STORAGE ENGINE     | NULL             | GPL     |
| MyISAM                         | ACTIVE   | STORAGE ENGINE     | NULL             | GPL     |
| CSV                            | ACTIVE   | STORAGE ENGINE     | NULL             | GPL     |
| BLACKHOLE                      | ACTIVE   | STORAGE ENGINE     | NULL             | GPL     |
| InnoDB                         | ACTIVE   | STORAGE ENGINE     | NULL             | GPL     |
| INNODB_RSEG                    | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_TRX                     | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_LOCKS                   | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_LOCK_WAITS              | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_CMP                     | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_CMP_RESET               | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_CMPMEM                  | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_CMPMEM_RESET            | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_SYS_TABLES              | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_SYS_TABLESTATS          | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_SYS_INDEXES             | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_SYS_COLUMNS             | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_SYS_FIELDS              | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_SYS_FOREIGN             | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_SYS_FOREIGN_COLS        | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_SYS_STATS               | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_TABLE_STATS             | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_INDEX_STATS             | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_BUFFER_POOL_PAGES       | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_BUFFER_POOL_PAGES_INDEX | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| INNODB_BUFFER_POOL_PAGES_BLOB  | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| XTRADB_ADMIN_COMMAND           | ACTIVE   | INFORMATION SCHEMA | NULL             | GPL     |
| FEDERATED                      | DISABLED | STORAGE ENGINE     | NULL             | GPL     |
| ARCHIVE                        | ACTIVE   | STORAGE ENGINE     | NULL             | GPL     |
| PERFORMANCE_SCHEMA             | ACTIVE   | STORAGE ENGINE     | NULL             | GPL     |
| partition                      | ACTIVE   | STORAGE ENGINE     | NULL             | GPL     |
| handlersocket                  | ACTIVE   | DAEMON             | handlersocket.so | BSD     |
+--------------------------------+----------+--------------------+------------------+---------+
36 rows in set (0.00 sec)

参考资料 Cmake使用   http://forge.mysql.com/wiki/Autotools_to_CMake_Transition_Guide

 

 

 

binlog_format=ROW/STATEMENT/MIX 对记录不存在的对比

昨天一台(slave)不停的出现包含HA_ERR_KEY_NOT_FOUND的复制错误

  1. Include/my_base.sh (376行)  #define HA_ERR_KEY_NOT_FOUND    120     /* Didn’t find key on read or update */

翻译的意思是查询或者更新操作找不到键值,实际进行测试的时候 ,where查询条件为索引和普通列值的时候,当主库binlog_format=row的时候,slave也会报错HA_ERR_KEY_NOT_FOUND

改slave对应的主库binlog_format=ROW

  1. 2. 测试重现

v031082.sqa.cm4   搞两个mysql实例   做主备

主库 /u01/mysql 3306    binlog_format=ROW

备库 /u01/mysql2 3309  binlog_format=STATEMENT

主库 create table t1(id int ,name varchar(100);

Insert into table t1 (name) value (‘mysql’);

Insert into table t1 (name) value (‘hbase’);

Insert into table t1 (name) value (‘oracle’);

主备库确认三条记录都在,备库清空t1表 .

备库 show slave status\G无告警

ROWSTATEMENT的类似操作对比

MySQL 主库 Binlog_format=row 主库的binlog_format=MIX/statement;
v031082.sqa.cm4 3306 Master delete from t1 where ;

delete from t1 where name=’hbase’;

Delete from t1 where name=’mysql’
v031082.sqa.cm4 3309 Slave 备库此时show slave status ;会出现

Could not execute Update_rows event on table test.t1;

Can’t find record in ‘t1′, Error_code: 1032;

handler error HA_ERR_KEY_NOT_FOUND;

the event’s master log mysql-bin.000001, end_log_pos 3499

备库没有错误信息 (目前线上大部分的MySQL 主库binlog_format=statement,如果TC迁移到MySQL,需要考虑好到底是采用MIX还是ROW)

源码剖析

storage/innodb_plugin/handler/ha_innodb.cc 这里包含index_read(),index_first(),index_last()函数,这些函数都会判断记录是否存在

/**********************************************************************//**

Positions an index cursor to the index specified in the handle. Fetches the

row if any.

@return  0, HA_ERR_KEY_NOT_FOUND, or error number */

UNIV_INTERN

Int ha_innobase::index_read(

case DB_RECORD_NOT_FOUND:

error = HA_ERR_KEY_NOT_FOUND;

table->status = STATUS_NOT_FOUND;

break;

}

/********************************************************************//**

Positions a cursor on the first record in an index and reads the

corresponding row to buf.

@return 0, HA_ERR_END_OF_FILE, or error code */

UNIV_INTERN Int ha_innobase::index_first(

if (error == HA_ERR_KEY_NOT_FOUND) {

error = HA_ERR_END_OF_FILE;

}

)

/********************************************************************//**

Positions a cursor on the last record in an index and reads the

corresponding row to buf.

@return 0, HA_ERR_END_OF_FILE, or error code */

UNIV_INTERN  int  ha_innobase::index_last(

if (error == HA_ERR_KEY_NOT_FOUND) {

error = HA_ERR_END_OF_FILE;

}

)

MySQL 5.0 5.1 下InnoDB的预热方法

asdfsdfsadf0.00 creates/s, 0.00 writes/s
Buffer pool hit rate 757 / 1000
————–
ROW OPERATIONS
————–
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
Main thread process no. 12487, id 1157658976, state: waiting for server activity
Number of rows inserted 0, updated 0, deleted 0, read 21
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.07 reads/s
—————————-
END OF INNODB MONITOR OUTPUT
==========================MyS

之前在做一个项目的MySQL数据库极限压测, 有部分场景是涉及到MySQL重启的,而这个项目使用的是InnoDB存储引擎。

重启完毕后,一开始十几分钟的性能是非常差的,原因是因为InnoDB有innodb buffer pool(简称ibf)的概念

和innodb buffer pool相关的参数innodb_buffer_pool_size,size越大,可以放到内存的数据越多,而大多数的项目都会有热点数据的存在,当热点数据经过LRU算法进入到buffer pool之后,读磁盘的次数减少,读的都是内存,速度是最快的

问题来了,数据库一重启,热点数据都被清空,bf里面都是空的.等待app的sql请求过来让bf填满数据是一个方法,但30分钟内很难把热点数据都装载进来.

这个时候,我们可以采取人工预热的办法来让bf满足我们的需求

MySQL 5.0的预热是最简单的

方法1 : 在MySQL重启后 执行 SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES,经过我在一台5.0MySQL的实验 在重启后查看show innodb status\G 和执行完这条语句后 Free buffers的页数会减少.

这个count语句有何作用呢?InnoDB的存储格式和MyISAM不一样, innodb会在mysql启动后的第一次访问表的时候,统计表的索引基数等相关信息,如果表很多的话,这也是一个巨大的开销.所以在正式提供服务之前,就把表打开,放入到bp里面

MySQL 5.1的数据预热

我在一台5.1.48的MySQL进行了重启,测试了同样的SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES 但发现free buffers的页数没有变少,情况和mysqlperformanceblog.com作者所说的一样–这个方法在5.1之后就无法达到我们的需求了

可以采用另外一种方法:获得数据库里面的库和对应的表,来进行预热,核心代码是这一句

SELECT table_schema, table_name FROM information_schema.tables

可以用perl或者python来获取库和表 然后执行 select * from db.table limit 1 来实现我们的方法

最后提一下,我们可以再my.cnf 加入init-file=/mysql/init.sql ,在每次mysql重启的时候就自动执行这个预热的sql  当然了 sql是要我们自己生成的哦

公司的社招培训第一天收获

这一周的周二到周四都是参加公司的社招新人培训,今天给我们分享的有淘宝的业务介绍,工程师@淘宝 by(文初) , 毕玄给我们讲淘宝架构介绍&未来发展,以及伏威给我们分享 用户体验,速度,稳定,成本–四个关键词

淘宝的业务介绍,是一位消费者事业部的产品经理给我们分享,其中一个问题让我印象非常深刻,淘宝有一年的在线交易总额KPI是1000亿,但实际只有达到的是999.4亿,相差了0.6亿,去了哪里?是因为临近过年之前,交易量瞬间上升,系统抗不住,服务不可用的时间非常长,从而导致了当年的KPI没有100%实现,上课的时候听到这个情况,心情挺不好受的,也感觉压力很大.这个培训,我觉得最大的收获是了解了前人的一些痛苦,自己来听一番,也感受这个过程,以后在工作的时候对类似的情况有所考虑

第二位给我们做分享的是放翁,工程师@淘宝的话题。认识文初,我依稀记得是大三的时候在javaeye.com看到他的博客,从他的博客文章,感觉他是沟通能力非常强的技术高手,当年的我,也没想到可以一睹他的风采。今天他全程的分享都是脱稿,而条理也非常清晰。他所分享的内容我做了记录:

1. 工程师如何把事情做到极致–把所负责的事情产品化,记录下来分享,不用怕吃亏

2.责任: 产品责任,关注自己的客户的需求,提前想到他们会有什么样的疑惑

3.心态: 在淘宝,你会发现你很忙,如果没有一个良好的心态,很容易把自己给压垮

4.沟通: 今天你给别人什么态度,明天别人就会给你什么态度。

5.时间管理:首先要和清晰的知道,自己今天要完成什么;不要做万金油,懂得让别人知道怎样解决问题,选择好的方式去帮助别人

放翁的分享很精彩,营养很好.值得好好的记录下来

下午是毕玄给我们做淘宝架构&未来发展,分享了淘宝的v1,v2,v3架构的优势和缺点不足。毕玄是淘宝秒杀活动的技术方案提供者 ,具体可以看这篇文章  http://www.aliresearch.com/viewpoint/6774/

v1阶段 采用了外国的技术方案来进行,一开始业务不是非常庞大,也勉强维持的过去

v2阶段,业务开始激增,整个淘宝的代码都放在一个工程,每次打包都要个20多分钟,大家都可以修改代码,数据都在一个数据库里面,日子过得不轻松

v3阶段,也就是目前我们的所在阶段,一个关键词–拆分 。从上层开始,拆应用,拆项目,产生各种各种的中间件,tfs,taif,notify,hsf,tddl,数据库分库分表,分机房。分布式的一个好处是,挂了一个子节点,其他节点还可以顶住其他的业务,鸡蛋没有放在同一个篮子。但也带来一个难题–应用拆分了,数据库拆分了,一大堆中间件,互相的依赖非常强,随便哪个子系统出了问题,都可能导致一对服务不可用。鸡蛋没有在同一个篮子里面,分散放,某个地方不小心,就打烂一两个鸡蛋了。

最后的是伏威给我们分享2010年淘宝的技术方面的四个关键词: 用户体验,速度,稳定,成本.  其实有3个词,我认为都是和v3阶段的拆分有关系,分别是用户体验,稳定,成本。

用户体验和稳定:  这两个词其实有非常大的关系,系统不稳定,用户访问不了网站,用户体验就非常糟糕了。

成本: 分布式和拆分所带来的,就是设备数量的激增,从而带来各种各样的成本问题,机柜,服务器,内存,cpu,人力成本等等

今天的分享,既有经验的收获,也带给了我思考,比如放翁所提到的责任精神,比如毕玄所提到的未来10w级别的服务器,如何智能化管理,还有伏威所提到的四个关键词,这些点,对于我自己的工作,应该也是需要加以注意并做好的,而这,就是我的工作的意义所在”个人能力得到提升,所做的事情解决了已有的问题,证明自己的价值”