mysql无法正常关闭问题追查

本文的追查过程来源于某次mysql无法正常关闭。

 

1、复现

第一次出现时环境比较复杂,多次试验后发现,如下过程能够稳定复现。

a)      系统环境

gcc版本

Using built-in specs.

Target: x86_64-redhat-linux

Configured with: ../configure –prefix=/usr –mandir=/usr/share/man –infodir=/usr/share/info –enable-shared –enable-threads=posix

Thread model: posix

gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)

b)      复现过程

安装(使用版本mysql-5.1.45, innodb-plugin1.0.6)

./configure -prefix=/data/mysql5 –with-plugins=partition,heap,innodb_plugin,myisam,myisammrg,csv,example –with-extra-charsets=all –enable-assemble –enable-static  –enable-thread-safe-client
make && make install

 

执行

1) >use test;2) >create table t(c int) ENGINE=InnoDB;

 

3) >alter table t add index c(`c`);

4) >quit;

5) #bin/myqladmin –uroot –p shutdown //终端下关闭

现象:执行shutdown语句时,输出如下

bin/mysqld_safe: line 137: 15569 Segmentation fault      nohup /data/mysql5/libexec/mysqld –defaults-file=my.cnf –based1100919 15:53:40 mysqld_safe Number of processes running now: 0100919 15:53:40 mysqld_safe mysqld restarted

 

说明:正常的执行mysqladmin应该输出如下

100919 15:50:18 mysqld_safe mysqld from pid file /data/mysql5/run/mysqld.pid ended

 

2、追查

       刚开始以为是代码问题,改用debug模式时发现在执行步骤3)的时候mysqld就dump导致重启了。追查导致dump的代码执行路径如下

add_index –> row_merge_build_indexes –> row_merge_sort –> row_merge –> row_merge_blocks_copy

    前两个函数在handler/handler0alter.cc,后面的函数在row/row0merge.c,功能是新建的索引排序并合并到同一个文件中。

       发现dump的点居然是row_merge_blocks_copy函数的传参过程,因此怀疑是内存访问方面的问题。使用valgrind试运行。

在非debug模式下使用valgrind启动mysql,发现在执行shutdown命令时,valgrind有如下输出:

==5998== Thread 16:==5998== Invalid read of size 4==5998==    at 0×30B560B0F0: pthread_kill (in /lib64/libpthread-2.5.so)==5998==    by 0×7822A4: thr_alarm (in /home/dingqi/innodb_ssd/mysql/libexec/mysqld)

 

==5998==    by 0×598E62: my_real_read(st_net*, unsigned long*) (in /home/dingqi/innodb_ssd/mysql/libexec/mysqld)

==5998==    by 0×599264: my_net_read (in /home/dingqi/innodb_ssd/mysql/libexec/mysqld)

==5998==    by 0×5AA14E: handle_one_connection (in /home/dingqi/innodb_ssd/mysql/libexec/mysqld)

==5998==    by 0×30B56062F6: start_thread (in /lib64/libpthread-2.5.so)

==5998==    by 0×30B4AD1B6C: clone (in /lib64/libc-2.5.so)

==5998==  Address 0×3197D9D0 is on thread 15’s stack

 

thread 16访问了thread 15的栈空间数据!

3、分析

       这里我们先不考虑两个thread分别是作什么的,但这种错误必然留下隐患。

在手头的其他环境对照试验如下:

环境 Os & gcc版本 结果
原环境 x86_64-redhat-linux

 

gcc version 4.1.2 20071124 (Red Hat 4.1.2-42)

异常
对照1 x86_64-redhat-linux

 

gcc version 3.4.6 20060404 (Red Hat 3.4.6-3)

正常
对照2 Target: i386-redhat-linux

 

gcc version 4.1.2 20071124 (Red Hat 4.1.2-42)

正常

手头环境不多,初步认为是: 在64位机器上gcc版本为4.1.2时,会出现如上问题。

       需要查出为什么环境不同造成生成的可执行版本有差异。想到Makefile。

       将不同环境下的Makefile作diff后赫然发现,出问题版本的Makefile有这行

CXXFLAGS =  -O3  -fno-implicit-templates -fno-exceptions -fno-rtti 与其他机器不同。

       而这个文件中CFLAGS确是-O2!  是否因为优化级别不同造成的?

       在原环境中重复步骤,当将./configure 改成 CFLAG=”-O2 ” CXXFLAGS=”-O2 ” ./configure, 结果发现运行正常了。

      4、阶段结论及后续思考 

      1) 阶段结论: 由于出问题环境中configure后生成的Makefile中CXXFLAGS为-O3,与CFLAGS中的-O2冲突,导致线程访问出错。

为验证此结论,将CFLAGS和CXXFLAGS都设置为-O3或-O2,在原环境上重复步骤,运行正常。

因此对于用于线上的服务,编译时最好明确指明需要的参数,以防默认参数之间的冲突造成异常

     2)后续的问题是, 为什么这两个优化级别不同会导致如上的现象? Debug模式下参数传递过程中dump是否也是这个原因?优化级别是如何影响到此过程的? 另查。

时间: 2024-10-30 20:33:56

mysql无法正常关闭问题追查的相关文章

linux下Mysql的启动关闭的命令

 下面我来为各位介绍linux下Mysql的启动关闭的命令,有需要了解的朋友不防进入看看吧.     linux下Mysql的启动关闭(本文基于centos6.4.mysql5.7.3),mysql安装在/usr/local/mysql目录下: [root@lnmp ~]# /usr/local/mysql/bin/mysql --version /usr/local/mysql/bin/mysql  Ver 14.14 Distrib 5.7.3-m13, for Linux (x86_64)

redhat下安装mysql 5.6.20,解压zip包,查看已经安装过的mysql,卸载rpm安装包,安装mysql服务器端和客户端,修改mysql用户名,登陆mysql,启动关闭mysql

 1 将相关的mysql rpm包上传到redhat上 2  我的电脑是Redhat 6.*版本,所以这里使用上面一个 3  解压zip包 4  安装以下几个rpm MySQL-client-advanced-5.6.20-1.el6.x86_64.rpm MySQL-server-advanced-5.6.20-1.el6.x86_64.rpm 5  查看已经安装过的mysql rpm –aq | grep mysql 结果: mysql-libs-5.1.66-2.el6_3.x86_6

mysqld_multi配置MySQL多实例关闭不了

在启用MySQL多实例中,很多环境会选择使用mysqld_multi管理多实例,但不幸的是从MySQL 5.6 后, mysqld_mutli不能把MySQL关掉了. 对于这个问题的处理办法,首先确认: mysqladmin -h127.0.0.1 -P3307 -umdev -p shutdown or mysqladmin -S /tmp/mysql3307.sock -umdev -p shutdown 工作没问题. 创建用户: create user 'mdev'@'localhost'

mysql日志启用/关闭与查看方法

1. 错误日志 用–log-error[=file_name]选项来指定 mysqld 保存错误日志文件的位置.如果没有给定 file_name 值,mysqld 使用错误日志名 host_name.err 并在数据目录中写入日志文件.如果你执行 FLUSH LOGS,错误日志用-old 重新命名后缀并且 mysqld 创建一个新的空日志文件.(如果未给出–log-error 选项,则不会重新命名). 如果不指定–log-error,或者(在Windows中)如果你使用–console 选项,错

Linux 平台MySQL启动关闭方式总结

  MySQL的启动方法有很多种,下面对比.总结这几种方法的一些差异和特性,下面实验的版本为MySQL 5.6.如有疏漏或不足,敬请指点一二.   1:使用mysqld启动.关闭MySQL服务      mysqld是MySQL的守护进程,我们可以用mysqld来启动.关闭MySQL服务,关于mysqld, MySQL 5.6官方介绍资料如下所示: mysqld, also known as MySQL Server, is the main program that does most of

MySQL关闭过程详解和安全关闭MySQL的方法_Mysql

本文分析了mysqld进程关闭的过程,以及如何安全.缓和地关闭MySQL实例,对这个过程不甚清楚的同学可以参考下. 关闭过程: 1.发起shutdown,发出SIGTERM信号 2.有必要的话,新建一个关闭线程(shutdown thread)    如果是客户端发起的关闭,则会新建一个专用的关闭线程    如果是直接收到 SIGTERM 信号进行关闭的话,专门负责信号处理的线程就会负责关闭工作,或者新建一个独立的线程负责这个事    当无法创建独立的关闭线程时(例如内存不足),MySQL Se

关闭MySQL日志方法详解

在配置文件中指定log的出位置. Windows:Windows 的配置文件为 my.ini,一般在 MySQL 的安装目录下或者 c:Windows 下. Linux:Linux 的配置文件为 my.cnf ,一般在 /etc 下. 大家也可以用下面的命令查一下(如果不是LNMP,路径可能不同):  代码如下 复制代码 du -h --max-depth=1 /usr/local/mysql/var/* 如果看到大量大文件,且名为 mysql-bin.000014 这样的,说明你也需要关闭日志

MySQL更改数据库数据存储目录

MySQL数据库默认的数据库文件位于/var/lib/mysql下,有时候由于存储规划等原因,需要更改MySQL数据库的数据存储目录.下文总结整理了实践过程的操作步骤.   1:确认MySQL数据库存储目录 [root@DB-Server tmp]# mysqladmin -u root -p variables | grep datadir   Enter password:   | datadir | /var/lib/mysql/     2:关闭MySQL服务 在更改MySQL的数据目录

ubuntu下简单配置mysql数据库

ubuntu下简单配置mysql数据库 一). ubuntu下mysql安装布局: /usr/bin                      客户端程序和mysql_install_db /db                             数据库和日志文件 /var/run mysqld        服务器 /etc/mysql mysql       配置文件my.cnf /usr/share/mysql       字符集,基准程序和错误消息 /etc/init.d/mysq