--1、top -H 查看具體線程的CPU消耗
[root@hostmysql80 mysql]# top -H
--2、iotop -u mysql 查看具體線程的IO消耗
[root@hostmysql80 mysql_setup]# iotop -u mysql
--3、mysql中 查看操作系統線程id(thread_os_id) 和sql 對應
SELECT a.name,
a.thread_id,
a.thread_os_id, //操作系統的線程id (top -H 對應PID, iotop -u mysql 對應TID)
a.processlist_id, //mysql進程id,可以kill query 或者kill (connection)殺掉。
a.type, //線程類型,分前臺線程和後臺線程
b.user, //用戶
b.host, //ip
b.db, //操作的庫名稱
b.command, //sql類型
b.time, //sql執行時間 單位:秒
b.state, //sql狀態
b.info //sql語句
FROM performance_schema.threads a
LEFT JOIN information_schema.processlist b
ON a.processlist_id = b.id
where a.type = 'FOREGROUND';
--1、執行一個大sql
mysql> update test_limit_table set b=round(rand()*b,0);
--2、查看cpu高的線程是 2142,top -H 的時候 此時PID不是進程ID 而是線程id(LWP id)
[root@hostmysql80 mysql]# top -H
top - 10:41:23 up 17 min, 4 users, load average: 2.38, 2.39, 1.41
Threads: 324 total, 2 running, 322 sleeping, 0 stopped, 0 zombie
%Cpu(s): 69.9 us, 17.8 sy, 0.0 ni, 0.0 id, 10.3 wa, 0.0 hi, 2.1 si, 0.0 st
KiB Mem : 284388 total, 4424 free, 162408 used, 117556 buff/cache
KiB Swap: 2097148 total, 1566856 free, 530292 used. 79560 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2142 mysql 20 0 2195448 74992 2348 R 83.1 26.4 0:03.78 mysqld
27 root 20 0 0 0 0 S 0.7 0.0 0:24.16 kswapd0
--3、查看 2142線程的 具體的sql
mysql> SELECT a.name,
a.thread_id,
a.thread_os_id,
a.processlist_id,
a.type,
b.user,
b.host,
b.db,
b.command,
b.time,
b.state,
b.info
FROM performance_schema.threads a
LEFT JOIN information_schema.processlist b
ON a.processlist_id = b.id
where a.type = 'FOREGROUND'
and a.thread_os_id =2142;
+---------------------------+-----------+--------------+----------------+------------+------+-----------+-------+---------+------+----------+-------------------------------------------------+
| name | thread_id | thread_os_id | processlist_id | type | user | host | db | command | time | state | info |
+---------------------------+-----------+--------------+----------------+------------+------+-----------+-------+---------+------+----------+-------------------------------------------------+
| thread/sql/one_connection | 34 | 2142 | 7 | FOREGROUND | root | localhost | flydb | Query | 28 | updating | update test_limit_table set b=round(rand()*b,0) |
+---------------------------+-----------+--------------+----------------+------------+------+-----------+-------+---------+------+----------+-------------------------------------------------+
1 row in set (2.23 sec)
--4、同理 監控IO資源的具體線程id 是TID, 也是2142線程
[root@hostmysql80 mysql_setup]# iotop -u mysql
Total DISK READ : 24.30 M/s | Total DISK WRITE : 23.36 M/s
Actual DISK READ: 45.48 M/s | Actual DISK WRITE: 26.56 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
2142 be/4 mysql 7.33 M/s 1051.47 K/s 51.21 % 11.29 % mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
2108 be/4 mysql 2.20 M/s 7.73 M/s 0.00 % 8.03 % mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
2115 be/4 mysql 9.18 M/s 0.00 B/s 0.00 % 5.11 % mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
2117 be/4 mysql 1669.21 K/s 1113.90 K/s 0.00 % 4.82 % mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
2110 be/4 mysql 2.71 M/s 7.83 M/s 1.89 % 4.24 % mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
2106 be/4 mysql 0.00 B/s 0.00 B/s 0.00 % 2.41 % mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
2109 be/4 mysql 0.00 B/s 3.75 M/s 0.00 % 2.41 % mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
.......
--1、linux和POSIX的線程概念:
第一種:在linux下每一個進程都一個進程id,類型pid_t,可以由 getpid()獲取。
第二種:POSIX線程也有線程id,類型pthread_t,可以由 pthread_self()獲取,線程id由線程庫維護。
但是各個進程獨立,所以會有不同進程中線程號相同節的情況。那麼這樣就會存在一個問題,我的進程p1中的線程pt1要與進程p2中的線程pt2通信怎麼辦,進程id不可以,線程id又可能重複,所以這裏會有一個真實的線程id唯一標識,tid。glibc沒有實現gettid的函數,所以我們可以通過linux下的系統調用 syscall(SYS_gettid) 來獲得。
--2、performance_schema.threads表的 thread_os_id字段的 來源 如下: linux環境下 是由syscall(SYS_gettid)實現gettid函數 來獲得 是第一種 是linux下進程的中的線程id
/**
Return the operating system thread id.
With Linux, threads have:
- an internal id, @c pthread_self(), visible in process
- an external id, @c gettid(), visible in the operating system,
for example with perf in linux.
This helper returns the underling operating system thread id.
*/
static inline my_thread_os_id_t my_thread_os_id()
{
...
#ifdef HAVE_SYS_GETTID
/*
Linux.
See man gettid
See GLIBC Bug 6399 - gettid() should have a wrapper
https://sourceware.org/bugzilla/show_bug.cgi?id=6399
*/
return syscall(SYS_gettid); //linux環境下 是由syscall(SYS_gettid)實現gettid函數 來獲得 是第一種 是linux下進程的中的線程id
#else
#ifdef _WIN32
/* Windows */
return GetCurrentThreadId(); //windows環境下 用的是GetCurrentThreadId() 返回系統線程id
#else
.......
}
--3、查看 show engine innodb status 中的 該sql語句的OS thread handle 爲 140090860746496。 和 2142的linux下線程id 不同。 是第二種 POSIX線程的線程id,由pthread_self()函數取得。
mysql> show engine innodb status\G
...
------------
TRANSACTIONS
------------
....
MySQL thread id 7, OS thread handle 140090860746496, query id 98 localhost root updating
update test_limit_table set b=round(rand()*b,0)
......
--源碼,linux環境是調用pthread_self()返回 POSIX線程的線程id。 而windows系統依然是GetCurrentThreadId()函數返回的線程id。
static inline my_thread_t my_thread_self()
{
#ifdef _WIN32
return GetCurrentThreadId();
#else
return pthread_self();
#endif
}
總結: linux環境下 , performance_schema.threads表的 thread_os_id字段 是由syscall(SYS_gettid)實現gettid函數 來獲得 linux的線程id。
show engine innodb status 中的OS thread handle 是由pthread_self()函數 來獲得 POSIX線程的線程id。
windows環境下, performance_schema.threads表的 thread_os_id字段 和 show engine innodb status 中的OS thread handle 都是由GetCurrentThreadId() 函數獲得一致的系統線程id