summaryrefslogtreecommitdiffstats
path: root/scripts/sys_schema/procedures/diagnostics.sql
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/sys_schema/procedures/diagnostics.sql')
-rw-r--r--scripts/sys_schema/procedures/diagnostics.sql1064
1 files changed, 1064 insertions, 0 deletions
diff --git a/scripts/sys_schema/procedures/diagnostics.sql b/scripts/sys_schema/procedures/diagnostics.sql
new file mode 100644
index 00000000..2e79c5c1
--- /dev/null
+++ b/scripts/sys_schema/procedures/diagnostics.sql
@@ -0,0 +1,1064 @@
+-- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; version 2 of the License.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+DROP PROCEDURE IF EXISTS diagnostics;
+
+DELIMITER $$
+
+CREATE DEFINER='mariadb.sys'@'localhost' PROCEDURE diagnostics (
+ IN in_max_runtime int unsigned, IN in_interval int unsigned,
+ IN in_auto_config enum ('current', 'medium', 'full')
+ )
+ COMMENT '
+ Description
+ -----------
+
+ Create a report of the current status of the server for diagnostics purposes. Data collected includes (some items depends on versions and settings):
+
+ * The GLOBAL VARIABLES
+ * Several sys schema views including metrics or equivalent (depending on version and settings)
+ * Queries in the 95th percentile
+ * Several ndbinfo views for MySQL Cluster
+ * Replication (both master and slave) information.
+
+ Some of the sys schema views are calculated as initial (optional), overall, delta:
+
+ * The initial view is the content of the view at the start of this procedure.
+ This output will be the same as the the start values used for the delta view.
+ The initial view is included if @sys.diagnostics.include_raw = ''ON''.
+ * The overall view is the content of the view at the end of this procedure.
+ This output is the same as the end values used for the delta view.
+ The overall view is always included.
+ * The delta view is the difference from the beginning to the end. Note that for min and max values
+ they are simply the min or max value from the end view respectively, so does not necessarily reflect
+ the minimum/maximum value in the monitored period.
+ Note: except for the metrics views the delta is only calculation between the first and last outputs.
+
+ Requires the SUPER privilege for "SET sql_log_bin = 0;".
+
+ Versions supported:
+ * MySQL 5.6: 5.6.10 and later
+ * MySQL 5.7: 5.7.9 and later
+
+ Parameters
+ -----------
+
+ in_max_runtime (INT UNSIGNED):
+ The maximum time to keep collecting data.
+ Use NULL to get the default which is 60 seconds, otherwise enter a value greater than 0.
+ in_interval (INT UNSIGNED):
+ How long to sleep between data collections.
+ Use NULL to get the default which is 30 seconds, otherwise enter a value greater than 0.
+ in_auto_config (ENUM(''current'', ''medium'', ''full''))
+ Automatically enable Performance Schema instruments and consumers.
+ NOTE: The more that are enabled, the more impact on the performance.
+ Supported values are:
+ * current - use the current settings.
+ * medium - enable some settings.
+ * full - enables all settings. This will have a big impact on the
+ performance - be careful using this option.
+ If another setting the ''current'' is chosen, the current settings
+ are restored at the end of the procedure.
+
+
+ Configuration Options
+ ----------------------
+
+ sys.diagnostics.allow_i_s_tables
+ Specifies whether it is allowed to do table scan queries on information_schema.TABLES. This can be expensive if there
+ are many tables. Set to ''ON'' to allow, ''OFF'' to not allow.
+ Default is ''OFF''.
+
+ sys.diagnostics.include_raw
+ Set to ''ON'' to include the raw data (e.g. the original output of "SELECT * FROM sys.metrics").
+ Use this to get the initial values of the various views.
+ Default is ''OFF''.
+
+ sys.statement_truncate_len
+ How much of queries in the process list output to include.
+ Default is 64.
+
+ sys.debug
+ Whether to provide debugging output.
+ Default is ''OFF''. Set to ''ON'' to include.
+
+
+ Example
+ --------
+
+ To create a report and append it to the file diag.out:
+
+ mysql> TEE diag.out;
+ mysql> CALL sys.diagnostics(120, 30, ''current'');
+ ...
+ mysql> NOTEE;
+ '
+ SQL SECURITY INVOKER
+ NOT DETERMINISTIC
+ READS SQL DATA
+BEGIN
+ DECLARE v_start, v_runtime, v_iter_start, v_sleep DECIMAL(20,2) DEFAULT 0.0;
+ DECLARE v_has_innodb, v_has_ndb, v_has_ps, v_has_replication, v_has_ps_replication VARCHAR(8) CHARSET utf8 DEFAULT 'NO';
+ DECLARE v_this_thread_enabled, v_has_ps_vars, v_has_metrics ENUM('YES', 'NO');
+ DECLARE v_table_name, v_banner VARCHAR(64) CHARSET utf8;
+ DECLARE v_sql_status_summary_select, v_sql_status_summary_delta, v_sql_status_summary_from, v_no_delta_names TEXT;
+ DECLARE v_output_time, v_output_time_prev DECIMAL(20,3) UNSIGNED;
+ DECLARE v_output_count, v_count, v_old_group_concat_max_len INT UNSIGNED DEFAULT 0;
+ -- The width of each of the status outputs in the summery
+ DECLARE v_status_summary_width TINYINT UNSIGNED DEFAULT 50;
+ DECLARE v_done BOOLEAN DEFAULT FALSE;
+ -- Do not include the following ndbinfo views:
+ -- 'blocks' Static
+ -- 'config_params' Static
+ -- 'dict_obj_types' Static
+ -- 'disk_write_speed_base' Can generate lots of output - only include aggregate views here
+ -- 'memory_per_fragment' Can generate lots of output
+ -- 'memoryusage' Handled separately
+ -- 'operations_per_fragment' Can generate lots of output
+ -- 'threadblocks' Only needed once
+ DECLARE c_ndbinfo CURSOR FOR
+ SELECT TABLE_NAME
+ FROM information_schema.TABLES
+ WHERE TABLE_SCHEMA = 'ndbinfo'
+ AND TABLE_NAME NOT IN (
+ 'blocks',
+ 'config_params',
+ 'dict_obj_types',
+ 'disk_write_speed_base',
+ 'memory_per_fragment',
+ 'memoryusage',
+ 'operations_per_fragment',
+ 'threadblocks'
+ );
+ DECLARE c_sysviews_w_delta CURSOR FOR
+ SELECT table_name
+ FROM tmp_sys_views_delta
+ ORDER BY table_name;
+ DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
+
+ -- Do not track the current thread - no reason to clutter the output
+ SELECT INSTRUMENTED INTO v_this_thread_enabled FROM performance_schema.threads WHERE PROCESSLIST_ID = CONNECTION_ID();
+ IF (v_this_thread_enabled = 'YES') THEN
+ CALL sys.ps_setup_disable_thread(CONNECTION_ID());
+ END IF;
+
+ -- Check options are sane
+ IF (in_max_runtime < in_interval) THEN
+ SIGNAL SQLSTATE '45000'
+ SET MESSAGE_TEXT = 'in_max_runtime must be greater than or equal to in_interval';
+ END IF;
+ IF (in_max_runtime = 0) THEN
+ SIGNAL SQLSTATE '45000'
+ SET MESSAGE_TEXT = 'in_max_runtime must be greater than 0';
+ END IF;
+ IF (in_interval = 0) THEN
+ SIGNAL SQLSTATE '45000'
+ SET MESSAGE_TEXT = 'in_interval must be greater than 0';
+ END IF;
+
+ -- Set configuration options
+ IF (@sys.diagnostics.allow_i_s_tables IS NULL) THEN
+ SET @sys.diagnostics.allow_i_s_tables = sys.sys_get_config('diagnostics.allow_i_s_tables', 'OFF');
+ END IF;
+ IF (@sys.diagnostics.include_raw IS NULL) THEN
+ SET @sys.diagnostics.include_raw = sys.sys_get_config('diagnostics.include_raw' , 'OFF');
+ END IF;
+ IF (@sys.debug IS NULL) THEN
+ SET @sys.debug = sys.sys_get_config('debug' , 'OFF');
+ END IF;
+ IF (@sys.statement_truncate_len IS NULL) THEN
+ SET @sys.statement_truncate_len = sys.sys_get_config('statement_truncate_len' , '64' );
+ END IF;
+
+ -- Temporary table are used - disable sql_log_bin if necessary to prevent them replicating
+ SET @log_bin := @@sql_log_bin;
+ IF (@log_bin = 1) THEN
+ SET sql_log_bin = 0;
+ END IF;
+
+ -- Some metrics variables doesn't make sense in delta and rate calculations even if they are numeric
+ -- as they really are more like settings or "current" status.
+ SET v_no_delta_names = CONCAT('s%{COUNT}.Variable_name NOT IN (',
+ '''innodb_buffer_pool_pages_total'', ',
+ '''innodb_page_size'', ',
+ '''last_query_cost'', ',
+ '''last_query_partial_plans'', ',
+ '''qcache_total_blocks'', ',
+ '''slave_last_heartbeat'', ',
+ '''ssl_ctx_verify_depth'', ',
+ '''ssl_ctx_verify_mode'', ',
+ '''ssl_session_cache_size'', ',
+ '''ssl_verify_depth'', ',
+ '''ssl_verify_mode'', ',
+ '''ssl_version'', ',
+ '''buffer_flush_lsn_avg_rate'', ',
+ '''buffer_flush_pct_for_dirty'', ',
+ '''buffer_flush_pct_for_lsn'', ',
+ '''buffer_pool_pages_total'', ',
+ '''lock_row_lock_time_avg'', ',
+ '''lock_row_lock_time_max'', ',
+ '''innodb_page_size''',
+ ')');
+
+ IF (in_auto_config <> 'current') THEN
+ IF (@sys.debug = 'ON') THEN
+ SELECT CONCAT('Updating Performance Schema configuration to ', in_auto_config) AS 'Debug';
+ END IF;
+ CALL sys.ps_setup_save(0);
+
+ IF (in_auto_config = 'medium') THEN
+ -- Enable all consumers except %history and %history_long
+ UPDATE performance_schema.setup_consumers
+ SET ENABLED = 'YES'
+ WHERE NAME NOT LIKE '%\_history%';
+
+ -- Enable all instruments except wait/synch/%
+ UPDATE performance_schema.setup_instruments
+ SET ENABLED = 'YES',
+ TIMED = 'YES'
+ WHERE NAME NOT LIKE 'wait/synch/%';
+ ELSEIF (in_auto_config = 'full') THEN
+ UPDATE performance_schema.setup_consumers
+ SET ENABLED = 'YES';
+
+ UPDATE performance_schema.setup_instruments
+ SET ENABLED = 'YES',
+ TIMED = 'YES';
+ END IF;
+
+ -- Enable all threads except this one
+ UPDATE performance_schema.threads
+ SET INSTRUMENTED = 'YES'
+ WHERE PROCESSLIST_ID <> CONNECTION_ID();
+ END IF;
+
+ SET v_start = UNIX_TIMESTAMP(NOW(2)),
+ in_interval = IFNULL(in_interval, 30),
+ in_max_runtime = IFNULL(in_max_runtime, 60);
+
+ -- Get a quick ref with hostname, server UUID, and the time for the report.
+ SET v_banner = REPEAT(
+ '-',
+ LEAST(
+ GREATEST(
+ 36,
+ CHAR_LENGTH(VERSION()),
+ CHAR_LENGTH(@@global.version_comment),
+ CHAR_LENGTH(@@global.version_compile_os),
+ CHAR_LENGTH(@@global.version_compile_machine),
+ CHAR_LENGTH(@@global.socket),
+ CHAR_LENGTH(@@global.datadir)
+ ),
+ 64
+ )
+ );
+ SELECT 'Hostname' AS 'Name', @@global.hostname AS 'Value'
+ UNION ALL
+ SELECT 'Port' AS 'Name', @@global.port AS 'Value'
+ UNION ALL
+ SELECT 'Socket' AS 'Name', @@global.socket AS 'Value'
+ UNION ALL
+ SELECT 'Datadir' AS 'Name', @@global.datadir AS 'Value'
+ UNION ALL
+ SELECT REPEAT('-', 23) AS 'Name', v_banner AS 'Value'
+ UNION ALL
+ SELECT 'MySQL Version' AS 'Name', VERSION() AS 'Value'
+ UNION ALL
+ SELECT 'Sys Schema Version' AS 'Name', (SELECT sys_version FROM sys.version) AS 'Value'
+ UNION ALL
+ SELECT 'Version Comment' AS 'Name', @@global.version_comment AS 'Value'
+ UNION ALL
+ SELECT 'Version Compile OS' AS 'Name', @@global.version_compile_os AS 'Value'
+ UNION ALL
+ SELECT 'Version Compile Machine' AS 'Name', @@global.version_compile_machine AS 'Value'
+ UNION ALL
+ SELECT REPEAT('-', 23) AS 'Name', v_banner AS 'Value'
+ UNION ALL
+ SELECT 'UTC Time' AS 'Name', UTC_TIMESTAMP() AS 'Value'
+ UNION ALL
+ SELECT 'Local Time' AS 'Name', NOW() AS 'Value'
+ UNION ALL
+ SELECT 'Time Zone' AS 'Name', @@global.time_zone AS 'Value'
+ UNION ALL
+ SELECT 'System Time Zone' AS 'Name', @@global.system_time_zone AS 'Value'
+ UNION ALL
+ SELECT 'Time Zone Offset' AS 'Name', TIMEDIFF(NOW(), UTC_TIMESTAMP()) AS 'Value';
+
+ -- Are the InnoDB, NDBCluster, and Performance Schema storage engines present?
+ SET v_has_innodb = IFNULL((SELECT SUPPORT FROM information_schema.ENGINES WHERE ENGINE = 'InnoDB'), 'NO'),
+ v_has_ndb = IFNULL((SELECT SUPPORT FROM information_schema.ENGINES WHERE ENGINE = 'NDBCluster'), 'NO'),
+ v_has_ps = IFNULL((SELECT SUPPORT FROM information_schema.ENGINES WHERE ENGINE = 'PERFORMANCE_SCHEMA'), 'NO'),
+ v_has_ps_replication = IF(v_has_ps = 'YES'
+ AND EXISTS(SELECT 1 FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'performance_schema' AND TABLE_NAME = 'replication_applier_status'),
+ 'YES',
+ 'NO'
+ ),
+ v_has_replication = 'MAYBE',
+ v_has_metrics = IF(v_has_ps = 'YES' OR (sys.version_major() = 5 AND sys.version_minor() = 6), 'YES', 'NO'),
+ v_has_ps_vars = 'NO';
+
+ -- 5.7.7 introduced the possibility to get SHOW [GLOBAL|SESSION] VARIABLES and SHOW [GLOBAL|SESSION] STATUS
+ -- from the Performance Schema. But it's optional whether it's enabled.
+ -- 5.7.9 changes so the Performance Schema tables always work.
+ -- Note that @@global.show_compatibility_56 = OFF will only actually work if the Performance Schema is enabled in <=5.7.8,
+ -- however except overriding the global value there is nothing that can be done about it.
+ -- v_has_ps_vars defaults to NO
+ /*!50707 SET v_has_ps_vars = IF(@@global.show_compatibility_56, 'NO', 'YES');*/
+ /*!50709 SET v_has_ps_vars = 'YES';*/
+
+ IF (@sys.debug = 'ON') THEN
+ SELECT v_has_innodb AS 'Has_InnoDB', v_has_ndb AS 'Has_NDBCluster',
+ v_has_ps AS 'Has_Performance_Schema', v_has_ps_vars AS 'Has_P_S_SHOW_Variables',
+ v_has_metrics AS 'Has_metrics',
+ v_has_ps_replication 'AS Has_P_S_Replication', v_has_replication AS 'Has_Replication';
+ END IF;
+
+ IF (v_has_innodb IN ('DEFAULT', 'YES')) THEN
+ -- Need to use prepared statement as just having the query as a plain command
+ -- will generate an error if the InnoDB storage engine is not present
+ SET @sys.diagnostics.sql = 'SHOW ENGINE InnoDB STATUS';
+ PREPARE stmt_innodb_status FROM @sys.diagnostics.sql;
+ END IF;
+
+ IF (v_has_ps = 'YES') THEN
+ -- Need to use prepared statement as just having the query as a plain command
+ -- will generate an error if the InnoDB storage engine is not present
+ SET @sys.diagnostics.sql = 'SHOW ENGINE PERFORMANCE_SCHEMA STATUS';
+ PREPARE stmt_ps_status FROM @sys.diagnostics.sql;
+ END IF;
+
+ IF (v_has_ndb IN ('DEFAULT', 'YES')) THEN
+ -- Need to use prepared statement as just having the query as a plain command
+ -- will generate an error if the NDBCluster storage engine is not present
+ SET @sys.diagnostics.sql = 'SHOW ENGINE NDBCLUSTER STATUS';
+ PREPARE stmt_ndbcluster_status FROM @sys.diagnostics.sql;
+ END IF;
+
+ SET @sys.diagnostics.sql_gen_query_template = 'SELECT CONCAT(
+ ''SELECT '',
+ GROUP_CONCAT(
+ CASE WHEN (SUBSTRING(TABLE_NAME, 3), COLUMN_NAME) IN (
+ (''io_global_by_file_by_bytes'', ''total''),
+ (''io_global_by_wait_by_bytes'', ''total_requested'')
+ )
+ THEN CONCAT(''sys.format_bytes('', COLUMN_NAME, '') AS '', COLUMN_NAME)
+ WHEN SUBSTRING(COLUMN_NAME, -8) = ''_latency''
+ THEN CONCAT(''sys.format_time('', COLUMN_NAME, '') AS '', COLUMN_NAME)
+ WHEN SUBSTRING(COLUMN_NAME, -7) = ''_memory'' OR SUBSTRING(COLUMN_NAME, -17) = ''_memory_allocated''
+ OR ((SUBSTRING(COLUMN_NAME, -5) = ''_read'' OR SUBSTRING(COLUMN_NAME, -8) = ''_written'' OR SUBSTRING(COLUMN_NAME, -6) = ''_write'') AND SUBSTRING(COLUMN_NAME, 1, 6) <> ''COUNT_'')
+ THEN CONCAT(''sys.format_bytes('', COLUMN_NAME, '') AS '', COLUMN_NAME)
+ ELSE COLUMN_NAME
+ END
+ ORDER BY ORDINAL_POSITION
+ SEPARATOR '',\n ''
+ ),
+ ''\n FROM tmp_'', SUBSTRING(TABLE_NAME FROM 3), ''_%{OUTPUT}''
+ ) AS Query INTO @sys.diagnostics.sql_select
+ FROM information_schema.COLUMNS
+ WHERE TABLE_SCHEMA = ''sys'' AND TABLE_NAME = ?
+ GROUP BY TABLE_NAME';
+
+ SET @sys.diagnostics.sql_gen_query_delta = 'SELECT CONCAT(
+ ''SELECT '',
+ GROUP_CONCAT(
+ CASE WHEN FIND_IN_SET(COLUMN_NAME, diag.pk)
+ THEN COLUMN_NAME
+ WHEN diag.TABLE_NAME = ''io_global_by_file_by_bytes'' AND COLUMN_NAME = ''write_pct''
+ THEN CONCAT(''IFNULL(ROUND(100-(((e.total_read-IFNULL(s.total_read, 0))'',
+ ''/NULLIF(((e.total_read-IFNULL(s.total_read, 0))+(e.total_written-IFNULL(s.total_written, 0))), 0))*100), 2), 0.00) AS '',
+ COLUMN_NAME)
+ WHEN (diag.TABLE_NAME, COLUMN_NAME) IN (
+ (''io_global_by_file_by_bytes'', ''total''),
+ (''io_global_by_wait_by_bytes'', ''total_requested'')
+ )
+ THEN CONCAT(''sys.format_bytes(e.'', COLUMN_NAME, ''-IFNULL(s.'', COLUMN_NAME, '', 0)) AS '', COLUMN_NAME)
+ WHEN SUBSTRING(COLUMN_NAME, 1, 4) IN (''max_'', ''min_'') AND SUBSTRING(COLUMN_NAME, -8) = ''_latency''
+ THEN CONCAT(''sys.format_time(e.'', COLUMN_NAME, '') AS '', COLUMN_NAME)
+ WHEN COLUMN_NAME = ''avg_latency''
+ THEN CONCAT(''sys.format_time((e.total_latency - IFNULL(s.total_latency, 0))'',
+ ''/NULLIF(e.total - IFNULL(s.total, 0), 0)) AS '', COLUMN_NAME)
+ WHEN SUBSTRING(COLUMN_NAME, -12) = ''_avg_latency''
+ THEN CONCAT(''sys.format_time((e.'', SUBSTRING(COLUMN_NAME FROM 1 FOR CHAR_LENGTH(COLUMN_NAME)-12), ''_latency - IFNULL(s.'', SUBSTRING(COLUMN_NAME FROM 1 FOR CHAR_LENGTH(COLUMN_NAME)-12), ''_latency, 0))'',
+ ''/NULLIF(e.'', SUBSTRING(COLUMN_NAME FROM 1 FOR CHAR_LENGTH(COLUMN_NAME)-12), ''s - IFNULL(s.'', SUBSTRING(COLUMN_NAME FROM 1 FOR CHAR_LENGTH(COLUMN_NAME)-12), ''s, 0), 0)) AS '', COLUMN_NAME)
+ WHEN SUBSTRING(COLUMN_NAME, -8) = ''_latency''
+ THEN CONCAT(''sys.format_time(e.'', COLUMN_NAME, '' - IFNULL(s.'', COLUMN_NAME, '', 0)) AS '', COLUMN_NAME)
+ WHEN COLUMN_NAME IN (''avg_read'', ''avg_write'', ''avg_written'')
+ THEN CONCAT(''sys.format_bytes(IFNULL((e.total_'', IF(COLUMN_NAME = ''avg_read'', ''read'', ''written''), ''-IFNULL(s.total_'', IF(COLUMN_NAME = ''avg_read'', ''read'', ''written''), '', 0))'',
+ ''/NULLIF(e.count_'', IF(COLUMN_NAME = ''avg_read'', ''read'', ''write''), ''-IFNULL(s.count_'', IF(COLUMN_NAME = ''avg_read'', ''read'', ''write''), '', 0), 0), 0)) AS '',
+ COLUMN_NAME)
+ WHEN SUBSTRING(COLUMN_NAME, -7) = ''_memory'' OR SUBSTRING(COLUMN_NAME, -17) = ''_memory_allocated''
+ OR ((SUBSTRING(COLUMN_NAME, -5) = ''_read'' OR SUBSTRING(COLUMN_NAME, -8) = ''_written'' OR SUBSTRING(COLUMN_NAME, -6) = ''_write'') AND SUBSTRING(COLUMN_NAME, 1, 6) <> ''COUNT_'')
+ THEN CONCAT(''sys.format_bytes(e.'', COLUMN_NAME, '' - IFNULL(s.'', COLUMN_NAME, '', 0)) AS '', COLUMN_NAME)
+ ELSE CONCAT(''(e.'', COLUMN_NAME, '' - IFNULL(s.'', COLUMN_NAME, '', 0)) AS '', COLUMN_NAME)
+ END
+ ORDER BY ORDINAL_POSITION
+ SEPARATOR '',\n ''
+ ),
+ ''\n FROM tmp_'', diag.TABLE_NAME, ''_end e
+ LEFT OUTER JOIN tmp_'', diag.TABLE_NAME, ''_start s USING ('', diag.pk, '')''
+ ) AS Query INTO @sys.diagnostics.sql_select
+ FROM tmp_sys_views_delta diag
+ INNER JOIN information_schema.COLUMNS c ON c.TABLE_NAME = CONCAT(''x$'', diag.TABLE_NAME)
+ WHERE c.TABLE_SCHEMA = ''sys'' AND diag.TABLE_NAME = ?
+ GROUP BY diag.TABLE_NAME';
+
+ IF (v_has_ps = 'YES') THEN
+ -- Create temporary table with the ORDER BY clauses. Will be required both for the initial (if included) and end queries
+ DROP TEMPORARY TABLE IF EXISTS tmp_sys_views_delta;
+ CREATE TEMPORARY TABLE tmp_sys_views_delta (
+ TABLE_NAME varchar(64) NOT NULL,
+ order_by text COMMENT 'ORDER BY clause for the initial and overall views',
+ order_by_delta text COMMENT 'ORDER BY clause for the delta views',
+ where_delta text COMMENT 'WHERE clause to use for delta views to only include rows with a "count" > 0',
+ limit_rows int unsigned COMMENT 'The maximum number of rows to include for the view',
+ pk varchar(128) COMMENT 'Used with the FIND_IN_SET() function so use comma separated list without whitespace',
+ PRIMARY KEY (TABLE_NAME)
+ );
+
+ -- %{OUTPUT} will be replace by the suffix used for the output.
+ IF (@sys.debug = 'ON') THEN
+ SELECT 'Populating tmp_sys_views_delta' AS 'Debug';
+ END IF;
+ INSERT INTO tmp_sys_views_delta
+ VALUES ('host_summary' , '%{TABLE}.statement_latency DESC',
+ '(e.statement_latency-IFNULL(s.statement_latency, 0)) DESC',
+ '(e.statements - IFNULL(s.statements, 0)) > 0', NULL, 'host'),
+ ('host_summary_by_file_io' , '%{TABLE}.io_latency DESC',
+ '(e.io_latency-IFNULL(s.io_latency, 0)) DESC',
+ '(e.ios - IFNULL(s.ios, 0)) > 0', NULL, 'host'),
+ ('host_summary_by_file_io_type' , '%{TABLE}.host, %{TABLE}.total_latency DESC',
+ 'e.host, (e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'host,event_name'),
+ ('host_summary_by_stages' , '%{TABLE}.host, %{TABLE}.total_latency DESC',
+ 'e.host, (e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'host,event_name'),
+ ('host_summary_by_statement_latency' , '%{TABLE}.total_latency DESC',
+ '(e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'host'),
+ ('host_summary_by_statement_type' , '%{TABLE}.host, %{TABLE}.total_latency DESC',
+ 'e.host, (e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'host,statement'),
+ ('io_by_thread_by_latency' , '%{TABLE}.total_latency DESC',
+ '(e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'user,thread_id,processlist_id'),
+ ('io_global_by_file_by_bytes' , '%{TABLE}.total DESC',
+ '(e.total-IFNULL(s.total, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', 100, 'file'),
+ ('io_global_by_file_by_latency' , '%{TABLE}.total_latency DESC',
+ '(e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', 100, 'file'),
+ ('io_global_by_wait_by_bytes' , '%{TABLE}.total_requested DESC',
+ '(e.total_requested-IFNULL(s.total_requested, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'event_name'),
+ ('io_global_by_wait_by_latency' , '%{TABLE}.total_latency DESC',
+ '(e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'event_name'),
+ ('schema_index_statistics' , '(%{TABLE}.select_latency+%{TABLE}.insert_latency+%{TABLE}.update_latency+%{TABLE}.delete_latency) DESC',
+ '((e.select_latency+e.insert_latency+e.update_latency+e.delete_latency)-IFNULL(s.select_latency+s.insert_latency+s.update_latency+s.delete_latency, 0)) DESC',
+ '((e.rows_selected+e.insert_latency+e.rows_updated+e.rows_deleted)-IFNULL(s.rows_selected+s.rows_inserted+s.rows_updated+s.rows_deleted, 0)) > 0',
+ 100, 'table_schema,table_name,index_name'),
+ ('schema_table_statistics' , '%{TABLE}.total_latency DESC',
+ '(e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total_latency-IFNULL(s.total_latency, 0)) > 0', 100, 'table_schema,table_name'),
+ ('schema_tables_with_full_table_scans', '%{TABLE}.rows_full_scanned DESC',
+ '(e.rows_full_scanned-IFNULL(s.rows_full_scanned, 0)) DESC',
+ '(e.rows_full_scanned-IFNULL(s.rows_full_scanned, 0)) > 0', 100, 'object_schema,object_name'),
+ ('user_summary' , '%{TABLE}.statement_latency DESC',
+ '(e.statement_latency-IFNULL(s.statement_latency, 0)) DESC',
+ '(e.statements - IFNULL(s.statements, 0)) > 0', NULL, 'user'),
+ ('user_summary_by_file_io' , '%{TABLE}.io_latency DESC',
+ '(e.io_latency-IFNULL(s.io_latency, 0)) DESC',
+ '(e.ios - IFNULL(s.ios, 0)) > 0', NULL, 'user'),
+ ('user_summary_by_file_io_type' , '%{TABLE}.user, %{TABLE}.latency DESC',
+ 'e.user, (e.latency-IFNULL(s.latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'user,event_name'),
+ ('user_summary_by_stages' , '%{TABLE}.user, %{TABLE}.total_latency DESC',
+ 'e.user, (e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'user,event_name'),
+ ('user_summary_by_statement_latency' , '%{TABLE}.total_latency DESC',
+ '(e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'user'),
+ ('user_summary_by_statement_type' , '%{TABLE}.user, %{TABLE}.total_latency DESC',
+ 'e.user, (e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'user,statement'),
+ ('wait_classes_global_by_avg_latency' , 'IFNULL(%{TABLE}.total_latency / NULLIF(%{TABLE}.total, 0), 0) DESC',
+ 'IFNULL((e.total_latency-IFNULL(s.total_latency, 0)) / NULLIF((e.total - IFNULL(s.total, 0)), 0), 0) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'event_class'),
+ ('wait_classes_global_by_latency' , '%{TABLE}.total_latency DESC',
+ '(e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'event_class'),
+ ('waits_by_host_by_latency' , '%{TABLE}.host, %{TABLE}.total_latency DESC',
+ 'e.host, (e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'host,event'),
+ ('waits_by_user_by_latency' , '%{TABLE}.user, %{TABLE}.total_latency DESC',
+ 'e.user, (e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'user,event'),
+ ('waits_global_by_latency' , '%{TABLE}.total_latency DESC',
+ '(e.total_latency-IFNULL(s.total_latency, 0)) DESC',
+ '(e.total - IFNULL(s.total, 0)) > 0', NULL, 'events')
+ ;
+ END IF;
+
+
+ SELECT '
+
+=======================
+
+ Configuration
+
+=======================
+
+' AS '';
+ -- Get the configuration.
+ SELECT 'GLOBAL VARIABLES' AS 'The following output is:';
+ IF (v_has_ps_vars = 'YES') THEN
+ SELECT LOWER(VARIABLE_NAME) AS Variable_name, VARIABLE_VALUE AS Variable_value FROM performance_schema.global_variables ORDER BY VARIABLE_NAME;
+ ELSE
+ SELECT LOWER(VARIABLE_NAME) AS Variable_name, VARIABLE_VALUE AS Variable_value FROM information_schema.GLOBAL_VARIABLES ORDER BY VARIABLE_NAME;
+ END IF;
+
+ IF (v_has_ps = 'YES') THEN
+ -- Overview of the Performance Schema dynamic settings used for this report.
+ SELECT 'Performance Schema Setup - Actors' AS 'The following output is:';
+ SELECT * FROM performance_schema.setup_actors;
+
+ SELECT 'Performance Schema Setup - Consumers' AS 'The following output is:';
+ SELECT NAME AS Consumer, ENABLED, sys.ps_is_consumer_enabled(NAME) AS COLLECTS
+ FROM performance_schema.setup_consumers;
+
+ SELECT 'Performance Schema Setup - Instruments' AS 'The following output is:';
+ SELECT SUBSTRING_INDEX(NAME, '/', 2) AS 'InstrumentClass',
+ ROUND(100*SUM(IF(ENABLED = 'YES', 1, 0))/COUNT(*), 2) AS 'EnabledPct',
+ ROUND(100*SUM(IF(TIMED = 'YES', 1, 0))/COUNT(*), 2) AS 'TimedPct'
+ FROM performance_schema.setup_instruments
+ GROUP BY SUBSTRING_INDEX(NAME, '/', 2)
+ ORDER BY SUBSTRING_INDEX(NAME, '/', 2);
+
+ SELECT 'Performance Schema Setup - Objects' AS 'The following output is:';
+ SELECT * FROM performance_schema.setup_objects;
+
+ SELECT 'Performance Schema Setup - Threads' AS 'The following output is:';
+ SELECT `TYPE` AS ThreadType, COUNT(*) AS 'Total', ROUND(100*SUM(IF(INSTRUMENTED = 'YES', 1, 0))/COUNT(*), 2) AS 'InstrumentedPct'
+ FROM performance_schema.threads
+ GROUP BY TYPE;
+ END IF;
+
+
+ IF (v_has_replication = 'NO') THEN
+ SELECT 'No Replication Configured' AS 'Replication Status';
+ ELSE
+ -- No guarantee that replication is actually configured, but we can't really know
+ SELECT CONCAT('Replication Configured: ', v_has_replication, ' - Performance Schema Replication Tables: ', v_has_ps_replication) AS 'Replication Status';
+
+ IF (v_has_ps_replication = 'YES') THEN
+ SELECT 'Replication - Connection Configuration' AS 'The following output is:';
+ SELECT * FROM performance_schema.replication_connection_configuration/*!50706 ORDER BY CHANNEL_NAME*/;
+ END IF;
+
+ IF (v_has_ps_replication = 'YES') THEN
+ SELECT 'Replication - Applier Configuration' AS 'The following output is:';
+ SELECT * FROM performance_schema.replication_applier_configuration ORDER BY CHANNEL_NAME;
+ END IF;
+ END IF;
+
+
+ IF (v_has_ndb IN ('DEFAULT', 'YES')) THEN
+ SELECT 'Cluster Thread Blocks' AS 'The following output is:';
+ SELECT * FROM ndbinfo.threadblocks;
+ END IF;
+
+ -- For a number of sys views as well as events_statements_summary_by_digest,
+ -- just get the start data and then at the end output the overall and delta values
+ IF (v_has_ps = 'YES') THEN
+ IF (@sys.diagnostics.include_raw = 'ON') THEN
+ SELECT '
+
+========================
+
+ Initial Status
+
+========================
+
+' AS '';
+ END IF;
+
+ DROP TEMPORARY TABLE IF EXISTS tmp_digests_start;
+ CALL sys.statement_performance_analyzer('create_tmp', 'tmp_digests_start', NULL);
+ CALL sys.statement_performance_analyzer('snapshot', NULL, NULL);
+ CALL sys.statement_performance_analyzer('save', 'tmp_digests_start', NULL);
+
+ -- Loop over the sys views where deltas should be calculated.
+ IF (@sys.diagnostics.include_raw = 'ON') THEN
+ SET @sys.diagnostics.sql = REPLACE(@sys.diagnostics.sql_gen_query_template, '%{OUTPUT}', 'start');
+ IF (@sys.debug = 'ON') THEN
+ SELECT 'The following query will be used to generate the query for each sys view' AS 'Debug';
+ SELECT @sys.diagnostics.sql AS 'Debug';
+ END IF;
+ PREPARE stmt_gen_query FROM @sys.diagnostics.sql;
+ END IF;
+ SET v_done = FALSE;
+ OPEN c_sysviews_w_delta;
+ c_sysviews_w_delta_loop: LOOP
+ FETCH c_sysviews_w_delta INTO v_table_name;
+ IF v_done THEN
+ LEAVE c_sysviews_w_delta_loop;
+ END IF;
+
+ IF (@sys.debug = 'ON') THEN
+ SELECT CONCAT('The following queries are for storing the initial content of ', v_table_name) AS 'Debug';
+ END IF;
+
+ CALL sys.execute_prepared_stmt(CONCAT('DROP TEMPORARY TABLE IF EXISTS `tmp_', v_table_name, '_start`'));
+ CALL sys.execute_prepared_stmt(CONCAT('CREATE TEMPORARY TABLE `tmp_', v_table_name, '_start` SELECT * FROM `sys`.`x$', v_table_name, '`'));
+
+ IF (@sys.diagnostics.include_raw = 'ON') THEN
+ SET @sys.diagnostics.table_name = CONCAT('x$', v_table_name);
+ EXECUTE stmt_gen_query USING @sys.diagnostics.table_name;
+ -- If necessary add ORDER BY and LIMIT
+ SELECT CONCAT(@sys.diagnostics.sql_select,
+ IF(order_by IS NOT NULL, CONCAT('\n ORDER BY ', REPLACE(order_by, '%{TABLE}', CONCAT('tmp_', v_table_name, '_start'))), ''),
+ IF(limit_rows IS NOT NULL, CONCAT('\n LIMIT ', limit_rows), '')
+ )
+ INTO @sys.diagnostics.sql_select
+ FROM tmp_sys_views_delta
+ WHERE TABLE_NAME = v_table_name;
+ SELECT CONCAT('Initial ', v_table_name) AS 'The following output is:';
+ CALL sys.execute_prepared_stmt(@sys.diagnostics.sql_select);
+ END IF;
+ END LOOP;
+ CLOSE c_sysviews_w_delta;
+
+ IF (@sys.diagnostics.include_raw = 'ON') THEN
+ DEALLOCATE PREPARE stmt_gen_query;
+ END IF;
+ END IF;
+
+ -- If in_include_status_summary is TRUE then a temporary table is required to store the data
+ SET v_sql_status_summary_select = 'SELECT Variable_name',
+ v_sql_status_summary_delta = '',
+ v_sql_status_summary_from = '';
+
+ -- Start the loop
+ REPEAT
+ SET v_output_count = v_output_count + 1;
+ IF (v_output_count > 1) THEN
+ -- Don't sleep on the first execution
+ SET v_sleep = in_interval-(UNIX_TIMESTAMP(NOW(2))-v_iter_start);
+ SELECT NOW() AS 'Time', CONCAT('Going to sleep for ', v_sleep, ' seconds. Please do not interrupt') AS 'The following output is:';
+ DO SLEEP(in_interval);
+ END IF;
+ SET v_iter_start = UNIX_TIMESTAMP(NOW(2));
+
+ SELECT NOW(), CONCAT('Iteration Number ', IFNULL(v_output_count, 'NULL')) AS 'The following output is:';
+
+ -- Even in 5.7 there is no way to get all the info from SHOW MASTER|SLAVE STATUS using the Performance Schema or
+ -- other tables, so include them even though they are no longer optimal solutions and if present get the additional
+ -- information from the other tables available.
+ IF (@@log_bin = 1) THEN
+ SELECT 'SHOW MASTER STATUS' AS 'The following output is:';
+ SHOW MASTER STATUS;
+ END IF;
+
+ IF (v_has_replication <> 'NO') THEN
+ SELECT 'SHOW SLAVE STATUS' AS 'The following output is:';
+ SHOW SLAVE STATUS;
+ END IF;
+
+ -- We need one table per output as a temporary table cannot be opened twice in the same query, and we need to
+ -- join the outputs in the summary at the end.
+ SET v_table_name = CONCAT('tmp_metrics_', v_output_count);
+ CALL sys.execute_prepared_stmt(CONCAT('DROP TEMPORARY TABLE IF EXISTS ', v_table_name));
+
+ -- Currently information_schema.GLOBAL_STATUS has VARIABLE_VALUE as varchar(1024)
+ CALL sys.execute_prepared_stmt(CONCAT('CREATE TEMPORARY TABLE ', v_table_name, ' (
+ Variable_name VARCHAR(193) NOT NULL,
+ Variable_value VARCHAR(1024),
+ Type VARCHAR(100) NOT NULL,
+ Enabled ENUM(''YES'', ''NO'', ''PARTIAL'') NOT NULL,
+ PRIMARY KEY (Type, Variable_name)
+) ENGINE = InnoDB DEFAULT CHARSET=utf8'));
+
+ IF (v_has_metrics) THEN
+ SET @sys.diagnostics.sql = CONCAT(
+ 'INSERT INTO ', v_table_name,
+ ' SELECT Variable_name, REPLACE(Variable_value, ''\n'', ''\\\\n'') AS Variable_value, Type, Enabled FROM sys.metrics'
+ );
+ ELSE
+ -- 5.7+ and the Performance Schema disabled. Use information_schema.GLOBAL_STATUS instead like in 5.6.
+ SET @sys.diagnostics.sql = CONCAT(
+ 'INSERT INTO ', v_table_name,
+ '(SELECT LOWER(VARIABLE_NAME) AS Variable_name, REPLACE(VARIABLE_VALUE, ''\n'', ''\\\\n'') AS Variable_value,
+ ''Global Status'' AS Type, ''YES'' AS Enabled
+ FROM performance_schema.global_status
+) UNION ALL (
+SELECT NAME AS Variable_name, COUNT AS Variable_value,
+ CONCAT(''InnoDB Metrics - '', SUBSYSTEM) AS Type,
+ IF(STATUS = ''enabled'', ''YES'', ''NO'') AS Enabled
+ FROM information_schema.INNODB_METRICS
+ -- Deduplication - some variables exists both in GLOBAL_STATUS and INNODB_METRICS
+ -- Keep the one from GLOBAL_STATUS as it is always enabled and it''s more likely to be used for existing tools.
+ WHERE NAME NOT IN (
+ ''lock_row_lock_time'', ''lock_row_lock_time_avg'', ''lock_row_lock_time_max'', ''lock_row_lock_waits'',
+ ''buffer_pool_reads'', ''buffer_pool_read_requests'', ''buffer_pool_write_requests'', ''buffer_pool_wait_free'',
+ ''buffer_pool_read_ahead'', ''buffer_pool_read_ahead_evicted'', ''buffer_pool_pages_total'', ''buffer_pool_pages_misc'',
+ ''buffer_pool_pages_data'', ''buffer_pool_bytes_data'', ''buffer_pool_pages_dirty'', ''buffer_pool_bytes_dirty'',
+ ''buffer_pool_pages_free'', ''buffer_pages_created'', ''buffer_pages_written'', ''buffer_pages_read'',
+ ''buffer_data_reads'', ''buffer_data_written'', ''file_num_open_files'',
+ ''os_log_bytes_written'', ''os_log_fsyncs'', ''os_log_pending_fsyncs'', ''os_log_pending_writes'',
+ ''log_waits'', ''log_write_requests'', ''log_writes'', ''innodb_dblwr_writes'', ''innodb_dblwr_pages_written'', ''innodb_page_size'')
+) UNION ALL (
+SELECT ''NOW()'' AS Variable_name, NOW(3) AS Variable_value, ''System Time'' AS Type, ''YES'' AS Enabled
+) UNION ALL (
+SELECT ''UNIX_TIMESTAMP()'' AS Variable_name, ROUND(UNIX_TIMESTAMP(NOW(3)), 3) AS Variable_value, ''System Time'' AS Type, ''YES'' AS Enabled
+)
+ ORDER BY Type, Variable_name;'
+ );
+ END IF;
+ CALL sys.execute_prepared_stmt(@sys.diagnostics.sql);
+
+ -- Prepare the query to retrieve the summary
+ CALL sys.execute_prepared_stmt(
+ CONCAT('SELECT Variable_value INTO @sys.diagnostics.output_time FROM ', v_table_name, ' WHERE Type = ''System Time'' AND Variable_name = ''UNIX_TIMESTAMP()''')
+ );
+ SET v_output_time = @sys.diagnostics.output_time;
+
+ -- Limit each value to v_status_summary_width chars (when v_has_ndb = TRUE the values can be very wide - refer to the output here for the full values)
+ -- v_sql_status_summary_select, v_sql_status_summary_delta, v_sql_status_summary_from
+ SET v_sql_status_summary_select = CONCAT(v_sql_status_summary_select, ',
+ CONCAT(
+ LEFT(s', v_output_count, '.Variable_value, ', v_status_summary_width, '),
+ IF(', REPLACE(v_no_delta_names, '%{COUNT}', v_output_count), ' AND s', v_output_count, '.Variable_value REGEXP ''^[0-9]+(\\\\.[0-9]+)?$'', CONCAT('' ('', ROUND(s', v_output_count, '.Variable_value/', v_output_time, ', 2), ''/sec)''), '''')
+ ) AS ''Output ', v_output_count, ''''),
+ v_sql_status_summary_from = CONCAT(v_sql_status_summary_from, '
+',
+ IF(v_output_count = 1, ' FROM ', ' INNER JOIN '),
+ v_table_name, ' s', v_output_count,
+ IF (v_output_count = 1, '', ' USING (Type, Variable_name)'));
+ IF (v_output_count > 1) THEN
+ SET v_sql_status_summary_delta = CONCAT(v_sql_status_summary_delta, ',
+ IF(', REPLACE(v_no_delta_names, '%{COUNT}', v_output_count), ' AND s', (v_output_count-1), '.Variable_value REGEXP ''^[0-9]+(\\\\.[0-9]+)?$'' AND s', v_output_count, '.Variable_value REGEXP ''^[0-9]+(\\\\.[0-9]+)?$'',
+ CONCAT(IF(s', (v_output_count-1), '.Variable_value REGEXP ''^[0-9]+\\\\.[0-9]+$'' OR s', v_output_count, '.Variable_value REGEXP ''^[0-9]+\\\\.[0-9]+$'',
+ ROUND((s', v_output_count, '.Variable_value-s', (v_output_count-1), '.Variable_value), 2),
+ (s', v_output_count, '.Variable_value-s', (v_output_count-1), '.Variable_value)
+ ),
+ '' ('', ROUND((s', v_output_count, '.Variable_value-s', (v_output_count-1), '.Variable_value)/(', v_output_time, '-', v_output_time_prev, '), 2), ''/sec)''
+ ),
+ ''''
+ ) AS ''Delta (', (v_output_count-1), ' -> ', v_output_count, ')''');
+ END IF;
+
+ SET v_output_time_prev = v_output_time;
+
+ IF (@sys.diagnostics.include_raw = 'ON') THEN
+ IF (v_has_metrics) THEN
+ SELECT 'SELECT * FROM sys.metrics' AS 'The following output is:';
+ ELSE
+ SELECT 'sys.metrics equivalent' AS 'The following output is:';
+ END IF;
+ -- Ensures that the output here is the same as the one used in the status summary at the end
+ CALL sys.execute_prepared_stmt(CONCAT('SELECT Type, Variable_name, Enabled, Variable_value FROM ', v_table_name, ' ORDER BY Type, Variable_name'));
+ END IF;
+
+ -- InnoDB
+ IF (v_has_innodb IN ('DEFAULT', 'YES')) THEN
+ SELECT 'SHOW ENGINE INNODB STATUS' AS 'The following output is:';
+ EXECUTE stmt_innodb_status;
+ SELECT 'InnoDB - Transactions' AS 'The following output is:';
+ SELECT * FROM information_schema.INNODB_TRX;
+ END IF;
+
+ -- NDBCluster
+ IF (v_has_ndb IN ('DEFAULT', 'YES')) THEN
+ SELECT 'SHOW ENGINE NDBCLUSTER STATUS' AS 'The following output is:';
+ EXECUTE stmt_ndbcluster_status;
+
+ SELECT 'ndbinfo.memoryusage' AS 'The following output is:';
+ SELECT node_id, memory_type, sys.format_bytes(used) AS used, used_pages, sys.format_bytes(total) AS total, total_pages,
+ ROUND(100*(used/total), 2) AS 'Used %'
+ FROM ndbinfo.memoryusage;
+
+ -- Loop over the ndbinfo tables (except memoryusage which was handled separately above).
+ -- The exact tables available are version dependent, so get the list from the Information Schema.
+ SET v_done = FALSE;
+ OPEN c_ndbinfo;
+ c_ndbinfo_loop: LOOP
+ FETCH c_ndbinfo INTO v_table_name;
+ IF v_done THEN
+ LEAVE c_ndbinfo_loop;
+ END IF;
+
+ SELECT CONCAT('SELECT * FROM ndbinfo.', v_table_name) AS 'The following output is:';
+ CALL sys.execute_prepared_stmt(CONCAT('SELECT * FROM `ndbinfo`.`', v_table_name, '`'));
+ END LOOP;
+ CLOSE c_ndbinfo;
+
+ SELECT * FROM information_schema.FILES;
+ END IF;
+
+ SELECT 'SELECT * FROM sys.processlist' AS 'The following output is:';
+ SELECT processlist.* FROM sys.processlist;
+
+ IF (v_has_ps = 'YES') THEN
+ -- latest_file_io
+ IF (sys.ps_is_consumer_enabled('events_waits_history_long') = 'YES') THEN
+ SELECT 'SELECT * FROM sys.latest_file_io' AS 'The following output is:';
+ SELECT * FROM sys.latest_file_io;
+ END IF;
+
+ -- current memory usage
+ IF (EXISTS(SELECT 1 FROM performance_schema.setup_instruments WHERE NAME LIKE 'memory/%' AND ENABLED = 'YES')) THEN
+ SELECT 'SELECT * FROM sys.memory_by_host_by_current_bytes' AS 'The following output is:';
+ SELECT * FROM sys.memory_by_host_by_current_bytes;
+
+ SELECT 'SELECT * FROM sys.memory_by_thread_by_current_bytes' AS 'The following output is:';
+ SELECT * FROM sys.memory_by_thread_by_current_bytes;
+
+ SELECT 'SELECT * FROM sys.memory_by_user_by_current_bytes' AS 'The following output is:';
+ SELECT * FROM sys.memory_by_user_by_current_bytes;
+
+ SELECT 'SELECT * FROM sys.memory_global_by_current_bytes' AS 'The following output is:';
+ SELECT * FROM sys.memory_global_by_current_bytes;
+ END IF;
+ END IF;
+
+ SET v_runtime = (UNIX_TIMESTAMP(NOW(2)) - v_start);
+ UNTIL (v_runtime + in_interval >= in_max_runtime) END REPEAT;
+
+ -- Get Performance Schema status
+ IF (v_has_ps = 'YES') THEN
+ SELECT 'SHOW ENGINE PERFORMANCE_SCHEMA STATUS' AS 'The following output is:';
+ EXECUTE stmt_ps_status;
+ END IF;
+
+ -- Deallocate prepared statements
+ IF (v_has_innodb IN ('DEFAULT', 'YES')) THEN
+ DEALLOCATE PREPARE stmt_innodb_status;
+ END IF;
+ IF (v_has_ps = 'YES') THEN
+ DEALLOCATE PREPARE stmt_ps_status;
+ END IF;
+ IF (v_has_ndb IN ('DEFAULT', 'YES')) THEN
+ DEALLOCATE PREPARE stmt_ndbcluster_status;
+ END IF;
+
+
+ SELECT '
+
+============================
+
+ Schema Information
+
+============================
+
+' AS '';
+
+ SELECT COUNT(*) AS 'Total Number of Tables' FROM information_schema.TABLES;
+
+ -- The cost of information_schema.TABLES.DATA_LENGTH depends mostly on the number of tables
+ IF (@sys.diagnostics.allow_i_s_tables = 'ON') THEN
+ SELECT 'Storage Engine Usage' AS 'The following output is:';
+ SELECT ENGINE, COUNT(*) AS NUM_TABLES,
+ sys.format_bytes(SUM(DATA_LENGTH)) AS DATA_LENGTH,
+ sys.format_bytes(SUM(INDEX_LENGTH)) AS INDEX_LENGTH,
+ sys.format_bytes(SUM(DATA_LENGTH+INDEX_LENGTH)) AS TOTAL
+ FROM information_schema.TABLES
+ GROUP BY ENGINE;
+
+ SELECT 'Schema Object Overview' AS 'The following output is:';
+ SELECT * FROM sys.schema_object_overview;
+
+ SELECT 'Tables without a PRIMARY KEY' AS 'The following output is:';
+ SELECT TABLES.TABLE_SCHEMA, ENGINE, COUNT(*) AS NumTables
+ FROM information_schema.TABLES
+ LEFT OUTER JOIN information_schema.STATISTICS ON STATISTICS.TABLE_SCHEMA = TABLES.TABLE_SCHEMA
+ AND STATISTICS.TABLE_NAME = TABLES.TABLE_NAME
+ AND STATISTICS.INDEX_NAME = 'PRIMARY'
+ WHERE STATISTICS.TABLE_NAME IS NULL
+ AND TABLES.TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
+ AND TABLES.TABLE_TYPE = 'BASE TABLE'
+ GROUP BY TABLES.TABLE_SCHEMA, ENGINE;
+ END IF;
+
+ IF (v_has_ps = 'YES') THEN
+ SELECT 'Unused Indexes' AS 'The following output is:';
+ SELECT object_schema, COUNT(*) AS NumUnusedIndexes
+ FROM performance_schema.table_io_waits_summary_by_index_usage
+ WHERE index_name IS NOT NULL
+ AND count_star = 0
+ AND object_schema NOT IN ('mysql', 'sys')
+ AND index_name != 'PRIMARY'
+ GROUP BY object_schema;
+ END IF;
+
+ IF (v_has_ps = 'YES') THEN
+ SELECT '
+
+=========================
+
+ Overall Status
+
+=========================
+
+' AS '';
+
+ SELECT 'CALL sys.ps_statement_avg_latency_histogram()' AS 'The following output is:';
+ CALL sys.ps_statement_avg_latency_histogram();
+
+ CALL sys.statement_performance_analyzer('snapshot', NULL, NULL);
+ CALL sys.statement_performance_analyzer('overall', NULL, 'with_runtimes_in_95th_percentile');
+
+ SET @sys.diagnostics.sql = REPLACE(@sys.diagnostics.sql_gen_query_template, '%{OUTPUT}', 'end');
+ IF (@sys.debug = 'ON') THEN
+ SELECT 'The following query will be used to generate the query for each sys view' AS 'Debug';
+ SELECT @sys.diagnostics.sql AS 'Debug';
+ END IF;
+ PREPARE stmt_gen_query FROM @sys.diagnostics.sql;
+
+ SET v_done = FALSE;
+ OPEN c_sysviews_w_delta;
+ c_sysviews_w_delta_loop: LOOP
+ FETCH c_sysviews_w_delta INTO v_table_name;
+ IF v_done THEN
+ LEAVE c_sysviews_w_delta_loop;
+ END IF;
+
+ IF (@sys.debug = 'ON') THEN
+ SELECT CONCAT('The following queries are for storing the final content of ', v_table_name) AS 'Debug';
+ END IF;
+
+ CALL sys.execute_prepared_stmt(CONCAT('DROP TEMPORARY TABLE IF EXISTS `tmp_', v_table_name, '_end`'));
+ CALL sys.execute_prepared_stmt(CONCAT('CREATE TEMPORARY TABLE `tmp_', v_table_name, '_end` SELECT * FROM `sys`.`x$', v_table_name, '`'));
+
+ IF (@sys.diagnostics.include_raw = 'ON') THEN
+ SET @sys.diagnostics.table_name = CONCAT('x$', v_table_name);
+ EXECUTE stmt_gen_query USING @sys.diagnostics.table_name;
+ -- If necessary add ORDER BY and LIMIT
+ SELECT CONCAT(@sys.diagnostics.sql_select,
+ IF(order_by IS NOT NULL, CONCAT('\n ORDER BY ', REPLACE(order_by, '%{TABLE}', CONCAT('tmp_', v_table_name, '_end'))), ''),
+ IF(limit_rows IS NOT NULL, CONCAT('\n LIMIT ', limit_rows), '')
+ )
+ INTO @sys.diagnostics.sql_select
+ FROM tmp_sys_views_delta
+ WHERE TABLE_NAME = v_table_name;
+ SELECT CONCAT('Overall ', v_table_name) AS 'The following output is:';
+ CALL sys.execute_prepared_stmt(@sys.diagnostics.sql_select);
+ END IF;
+ END LOOP;
+ CLOSE c_sysviews_w_delta;
+
+ DEALLOCATE PREPARE stmt_gen_query;
+
+
+ SELECT '
+
+======================
+
+ Delta Status
+
+======================
+
+' AS '';
+
+ CALL sys.statement_performance_analyzer('delta', 'tmp_digests_start', 'with_runtimes_in_95th_percentile');
+ CALL sys.statement_performance_analyzer('cleanup', NULL, NULL);
+
+ DROP TEMPORARY TABLE tmp_digests_start;
+
+ -- @sys.diagnostics.sql_gen_query_delta is defined near the to together with @sys.diagnostics.sql_gen_query_template
+ IF (@sys.debug = 'ON') THEN
+ SELECT 'The following query will be used to generate the query for each sys view delta' AS 'Debug';
+ SELECT @sys.diagnostics.sql_gen_query_delta AS 'Debug';
+ END IF;
+ PREPARE stmt_gen_query_delta FROM @sys.diagnostics.sql_gen_query_delta;
+
+ SET v_old_group_concat_max_len = @@session.group_concat_max_len;
+ SET @@session.group_concat_max_len = 2048;
+ SET v_done = FALSE;
+ OPEN c_sysviews_w_delta;
+ c_sysviews_w_delta_loop: LOOP
+ FETCH c_sysviews_w_delta INTO v_table_name;
+ IF v_done THEN
+ LEAVE c_sysviews_w_delta_loop;
+ END IF;
+
+ SET @sys.diagnostics.table_name = v_table_name;
+ EXECUTE stmt_gen_query_delta USING @sys.diagnostics.table_name;
+ -- If necessary add WHERE, ORDER BY, and LIMIT
+ SELECT CONCAT(@sys.diagnostics.sql_select,
+ IF(where_delta IS NOT NULL, CONCAT('\n WHERE ', where_delta), ''),
+ IF(order_by_delta IS NOT NULL, CONCAT('\n ORDER BY ', order_by_delta), ''),
+ IF(limit_rows IS NOT NULL, CONCAT('\n LIMIT ', limit_rows), '')
+ )
+ INTO @sys.diagnostics.sql_select
+ FROM tmp_sys_views_delta
+ WHERE TABLE_NAME = v_table_name;
+
+ SELECT CONCAT('Delta ', v_table_name) AS 'The following output is:';
+ CALL sys.execute_prepared_stmt(@sys.diagnostics.sql_select);
+
+ CALL sys.execute_prepared_stmt(CONCAT('DROP TEMPORARY TABLE `tmp_', v_table_name, '_end`'));
+ CALL sys.execute_prepared_stmt(CONCAT('DROP TEMPORARY TABLE `tmp_', v_table_name, '_start`'));
+ END LOOP;
+ CLOSE c_sysviews_w_delta;
+ SET @@session.group_concat_max_len = v_old_group_concat_max_len;
+
+ DEALLOCATE PREPARE stmt_gen_query_delta;
+ DROP TEMPORARY TABLE tmp_sys_views_delta;
+ END IF;
+
+ IF (v_has_metrics) THEN
+ SELECT 'SELECT * FROM sys.metrics' AS 'The following output is:';
+ ELSE
+ SELECT 'sys.metrics equivalent' AS 'The following output is:';
+ END IF;
+ CALL sys.execute_prepared_stmt(
+ CONCAT(v_sql_status_summary_select, v_sql_status_summary_delta, ', Type, s1.Enabled', v_sql_status_summary_from,
+ '
+ ORDER BY Type, Variable_name'
+ )
+ );
+
+ -- Remove all the metrics temporary tables again
+ SET v_count = 0;
+ WHILE (v_count < v_output_count) DO
+ SET v_count = v_count + 1;
+ SET v_table_name = CONCAT('tmp_metrics_', v_count);
+ CALL sys.execute_prepared_stmt(CONCAT('DROP TEMPORARY TABLE IF EXISTS ', v_table_name));
+ END WHILE;
+
+ IF (in_auto_config <> 'current') THEN
+ CALL sys.ps_setup_reload_saved();
+ SET sql_log_bin = @log_bin;
+ END IF;
+
+ -- Reset the @sys.diagnostics.% user variables internal to this procedure
+ SET @sys.diagnostics.output_time = NULL,
+ @sys.diagnostics.sql = NULL,
+ @sys.diagnostics.sql_gen_query_delta = NULL,
+ @sys.diagnostics.sql_gen_query_template = NULL,
+ @sys.diagnostics.sql_select = NULL,
+ @sys.diagnostics.table_name = NULL;
+
+ -- Restore INSTRUMENTED for this thread
+ IF (v_this_thread_enabled = 'YES') THEN
+ CALL sys.ps_setup_enable_thread(CONNECTION_ID());
+ END IF;
+
+ IF (@log_bin = 1) THEN
+ SET sql_log_bin = @log_bin;
+ END IF;
+END$$
+
+DELIMITER ; \ No newline at end of file