performance_schema中有很多的表(語句信息表,事務信息表等)記錄執行的SQL的具體信息,執行事務的具體信息,其中都會有一個叫做TIMER_START的字段,這個字段的值易讀性很差,官方文檔說是皮秒,但也沒說怎么轉成人類易讀的形式,通過以下的方法可以將其轉換為人易讀的格式。
舉例
以performance_schema.events_statements_history_long表為例,擺上對應的SQL語句,可以考慮將其寫成函數。
SELECT
*,
DATE_SUB(NOW(), INTERVAL (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='UPTIME') - TIMER_START*10e-13 second) AS 'start_time',
ROUND(timer_wait*10E-10, 3) AS 'wait in (ms)'
FROM
performance_schema.events_statements_history_long
where thread_id=194277
limit 1\G;
*************************** 1. row ***************************
THREAD_ID: 194277
EVENT_ID: 323
END_EVENT_ID: 354
EVENT_NAME: statement/sql/select
SOURCE:
TIMER_START: 1122588644870331000
TIMER_END: 1122588645297519000
TIMER_WAIT: 427188000
LOCK_TIME: 327000000
SQL_TEXT: select count(*) from mysql.user
DIGEST: a41461c07eca51bcda21d91cf128cfa6
DIGEST_TEXT: SELECT COUNT ( * ) FROM `mysql` . `user`
CURRENT_SCHEMA: NULL
OBJECT_TYPE: NULL
OBJECT_SCHEMA: NULL
OBJECT_NAME: NULL
OBJECT_INSTANCE_BEGIN: NULL
MYSQL_ERRNO: 0
RETURNED_SQLSTATE: NULL
MESSAGE_TEXT: NULL
ERRORS: 0
WARNINGS: 0
ROWS_AFFECTED: 0
ROWS_SENT: 1
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
start_time: 2020-10-22 10:07:39.644871
wait in (ms): 0.427
1 row in set (0.10 sec)
關鍵字段
DATE_SUB(
NOW(),
INTERVAL (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='UPTIME') - TIMER_START*10e-13 second
) AS 'start_time'
DATE_SUB(指定日期A, 需要減去的時間間隔B):如現在是2020-10-22 10:15:00.000(參數A),我指定需要減去的天數為2即INTERVAL 2 DAY(參數B),就能返回得到2020-10-20 10:15:00.000
結論
timer_*即從數據庫正常啟動以來經過的時間,但這個時間不一定準確,官方文檔內說這個會基于處理器的啥啥啥進行計算,可能會有波動。
筆者有一臺數據庫的timer_*字段信息用以上方法計算之后,相差特別大(大的離譜那種,時間多了1年),不知道原因,這臺經歷過升級,有知道的大佬,歡迎留言。
創建時間轉換函數,方便調用
begin;
set global log_bin_trust_function_creators=on;
DELIMITER $$
DROP FUNCTION IF EXISTS timer_to_date$$
CREATE FUNCTION timer_to_date(timer bigint(20) unsigned) RETURNS varchar(50)
BEGIN
DECLARE res_date varchar(50);
DECLARE uptime int;
SET uptime=(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME='UPTIME');
SET res_date=DATE_SUB(NOW(),INTERVAL @uptime - timer*10e-13 second);
return res_date;
END $$
delimiter ;
set global log_bin_trust_function_creators=off;
commit;