web-dev-qa-db-fra.com

Comment puis-je résoudre cette erreur ORA-01652 lorsque j'ai déjà ajouté un nouveau fichier à l'espace de table TEMP?

J'ai hérité des responsabilités de base de type DBA sur une base de données Oracle et je suis bloqué sur une erreur ORA-01652 lors de l'exécution d'une requête contenant de nombreuses jointures et regroupements. Voici l'erreur que j'obtiens:

ORA-01652: unable to extend temp segment by 128 in tablespace TEMP
01652. 00000 -  "unable to extend temp segment by %s in tablespace %s"
*Cause:    Failed to allocate an extent of the required number of blocks for
           a temporary segment in the tablespace indicated.
*Action:   Use ALTER TABLESPACE ADD DATAFILE statement to add one or more
           files to the tablespace indicated.

J'ai suivi (ou du moins essayé) le message d'erreur et créé un nouveau fichier de données. Voici la commande que j'ai utilisée pour cela:

ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/app/Oracle/oradata/ABCDEFG/temp02.dbf'
SIZE 1024M REUSE AUTOEXTEND ON NEXT 50M  MAXSIZE 4096M;

Maintenant, quand je regarde dans DBA_TEMP_FILES Je vois à la fois l'ancien et le nouveau fichier associés à l'espace de table TEMP, mais quand j'essaie de relancer ma requête, j'obtiens le même message d'erreur.

Donc, ma question est pourquoi cette erreur se produit-elle toujours, étant donné que la requête que j'exécute est grande mais pas que grande. Ai-je créé le fichier de données correctement? Comment puis-je diagnostiquer cela plus en détail?

5
Chris Farmer

Chaque espace disque logique possède un ou plusieurs fichiers de données qu'il utilise pour stocker des données.

La taille maximale d'un fichier de données dépend de la taille de bloc de la base de données. Je crois que, par défaut, cela vous laisse avec un maximum de Go par fichier de données.

exécutez la commande suivante pour la taille réelle autorisée:

select value from v$parameter where name = 'db_block_size';

Comparez le résultat obtenu avec la première colonne ci-dessous, et cela indiquera la taille maximale de votre fichier de données.

J'ai Oracle Personal Edition 11g r2 et dans une installation par défaut, il avait une taille de bloc de 8 192 (32 Go par fichier de données).

Block Sz   Max Datafile Sz (Gb)   Max DB Sz (Tb)

--------   --------------------   --------------

   2,048                  8,192          524,264

   4,096                 16,384        1,048,528

   8,192                 32,768        2,097,056

  16,384                 65,536        4,194,112

  32,768                131,072        8,388,224

Vous pouvez exécuter cette requête pour trouver les fichiers de données dont vous disposez, les espaces disque logiques auxquels ils sont associés et ce à quoi vous avez actuellement défini la taille maximale du fichier (qui ne peut pas dépasser les 32 Go susmentionnés):

select bytes/1024/1024 as mb_size,
       maxbytes/1024/1024 as maxsize_set,
       x.*
from   dba_data_files x

MAXSIZE_SET est la taille maximale à laquelle vous avez défini le fichier de données. Il est également important de savoir si vous avez défini l'option AUTOEXTEND sur ON (son nom fait ce qu'il implique).

Si votre fichier de données a une taille maximale faible ou si l'extension automatique n'est pas activée, vous pouvez simplement exécuter:

alter database datafile 'path_to_your_file\that_file.DBF' autoextend on maxsize unlimited;

Cependant, si sa taille est à/près de 32 Go, une extension automatique est activée, alors oui, vous avez besoin d'un autre fichier de données pour le tablespace:

alter tablespace system add datafile 'path_to_your_datafiles_folder\name_of_df_you_want.dbf' size 10m autoextend on maxsize unlimited;

De plus, c'est généralement une bonne pratique/courante pour vous d'avoir un espace de table dédié aux index (il ne semble pas que ce soit le cas, car vous n'avez pas spécifié l'espace de table dans votre instruction create index, et il utilise la valeur par défaut système tablespace), donc après avoir créé un tel tablespace, vous exécuteriez quelque chose comme ceci (dans votre cas):

CREATE INDEX FTS_INDEX ON FILTERED_TEKLI_IIS_TABLOSU (ilAdi,ilceAdi,caddeAdi)
tablespace name_of_ts_for_indexes

(Après avoir créé ce tablespace et un fichier de données pour celui-ci), via:

create tablespace name_of_ts_for_indexes datafile
'c:\app\xyz\oradata\orcl\name_of_ts_for_indexes01.dbf' autoextend on maxsize unlimited nologging;

De cette façon, vos tables seraient sur un espace table et les index sur un autre.

Merci à Brian D. pour des informations supplémentaires.

2
Hector

À moins que vous ayez des raisons de croire que votre requête devrait nécessiter plus de 4 Go d'espace TEMP, ce qui serait très inhabituel à moins que vous ne fassiez quelque chose comme la construction d'agrégats à partir de très très grandes tables, cela ressemble à votre requête a un bug. Si j'avais une requête qui contenait "beaucoup de jointures" et épuisait systématiquement l'espace de table TEMP, je parierais qu'il manquait une ou plusieurs conditions de jointure, ce qui oblige Oracle à effectuer une ou plusieurs jointures cartésiennes (ce qui signifie que N lignes dans une table et M lignes dans une autre table deviennent N * M lignes dans le jeu de résultats). Avec des tables même moyennement grandes, cela nécessite une quantité considérable d'espace temporaire.

Si vous regardez le plan de requête, je parierais que vous verriez un ou plusieurs MERGE JOIN CARTESIAN opérations. Si vous pouvez identifier les tables jointes cartésiennes, cela devrait vous aider à identifier les conditions de jointure manquantes.

Si vous utilisez l'ancienne syntaxe de jointure où toutes les conditions de jointure apparaissent dans la clause WHERE

SELECT ...
  FROM a,
       b,
       c
 WHERE a.foo = b.foo

vous pouvez essayer de réécrire la requête à l'aide de la syntaxe SQL 99. Cela rend généralement plus facile de remarquer que vous manquez une condition de jointure

SELECT ...
  FROM a 
       JOIN b
         ON( a.foo = b.foo )
       JOIN c
         <<oops, no join condition>>
0
Justin Cave