1. 程式人生 > 實用技巧 >MySQL 檢視最近執行失敗的SQL語句

MySQL 檢視最近執行失敗的SQL語句

MySQL版本:5.7.31
根據《MySQL效能優化金字塔法則》做的實驗,好書推薦!

performance_schema中語句時間記錄表中針對每一條語句的執行狀態都記錄了較為詳細的資訊,其中就包含了執行錯誤資訊。

一、檢視語句記錄功能是否開啟

記錄語句資訊的表一般為performance_schema中的四張表,分別為

  • events_statements_current,預設記錄每個執行緒最近的一條SQL資訊
  • events_statements_history,預設記錄每個執行緒最近的十條SQL資訊
  • events_statements_history_long ,預設記錄每個執行緒最近的10000條SQL資訊
mysql> select * from performance_schema.setup_consumers where name like 'events_statements%';
+--------------------------------+---------+
| NAME                           | ENABLED |
+--------------------------------+---------+
| events_statements_current      | YES     |
| events_statements_history      | YES     |
| events_statements_history_long | NO      | -- 未啟用
+--------------------------------+---------+

二、開啟語句記錄功能

生產環境中,每個執行緒執行的SQL很多,我們啟用events_statements_history_long表記錄更多的SQL資訊(可以通過修改performance_schema.threads針對特定的執行緒進行記錄資訊,降低對效能的影響程度)

啟用events_statements_history_long

mysql > update performance_schema.setup_consumers set enabled = 'YES' where name ='events_statements_history_long';

三、模擬執行SQL失敗

3.1 情況1:明確知道SQL錯誤號

會話1,執行明顯格式錯誤的SQL,這裡可以看到錯誤號是1096

mysql> select *;
ERROR 1096 (HY000): No tables used

會話2,可以看到執行的對應內部執行緒號等具體資訊,環境是測試環境,所以剛好查出只有這一條,生產中應該查出來不止一條,會有很多條。

mysql> select * from performance_schema.events_statements_history_long where mysql_errno=1096\G;

*************************** 1. row ***************************
              THREAD_ID: 173475    <-- 內部執行緒號
               EVENT_ID: 38480
           END_EVENT_ID: 38497
             EVENT_NAME: statement/sql/select
                 SOURCE: 
            TIMER_START: 1050983430258683000
              TIMER_END: 1050983430962477000
             TIMER_WAIT: 703794000
              LOCK_TIME: 0
               SQL_TEXT: select *
                 DIGEST: ed17d00b1d52bf7da4ae01c523c15c5a
            DIGEST_TEXT: SELECT * 
         CURRENT_SCHEMA: performance_schema
            OBJECT_TYPE: NULL
          OBJECT_SCHEMA: NULL
            OBJECT_NAME: NULL
  OBJECT_INSTANCE_BEGIN: NULL
            MYSQL_ERRNO: 1096   <-- 錯誤號
      RETURNED_SQLSTATE: HY000
           MESSAGE_TEXT: No tables used
                 ERRORS: 1
               WARNINGS: 0
          ROWS_AFFECTED: 0
              ROWS_SENT: 0
          ROWS_EXAMINED: 0
CREATED_TMP_DISK_TABLES: 0
     CREATED_TMP_TABLES: 0
       SELECT_FULL_JOIN: 0
 SELECT_FULL_RANGE_JOIN: 0
           SELECT_RANGE: 0
     SELECT_RANGE_CHECK: 0
            SELECT_SCAN: 0
      SORT_MERGE_PASSES: 0
             SORT_RANGE: 0
              SORT_ROWS: 0
              SORT_SCAN: 0
          NO_INDEX_USED: 0
     NO_GOOD_INDEX_USED: 0
       NESTING_EVENT_ID: NULL
     NESTING_EVENT_TYPE: NULL
    NESTING_EVENT_LEVEL: 0
1 row in set (0.01 sec)

3.2 情況2:不知道錯誤號,只想看最近執行出錯的SQL是哪些

mysql>select * from performance_schema.events_statements_history_long where errors != 0\G;

*************************** 1. row ***************************
              THREAD_ID: 173475
               EVENT_ID: 38480
           END_EVENT_ID: 38497
             EVENT_NAME: statement/sql/select
                 SOURCE: 
            TIMER_START: 1050983430258683000
              TIMER_END: 1050983430962477000
             TIMER_WAIT: 703794000
              LOCK_TIME: 0
               SQL_TEXT: select *
                 DIGEST: ed17d00b1d52bf7da4ae01c523c15c5a
            DIGEST_TEXT: SELECT * 
         CURRENT_SCHEMA: performance_schema
            OBJECT_TYPE: NULL
          OBJECT_SCHEMA: NULL
            OBJECT_NAME: NULL
  OBJECT_INSTANCE_BEGIN: NULL
            MYSQL_ERRNO: 1096
      RETURNED_SQLSTATE: HY000
           MESSAGE_TEXT: No tables used
                 ERRORS: 1
               WARNINGS: 0
          ROWS_AFFECTED: 0
              ROWS_SENT: 0
          ROWS_EXAMINED: 0
CREATED_TMP_DISK_TABLES: 0
     CREATED_TMP_TABLES: 0
       SELECT_FULL_JOIN: 0
 SELECT_FULL_RANGE_JOIN: 0
           SELECT_RANGE: 0
     SELECT_RANGE_CHECK: 0
            SELECT_SCAN: 0
      SORT_MERGE_PASSES: 0
             SORT_RANGE: 0
              SORT_ROWS: 0
              SORT_SCAN: 0
          NO_INDEX_USED: 0
     NO_GOOD_INDEX_USED: 0
       NESTING_EVENT_ID: NULL
     NESTING_EVENT_TYPE: NULL
    NESTING_EVENT_LEVEL: 0

補充:

  • 表中的TIMER_WAITLOCK_TIME可以用sys.format_time()函式進行轉換,變成微秒等我們能直觀瞭解的時間大小
  • 內部執行緒號:THREAD_ID = sys.ps_thread_id(process_id)