JDBC与MySQL临时表空间的分析

MySQL的JDBC驱动源码解析 一、背景           MySQL是一个中小型关系型数据库管理系统,目前我们淘宝也使用的也非常广泛。为了对开发中间DAO持久层的问题能有更深的理解以及最近在使用的phoenix on Hbase的SQL也是实现的JDBC规范,在遇到问题的时候能够有更多的思路,于是研究了一下MySQL_JDBC驱动的源码,大家都知道JDBC是Java访问数据库的一套规范,具体访问数据库的细节有各个数据库厂 阅读详情

文章来源:爱可生云数据库

作者:秦沛、胡呈清

 

背景

应用 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 < 1; i++) {
            TestThread insertThread = new TestThread(props,cdl, url);
            Thread t = new Thread(insertThread);
            t.start();
            System.out.println("Test start");
        }
        try {
            cdl.await();
            long end = System.currentTimeMillis();
            System.out.println("Test end,total cost:" + (end-start) + "ms");
        } catch (Exception e) {
        }
    }
 
    class TestThread implements Runnable {
        Properties props;
        private CountDownLatch countDownLatch;
        String url;
        public TestThread(Properties props,CountDownLatch cdl,String url) {
            this.props = props;
            this.countDownLatch = cdl;
            this.url = url;
        }
        public void run() {
            Connection connection = null;
            PreparedStatement ps = null;
            Statement st = null;
            long start = System.currentTimeMillis();
            try {
                connection = DriverManager.getConnection(url,props);
                connection.setAutoCommit(false);
                st = connection.createStatement();
                 
                //st.setFetchSize(500);
                st.setFetchSize(Integer.MIN_VALUE);  //仅修改此处即可
                 
                ResultSet rstmp;
                 
                st.executeQuery("select sum(k) from sbtest1 group by k");
                rstmp = st.getResultSet();
                while(rstmp.next()){
                     
                }
            } catch (Exception e) {
                System.out.println(System.currentTimeMillis() - start);
                System.out.println(new java.util.Date().toString());
                e.printStackTrace();
            } finally {
                if (ps != null)
                    try {
                        ps.close();
                    } catch (SQLException e1) {
                        e1.printStackTrace();
                    }
                if (connection != null)
                    try {
                        connection.close();
                    } catch (SQLException e1) {
                        e1.printStackTrace();
                    }
                this.countDownLatch.countDown();
            }
        }
    }
}

 

精选优质文章:

 

最新干货 | MySQL中间件性能测试 I

Prometheus一条告警是怎么触发的

MySQL性能诊断实践之系统观测工具

安全考虑,binlog_row_image建议尽量使用FULL

大规模集群之告警系统实践

多从库时半同步复制不工作的BUG分析

MySQL瓶颈分析与优化

多从库时半同步复制不工作的BUG分析​​​​​​​

MySQL 临时表空间问题探究 然而,长时间运行的查询或频繁创建临时表可能导致临时表空间的问题。通过优化查询和适当调整临时表空间大小,可以有效地解决临时表空间问题。临时表过多:频繁创建临时表可能导致临时表空间的耗尽。当创建临时表时,MySQL将其存储在磁盘上,并为其分配临时表空间。通过以上示例中的代码,可以查询当前的临时表空间大小设置,并通过修改全局变量的方式,增加临时表空间的大小。临时表过大:如果临时表的数据量太大,临时表空间可能会被耗尽。增加临时表空间大小:如果频繁创建临时表或临时表数据量较大,可以考虑增加临时表空间的大小。 阅读详情

相关推荐

XianYuAutoDeliveryX:基于闲鱼API与大模型的智能自动发货系统实践

本文详细介绍了如何利用XianYuAutoDeliveryX系统,结合闲鱼API与大语言模型,构建一个智能自动发货解决方案。该系统能实现买家付款后秒级自动发货,并通过对接ChatGPT等大模型智能回复买家咨询,有效解放卖家时间,提升虚拟商品店铺的运营效率和客户体验。

bush的博客 1015

MySQL高级

MySQL高级(尚硅谷学习笔记)

啊莫的博客 1268

机械臂速成小指南(八):标准DH法实战——从连杆坐标系到运动学方程

本文详细介绍了机械臂运动学建模中的标准DH法,从连杆坐标系的建立到运动学方程的求解,提供了实用的操作步骤和代码示例。通过DH参数表和变换矩阵的构建,帮助读者快速掌握机械臂运动学建模的核心技术,并解决实际应用中的常见问题。

oo7890的博客 211

MySQL查看表占用空间大小

通过SQL查看MySQL表占用空间大小

东境物语 2万+

Seurat 单细胞转录组测序数据分析教程(三)——python(scanpy)

文章参考至,做了一个更详细的解读。本教程探讨了 scanpy 的可视化可能性,分为三个部分:嵌入的散点图(例如 UMAP、t-SNE)使用已知标记基因鉴定簇差异表达基因的可视化在本教程中,我们将使用来自 10x 的数据集,其中包含来自PBMC的 68k 个细胞。Scanpy 在其分布中包括该数据集的简化样本,该数据集仅包含 700 个细胞和 765 个高度可变的基因。该数据集已经过预处理和 UMAP 计算。在本教程中,我们还将使用以下文献标记:B细胞:CD79A、MS4A1。

coffeeii的博客 5827

从零构建生产级K8s-v1.35.0集群:基于Containerd与Cilium的kubeadm实战指南

本文详细介绍了从零构建生产级K8s-v1.35.0集群的全过程,涵盖环境准备、Containerd配置、Kubernetes组件安装、集群初始化及Cilium网络部署等关键步骤。通过实战经验分享系统调优技巧和常见问题解决方案,帮助读者快速搭建稳定高效的Kubernetes集群。

weixin_28725553的博客 219

mysql 临时表空间

Created_tmp_disk_tables /Created_tmp_tables > 25% 不要大于25% ,大于的话 需要调整下参数 ,往磁盘写的数量比较大的话,说明临时表空间大小设置的不合理,需要手动调整。临时表空间: 用来保存用户创建的临时表和磁盘内部的临时表, 从 mysql5.7 开始 模式采用独立表空间,之前都是放在系统表空间 ibdata1中。查看临时表空间的大小 ,一旦该大小超过内存当中的表时,它就会转成磁盘上的表。Created_tmp_files: 内存当中的临时表。

xu990128638的专栏 1342

禾赛XT16 vs XT32激光雷达实测对比:选16线还是32线?看完这篇不纠结

本文深度评测禾赛XT16与XT32激光雷达的性能差异与应用选择。通过实测数据对比,分析16线与32线激光雷达在点云密度、动态场景适应性及与IMU协同工作等方面的表现,帮助用户根据自动驾驶、机器人等不同应用场景做出最优选型决策。

table的专栏 944

Mysql 临时表空间

最近研究InnoDB的官方文档,看到了临时表空间一节,回想起之前碰到过客户执行SQL语句报ERROR-1114 The table ‘/tmp/xxxxxx’ is full的报错,当时也是查官方文档、查MOS才明白MySQL的临时表机制,而且从5.6-8.0.32,不同版本的临时表使用方法变化也是很大,所以决定梳理一下。

qq_29431123的博客 2699

搜索引擎——ElasticSearch汇总

汇总——ElasticSearch篇 全文检索 问题1:什么是全文检索? 基本概念:对**非结构化数据/结构化数据**先建立**索引**,再对索引进行搜索**文档**的过程叫做全文检索。 什么是非结构化与结构化数据? - 非结构化数据:没有固定的格式的数据(html,word,excel)---没有固定长度,字段约束,描述,散列数据 - 结构化数据:有固定的格式的数据(如:数据库数据)---有固定长度(varchar(50)),字段类型,描述修饰数据 搜索算法:顺序扫描法、倒排索引法 - 顺序

alonewolf_99的博客 1838

代谢组数据分析(五):代谢组的功能富集分析

本文介绍了代谢组数据分析中的功能分析,包括代谢物富集分析、GSEA和ssGSEA方法。文章详细阐述了分析原理、应用背景、数据准备、统计方法以及结果解释,强调了在代谢通路和代谢物ID对应关系建立、差异代谢物筛选、富集程度计算等方面的关键步骤。通过这些方法,可以揭示差异代谢物在生物过程中的作用,为疾病研究和药物开发提供依据。

专注生信领域 5980

mysql 临时表空间大小_JDBC与MySQL临时表空间的分析

文章来源:爱可生云数据库作者:秦沛、胡呈清背景应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间。为了限制临时表空间的大小,设置了:innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G问题描述在限制了临时表空间后...

weixin_32218639的博客 742

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

mysql查询创建临时表空间_JDBC与MySQL临时表空间的分析

原标题:JDBC与MySQL临时表空间的分析文章来源:爱可生云数据库作者:秦沛、胡呈清1.背景应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间。为了限制临时表空间的大小,设置了:innodb_temp_data_file_path = ibtmp1:12M:autoext...

weixin_36421674的博客 304

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

深度分析 | JDBC与MySQL临时表空间的分析

原创作者:秦沛、胡呈清 背景 应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间。为了限制临时表空间的大小,设置了: innodb_temp_data...

chiweiliu4439的博客 125

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

sql 临时表_深度分析 | JDBC与MySQL临时表空间的分析

原创作者:爱可生开源社区 背景应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间。为了限制临时表空间的大小,设置了:innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G问题描述在限制了临时表空间后,当应用仍按以前...

weixin_39915267的博客 111

mysql use temporary_JDBC与MySQL临时表空间的分析

背景应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间。为了限制临时表空间的大小,设置了:innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G问题描述在限制了临时表空间后,当应用仍按以前的方式访问时,ibtmp1...

weixin_39629075的博客 164

jdbc获取mysql第二行表信息_JDBC与MySQL临时表空间的分析-爱可生

背景应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间。为了限制临时表空间的大小,设置了:innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G问题描述在限制了临时表空间后,当应用仍按以前的方式访问时,ibtmp1...

weixin_39676972的博客 175

java mybatis mysql临时表_JDBC与MySQL临时表空间的分析-爱可生

背景应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间。为了限制临时表空间的大小,设置了:innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G问题描述在限制了临时表空间后,当应用仍按以前的方式访问时,ibtmp1...

weixin_31812189的博客 426

jdbc使用域名报错_深度分析 | JDBC与MySQL临时表空间的分析

原创作者:爱可生开源社区 背景应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间。为了限制临时表空间的大小,设置了:innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G问题描述在限制了临时表空间后,当应用仍按以前...

weixin_42461108的博客 406

jdbc获取mysql第二行表信息_深度分析 | JDBC与MySQL临时表空间的分析

背景应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间。为了限制临时表空间的大小,设置了:innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G问题描述在限制了临时表空间后,当应用仍按以前的方式访问时,i...

weixin_39849127的博客 101

mysql 表空间收缩_深度分析 | JDBC与MySQL临时表空间的分析

背景应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,耗尽服务器磁盘空间。为了限制临时表空间的大小,设置了:innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G问题描述在限制了临时表空间后,当应用仍按以前的方式访问时,i...

weixin_33502070的博客 143

mysql了解jdbc_关于JDBC与MySQL临时表空间的深入解析

背景临时表空间用来管理数据库排序操作以及用于存储临时表、中间排序结果等临时对象,相信大家在开发中经常会遇到相关的需求,下面本文将给大家详细JDBC与MySQL临时表空间的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧应用 JDBC 连接参数采用 useCursorFetch=true,查询结果集存放在 mysqld 临时表空间中,导致ibtmp1 文件大小暴增到90多G,...

weixin_39521808的博客 176
上一篇: Prometheus一条告警是怎么触发的
下一篇: 记一次 MySQL semaphore crash 的分析(有彩蛋)
爱可生开源社区
博客等级 码龄8年 1936粉丝 1004原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值