麒麟v10 上部署 TiDB v5.1.2 生产环境优化实践
576
2023-06-14
MySQL:终于为OS层面的线程命名了
一、问题来源
最近在检查某个数据库性能的时候,通过top -Hu mysql看到了一个特别奇怪的现象,线程有了自己的名字,我开始以为是哪个大厂自己维护的版本,如下:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 8146 mysql 20 0 4164720 734540 26624 S 0.0 9.9 0:00.96 mysqld 8159 mysql 20 0 4164720 734540 26624 S 0.0 9.9 0:00.02 ib_io_ibuf 8160 mysql 20 0 4164720 734540 26624 S 0.0 9.9 0:00.02 ib_io_log 8161 mysql 20 0 4164720 734540 26624 S 0.0 9.9 0:00.04 ib_io_rd-1 8162 mysql 20 0 4164720 734540 26624 S 0.0 9.9 0:00.03 ib_io_rd-2 ...
后来装了一个8.0.28才发现确实是官方版本的新玩意。但是虽然能够猜到一些线程的功能,可还是很陌生的样子,因为这个名字和performance_schema.thread中的名字并不一样。
这里我们就来看看它的做法和对应关系。不过这一小步,却是DBA的一大步,我们以往在看***的进程的时候都习惯了有命名的进程名字,这带来的好处是直接从OS层面就能判断大概哪个功能的压力增高。
二、以往的对应方法
我们知道以前在获取到线程的LWP号后需要到performance_schema.thread通过lwp和thread_os_id 对应,得到如下结果:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 5524 mysql 20 0 4052588 792400 11676 S 0.0 27.4 0:03.82 mysqld 5533 mysql 20 0 4052588 792400 11676 S 0.0 27.4 0:00.00 mysqld 5556 mysql 20 0 4052588 792400 11676 S 0.0 27.4 0:00.00 mysqld 5557 mysql 20 0 4052588 792400 11676 S 0.0 27.4 0:00.00 mysqld ...----------------------------------------+--------------+| name | thread_os_id |+----------------------------------------+--------------+| thread/sql/main | 5524 || thread/sql/thread_timer_notifier | 5533 || thread/innodb/io_ibuf_thread | 5556 || thread/innodb/io_read_thread | 5558 || thread/innodb/io_log_thread | 5557 |...
如果某个线程的CPU高或者IO高我们就能够知道是什么线程。当然你也可以和information_schema.processlist做join得到process id和state等有用的信息。
三、简单的实现方法讨论
比如以innodb为例,所有的线程的OS thread name都放到了all_innodb_threads这个一个数组中,其中每个元素是一个结构体,结构体中包含了我们OS thread name这个元素给予了大量的代码注释,我就放一点我们容易看懂的:
typedef struct PSI_thread_info_v5 PSI_thread_info; The thread name to advertise to the operating system. This feature is optional, and improves observability for platforms that support a flavor of pthread_setname_np().
这里我们也看到需要支持pthread_setname_np函数才行。在调用register_thread_class注册所有的class的时候会将这些OS thread name放到一个叫做thread_class_array全局内存中,这样再建立线程应该能轻松的从全局内存中拿到每个线程的OS thread name(当然我没去细看了)。接着,在建立线程的时候我们调用my_thread_self_setname设置OS thread name就可以了,实际上就是调用pthread_setname_np。
四、新的Linux OS thread name和performance_schema.threads中name的对应
为了快速的得到对应的办法,我稍微加了点输出内容,这样只要有线程启动,就会打印到error日志,因为如果一个一个去看每个线程启动的时候带入的OS thread name实在太慢了,耗不起,得到的结果如下:
可以看到建立的线程非常的多,但是我们得到它们的对应关系这就够了。这里不一一讨论每个线程的功能了,不过大部分我们都非常熟悉了,比如purge线程/cleaner线程 ,这里我列出一些,其他的就自己看看吧。
五、用pthread_setname_np为线程命名
这里我就随便写了4个循环的线程调用这个函数为我的线程命名为D-GPWK,需要耗用较高的CPU,看到的结果如下:
如果这个线程是MySQL的线程,当看到这个结果,我们就能明白大概的方向了。
《MySQL主从原理》作者:高鹏(八怪)
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。