Récupération de l'espace logique à partir d'un espace disque logique

11

J'ai un espace de table appelé DATA, et il est configuré avec l'extension automatique comme faux. Cet espace de table possède deux fichiers de données et est configuré de sorte qu'il occupe 350 Go d'espace physique.

Il y a une semaine, j'ai interrogé user_tablespaces et dba_data_files et j'ai remarqué qu'il y avait 20% d'espace logique disponible. J'ai ensuite procédé à un nettoyage et supprimé de nombreux enregistrements des tables de cet espace de table. Nous nous attendions à voir une grande augmentation de l'espace disponible. Malheureusement, lorsque j'ai interrogé les vues, j'ai remarqué que l'espace disponible était maintenant de 20,5%.

Cela pourrait-il être dû à la fragmentation des données? Pouvons-nous "défragmenter" l'espace de table d'une manière ou d'une autre et récupérer l'espace perdu? Ou devons-nous recréer l'espace de table à partir de zéro?

Nuno Furtado
la source

Réponses:

14

Lorsque vous supprimez des enregistrements, rien ne compacte automatiquement le segment, vous devrez donc effectuer une réduction du segment pour récupérer l'espace. Voici un extrait du Guide de l'administrateur 11.2 sur la récupération de l'espace perdu :

Au fil du temps, les mises à jour et les suppressions d'objets dans un espace de table peuvent créer des poches d'espace vide qui, individuellement, ne sont pas assez grandes pour être réutilisées pour de nouvelles données. Ce type d'espace vide est appelé espace libre fragmenté.

Les objets avec un espace libre fragmenté peuvent entraîner un gaspillage d'espace important et peuvent affecter les performances de la base de données. La méthode préférée pour défragmenter et récupérer cet espace consiste à effectuer une réduction de segment en ligne. Ce processus consolide l'espace libre fragmenté sous la ligne des hautes eaux et compacte le segment. Après compactage, la ligne des hautes eaux est déplacée, ce qui crée un nouvel espace libre au-dessus de la ligne des hautes eaux. Cet espace au-dessus de la ligne des hautes eaux est ensuite désalloué. Le segment reste disponible pour les requêtes et DML pendant la majeure partie de l'opération, et aucun espace disque supplémentaire n'a besoin d'être alloué.

Plus bas sur la même page, vous pouvez lire ceci:

La réduction de segment est une opération en ligne en place. Les opérations et requêtes DML peuvent être émises pendant la phase de déplacement des données de la réduction des segments. Les opérations DML simultanées sont bloquées pendant une courte période à la fin de l'opération de réduction, lorsque l'espace est désalloué. Les index sont conservés pendant l'opération de retrait et restent utilisables une fois l'opération terminée. La réduction de segment ne nécessite pas d'allocation d'espace disque supplémentaire.

Le rétrécissement du segment récupère l'espace inutilisé au-dessus et en dessous de la ligne des hautes eaux. En revanche, la désallocation d'espace récupère l'espace inutilisé uniquement au-dessus de la ligne des hautes eaux. Dans les opérations de réduction, par défaut, la base de données compacte le segment, ajuste la ligne des hautes eaux et libère l'espace récupéré.

La page contient beaucoup plus d'informations sur la question, y compris des exemples.

La section «Espace de segment et la ligne des hautes eaux» du Guide des concepts peut également être utile.

Leigh Riffel
la source
9

Oui, ce sera dû à la fragmentation.

Pour récupérer l'espace, obtenez d'abord une liste des tables dans l'espace table avec la requête suivante (en ignorant les partitions - modifiez votre question si vous les utilisez):

select distinct table_name from dba_tables where tablespace_name = 'DATA';

Ensuite, pour chaque table, activez le déplacement des lignes:

alter table TABLEINDATAPARTITION enable row movement;

Vous pouvez ensuite réduire le tableau:

alter table TABLEINDATAPARTITION shrink space;

Réduisez ensuite les fichiers de données avec:

alter database datafile '/path/to/my/file/data01.dbf' resize 20480M;

Les noms des fichiers de données peuvent être obtenus à partir de la DBA_DATA_FILESvue, que vous connaissez déjà.

Philᵀᴹ
la source
Excellent, une réponse pratique. +1
Leigh Riffel