阿八博客
  • 100000+

    文章

  • 23

    评论

  • 20

    友链

  • 最近新加了很多技术文章,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

社区投稿 | 线程简介和 MySQL 调试环境搭建

欢迎来到阿八个人博客网站。本 阿八个人博客 网站提供最新的站长新闻,各种互联网资讯。 喜欢本站的朋友可以收藏本站,或者加QQ:我们大家一起来交流技术! URL链接:https://www.abboke.com/jsh/2019/0920/114350.html
作者:高鹏
文章末尾有他著作的《深入理解MySQL主从原理 32讲》,深入透彻理解MySQL主从,GTID相关技术知识

本文节选自《深入理解MySQL主从原理》第29节
注意:本文分为正文和附件两部分,都是图片格式,如果正文有图片不清晰可以将附件的图片保存到本地查看

背景

我想简单说一下我的 MySQL 调试环境的搭建,但是在此之前不得不简单说一下什么是线程,因为如果不解释一下什么是线程,简单的调试可能都会有阻碍,同时了解线程对我们普通DBA诊断性能问题也有极大的帮助
但是详细解释线程已经超出了我的能力范围也超出了本系列讨论的范围

具体我推荐给大家两本书:

《POSIX 多线程程序设计》《Linux UNIX 系统编程手册》 第29到32章

第一本书很老了,但是我觉得还可以,如果有兴趣可以参考一下

一、线程简介

我们知道 mysqld 是一个单进程多线程的用户程序,因此我们有必要了解一下什么线程
实际上 MySQL 中的线程都是 POSIX 线程,比如我们的会话线程、DUMP 线程、IO 线程以及其他一些 InnoDB 线程都是 POSIX 线程

进程实际上就是运行中的程序,一个进程中可以包含多个线程,也可以只包含一个线程
在 Linux 中线程也叫轻量级进程(light-weight process)简称为 LWP,进程的第一个线程通常称为主控线程
进程是内存分配的最小单位,线程是 CPU 调度的最小单位,也就是说如果 CPU 有足够多核,那么多个线程可以达到并行处理的效果,内核直接调度线程
下面是我学习 Linux 线程的时候看到的一张我认为比较好理解的图,我重新画了一下放在下面供大家参考(图29-1,高清原图包含在文末原图中):

我们发现线程的堆内存和全局变量是共享的,因此线程之间数据共享很轻松,但是要控制好这些共享内存就需要引入我们的线程同步技术,比如我们常说的 Mutex

如果想了解线程到底共享了哪些资源,线程和进程到底各有什么优势和劣势,可执行参考上面我给出的书籍

二、PID、LWP ID、Thread TID

如果要进行调试就需要了解这三种 ID,其中 PID 和 LWP ID 是比较重要,因为不管是调试和运维都会遇到它们,而 Thread TID 不做多线程开发一般很少用到

下面是我对它们的总结:

PID:内核分配,用于识别各个进程的 ID
这个应该是大家最熟悉的
LWP ID:内核分配,用于识别各个线程的 ID,它就像是线程是‘PID’一样
同一个进程下的所有线程有相同的 PID,但是 LWP ID 却不一样,主控线程的 LWP ID 就是进程 PID
Thread TID:进程内部用于识别各个线程的内部 ID,这个 ID 用得不多

下面我写了一个简单的 C 测试程序仅仅用于观察这些 ID,它是通过主控线程再创建一个线程,也就是说这个进程包含了两个线程
它们分别打印自己的 PID、LWP ID、Thread TID,然后做一个循环自加操作引起高 CPU 消耗现象便于观察
然后我们使用 Linux 的 top -H 和 ps -eLlf 命令分别进行观察

程序输出

下面是程序的输出:

注意如果这个时候查看这个进程占用的 %cpu 就超过了 100%,接近 200%,如下:

三、如何将 MySQL 的线程和 LWP ID 进行对应

在 5.7 中我们已经可以通过 MySQL 语句和 LWP ID 进行对应了,这让性能诊断变得更加便捷
比如我上面的列子如果两个高耗 CPU 的线程是 MySQL 的线程那么我们就拿到了线程的 LWP ID,然后可以通过语句找到这两个线程到底是 MySQL 的什么线程
语句如下:

我们可以发现他们是可以对应上的,这个最好自己实际试试就知道了

四、调试环境搭建

调试环境的搭建我认为不管使用什么方法只要能够起到调试的作用就可以了
这里介绍一下我的方法
我是在 Linux 下面直接使用 gdb 调试的,我觉得这个方法搭建非常简单并且很奏效,基本上只要会源码安装就能完成调试环境的搭建
下面来看看步骤:

1. 第一步下载 MySQL 源码包,解压

我特意重新下载了官方版的 5.7.26 源码

2. 使用源码安装的方法安装 MySQL,注意需要开启debug选项

下面是我使用的选项:

5. 准备 gdb 命令文件

如下是我准备的命令文件:

下面就是我启动调试环境成功的记录:

注意到了这里的 LWP ID 了吗,前面我们已经讨论过了
这个时候 MySQL 客户端程序已经可以连接 mysqld 了如下:

然后我们在 MySQL 客户端执行一个事务如下,并且提交:

我们使用 bt 命令查看栈帧发现如下:

相关文章

暂住......别动,不想说点什么吗?
  • 全部评论(0
    还没有评论,快来抢沙发吧!