借助 summarize

使用 summarize_binlogs.sh 脚本,可以自动化分析 MySQL 二进制日志(Binlog)文件的各项事务内容,并输出每个事务的时间戳、操作表、查询类型及受影响的行数等信息。通过对 MySQL Binlog 的分析,可以更深入地了解数据库内的变更记录、审计信息,并识别影响系统性能的事务操作。这种分析在数据同步、性能调优和故障排查等方面有着重要的应用价值。

脚本使用方法

/root/summarize_binlogs.sh 脚本需要指定 MySQL Binlog 文件路径(通过 -f 参数),并可选地提供起始时间和结束时间以限制分析范围。以下是该脚本的基本用法:

代码语言:bash复制
# /root/summarize_binlogs.sh
Error: Binlog file is required.
Usage: /root/summarize_binlogs.sh -f <binlog_file> [-s <start_time>] [-e <end_time>]
  -f : MySQL binlog file (required)
  -s : Start time (optional, format: 'YYYY-MM-DD HH:MM:SS')
  -e : End time (optional, format: 'YYYY-MM-DD HH:MM:SS')

在执行脚本时,需要指定具体的 Binlog 文件路径。起始时间和结束时间可选,以便只分析特定时间段的事务。例如:

代码语言:bash复制
# /root/summarize_binlogs.sh -f mysql-bin.000009 | more

分析输出示例

脚本会逐行解析 MySQL Binlog,生成记录时间戳、操作的数据库表、查询类型(INSERT、UPDATE、DELETE),以及受影响的行数等信息。输出格式如下:

代码语言:txt复制
Timestamp : #240815 17:19:43 Table : `test`.`sbtest1` Query Type : UPDATE 1 row(s) affected
[Transaction total : 1 ==> Insert(s) : 0 | Update(s) : 1 | Delete(s) : 0] 
--More--

该示例展示了 sbtest1 表在指定时间点的 UPDATE 操作,涉及1行更新。脚本逐行分析这些事务并输出,从而形成清晰的数据库变更记录。

应用场景与示例

示例 1:按事务大小排序,找出前10个最大事务

在数据库的主从复制环境中,大事务是常见的复制延迟问题来源。通过以下命令,可以按事务大小排序并显示前10个最大的事务,以便定位可能引起性能瓶颈的大事务:

代码语言:bash复制
# /root/summarize_binlogs.sh -f mysql-bin.000009 | awk '
  /Timestamp :/ {
    timestamp = substr($0, index($0, "#"), 17)
    match($0, /Table : `[^`]+`.`[^`]+`/)
    table = substr($0, RSTART, RLENGTH)
  }
  /\[Transaction total :/ {
    gsub("`", "", table)
    print timestamp, table, $0
  }
' | sort -rn -k9,9 | head -n 10

输出结果如下:

代码语言:txt复制
#240816 10:38:23  Table : test.sbtest1 [Transaction total : 2716 ==> Insert(s) : 2716 | Update(s) : 0 | Delete(s) : 0] 
#240816 10:34:37  Table : test.sbtest1 [Transaction total : 2716 ==> Insert(s) : 2716 | Update(s) : 0 | Delete(s) : 0] 

此输出展示了 sbtest1 表在指定时间点上,包含 2716 次 INSERT 操作的大事务。通过识别这些大事务,可以分析出数据库性能可能受限的部分,并据此进行数据库调优。

示例 2:统计各表的操作数量

此功能统计 MySQL Binlog 中各表的 INSERT、UPDATE 和 DELETE 操作的数量,输出表级别的操作汇总。通过以下命令,可以按总操作数量降序排列:

代码语言:bash复制
# /root/summarize_binlogs.sh -f mysql-bin.000009 | awk '
{
  if ($0 ~ /Table : `([^`]+)`\.`([^`]+)`/) {
    db = gensub(/.*Table : `([^`]+)`.*/, "\\1", "g", $0);
    tb = gensub(/.*Table : `[^`]+`\.`([^`]+)`.*/, "\\1", "g", $0);
  }
  
  if ($0 ~ /Query Type : INSERT/) {
    insert[db "." tb]++;
  } else if ($0 ~ /Query Type : UPDATE/) {
    update[db "." tb]++;
  } else if ($0 ~ /Query Type : DELETE/) {
    del[db "." tb]++;
  }
}

END {
  printf "%-25s %-10s %-10s %-10s %-10s\n", "Table", "INSERT", "UPDATE", "DELETE", "TOTAL";
  printf "---------------------------------------------------------------\n";
  
  for (db_tb in insert) {
    total = insert[db_tb] + update[db_tb] + del[db_tb];
    output[db_tb] = sprintf("%-25s %-10d %-10d %-10d %-10d", db_tb, insert[db_tb], update[db_tb], del[db_tb], total);
    total_count[db_tb] = total;
  }

  n = asorti(total_count, sorted, "@val_num_desc");
  for (i = 1; i <= n; i++) {
    db_tb = sorted[i];
    print output[db_tb];
  }
}
'

输出结果如下:

代码语言:txt复制
Table                     INSERT     UPDATE     DELETE     TOTAL     
---------------------------------------------------------------
test.sbtest1              37561      75106      37553      150220    
test.t1                   3          0          0          3         

该输出清晰地展示了各个表的总操作量。通过这些统计,可以识别出操作频繁的表,并结合数据库设计进一步优化访问模式,从而提高数据库性能。

总结

对 MySQL Binlog 进行深入分析不仅有助于审计数据库操作、跟踪变更,还能帮助识别性能瓶颈和优化数据同步。通过 summarize_binlogs.sh 脚本,用户可以快速筛选出大事务、统计表级操作数量,从而有效诊断数据库问题。这种数据分析方法为数据管理、故障排查以及系统调优提供了强大的支持,是维护数据库稳定性和高效性的有力工具。