Skip to content
This repository was archived by the owner on Aug 28, 2024. It is now read-only.

Commit ab18b6e

Browse files
committed
Add ps_thread_stack() function, to print a full Performance Schema thread stack, in JSON format, with SELECT sys.ps_thread_stack(<thd_id>, <debug>);
1 parent fedf32f commit ab18b6e

File tree

4 files changed

+198
-0
lines changed

4 files changed

+198
-0
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,31 @@ mysql> SELECT sys.ps_is_account_enabled('localhost', 'root');
259259
1 row in set (0.01 sec)
260260
```
261261

262+
#### ps_thread_stack
263+
264+
##### Description
265+
266+
Outputs a JSON formatted stack of all statements, stages and events within Performance Schema for the specified thread.
267+
268+
##### Parameters
269+
270+
* thd_id (BIGINT): The id of the thread to trace. This should match the thread_id column from the performance_schema.threads table.
271+
272+
##### Example
273+
274+
(line separation added for output)
275+
276+
```SQL
277+
mysql> SELECT sys.ps_thread_stack(37, FALSE) AS thread_stack\\G
278+
*************************** 1. row ***************************
279+
thread_stack: {"rankdir": "LR","nodesep": "0.10","stack_created": "2014-02-19 13:39:03",
280+
"mysql_version": "5.7.3-m13","mysql_user": "root@localhost","events":
281+
[{"nesting_event_id": "0", "event_id": "10", "timer_wait": 256.35, "event_info":
282+
"sql/select", "wait_info": "select @@version_comment limit 1\\nerrors: 0\\nwarnings: 0\\nlock time:
283+
...
284+
```
285+
286+
262287
### Procedures
263288
264289
#### create_synonym_db

functions/ps_thread_stack.sql

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
2+
3+
This program is free software; you can redistribute it and/or modify
4+
it under the terms of the GNU General Public License as published by
5+
the Free Software Foundation; version 2 of the License.
6+
7+
This program is distributed in the hope that it will be useful,
8+
but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
GNU General Public License for more details.
11+
12+
You should have received a copy of the GNU General Public License
13+
along with this program; if not, write to the Free Software
14+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15+
16+
DROP FUNCTION IF EXISTS ps_thread_stack;
17+
18+
DELIMITER $$
19+
20+
CREATE DEFINER='root'@'localhost' FUNCTION ps_thread_stack (
21+
thd_id INT,
22+
debug BOOLEAN
23+
)
24+
RETURNS LONGTEXT CHARSET latin1
25+
COMMENT '
26+
Description
27+
-----------
28+
29+
Outputs a JSON formatted stack of all statements, stages and events
30+
within Performance Schema for the specified thread.
31+
32+
Parameters
33+
-----------
34+
35+
thd_id (BIGINT):
36+
The id of the thread to trace. This should match the thread_id
37+
column from the performance_schema.threads table.
38+
in_verbose (BOOLEAN):
39+
Include file:lineno information in the events.
40+
41+
Example
42+
-----------
43+
44+
(line separation added for output)
45+
46+
mysql> SELECT sys.ps_thread_stack(37, FALSE) AS thread_stack\\G
47+
*************************** 1. row ***************************
48+
thread_stack: {"rankdir": "LR","nodesep": "0.10","stack_created": "2014-02-19 13:39:03",
49+
"mysql_version": "5.7.3-m13","mysql_user": "root@localhost","events":
50+
[{"nesting_event_id": "0", "event_id": "10", "timer_wait": 256.35, "event_info":
51+
"sql/select", "wait_info": "select @@version_comment limit 1\\nerrors: 0\\nwarnings: 0\\nlock time:
52+
...
53+
'
54+
SQL SECURITY INVOKER
55+
NOT DETERMINISTIC
56+
READS SQL DATA
57+
BEGIN
58+
59+
DECLARE json_objects LONGTEXT;
60+
61+
/*!50602
62+
/* Do not track the current thread, it will kill the stack */
63+
UPDATE performance_schema.threads
64+
SET instrumented = 'NO'
65+
WHERE processlist_id = CONNECTION_ID();
66+
*/
67+
68+
SET SESSION group_concat_max_len=@@global.max_allowed_packet;
69+
70+
/* Select the entire stack of events */
71+
SELECT GROUP_CONCAT(CONCAT( '{'
72+
, CONCAT_WS( ', '
73+
, CONCAT('"nesting_event_id": "', IF(nesting_event_id IS NULL, '0', nesting_event_id), '"')
74+
, CONCAT('"event_id": "', event_id, '"')
75+
/* Convert from picoseconds to microseconds */
76+
, CONCAT( '"timer_wait": ', ROUND(timer_wait/1000000, 2))
77+
, CONCAT( '"event_info": "'
78+
, CASE
79+
WHEN event_name NOT LIKE 'wait/io%' THEN SUBSTRING_INDEX(event_name, '/', -2)
80+
WHEN event_name NOT LIKE 'wait/io/file%' OR event_name NOT LIKE 'wait/io/socket%' THEN SUBSTRING_INDEX(event_name, '/', -4)
81+
ELSE event_name
82+
END
83+
, '"'
84+
)
85+
/* Always dump the extra wait information gathered for statements */
86+
, CONCAT( '"wait_info": "', IFNULL(wait_info, ''), '"')
87+
/* If debug is enabled, add the file:lineno information for waits */
88+
, CONCAT( '"source": "', IF(true AND event_name LIKE 'wait%', IFNULL(wait_info, ''), ''), '"')
89+
/* Depending on the type of event, name it appropriately */
90+
, CASE
91+
WHEN event_name LIKE 'wait/io/file%' THEN '"event_type": "io/file"'
92+
WHEN event_name LIKE 'wait/io/table%' THEN '"event_type": "io/table"'
93+
WHEN event_name LIKE 'wait/io/socket%' THEN '"event_type": "io/socket"'
94+
WHEN event_name LIKE 'wait/synch/mutex%' THEN '"event_type": "synch/mutex"'
95+
WHEN event_name LIKE 'wait/synch/cond%' THEN '"event_type": "synch/cond"'
96+
WHEN event_name LIKE 'wait/synch/rwlock%' THEN '"event_type": "synch/rwlock"'
97+
WHEN event_name LIKE 'wait/lock%' THEN '"event_type": "lock"'
98+
WHEN event_name LIKE 'statement/%' THEN '"event_type": "stmt"'
99+
WHEN event_name LIKE 'stage/%' THEN '"event_type": "stage"'
100+
WHEN event_name LIKE '%idle%' THEN '"event_type": "idle"'
101+
ELSE ''
102+
END
103+
)
104+
, '}'
105+
)
106+
ORDER BY event_id ASC SEPARATOR ',') event
107+
INTO json_objects
108+
FROM (
109+
/*!50600
110+
/* Select all statements, with the extra tracing information available */
111+
(SELECT thread_id, event_id, event_name, timer_wait, timer_start, nesting_event_id,
112+
CONCAT(sql_text, '\\n',
113+
'errors: ', errors, '\\n',
114+
'warnings: ', warnings, '\\n',
115+
'lock time: ', ROUND(lock_time/1000000, 2),'us\\n',
116+
'rows affected: ', rows_affected, '\\n',
117+
'rows sent: ', rows_sent, '\\n',
118+
'rows examined: ', rows_examined, '\\n',
119+
'tmp tables: ', created_tmp_tables, '\\n',
120+
'tmp disk tables: ', created_tmp_disk_tables, '\\n',
121+
'select scan: ', select_scan, '\\n',
122+
'select full join: ', select_full_join, '\\n',
123+
'select full range join: ', select_full_range_join, '\\n',
124+
'select range: ', select_range, '\\n',
125+
'select range check: ', select_range_check, '\\n',
126+
'sort merge passes: ', sort_merge_passes, '\\n',
127+
'sort rows: ', sort_rows, '\\n',
128+
'sort range: ', sort_range, '\\n',
129+
'sort scan: ', sort_scan, '\\n',
130+
'no index used: ', IF(no_index_used, 'TRUE', 'FALSE'), '\\n',
131+
'no good index used: ', IF(no_good_index_used, 'TRUE', 'FALSE'), '\\n'
132+
) AS wait_info
133+
FROM performance_schema.events_statements_history_long WHERE thread_id = thd_id)
134+
UNION
135+
/* Select all stages */
136+
(SELECT thread_id, event_id, event_name, timer_wait, timer_start, nesting_event_id, null AS wait_info
137+
FROM performance_schema.events_stages_history_long WHERE thread_id = thd_id)
138+
UNION*/
139+
/* Select all events, adding information appropriate to the event */
140+
(SELECT thread_id, event_id,
141+
CONCAT(event_name ,
142+
IF(event_name NOT LIKE 'wait/synch/mutex%', IFNULL(CONCAT(' - ', operation), ''), ''),
143+
IF(number_of_bytes IS NOT NULL, CONCAT(' ', number_of_bytes, ' bytes'), ''),
144+
IF(event_name LIKE 'wait/io/file%', '\\n', ''),
145+
IF(object_schema IS NOT NULL, CONCAT('\\nObject: ', object_schema, '.'), ''),
146+
IF(object_name IS NOT NULL,
147+
IF (event_name LIKE 'wait/io/socket%',
148+
/* Print the socket if used, else the IP:port as reported */
149+
CONCAT(IF (object_name LIKE ':0%', @@socket, object_name)),
150+
object_name),
151+
''),
152+
/*!50600 IF(index_name IS NOT NULL, CONCAT(' Index: ', index_name), ''),*/'\\n'
153+
) AS event_name,
154+
timer_wait, timer_start, nesting_event_id, source AS wait_info
155+
FROM performance_schema.events_waits_history_long WHERE thread_id = thd_id)) events
156+
ORDER BY event_id;
157+
158+
RETURN CONCAT('{',
159+
CONCAT_WS(',',
160+
'"rankdir": "LR"',
161+
'"nodesep": "0.10"',
162+
CONCAT('"stack_created": "', NOW(), '"'),
163+
CONCAT('"mysql_version": "', VERSION(), '"'),
164+
CONCAT('"mysql_user": "', CURRENT_USER(), '"'),
165+
CONCAT('"events": [', IFNULL(json_objects,''), ']')
166+
),
167+
'}');
168+
169+
END$$
170+
171+
DELIMITER ;

sys_56.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ SOURCE ./functions/format_path.sql
2222
SOURCE ./functions/format_statement.sql
2323
SOURCE ./functions/format_time.sql
2424
SOURCE ./functions/ps_is_account_enabled.sql
25+
SOURCE ./functions/ps_thread_stack.sql
2526

2627
SOURCE ./procedures/create_synonym_db.sql
2728

sys_57.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ SOURCE ./functions/format_path.sql
2222
SOURCE ./functions/format_statement.sql
2323
SOURCE ./functions/format_time.sql
2424
SOURCE ./functions/ps_is_account_enabled.sql
25+
SOURCE ./functions/ps_thread_stack.sql
2526

2627
SOURCE ./procedures/create_synonym_db.sql
2728

0 commit comments

Comments
 (0)