1. 程式人生 > 資料庫 >MySQL如何計算統計redo log大小

MySQL如何計算統計redo log大小

 

在MySQL中如何計算、統計重做日誌(redo log)的生成情況呢? 例如10分鐘內,生成了多少M的redo log呢?30分鐘內又生成了多少M的redo log.....。MySQL沒有像Oracle中那樣的系統檢視統計這些資料,但是我們可以通過一些方法曲線的統計二進位制日誌的生成量。

 

 

雖然我在這篇部落格中介紹了,MySQL 8.0引入了innodb_dedicated_server自適應引數,可基於伺服器的記憶體來動態設定innodb_buffer_pool_size,innodb_log_file_size和innodb_flush_method。預設情況下,此引數是關閉的。但是在MySQL 8.0之前,通過計算重做日誌(redo log)的生成量來判斷判斷innodb_log_buffer_size和innodb_log_file_size的大小是否合適是非常必要的,個人認為即使MySQL 8.0版本下,這個也是非常有參考和研究意義的。我們通過統計、分析計算重做日誌(redo log)的生成量,從而判斷InnoDB的事務日誌檔案大概能支撐多長時間就會切換。有具體資料支撐,你才好分析判斷,否則巧婦也難為無米之炊。

 

在MySQL的information_schema.global_status或performance_schema.global_status中有個伺服器狀態變數(Server Status Variables)Innodb_os_log_written,它記錄了Innodb的重做日誌(redo log)的生成量,它記錄寫入InnoDB重做日誌檔案的位元組數,它是一個累積值。官方文件關於此伺服器狀態變數的描述如下

 

Innodb_os_log_written

The number of bytes written to the InnoDB redo log files.

 

我們主要通過一個計劃任務/事件排程定期的去採集Innodb_os_log_written伺服器狀態變數獲取重做日誌的大小,將其儲存在innodb_log_size_his表中,方便分析統計。具體指令碼如下:

 

注意:performance_schema.global_status是MySQL 5.7引入的,而MySQL 8.0開始,information_schema.global_status直接被丟棄了。所以注意MySQL版本,選擇合適指令碼。

 

USE mysqls;
 
CREATE TABLE IF NOT EXISTS innodb_log_size_his
(
    log_id          INT AUTO_INCREMENT PRIMARY KEY COMMENT '日誌編號',
    log_date        DATETIME COMMENT '記錄當前資料的時間',
    log_size        DOUBLE COMMENT 'redo log的大小,單位為mb'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT 'redo日誌大小資訊表';
 
 
--MySQL 5.*版本用下面指令碼
DELIMITER &&
 
DROP PROCEDURE IF EXISTS `Record_Innodb_Log_Size`&&
 
CREATE PROCEDURE Record_Innodb_Log_Size()
BEGIN
      INSERT INTO mysql.`innodb_log_size_his`
      (
          log_date,
          log_size
      )
      SELECT now() AS log_date,
             ROUND(CAST(VARIABLE_VALUE AS DOUBLE )/1024/1024, 1) as log_size
      FROM information_schema.global_status
      WHERE VARIABLE_NAME = 'innodb_os_log_written';
END &&
 
DELIMITER ;
 
 
--MySQL 8.0以上版本使用下面指令碼
DELIMITER &&
 
DROP PROCEDURE IF EXISTS `Record_Innodb_Log_Size`&&
 
CREATE PROCEDURE Record_Innodb_Log_Size()
BEGIN
      INSERT INTO mysql.`innodb_log_size_his`
      (
          log_date,
          log_size
      )
      SELECT now() AS log_date,
             ROUND(CAST(VARIABLE_VALUE AS DOUBLE )/1024/1024, 1) as log_size
      FROM performance_schema.global_status
      WHERE VARIABLE_NAME = 'innodb_os_log_written';
    
END &&
 
DELIMITER ;

 

然後建立MySQL的計劃任務/事件排程,這個可以根據需求彈性設定。

 

CREATE EVENT DPA_BINGLOG_SIZE 
ON SCHEDULE EVERY 10 MINUTE STARTS '2020-10-16 08:00:00' 
ON COMPLETION PRESERVE 
DO CALL mysql.Record_Innodb_Log_Size;

 

然後你就可以基於這個表做一些簡單的分析和統計了,例如,統計10分鐘內生成重做日誌生成了多少。如下所示:

 

SELECT m.*
      ,@lag  AS last_redo_size
      ,ROUND(m.log_size - @lag,2) AS gen_redo_size
      ,@lag:=log_size
FROM mysql.`innodb_log_size_his` m, (SELECT @lag :='') AS n
WHERE m.log_date >= date_add(now(), interval -1 day)
ORDER BY m.log_id;

 

clip_image001