Resumable Space Allocation

Como funciona o Resumable Space Allocation

O Resumable Space Allocation é uma funcionalidade do Oracle Database que possibilita suspender a execução de atividades executadas no banco de dados quando um problema de alocação de armazenamento ocorre, e posteriormente resumí-las automaticamente, quando o problema for sanado. Basicamente, ao invés do usuário receber erros como o ORA-01653 (unable to increase tablespace) ou o ORA-1536 (space quota exceeded for tablespace), ele tem sua sessão suspensa, sem receber erros, e a operação que a sessão solicitou será executada após o problema ser resolvido.

Como habilitar?

O Resumable Space Allocation pode ser habilitado a nível de sessão, com o comando:

SQL> ALTER SESSION ENABLE RESUMABLE TIMEOUT 3600;

Nesse caso o valor de TIMEOUT indica o tempo máximo que a sessão ficará suspensa, ou seja, o tempo que ela irá aguardar até que o problema seja resolvido. Caso o problema não seja solucionado dentro dessa janela, o erro será retornado para a sessão.

Para habilitar a funcionalidade a nível de sistema, precisamos configurar um valor maior que 0 (zero) para o parâmetro RESUMABLE_TIMEOUT:

SQL> ALTER SYSTEM SET RESUMABLE_TIMEOUT=3600;

Resumable Space Allocation na prática

Vamos fazer um teste de como funciona o Resumable Space Allocation na prática. Inicialmente irei criar uma tablespace com um datafile de 1MB (sem autoextend), e tentar criar uma tabela que tenha um tamanho superior a esse na tablespace:

SQL> CREATE TABLESPACE TBS01 DATAFILE SIZE 1M;

Tablespace created.

SQL> CREATE TABLE OBJS TABLESPACE TBS01 AS SELECT * FROM DBA_OBJECTS;
CREATE TABLE OBJS TABLESPACE TBS01 AS SELECT * FROM DBA_OBJECTS
*
ERROR at line 1:
ORA-01652: unable to extend temp segment by 8 in tablespace TBS01

Aqui temos um erro ORA-01652, já que o Oracle não consegue alocar mais espaço para comportar os dados dessa tabela. Agora vamos habilitar o Resumable Space Allocation e repetir o comando de criação da tabela:

SQL> ALTER SYSTEM SET RESUMABLE_TIMEOUT=3600;

System altered.

SQL> CREATE TABLE OBJS TABLESPACE TBS01 AS SELECT * FROM DBA_OBJECTS;

Dessa vez, ao invés de retornar um erro, minha sessão ficou “presa”. Neste momento, olhando no alert log do banco, temos a seguinte informação:

PDB(3):statement in resumable session 'User SYS(0), Session 41, Instance 1' was suspended due to
PDB(3):    ORA-01652: unable to extend temp segment by 8 in tablespace TBS01

O log nos mostra que a sessão foi suspensa devido ao erro que vimos anteriormente. Também podemos consultar a existência de sessões suspensas nas views DBA_RESUMABLE ou USER_RESUMABLE:

SQL> SET LINES WINDOW
SQL> COL NAME FOR A40
SQL> COL SQL_TEXT FOR A35
SQL> SELECT SESSION_ID, STATUS, TIMEOUT, START_TIME, NAME, SQL_TEXT FROM DBA_RESUMABLE;

SESSION_ID STATUS       TIMEOUT START_TIME           NAME                                     SQL_TEXT
---------- --------- ---------- -------------------- ---------------------------------------- -----------------------------------
        41 SUSPENDED       3600 05/22/25 20:39:56    User SYS(0), Session 41, Instance 1      CREATE TABLE OBJS TABLESPACE TBS01
                                                                                              AS SELECT * FROM DBA_OBJECTS

O próximo passo é resolver o problema:

SQL> SELECT FILE_ID FROM DBA_DATA_FILES WHERE TABLESPACE_NAME='TBS01';

   FILE_ID
----------
        17

SQL> ALTER DATABASE DATAFILE 17 RESIZE 500M;

Database altered.

Se acompanharmos o alert log, após o resize, veremos que a sessão suspensa será automaticamente resumida:

PDB(3):Resize operation completed for file# 17, old size 1024K, new size 512000K
PDB(3):Completed: ALTER DATABASE DATAFILE 17 RESIZE 500M
2025-05-22T20:47:36.490670-03:00
PDB(3):statement in resumable session 'User SYS(0), Session 41, Instance 1' was resumed

A entrada da view DBA_RESUMABLE também é atualizada, alterando o status para NORMAL:

SQL> SELECT SESSION_ID, STATUS, TIMEOUT, START_TIME, NAME, SQL_TEXT FROM DBA_RESUMABLE;

SESSION_ID STATUS       TIMEOUT START_TIME           NAME                                     SQL_TEXT
---------- --------- ---------- -------------------- ---------------------------------------- -----------------------------------
        41 NORMAL          3600                      User SYS(0), Session 41, Instance 1      CREATE TABLE OBJS TABLESPACE TBS01
                                                                                              AS SELECT * FROM DBA_OBJECTS

Resumable Space Allocation e Data Pump

Uma interação interessante acontece entre o Resumable Space Allocation e o Data Pump. Caso tenhamos um problema de alocação de espaço durante a importação de um dump, por exemplo, recebemos a mensagem:

ORA-39171: Job is experiencing a resumable wait.
Resumable error: ORA-01652: unable to extend temp segment by 128 in tablespace ...

Esse comportamento ocorre mesmo que nosso parâmetro RESUMABLE_TIMEOUT esteja setado para 0 (zero).

Vamos à demonstração, inicialmente setando o parâmetro RESUMABLE_TIMEOUT para 0:

SQL> ALTER SYSTEM SET RESUMABLE_TIMEOUT=0;

System altered.

Na sequência, com o usuário SYSTEM, vamos criar a tabela OBJS na TBS01, previamente criada, criar uma tablespace TBS02 com um datafile de 1MB, e um directory para exportação:

SQL> conn system@pdb
Enter password:

Connected.

SQL> CREATE TABLE OBJS TABLESPACE TBS01 AS SELECT * FROM DBA_OBJECTS;

Table created.

SQL> CREATE TABLESPACE TBS02 DATAFILE SIZE 1M;

Tablespace created.

SQL> CREATE DIRECTORY test AS '/home/oracle/';

Directory created.

Agora exportamos a tabela:

$ expdp system@pdb directory=test dumpfile=exp.dmp logfile=log.log tables=objs

Antes de proceder com a importação, vamos habilitar o SQL trace para o data pump, tanto para o processo master quanto para os workers:

SQL> BEGIN
    DBMS_MONITOR.SERV_MOD_ACT_TRACE_ENABLE(
        service_name => 'pdb',
        module_name  => 'Data Pump Master'
    );
    DBMS_MONITOR.SERV_MOD_ACT_TRACE_ENABLE(
        service_name => 'pdb',
        module_name  => 'Data Pump Worker'
    );
END;
/  2    3    4    5    6    7    8    9   10   11

PL/SQL procedure successfully completed.

Agora, ao tentar a importação do objeto, na tablespace TBS02, temos o ORA-39171:

$ impdp system@pdb directory=test dumpfile=exp.dmp logfile=log.log remap_table=objs:objs2 remap_tablespace=tbs01:tbs02 job_name=my_import

Import: Release 19.0.0.0.0 - Production on Thu May 22 21:55:08 2025
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.
Password:

Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Master table "SYSTEM"."MY_IMPORT" successfully loaded/unloaded
Starting "SYSTEM"."MY_IMPORT":  system/********@pdb directory=test dumpfile=exp.dmp logfile=log.log remap_table=objs:objs2 remap_tablespace=tbs01:tbs02 job_name=my_import
Processing object type TABLE_EXPORT/TABLE/TABLE
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
ORA-39171: Job is experiencing a resumable wait.
Resumable error: ORA-01653: unable to extend table SYSTEM.OBJS2 by 8 in tablespace TBS02
Resumable stmt:  BEGIN    SYS.KUPW$WORKER.MAIN('MY_IMPORT', 'SYSTEM', 0, 0);  END;
Resumable stmt status: SUSPENDED
Resumable stmt start: 05/22/25 21:55:16 stmt suspend: 05/22/25 21:55:16

Consultado a view DBA_RESUMABLE, temos:

SQL> SELECT SESSION_ID, STATUS, TIMEOUT, START_TIME, NAME, SQL_TEXT FROM DBA_RESUMABLE;

SESSION_ID STATUS       TIMEOUT START_TIME           NAME                                     SQL_TEXT
---------- --------- ---------- -------------------- ---------------------------------------- -----------------------------------
       280 SUSPENDED       7200 05/22/25 21:55:16    SYSTEM.MY_IMPORT                         BEGIN    SYS.KUPW$WORKER.MAIN('MY_
                                                                                              IMPORT', 'SYSTEM', 0, 0);  END;

Resolvendo o problema de espaço o job finaliza o import com sucesso.

E para responder o porquê a sessão do job de importação fica em modo suspenso, mesmo com o parâmetro RESUMABLE_TIMEOUT setado para 0 (zero), podemos analisar os traces gerados:

$ ls -lhtr *{dw,dm}*
-rw-r----- 1 oracle oinstall 339K May 22 21:49 orcl_dw00_746.trm
-rw-r----- 1 oracle oinstall 2.3M May 22 21:49 orcl_dw00_746.trc
-rw-r----- 1 oracle oinstall 493K May 22 21:49 orcl_dm00_737.trm
-rw-r----- 1 oracle oinstall 3.3M May 22 21:49 orcl_dm00_737.trc

Tanto no trace do processo DM (datapump master) quanto no DW (datapump worker) temos o seguinte comando executado:

=====================
PARSING IN CURSOR #140363711072024 len=54 dep=2 uid=9 oct=42 lid=9 tim=4589301413 hv=2457264351 ad='0' sqlid='dg2urtk97ds6z'
ALTER SESSION ENABLE RESUMABLE NAME 'SYSTEM.MY_IMPORT'
END OF STMT
PARSE #140363711072024:c=0,e=34,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=0,plh=0,tim=4589301413
EXEC #140363711072024:c=0,e=29,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=0,plh=0,tim=4589301480
CLOSE #140363711072024:c=0,e=0,dep=2,type=0,tim=4589301489
=====================

Antes de iniciar o processo de importação, o Resumable Space Allocation é habilitado a nível de sessão com o ALTER SESSION ENABLE RESUMABLE NAME 'SYSTEM.MY_IMPORT'. O NAME informado aparece na coluna “NAME” da view DBA_RESUMABLE, como mostrado acima. Como nenhum valor de timeout é especificado, o valor default de 7200 segundos (2 horas) é utilizado, também conforme a consulta acima retornou.

Com esse comportamento de habilitar o Resumable Space Allocation pelos processos do Data Pump, qualquer erro de alocação de espaço ou estouro de quota de usuário pode ser facilmente resolvido sem a necessidade de reiniciar o todo o processo de importação ou exportação novamente.

Conclusão

O Resumable Space Allocation é uma ferramenta que nos ajuda a minizar os impactos de problemas relacionados à alocação de espaço no Oracle, e particularmente sua utilização pelo Data Pump facilita a nossa vida como DBAs.

Caso queira saber mais sobre o Resumable Space Allocation, abaixo a referência da documentação oficial:

Managing Resumable Space Allocation;

Um grande abraço e até a próxima!

Publicar comentário