代码改变世界

MySQL 术语 : processes, threads, connections

2024-03-19 17:04  abce  阅读(133)  评论(0编辑  收藏  举报

MySQL 是单进程、多线程架构。通常说的连接(connections)是指TCP/IP连接。每个连接对应一个专用的线程。
但是这些线程有时候被叫做进程,有时候被当作连接。这也是为什么processes, threads, connections三者会让人产生混淆的原因。

MySQL 确实是一个单进程服务器。它是多线程的,因为服务器上有许多明显的和不太明显的线程。这些线程包括 InnoDB I/O 线程、DELAYED INSERT线程等。当然还有连接线程。稍后会详细介绍。

在较旧的 Linux 版本或 glibc-static 版本上,人们可能会把 MySQL 看成是一个多进程服务器。其实不然:这只是因为线程被映射到了操作系统进程。mysqld 是单个进程。

因此,每个新连接都有自己的线程。假设没有使用线程池,那么每个新连接都会创建一个新线程,而断开连接则会导致该线程被销毁。因此,连接和活动线程之间存在 1-1 映射关系。
但是,线程池意味着可能存在与任何连接都不相关的线程。

这里就是术语容易混淆的地方。当你想查看服务器上正在执行的程序时,可以发出 SHOW PROCESSLIST(显示进程列表):

>show processlist;
+----------+-----------------+---------------------+-----------+------------------+----------+-----------------------------------------------------------------+------------------+
| Id       | User            | Host                | db        | Command          | Time     | State                                                           | Info             |
+----------+-----------------+---------------------+-----------+------------------+----------+-----------------------------------------------------------------+------------------+
|        5 | event_scheduler | localhost           | NULL      | Daemon           | 20196680 | Waiting on empty queue                                          | NULL             |
| 48151579 | root            | localhost           | NULL      | Query            |        0 | init                                                            | show processlist |
...
+----------+-----------------+---------------------+-----------+------------------+----------+-----------------------------------------------------------------+------------------+

这里也许叫做"show threadlist"可能更合适!!!毕竟输出显示的不是真的进程。

这里 id=48151579 就是我当前创建的连接:

>SELECT CONNECTION_ID();
+-----------------+
| CONNECTION_ID() |
+-----------------+
|        48151579 |
+-----------------+

查看当前有多少活跃的进程或连接,可以通过Threads_running状态变量来查看:

>SHOW GLOBAL STATUS LIKE 'Threads_running';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| Threads_running | 5     |
+-----------------+-------+

在MySQL 8.0中,information_schema.processlist表已经过期,在以后的版本中会被移除。因此,使用information_schema.processlist表的show processlist也过期了。现在推荐使用performance_schema.processlist表。

information_schema.processlist.id 等价于 show processlist中显示的id,等价于performance_schema.threads.processlist_id。

>select thread_id,processlist_id,thread_os_id from performance_schema.threads;
+-----------+----------------+--------------+
| thread_id | processlist_id | thread_os_id |
+-----------+----------------+--------------+
|         1 |           NULL |         9240 |
|         3 |           NULL |         9248 |
|  48170655 |       48170192 |        34483 |
...

这里的thread_os_id是mysql内部线程对应的系统线程id。可以通过操作系统命令ps查看:ps -Lef|grep <thread_os_id>
对于前台线程(与用户连接有关),processlist_id表示连接标识符,等价于information_schema.processlist.id,也等价于show processlist中显示的id。
对于后台线程(与用户连接无关),processlist_id是null。

写到这里,看起来还是有点乱。