mysql tcmalloc_技术分享 | tcmalloc解决mysqld实例引发的cpu过高问题

news/2024/7/8 16:28:14

原创:任坤作者简介

任坤,现居珠海,先后担任专职 Oracle 和 MySQL DBA,现在主要负责 MySQL、mongoDB 和 Redis 维护工作。

背景

MySQL 版本:5.6.29,普通主从

OS:CentOS 6.8

最近一段时间线上某实例频繁报警CPU飙高,每次都捕获到同一种 SQL,结构如下:

select uid from test_history where cat_id = '99999' and create_time >= '2019-07-12 19:00:00.000' and uid in (......)

其中uid一次性会传入上百个。

表结构为

Create Table: CREATE TABLE `test_history` (

`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',

`cat_id` varchar(64) NOT NULL,

`uid` varchar(128) NOT NULL,

`msg` varchar(64) NOT NULL',

`create_time` datetime NOT NULL COMMENT '创建时间',

PRIMARY KEY (`id`),

UNIQUE KEY `idx_cat_uid` (`cat_id`,`uid`,`create_time`),

KEY `idx__time` (`create_time`)

) ENGINE=InnoDB AUTO_INCREMENT=***** DEFAULT CHARSET=utf8

SQL 使用到了索引idx_msg_uid_time,单条执行可以秒级完成,但是并发执行会遭遇执行时间过长(超过1个小时)且CPU过高的问题。

诊断思路

mpstat -P ALL 1,查看cpu使用情况,主要消耗在sys即os系统调用上

perf top,cpu主要消耗在_spin_lock

生成perf report查看详细情况

CPU主要消耗在mutex争用上,说明有锁热点。

采用pt-pmp跟踪mysqld执行情况,热点主要集中在mem_heap_alloc和mem_heap_free上。

Pstack提供更详细的API调用栈

#0 0x0000003e0caf80cf in __lll_unlock_wake_private () from /lib64/libc.so.6

#1 0x0000003e0ca7cf6a in _L_unlock_5936 () from /lib64/libc.so.6

#2 0x0000003e0ca78bbc in _int_free () from /lib64/libc.so.6

#3 0x000000000097dcb3 in mem_area_free(void*, mem_pool_t*) ()

#4 0x000000000097d2d2 in mem_heap_block_free(mem_block_info_t*, mem_block_info_t*) ()

#5 0x00000000009e6474 in row_vers_build_for_consistent_read(unsigned char const*, mtr_t*, dict_index_t*, unsigned long**, read_view_t*, mem_block_info_t**, mem_block_info_t*, unsigned char**) ()

#6 0x00000000009dce75 in row_search_for_mysql(unsigned char*, unsigned long, row_prebuilt_t*, unsigned long, unsigned long) ()

#7 0x0000000000939c95 in ha_innobase::index_read(unsigned char*, unsigned char const*, unsigned int, ha_rkey_function) ()

Innodb在读取数据记录时的API路径为

row_search_for_mysql --》

row_vers_build_for_consistent_read --》

mem_heap_create_block_func --》

mem_area_alloc --》

malloc --》

_L_unlock_10151 --》

__lll_unlock_wait_private

row_vers_build_for_consistent_read会陷入一个死循环,跳出条件是该条记录不需要快照读或者已经从undo中找出对应的快照版本,每次循环都会调用mem_heap_alloc/free。

而该表的记录更改很频繁,导致其undo history list比较长,搜索快照版本的代价更大,就会频繁的申请和释放堆内存。

Linux原生的内存库函数为ptmalloc,malloc/free调用过多时很容易产生锁热点。

当多条 SQL 并发执行时,会最终触发os层面的spinlock,导致上述情形。

解决方案

将mysqld的内存库函数替换成tcmalloc,相比ptmalloc,tcmalloc可以更好的支持高并发调用。

修改my.cnf,添加如下参数并重启

[mysqld_safe]

malloc-lib=tcmalloc

上周五早上7点执行的操作,到现在超过72小时,期间该实例没有再出现cpu长期飙高的情形。

以下是修改前后cpu使用率对比


http://www.niftyadmin.cn/n/2422878.html

相关文章

java连接mysql数据库教程视频_有没有Java教学视频讲如何jdbc链接mysql数据库的的...

展开全部一般的java web编程都会有jdbc编程教32313133353236313431303231363533e59b9ee7ad9431333337626133程,连接mysql oracle 等基本都是一样的。java数据库编程要用JDBCJDBC用法很简单,创建一个以JDBC连接数据库的程序,包含7个步骤:1、加…

[读书笔记]机器学习:实用案例解析(1)

第1章 使用R语言 #machine learing for heckers #chapter 1 library(ggplot2) library(plyr)#.tsv文件用制表符进行分割#字符串默认为factor类型,因此stringsAsFactors置FALSE防止转换#header置FALSE防止将第一行当做表头#定义空字符串为NA:na.strings …

使用QEMU调试Linux内核代码

http://blog.chinaunix.net/uid-20729583-id-1884617.html http://www.linuxidc.com/Linux/2014-08/105510.htm Linux内核代码的调试非常麻烦,一般都是加printk, 或者用JTAG调试。这里的方法是用QEMU来调试Linux内核。因为QEMU自己实现了一个gdb server, 所以可以非…

MongoCola使用教程 2 - MongoDB的Replset 初始化和配置

前言 首先再次感谢博客园的各位朋友。正是你们的关注才让我有信心将这个工具开发下去。 这周同样也有热心网友对于MongoCola存在的问题给予了反馈。 这次工具更新到了版本1.20,强化的地方是增加了Replset和Sharding的管理能力。MongoVUE和Mongocola以前在显示一个R…

Oracle RMAN 的 show,list,crosscheck,delete命令整理

1、SHOW命令:显示rman配置: RMAN> show all;2、REPORT命令:2.1、RMAN> report schema 报告目标数据库的物理结构;2.2、RMAN> report need backup days3/days 3; 报告最近3天没有被备份的数据文件;2.3、RMAN> report n…

python turtle画笑脸_如何用python画笑脸QQ表情——turtle库实践

from turtle import *screensize(600,600)speed(10)#笑脸的小圆脸pensize(5)color(dim grey,yellow)pu()goto(0,-100)begin_fill()circle(100)end_fill()#腮红#左侧seth(90)color(Light Pink,Light Pink)pu()goto(-55,-5)pd()begin_fill()circle(20)end_fill()#右侧color(Light…

maven项目迁入内网的各个坑

前言:我之前做的一个项目一直是在内网环境,进行开发的时候是在外网开发好了后打包传入内网。有许多的不便 因此我整个项目迁入内网才内网开发,琢磨了好一会才找到各个问题的解决方案。最近公司新进了一个新同事 然后让我带带,这就…

npm 模块安装机制简介

npm 是 Node 的模块管理器,功能极其强大。它是 Node 获得成功的重要原因之一。 正因为有了npm,我们只要一行命令,就能安装别人写好的模块 。 $ npm install 本文介绍 npm 模块安装机制的细节,以及如何解决安装速度慢的问题。 一、…