ps_thread_trx_info() - xiaoboluo768/mysql-system-schema GitHub Wiki

  • 在events_transactions_current、events_transactions_history、events_statements_history表中查询并返回指定内部线程ID的事务、语句事件信息(json格式返回),这些事件信息包括当前正在执行的事务以及已经执行完成的语句信息(必须启用events_transactions_current、events_transactions_history、events_statements_history对应的consumers配置才能够获取这些信息)

    • 如果ps_thread_trx_info()函数输出json格式字符串长度超过默认的65535字节长度,则返回json错误对象(如:{ "error": "Trx info truncated: Row 6 was cut by GROUP_CONCAT()" }),然后函数中会对该错误做进一步处理
    • 此函数在MySQL 5.7.9中新增
  • 参数:

    • in_thread_id BIGINT UNSIGNED:用于返回事务、语句事件信息的内部线程ID,该值与performance_schema.threads表中的THREAD_ID列值对应
  • 配置选项:

    • ps_thread_trx_info.max_length,@sys.ps_thread_trx_info.max_length:控制ps_thread_trx_info()函数输出的最大字节长度,默认为65535字节
  • 返回值:一个LONGTEXT长文本值

  • 定义语句

DROP FUNCTION IF EXISTS ps_thread_trx_info;

DELIMITER $$

CREATE DEFINER='root'@'localhost' FUNCTION ps_thread_trx_info (
        in_thread_id BIGINT UNSIGNED
    ) RETURNS LONGTEXT
    COMMENT '
             Description
             -----------

             Returns a JSON object with info on the given threads current transaction, 
             and the statements it has already executed, derived from the
             performance_schema.events_transactions_current and
             performance_schema.events_statements_history tables (so the consumers 
             for these also have to be enabled within Performance Schema to get full
             data in the object).

             When the output exceeds the default truncation length (65535), a JSON error
             object is returned, such as:

             { "error": "Trx info truncated: Row 6 was cut by GROUP_CONCAT()" }

             Similar error objects are returned for other warnings/and exceptions raised
             when calling the function.

             The max length of the output of this function can be controlled with the
             ps_thread_trx_info.max_length variable set via sys_config, or the
             @sys.ps_thread_trx_info.max_length user variable, as appropriate.

             Parameters
             -----------

             in_thread_id (BIGINT UNSIGNED):
               The id of the thread to return the transaction info for.

             Example
             -----------

             SELECT sys.ps_thread_trx_info(48)\\G
             *************************** 1. row ***************************
             sys.ps_thread_trx_info(48): [
               {
                 "time": "790.70 us",
                 "state": "COMMITTED",
                 "mode": "READ WRITE",
                 "autocommitted": "NO",
                 "gtid": "AUTOMATIC",
                 "isolation": "REPEATABLE READ",
                 "statements_executed": [
                   {
                     "sql_text": "INSERT INTO info VALUES (1, \'foo\')",
                     "time": "471.02 us",
                     "schema": "trx",
                     "rows_examined": 0,
                     "rows_affected": 1,
                     "rows_sent": 0,
                     "tmp_tables": 0,
                     "tmp_disk_tables": 0,
                     "sort_rows": 0,
                     "sort_merge_passes": 0
                   },
                   {
                     "sql_text": "COMMIT",
                     "time": "254.42 us",
                     "schema": "trx",
                     "rows_examined": 0,
                     "rows_affected": 0,
                     "rows_sent": 0,
                     "tmp_tables": 0,
                     "tmp_disk_tables": 0,
                     "sort_rows": 0,
                     "sort_merge_passes": 0
                   }
                 ]
               },
               {
                 "time": "426.20 us",
                 "state": "COMMITTED",
                 "mode": "READ WRITE",
                 "autocommitted": "NO",
                 "gtid": "AUTOMATIC",
                 "isolation": "REPEATABLE READ",
                 "statements_executed": [
                   {
                     "sql_text": "INSERT INTO info VALUES (2, \'bar\')",
                     "time": "107.33 us",
                     "schema": "trx",
                     "rows_examined": 0,
                     "rows_affected": 1,
                     "rows_sent": 0,
                     "tmp_tables": 0,
                     "tmp_disk_tables": 0,
                     "sort_rows": 0,
                     "sort_merge_passes": 0
                   },
                   {
                     "sql_text": "COMMIT",
                     "time": "213.23 us",
                     "schema": "trx",
                     "rows_examined": 0,
                     "rows_affected": 0,
                     "rows_sent": 0,
                     "tmp_tables": 0,
                     "tmp_disk_tables": 0,
                     "sort_rows": 0,
                     "sort_merge_passes": 0
                   }
                 ]
               }
             ]
             1 row in set (0.03 sec)
            '

    SQL SECURITY INVOKER
    NOT DETERMINISTIC
    READS SQL DATA
BEGIN
    DECLARE v_output LONGTEXT DEFAULT '{}';
    DECLARE v_msg_text TEXT DEFAULT '';
    DECLARE v_signal_msg TEXT DEFAULT '';
    DECLARE v_mysql_errno INT;
    DECLARE v_max_output_len BIGINT;
    -- Capture warnings/errors such as group_concat truncation
    -- and report as JSON error objects
    DECLARE EXIT HANDLER FOR SQLWARNING, SQLEXCEPTION
    BEGIN
        GET DIAGNOSTICS CONDITION 1
            v_msg_text = MESSAGE_TEXT,
            v_mysql_errno = MYSQL_ERRNO;

        IF v_mysql_errno = 1260 THEN
            SET v_signal_msg = CONCAT('{ "error": "Trx info truncated: ', v_msg_text, '" }');
        ELSE
            SET v_signal_msg = CONCAT('{ "error": "', v_msg_text, '" }');
        END IF;

        RETURN v_signal_msg;
    END;

    -- Set configuration options
    IF (@sys.ps_thread_trx_info.max_length IS NULL) THEN
        SET @sys.ps_thread_trx_info.max_length = sys.sys_get_config('ps_thread_trx_info.max_length', 65535);
    END IF;

    IF (@sys.ps_thread_trx_info.max_length != @@session.group_concat_max_len) THEN
        SET @old_group_concat_max_len = @@session.group_concat_max_len;
        -- Convert to int value for the SET, and give some surrounding space
        SET v_max_output_len = (@sys.ps_thread_trx_info.max_length - 5);
        SET SESSION group_concat_max_len = v_max_output_len;
    END IF;

    SET v_output = (
        SELECT CONCAT('[', IFNULL(GROUP_CONCAT(trx_info ORDER BY event_id), ''), '\n]') AS trx_info
          FROM (SELECT trxi.thread_id, 
                       trxi.event_id,
                       GROUP_CONCAT(
                         IFNULL(
                           CONCAT('\n  {\n',
                                  '    "time": "', IFNULL(sys.format_time(trxi.timer_wait), ''), '",\n',
                                  '    "state": "', IFNULL(trxi.state, ''), '",\n',
                                  '    "mode": "', IFNULL(trxi.access_mode, ''), '",\n',
                                  '    "autocommitted": "', IFNULL(trxi.autocommit, ''), '",\n',
                                  '    "gtid": "', IFNULL(trxi.gtid, ''), '",\n',
                                  '    "isolation": "', IFNULL(trxi.isolation_level, ''), '",\n',
                                  '    "statements_executed": [', IFNULL(s.stmts, ''), IF(s.stmts IS NULL, ' ]\n', '\n    ]\n'),
                                  '  }'
                           ), 
                           '') 
                         ORDER BY event_id) AS trx_info

                  FROM (
                        (SELECT thread_id, event_id, timer_wait, state,access_mode, autocommit, gtid, isolation_level
                           FROM performance_schema.events_transactions_current
                          WHERE thread_id = in_thread_id
                            AND end_event_id IS NULL)
                        UNION
                        (SELECT thread_id, event_id, timer_wait, state,access_mode, autocommit, gtid, isolation_level
                           FROM performance_schema.events_transactions_history
                          WHERE thread_id = in_thread_id)
                       ) AS trxi
                  LEFT JOIN (SELECT thread_id,
                                    nesting_event_id,
                                    GROUP_CONCAT(
                                      IFNULL(
                                        CONCAT('\n      {\n',
                                               '        "sql_text": "', IFNULL(sys.format_statement(REPLACE(sql_text, '\\', '\\\\')), ''), '",\n',
                                               '        "time": "', IFNULL(sys.format_time(timer_wait), ''), '",\n',
                                               '        "schema": "', IFNULL(current_schema, ''), '",\n',
                                               '        "rows_examined": ', IFNULL(rows_examined, ''), ',\n',
                                               '        "rows_affected": ', IFNULL(rows_affected, ''), ',\n',
                                               '        "rows_sent": ', IFNULL(rows_sent, ''), ',\n',
                                               '        "tmp_tables": ', IFNULL(created_tmp_tables, ''), ',\n',
                                               '        "tmp_disk_tables": ', IFNULL(created_tmp_disk_tables, ''), ',\n',
                                               '        "sort_rows": ', IFNULL(sort_rows, ''), ',\n',
                                               '        "sort_merge_passes": ', IFNULL(sort_merge_passes, ''), '\n',
                                               '      }'), '') ORDER BY event_id) AS stmts
                               FROM performance_schema.events_statements_history
                              WHERE sql_text IS NOT NULL
                                AND thread_id = in_thread_id
                              GROUP BY thread_id, nesting_event_id
                            ) AS s 
                    ON trxi.thread_id = s.thread_id 
                   AND trxi.event_id = s.nesting_event_id
                 WHERE trxi.thread_id = in_thread_id
                 GROUP BY trxi.thread_id, trxi.event_id
                ) trxs
          GROUP BY thread_id
    );

    IF (@old_group_concat_max_len IS NOT NULL) THEN
        SET SESSION group_concat_max_len = @old_group_concat_max_len;
    END IF;

    RETURN v_output;
END$$

DELIMITER ;
  • 示例
root@localhost : (none) 02:47:50> select sys.ps_thread_trx_info(50)\G
*************************** 1. row ***************************
sys.ps_thread_trx_info(50): [
  {
    "time": "10.99 m",
    "state": "ACTIVE",
    "mode": "READ WRITE",
    "autocommitted": "NO",
    "gtid": "AUTOMATIC",
    "isolation": "READ COMMITTED",
    "statements_executed": [
      {
        "sql_text": "select * from t_luoxiaobo limit 200",
        "time": "544.65 us",
        "schema": "luoxiaobo",
        "rows_examined": 200,
        "rows_affected": 0,
        "rows_sent": 200,
        "tmp_tables": 0,
        "tmp_disk_tables": 0,
        "sort_rows": 0,
        "sort_merge_passes": 0
      }
    ]
  }
]
1 row in set (0.01 sec)

root@localhost : (none) 02:58:42> select sys.ps_thread_trx_info(50)\G
*************************** 1. row ***************************
sys.ps_thread_trx_info(50): [
  {
    "time": "12.51 m",
    "state": "COMMITTED",
    "mode": "READ WRITE",
    "autocommitted": "NO",
    "gtid": "AUTOMATIC",
    "isolation": "READ COMMITTED",
    "statements_executed": [
      {
        "sql_text": "select * from t_luoxiaobo limit 200",
        "time": "544.65 us",
        "schema": "luoxiaobo",
        "rows_examined": 200,
        "rows_affected": 0,
        "rows_sent": 200,
        "tmp_tables": 0,
        "tmp_disk_tables": 0,
        "sort_rows": 0,
        "sort_merge_passes": 0
      },
      {
        "sql_text": "commit",
        "time": "55.36 us",
        "schema": "luoxiaobo",
        "rows_examined": 0,
        "rows_affected": 0,
        "rows_sent": 0,
        "tmp_tables": 0,
        "tmp_disk_tables": 0,
        "sort_rows": 0,
        "sort_merge_passes": 0
      }
    ]
  }
]
1 row in set (0.00 sec)

上一篇: ps_thread_stack()函数 | 下一篇: quote_identifier()函数