|
| 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 ; |
0 commit comments