mysql 超长记录_谁记录了mysql error log中的超长信息

【问题】

最近查看MySQL的error log文件时,发现有很多服务器的文件中有大量的如下日志,内容很长(大小在200K左右),从记录的内容看,并没有明显的异常信息。

有一台测试服务器也有类似的问题,为什么会记录这些信息,是谁记录的这些信息,分析的过程比较周折。

Status information:

Current dir:

Running threads: 2452  Stack size: 262144

Current locks:

lock: 0x7f783f5233f0:

Key caches:

default

Buffer_size:       8388608

Block_size:           1024

Division_limit:        100

Age_limit:             300

blocks used:            10

not flushed:             0

w_requests:           6619

writes:                  1

r_requests:         275574

reads:                1235

handler status:

read_key:   32241480828

read_next:  451035381896

read_rnd     149361175

read_first:    1090473

write:      4838429521

delete        12155820

update:     3331297842

【分析过程】

1、首先在官方文档中查到,当mysqld进程收到SIGHUP信号量时,就会输出类似的信息,

On Unix, signals can be sent to processes. mysqld responds to signals sent to it as follows:

SIGHUP causes the server to reload the grant tables and to flush tables, logs, the thread cache, and the host cache. These actions are like various forms of the FLUSH statement. The server also writes a status report to the error log that has this format:

2、有别的程序在kill mysqld进程吗,用systemtap脚本监控kill命令

probe nd_syscall.kill

{

target[tid()] = uint_arg(1);

signal[tid()] = uint_arg(2);

}

probe nd_syscall.kill.return

{

if (target[tid()] != 0) {

printf("%-6d %-12s %-5d %-6d %6d

", pid(), execname(),

signal[tid()], target[tid()], int_arg(1));

delete target[tid()];

delete signal[tid()];

}

}

用下面命令测试,确实会在error log中记录日志

kill -SIGHUP 12455

从systemtap的输出看到12455就是mysqld进程,被kill掉了,信号量是1,对应的就是SIGHUP

不过在测试环境后面问题重现时,却没有抓到SIGHUP的信号量。

FROM   COMMAND      SIG   TO     RESULT

17010  who          0     12153  1340429600

36681  bash         1     12455     642

3、看来并不是kill导致的,后面用gdb attach到mysqld进程上,在error log的三个入口函数sql_print_error,sql_print_warning,sql_print_information加上断点

但是在问题重现时,程序并没有停在断点处

4、写error log还有别的分支吗,翻源码找到了答案,原来是通过mysql_print_status函数直接写到error log中

void mysql_print_status()

{

char current_dir[FN_REFLEN];

STATUS_VAR current_global_status_var;

printf("

Status information:

");

(void) my_getwd(current_dir, sizeof(current_dir),MYF(0));

printf("Current dir: %s

", current_dir);

printf("Running threads: %u  Stack size: %ld

",

Global_THD_manager::get_instance()->get_thd_count(),

(long) my_thread_stack_size);

puts("");

fflush(stdout);

}

5、再次用gdb attach到mysqld进程上,在mysql_print_status函数上加断点,在问题重现时,线程停在断点处,通过ps的结果多次对比,判断是pt-stalk工具运行时调用了mysql_print_status

4cc97c93d19e1101421889fa1b450713.png

6、从堆栈中看到dispatch_command调用了mysql_print_status,下面是具体的逻辑,当command=COM_DEBUG时就会执行到mysql_print_status

case COM_DEBUG:

thd->status_var.com_other++;

if (check_global_access(thd, SUPER_ACL))

break;                /* purecov: inspected */

mysql_print_status();

query_logger.general_log_print(thd, command, NullS);

my_eof(thd);

break;

7、查看pt-stalk的代码

if [ "$mysql_error_log" -a ! "$OPT_MYSQL_ONLY" ]; then

log "The MySQL error log seems to be $mysql_error_log"

tail -f "$mysql_error_log" >"$d/$p-log_error" &

tail_error_log_pid=$!

$CMD_MYSQLADMIN $EXT_ARGV debug

else

log "Could not find the MySQL error log"

在调用mysqladmin时使用了debug模式

debug         Instruct server to write debug information to log

8、在percona官网上搜到了相关的bug描述,目前bug还未修复,会在下个版本中3.0.13中修复。

https://jira.percona.com/browse/PT-1340

898dec411f75a4d761f9fd9fa4c3d9b4.png

【解决方案】

定位到问题后,实际修复也比较简单,将pt-stalk脚本中$CMD_MYSQLADMIN $EXT_ARGV debug中的debug去掉就可以了,测试生效。

总结:

(1)  通过mysql_print_status函数直接写到error log中

(2)  执行mysqladmin debug

Status information:

Current dir: /data/mysql/mysql3306/data/

Running threads: 7 Stack size: 262144

Current locks:

lock: 0x7fdcb0a44780:

lock: 0x7fdcaf0ea980:

lock: 0x1edb5a0:

..........

..........

Key caches:

default

Buffer_size: 8388608

Block_size: 1024

Division_limit: 100

Age_limit: 300

blocks used: 9

not flushed: 0

w_requests: 0

writes: 0

r_requests: 82

reads: 13

handler status:

read_key: 16981474

read_next: 33963080

read_rnd 6

read_first: 192

write: 21270

delete 0

update: 16981221

Table status:

Opened tables: 956

Open tables: 206

Open files: 13

Open streams: 0

Memory status:

Events status:

LLA = Last Locked At LUA = Last Unlocked At

WOC = Waiting On Condition DL = Data Locked

Event scheduler status:

State : INITIALIZED

Thread id : 0

LLA : n/a:0

LUA : n/a:0

WOC : NO

Workers : 0

Executed : 0

Data locked: NO

Event queue status:

Element count : 0

Data locked : NO

Attempting lock : NO

LLA : init_queue:96

LUA : init_queue:104

WOC : NO

Next activation : never

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL Deadlock ERROR 1213 (40001)是一个常见的错误,通常发生在高并发的情况下。这个错误表示在一个事务出现了死锁,也就是两个或多个事务相互等待对方释放资源的情况。下面是排查这个错误的一般步骤: 1. 查看错误日志 首先,查看MySQL的错误日志,以了解死锁的详细信息。可以使用以下命令查看错误日志: ``` sudo tail -f /var/log/mysql/error.log ``` 2. 查看死锁信息 在错误日志,可以看到死锁的详细信息,包括哪些事务参与了死锁、哪些表和行受到了影响等。可以使用以下命令查看当前的死锁信息: ``` SHOW ENGINE INNODB STATUS; ``` 3. 分析死锁原因 分析死锁的原因非常重要,因为只有找到原因,才能采取相应的措施来避免死锁。通常,死锁的原因包括以下几个方面: - 并发访问同一行数据 - 事务执行顺序不当 - 事务使用了不同的锁类型 4. 解决死锁问题 解决死锁问题的方法也有很多种,根据死锁的原因不同,采取的措施也会有所不同。以下是一些常用的解决方法: - 优化SQL语句,减少事务执行时间 - 使用合适的锁类型,例如行锁、表锁、读锁、写锁等 - 调整事务隔离级别 - 对于高并发的场景,可以考虑使用分布式数据库或者缓存等技术来降低单个数据库的压力 综上所述,排查MySQL Deadlock ERROR 1213 (40001)错误需要综合考虑多方面的因素,并采取相应的措施来解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值