详解MySQL 表中非主键列溢出情况监控

时间:2022-01-15 08:31:38

今天,又掉坑了。 之前踩到过mysql主键溢出的情况,通过prometheus监控起来了,具体见这篇mysql主键溢出复盘

这次遇到的坑,更加的隐蔽。 是一个log表里面的一个int signed类型的列写满了。快速的解决方法当然还是只能切新表来救急了,然后搬迁老表的部分历史数据到热表。 

亡羊补牢,处理完故障后,赶紧写脚本把生产的其他表都捋一遍。

下面是我暂时用的一个检测脚本,还不太完善,凑合用

分2个文件(1个sql文件,1个shell脚本)

check.sql 内容如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
select
cast( pow(2, case data_type
  when 'tinyint'  then 7
  when 'smallint' then 15
  when 'mediumint' then 23
  when 'int'    then 31
  when 'bigint'  then 63
  end+(column_type like '% unsigned'))-1 as decimal(30,0)) as max_int,
' - ',
concat ('(', concat('select ','max(',column_name,')',' from ',table_schema,'.',table_name),')')
from
information_schema.columns
where
table_schema not in ('information_schema','sys','test','mysql','performance_schema')
and
 data_type in ('int' ) ;

直接到数据库里面执行,效果类似这样:

详解MySQL 表中非主键列溢出情况监控

check.sh 内容如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
# 监测int类型的当可用空间少500w的时候,提醒做ddl操作
# 设置 session级别的 max_execution_time为2秒,防止没有索引的大的拖慢数据库,但是这样可能漏判部分列,需要注意下
# 注意:我这里bigint类型的没有检查,如果需要请修改 check.sql where条件中的data_type加上 bigint的检查
 
source /etc/profile
set -u
 
mkdir $(date +%f) -pv
 
# step1 检测
for host in {'192.168.1.100','192.168.1.110','192.168.1.120','192.168.1.130'}; do
 
mysql -udts -pdts -h${host} -bn < check.sql  2>/dev/null > sql.log
wait
 
echo "说明: | 当前列允许的最大值 | 巡检用的sql   " >> $(date +%f)/$host.log
 
while read line; do
  ret=$(mysql -udts -pdts -h${host} -bne "set session max_execution_time=2000;select $line" 2>/dev/null)
  echo ${ret}
  if [[ "${ret}" == "null" ]]; then
  continue
  fi
  if [ ${ret} -lt 5000000 ] ; then
   echo "$line 剩余空间 ${ret}, 该表可用水位不足500w,建议做ddl修改为bigint类型" >> $(date +%f)/$host.log
  
  fi
done < ./sql.log
 
done
 
# step2 将检查的内容打包发邮件(这里可能需要根据自己生产的情况改改)
tar czf $(date +%f).tar.gz $(date +%f)
sendemail -s 192.168.1.200 -f post@domain.com -t ergou@domain.com -a $(date +%f).tar.gz -u "$(date +%f) int水位线巡检日志" -o message-content-type=html -o message-charset=utf8 -m "内容详见附件"
 
# step3 清理每日生成的以日期命名的目录和tar.gz文件,这里我就不贴命令

再配个每天上午10点的cronjob即可,

最终每天收到邮件里面内容大致类似如下:

详解MySQL 表中非主键列溢出情况监控

到此这篇关于详解mysql 表中非主键列溢出情况监控的文章就介绍到这了,更多相关mysql 非主键列溢出内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.51cto.com/lee90/2486466