惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
L
LangChain Blog
爱范儿
爱范儿
博客园_首页
Stack Overflow Blog
Stack Overflow Blog
MongoDB | Blog
MongoDB | Blog
博客园 - 三生石上(FineUI控件)
大猫的无限游戏
大猫的无限游戏
宝玉的分享
宝玉的分享
GbyAI
GbyAI
H
Help Net Security
A
About on SuperTechFans
Recent Announcements
Recent Announcements
Hugging Face - Blog
Hugging Face - Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
雷峰网
雷峰网
D
Docker
博客园 - Franky
有赞技术团队
有赞技术团队
G
Google Developers Blog

小松鼠的博客

记录一次线上k8s工作节点无法创建容器的问题排查思路与解决办法 记一次线上GoLang项目OOM排查过程 从LastPass转向拥抱开源KeePass的心路历程 故障定位与 AI 结合前后端编码实践 FileBeat收集nginx-ingress-controller日志 K8s云原生环境下文件描述符占用过高查询思路 2024年最新关闭火绒安全工具的开机自启方法 Kubernetes任务调度实践-Go语言实现Job和CronJob对比分析 离线更新k8s环境下的trivy漏洞库方法 使用Go语言接入Choerodon实现基于OAuth2的统一身份认证登录 在Vue2中自定义Switch组件并实现父子组件双向数据绑定 关于docker jdk1.8镜像中的GB18030-2022标准支持及验证 Go框架gin中的session存储gin-contrib-sessions和go-session 关于修改node_module中的源码问题记录 docker-compose网络和内网服务IP冲突问题 Spring Boot中4种文件下载方法的实现 避坑-不能将specific类型的gitlab-runner改变为share类型 Docker compose中的MySQL主从复制模式和percona-toolkit工具使用 在minio中开启https访问以及使用rclone备份minio桶 在多机Docker环境下部署Choerodon的解决方案 Prometheus中Monitor添加对SpringBoot Actuator的Basic认证 在Nginx的容器镜像中隐藏Nginx的Server响应头 K8s中的两种nginx-ingress-controller及其区别 两个docker工具:runlike和whaler Grafana中的邮件报警和截图插件grafana-image-enderer K8s中externalName-service和services-without-selectors maven配置文件settings.xml中的一些概念总结 K8s中flexvolume插件驱动的安装 K8s中的coredns无法解析svc问题排查 K8s中使用Ingress访问请求体过大问题解决
慎用存储过程:一条语句引发的数据库存储100%占用
ycyin · 2023-06-20 · via 小松鼠的博客

2023年6月19日大约 3 分钟数据库技术MySQL数据库存储过程


由于项目中使用了多级目录结构,数据库的存储使用id,parentId进行存储,有个需求就是通过id查询最顶层目录的id(最顶层目录id的parentId=0),想尝试使用存储过程来解决这个问题。因为存储过程使用到了临时表导致存储空间被占满。

现象与起因

根据监控查看到mysql存储空间被占满,但是使用SQL查询数据库表文件却只是占用了几个G。

SELECT
	table_schema AS '数据库',
	sum( table_rows ) AS '记录数',
	sum(
	TRUNCATE ( data_length / 1024 / 1024, 2 )) AS '数据容量(MB)',
	sum(
	TRUNCATE ( index_length / 1024 / 1024, 2 )) AS '索引容量(MB)' 
FROM
	information_schema.TABLES 
GROUP BY
	table_schema 
ORDER BY
	sum( data_length ) DESC,
	sum( index_length ) DESC;

到mysql数据库存储目录下使用du sh * 发现有一个ibtmp1文件很大,占用了分区所有空闲空间。

网上查了一下其中有一条原因可能是使用了大量的临时表造成的,回想起前几天执行了一个存储过程。

DELIMITER //
CREATE PROCEDURE get_top_folder_id(IN p_folder_id BIGINT, OUT p_top_folder_id BIGINT)
BEGIN
    DECLARE v_parent_id BIGINT;
    SET p_top_folder_id = p_folder_id;
    SET v_parent_id = (SELECT parent_id FROM test_issue_folder WHERE folder_id = p_folder_id);
    WHILE v_parent_id != 0 DO
            SET p_top_folder_id = v_parent_id;
            SET v_parent_id = (SELECT parent_id FROM test_issue_folder WHERE folder_id = v_parent_id);
        END WHILE;
END//
DELIMITER ;


CALL get_top_folder_id(:folder_id, @top_folder_id);
SELECT 184611653340499968 as folderId,@top_folder_id;

这个存储过程本身没有问题,只是184611653340499968这个folderId的parent_id是其本身,查询时造成了死循环,导致创建了大量的临时表。

如何处理

1)首先备份数据库,如果Mysql服务还能正常使用,可以用日常的备份机制做一次全备;如果Mysql服务已经异常了,可以考虑物理备份。

2)为了避免以后再次出现ibtmp1文件暴涨,限制其大小,需在mysql配置文件加入:

$ vim /etc/my.cnf
[mysqld]
innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:5G

3)与业务各方沟通好,重启Mysql实例(重启后ibtmp1文件会自动清理)。

4)重启后,验证配置是否生效:

mysql> show variables like 'innodb_temp_data_file_path';
+----------------------------+------------------------------+
| Variable_name              | Value                        |
+----------------------------+------------------------------+
| innodb_temp_data_file_path | ibtmp1:12M:autoextend:max:5G |
+----------------------------+------------------------------+
1 row in set (0.01 sec)

总结

  1. 尽量避免使用数据库的存储过程,可迁移性是个问题,另一个就是如果存储过程使用到临时表就很有可能出现本文的问题。
  2. 今后无论是代码还是SQL中,遇到递归/循环问题一定加上一个深度控制。比如在我的场景下加上循环10次还没找到顶级目录就退出循环。

**可能导致ibtmp1文件会暴涨的情况: **

  1. 用到临时表,当EXPLAIN 查看执行计划结果的 Extra 列中,如果包含 Using Temporary就表示会用到临时表。

  2. GROUP BY无索引字段或GROUP BY + ORDER BY的子句字段不一样时。

  3. order by与distinct共用,其中distinct与order by里的字段不一致(主键字段除外)。

  4. insert into table1 select xxx from table2语句。

参考

  1. mysql语句查看数据库表所占容量空间大小_mysql查询表占用空间大小_l386913的博客-CSDN博客
  2. Mysql里的ibtmp1文件太大,导致磁盘空间被占满_mysql临时文件太大_求知若渴,虚心若愚。的博客-CSDN博客