JDBC与MySQL临时表空间的分析
编程并不是一个机械性的工作,而是需要有思考,有创新的工作,语法是固定的,但解决问题的思路则是依靠人的思维,这就需要我们坚持学习和更新自己的知识。今天golang学习网就整理分享《JDBC与MySQL临时表空间的分析》,文章讲解的知识点主要包括MySQL,如果你对数据库方面的知识点感兴趣,就不要错过golang学习网,在这可以对大家的知识积累有所帮助,助力开发能力的提升。
背景
应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间。为了限制临时表空间的大小,设置了:
innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G
问题描述
在限制了临时表空间后,当应用仍按以前的方式访问时,ibtmp1文件达到2G后,程序一直等待直到超时断开连接。 SHOW PROCESSLIST显示程序的连接线程为sleep状态,state和info信息为空。 这个对应用开发来说不太友好,程序等待超时之后要分析原因也缺少提示信息。
问题分析过程
为了分析问题,我们进行了以下测试
测试环境:
mysql:5.7.16
java:1.8u162
jdbc 驱动:5.1.36
OS:Red Hat 6.4
1.手工模拟临时表超过最大限制的场景
模拟以下环境:
ibtmp1:12M:autoextend:max:30M
将一张 500万行的 sbtest 表的 k 字段索引删除
运行一条 group by 的查询,产生的临时表大小超过限制后,会直接报错:
select sum(k) from sbtest1 group by k;
ERROR 1114 (HY000): The table '/tmp/#sql_60f1_0' is full
2.检查驱动对 mysql 的设置
我们上一步看到,sql 手工执行会返回错误,但是 jdbc 不返回错误,导致连接一直 sleep,怀疑是 mysql 驱动做了特殊设置,驱动连接 mysql,通过 general_log 查看做了哪些设置。未发现做特殊设置。
3.测试 JDBC 连接
问题的背景中有对JDBC做特殊配置:useCursorFetch=true,不知道是否与隐藏报错有关,接下来进行测试:

发现以下现象:
·加参数 useCursorFetch=true时,做同样的查询确实不会报错
这个参数是为了防止返回结果集过大而采用分段读取的方式。即程序下发一个 sql 给 mysql 后,会等 mysql 可以读结果的反馈,由于 mysql 在执行sql时,返回结果达到 ibtmp 上限后报错,但没有关闭该线程,该线程处理 sleep 状态,程序得不到反馈,会一直等,没有报错。如果 kill 这个线程,程序则会报错。
·不加参数 useCursorFetch=true时,做同样的查询则会报错

结论
1.正常情况下,sql 执行过程中临时表大小达到 ibtmp 上限后会报错;
2.当JDBC设置 useCursorFetch=true,sql 执行过程中临时表大小达到 ibtmp 上限后不会报错。
解决方案
进一步了解到使用 useCursorFetch=true 是为了防止查询结果集过大撑爆 jvm;
但是使用 useCursorFetch=true 又会导致普通查询也生成临时表,造成临时表空间过大的问题;
临时表空间过大的解决方案是限制 ibtmp1 的大小,然而 useCursorFetch=true 又导致JDBC不返回错误。
所以需要使用其它方法来达到相同的效果,且 sql 报错后程序也要相应的报错。除了 useCursorFetch=true 这种段读取的方式外,还可以使用流读取的方式。流读取程序详见附件部分。
·报错对比
·段读取方式,sql 报错后,程序不报错
·流读取方式,sql 报错后,程序会报错
·内存占用对比
这里对比了普通读取、段读取、流读取三种方式,初始内存占用 28M 左右:
·普通读取后,内存占用 100M 多
·段读取后,内存占用 60M 左右
·流读取后,内存占用 60M 左右
补充知识点
MySQL共享临时表空间知识点
MySQL 5.7在 temporary tablespace上做了改进,已经实现将 temporary tablespace 从 ibdata(共享表空间文件)中分离。并且可以重启重置大小,避免出现像以前 ibdata 过大难以释放的问题。
其参数为:innodb_temp_data_file_path
1.表现
MySQL启动时 datadir 下会创建一个 ibtmp1 文件,初始大小为 12M,默认值下会无限扩展:
通常来说,查询导致的临时表(如group by)如果超出 tmp_table_size、max_heap_table_size 大小限制则创建 innodb 磁盘临时表(MySQL5.7默认临时表引擎为 innodb),存放在共享临时表空间;
如果某个操作创建了一个大小为100 M的临时表,则临时表空间数据文件会扩展到 100M大小以满足临时表的需要。当删除临时表时,释放的空间可以重新用于新的临时表,但 ibtmp1 文件保持扩展大小。
2.查询视图
可查询共享临时表空间的使用情况:
SELECT FILE_NAME, TABLESPACE_NAME, ENGINE, INITIAL_SIZE, TOTAL_EXTENTS*EXTENT_SIZE AS TotalSizeBytes, DATA_FREE,MAXIMUM_SIZE FROM INFORMATION_SCHEMA.FILES WHERE TABLESPACE_NAME = 'innodb_temporary'\G
*************************** 1. row ***************************
FILE_NAME: /data/mysql5722/data/ibtmp1
TABLESPACE_NAME: innodb_temporary
ENGINE: InnoDB
INITIAL_SIZE: 12582912
TotalSizeBytes: 31457280
DATA_FREE: 27262976
MAXIMUM_SIZE: 31457280
1 row in set (0.00 sec)
3.回收方式
重启 MySQL 才能回收
4.限制大小
为防止临时数据文件变得过大,可以配置该 innodb_temp_data_file_path (需重启生效)选项以指定最大文件大小,当数据文件达到最大大小时,查询将返回错误:
innodb_temp_data_file_path=ibtmp1:12M:autoextend:max:2G
5. 临时表空间与 tmpdir 对比
共享临时表空间用于存储非压缩InnoDB临时表(non-compressed InnoDB temporary tables)、关系对象(related objects)、回滚段(rollback segment)等数据;
tmpdir 用于存放指定临时文件(temporary files)和临时表(temporary tables),与共享临时表空间不同的是,tmpdir存储的是compressed InnoDB temporary tables。
可通过如下语句测试:
CREATE TEMPORARY TABLE compress_table (id int, name char(255)) ROW_FORMAT=COMPRESSED; CREATE TEMPORARY TABLE uncompress_table (id int, name char(255)) ;
附件
SimpleExample.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
public class SimpleExample {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Properties props = new Properties();
props.setProperty("user", "root");
props.setProperty("password", "root");
SimpleExample engine = new SimpleExample();
// engine.execute(props,"jdbc:mysql://10.186.24.31:3336/hucq?useSSL=false");
engine.execute(props,"jdbc:mysql://10.186.24.31:3336/hucq?useSSL=false&useCursorFetch=true");
}
final AtomicLong tmAl = new AtomicLong();
final String tableName="test";
public void execute(Properties props,String url) {
CountDownLatch cdl = new CountDownLatch(1);
long start = System.currentTimeMillis();
for (int i = 0; i
精选文章汇总:
MySQL中间件性能测试 I
MySQL性能诊断实践之系统观测工具
Prometheus一条告警是怎么触发的
多从库时半同步复制不工作的BUG分析
大规模集群之告警系统实践
安全考虑,binlog_row_image建议尽量使用FULL
多从库时半同步复制不工作的BUG分析
MySQL瓶颈分析与优化
使用VS Code调试MySQL
以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于数据库的相关知识,也可关注golang学习网公众号。
MySQL SQL模式特点汇总
- 上一篇
- MySQL SQL模式特点汇总
- 下一篇
- Spring Boot配置线程池使用多线程插入数据
-
- 数据库 · MySQL | 2天前 |
- MySQL数值函数大全及使用技巧
- 117浏览 收藏
-
- 数据库 · MySQL | 3天前 |
- 三种登录MySQL方法详解
- 411浏览 收藏
-
- 数据库 · MySQL | 4天前 |
- MySQL数据备份方法与工具推荐
- 420浏览 收藏
-
- 数据库 · MySQL | 4天前 |
- MySQL数据备份方法与工具推荐
- 264浏览 收藏
-
- 数据库 · MySQL | 5天前 |
- MySQL索引的作用是什么?
- 266浏览 收藏
-
- 数据库 · MySQL | 6天前 |
- MySQL排序原理与实战应用
- 392浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQLwhere条件查询技巧
- 333浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL常用数据类型有哪些?怎么选更合适?
- 234浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL常用命令大全管理员必学30条
- 448浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL高效批量插入数据方法大全
- 416浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL性能优化技巧大全
- 225浏览 收藏
-
- 数据库 · MySQL | 1星期前 |
- MySQL数据备份4种方法保障安全
- 145浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3182次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3393次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3425次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4528次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3802次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览

