oracle临时表空间无法释放的解决办法

 更新时间:2024年03月13日 10:53:49   作者:小百菜  
Oracle临时表空间主要是用于数据库较大的临时排序用,在PGA分配的工作区空间不足以容纳排序数据时使用临时表空间,但是容易遇到oracle临时表空间无法释放的问题,所以本文给大家介绍了oracle临时表空间无法释放的解决办法,需要的朋友可以参考下

项目报错:nested exception is java.sql.SQLException: ORA-01652: unable to extend temp segment by 128 in tablespace TEMP

原因是临时表空间满了,临时表空间一直增长,未释放导致临时表空间使用率100%。

查询临时表空间使用率

--临时表空间利用率
select c.tablespace_name "临时表空间名",
       round(c.bytes / 1024 / 1024 / 1024, 2) "临时表空间大小(G)",
       round((c.bytes - d.bytes_used) / 1024 / 1024 / 1024, 2) "临时表空间剩余大小(G)",
       round(d.bytes_used / 1024 / 1024 / 1024, 2) "临时表空间使用大小(G)",
       round(d.bytes_used * 100 / c.bytes, 4) || '%' "使用率 %"
  from (select tablespace_name, sum(bytes) bytes
          from dba_temp_files
         GROUP by tablespace_name) c,
       (select tablespace_name, sum(bytes_cached) bytes_used
          from v$temp_extent_pool
         GROUP by tablespace_name) d
 where c.tablespace_name = d.tablespace_name;

解决办法一:

--压缩一下临时表空间
--自动将表空间的临时文件缩小到最小可能的大小
alter tablespace TEMP shrink space;

解决办法二:

查询临时表空间位置,创建新的临时表空间

-- 查询临时表空间位置 
SELECT FILE_ID,
        TABLESPACE_NAME "临时表空间名",
        BYTES / 1024 / 1024 / 1024 "表空间大小(G)",
        FILE_NAME "文件路径"
   FROM DBA_TEMP_FILES
  order by TABLESPACE_NAME, FILE_NAME;
 
 
-- 例如查询结果如下:
-- /dev/shm/oradata/temp01.dbf
-- 创建新的临时表空间最好也放在这个目录下
 
-- 创建临时表空间
create temporary tablespace IRFS_TEMP 
tempfile '/dev/shm/oradata/irfs_temp01.dbf'
size 20g
autoextend off;

切换临时表空间为新的临时表空间,切换后删除原来的临时表空间。

-- 设置数据库的默认临时表空间,切换临时表空间
alter database default temporary tablespace IRFS_TEMP;
 
 
--查询默认的临时表空间
SELECT PROPERTY_NAME, PROPERTY_VALUE
 FROM DATABASE_PROPERTIES
 WHERE PROPERTY_NAME='DEFAULT_TEMP_TABLESPACE';
 
 
-- 删除原来的临时表空间(包括文件)
drop tablespace  TEMP including contents and datafiles;

解决办法三:

前两种方案,需要每隔一段时间就要去手动操作一次。

哪些情况会占用临时表空间?

1、当数据库执行如CREATE INDEX、ORDER BY、GROUP BY等操作时,如果内存中的排序区域大小不足,就会将数据放入临时表空间中进行排序。

2、操作CLOB或BLOB字段时,如果内存中的空间不足以容纳这些数据,Oracle会将这些数据放入临时表空间。

查询临时表空间占用sql

--查询临时表空间占用sql
SELECT se.username,
       se.sid,
       se.serial#,
       se.SQL_ID,
       se.sql_address,
       se.machine,
       sa.SQL_TEXT,
       sa.SQL_FULLTEXT,
       se.program,
       su.tablespace,
       su.segtype,
       su.contents
  FROM v$session se,
       v$sort_usage su,
       v$sqlarea sa
WHERE se.saddr=su.session_addr  and se.SQL_ID=sa.SQL_ID

表空间的释放通常依赖于事务提交或会话的断开。

事务的提交释放了事务占用的资源,包括临时表空间中的空间。

会话的断开也会释放该会话使用的表空间。

因此,如果临时表空间没有被释放,并不是由于自动扩展设置的原因。

在查找表空间未释放的原因时,您应该关注未提交的事务或仍然处于活动状态的会话。

对于临时表空间的释放问题,您可以继续检查未提交的事务或会话,并确保它们被正确提交或断开连接。

我的Oracle数据库版本是11gR2(11.2.0.4)

我这里是由于clob或者blob字段造成的。

具体原因是clob或者blob字段使用后会占用临时表空间,如果连接不断开就不会释放,只要想办法让连接使用后断开就行。

我使用了druid连接池,由于我的业务一天24小时都会使用,所以连接池中的连接一直处于活跃状态,没有到达配置的空闲5分钟删除掉连接,

当然也可以从空闲时间参数入手让空闲时间短点就删除掉连接,一句话就是想办法让连接断开,但是频繁的创建连接也不好那连接池也没有意义了。

解决思路,不要使用clob或者blob字段,想办法使用其它方案替代,我这里必须要用到clob,又没有找到替代方案。

我后面解决思路是,写了一个定时器,10分钟检测一次连接池,连接存活时间超过1天,就删除该连接,且一次最多删除一个连接防止把连接池清空了。该方案自行评估有无风险!

package com.study.pool;
 
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
 
import javax.sql.DataSource;
import java.sql.Connection;
 
/**
 * 清理连接存活时间超过1天的连接
 * 由于clob和blob字段导致临时表空间不释放,需要定期清理连接
 * @Date: 2024/2/29 16:49
 */
@Slf4j
@Component
@EnableScheduling
public class DruidPooledClear {
    @Autowired
    private JdbcTemplate jdbcTemplate;
 
    // @PostConstruct
    @Scheduled(cron = "25 1/10 * * * ?") //10分钟一次
    public void clearConnection() {
        try {
            DataSource dataSource = jdbcTemplate.getDataSource();
            if (dataSource instanceof DruidDataSource) {
                DruidDataSource druidDataSource = (DruidDataSource) dataSource;
                clearConnection(dataSource, druidDataSource);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
 
    /**
     * 清理连接,1次只清理一个连接,防止一次性把连接池清空
     * @date 2024/2/29 16:59
     */
    private void clearConnection(DataSource dataSource, DruidDataSource druidDataSource) {
        DruidPooledConnection druidPooledConnection = null;
        try {
            // 由于druidDataSource.getConnection()总是获取上一次使用的连接(最后一次使用的连接),无法遍历空闲连接,只有使用递归才获取所有空闲连接
            druidPooledConnection = druidDataSource.getConnection();
            // log.info("连接:" + druidPooledConnection.getConnectionHolder());
 
            // 连接创建单位:毫秒
            long connectedTimeMillis = druidPooledConnection.getConnectionHolder().getConnectTimeMillis();
            // 删除连接,连接存活时间超过1天
            if (System.currentTimeMillis() > connectedTimeMillis + 1000 * 60 * 60 * 24) {
                log.info("删除连接:" + druidPooledConnection.getConnectionHolder());
                // 这一步很关键,druidPooledConnection.getConnection() 取出的连接,已经不能归还给连接池了
                Connection connection = druidPooledConnection.getConnection();
                // 从连接池中移除连接
                DataSourceUtils.releaseConnection(connection, dataSource);
            } else {
                // int activeCount = druidDataSource.getActiveCount();//活跃连接数
                int poolingCount = druidDataSource.getPoolingCount();//空闲连接数
                // log.info("池中连接数:{},活跃连接数:{},空闲连接数:{}", activeCount + poolingCount, activeCount, poolingCount);
                if (poolingCount > 0) {
                    clearConnection(dataSource, druidDataSource);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            // 归还连接给连接池
            DataSourceUtils.releaseConnection(druidPooledConnection, dataSource);
        }
    }
}

以上就是oracle临时表空间无法释放的解决办法的详细内容,更多关于oracle临时表空间无法释放的资料请关注脚本之家其它相关文章!

相关文章

  • oracle11g客户端连接12c服务器ORA-01017错误问题解决

    oracle11g客户端连接12c服务器ORA-01017错误问题解决

    这篇文章主要介绍了oracle11g客户端连接12c服务器ORA-01017错误,本文给大家分享完美解决方法,对oracle 12c错误ORA-01017问题解决方法感兴趣的朋友跟随小编一起看看吧
    2023-06-06
  • Oracle 23ai中重要新特性VECTOR数据类型的使用

    Oracle 23ai中重要新特性VECTOR数据类型的使用

    Oracle 23ai 中的 VECTOR 数据类型是 Oracle 数据库在 AI 领域的一个重要新特性,它允许用户以向量的形式存储数据,并在这些向量的基础上进行高效的搜索和分析,下面就来介绍一下如何使用
    2024-08-08
  • PLSQL导入dmp文件的详细完整步骤

    PLSQL导入dmp文件的详细完整步骤

    plsql导入.sql和.dmp文件时,会经常用到,对于初学者来说可能没有那么简单,毕竟oracle数据库比较麻烦,下面这篇文章主要给大家介绍了关于PLSQL导入dmp文件的详细完整步骤,需要的朋友可以参考下
    2023-05-05
  • MSSQL与Oracle数据库事务隔离级别与锁机制对比

    MSSQL与Oracle数据库事务隔离级别与锁机制对比

    事务隔离级别是并发控制的整体解决方案,其实际上是综合利用各种类型的锁和行版本控制,来解决并发问题。锁是数据库并发控制的内部机制,是基础。对用户来说,只有当事务隔离级别无法解决一些并发问题和需求时,才有必要在语句中手动设置锁。
    2014-08-08
  • Oracle数据库执行慢问题排查详细过程

    Oracle数据库执行慢问题排查详细过程

    这篇文章主要给大家介绍了关于Oracle数据库执行慢问题排查的详细过程,在企业级应用中,数据库的稳定性和性能是至关重要的,文中给出了详细的代码实例,需要的朋友可以参考下
    2023-07-07
  • Oracle Decode()函数使用技巧分享

    Oracle Decode()函数使用技巧分享

    decode()函数是ORACLE PL/SQL是功能强大的函数之一,目前还只有ORACLE公司的SQL提供了此函数,其他数据库厂商的SQL实现还没有此功能
    2013-05-05
  • Oracle数据库中对null值的排序及mull与空字符串的区别

    Oracle数据库中对null值的排序及mull与空字符串的区别

    这篇文章主要介绍了Oracle数据库中对Null值的排序及Null与空字符串的区别,讲解了在order by排序中如何定义null值项的位置及其与字符串' '的不同,需要的朋友可以参考下
    2016-03-03
  • oracle导入导出某个schema数据的步骤

    oracle导入导出某个schema数据的步骤

    这篇文章主要介绍了oracle导入导出某个schema数据的步骤,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • Oracle 10g DG 数据文件迁移的实现

    Oracle 10g DG 数据文件迁移的实现

    我们常常需要对数据进行迁移,这篇文章主要介绍了Oracle 10g DG 数据文件迁移的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • ORACLE11g随RHEL5系统自动启动与关闭的设置方法

    ORACLE11g随RHEL5系统自动启动与关闭的设置方法

    最近,ORACLE系统基本调试通过,是时候设置ORACLE随RHEL自动启动与关闭服务的时候了,之所以把这个任务放在最后来做,是因为我觉得这个应该不会很难,但真正实施起来,还是遇到了个不小的障碍
    2009-08-08

最新评论