Introduction
Une base de données grandit au fil du temps (INSERTs, UPDATEs, imports datapump...) et, parfois, ses tablespaces atteignent leur taille maximale, ce qui bloque celle-ci. Nous allons voir comment augmenter sa taille, aussi bien d'un point de vue Oracle que d'un point de vue Unix.



Points d'attention
N/A.



Base de tests
Une base Oracle 18c multi-tenants. 




Exemples

============================================================================================
Infos sur le tablespace
============================================================================================
Dans notre base nous avons un tablespace rempli à 95%, ce qui génère une alerte et un appel urgent au DBA :-)
     SQL> SELECT TABLESPACE_NAME, TABLESPACE_SIZE, USED_SPACE, ROUND(USED_PERCENT, 2) FROM DBA_TABLESPACE_USAGE_METRICS WHERE TABLESPACE_NAME = 'TEST01';
     TABLESPACE_NAME TABLESPACE_SIZE USED_SPACE ROUND(USED_PERCENT,2)
     ------------------------------ --------------- ---------- ------
     TEST01 38400 36320 94,58

En premier, nous devons récupérer le ou les datafiles composant ce tablespace. Une façon est de générer l'ordre DDL de ce tbs ou bien d'interroger la vue DBA_DATA_FILES; je vais passer par l'ordre DDL avec le package DBMS_METADATA. Ce tablespace utilise un seul fichier; ATTENTION, si vous avez déjà fait un resize de ce tbs, il y aura dans l'ordre DLL un ALTER TABLE montrant ce resize après le CREATE. Ce que cela implique, c'est que pour calculer la taille max de ce tbs, il faut additionner la taille initiale à la taille des N resizes.
     SQL> set long 1000000
     SQL> select dbms_metadata.get_ddl('TABLESPACE', 'TEST01') from dual;
     DBMS_METADATA.GET_DDL('TABLESPACE','TEST01')
     ----------------------------------------------------
     CREATE TABLESPACE "TEST01" DATAFILE
     '/u02/oradata/ZZSXM/TEST0101.DBF' SIZE 314572800
     LOGGING ONLINE PERMANENT BLOCKSIZE 8192
     EXTENT MANAGEMENT LOCAL AUTOALLOCATE DEFAULT
     NOCOMPRESS SEGMENT SPACE MANAGEMENT AUTO

Quelle est la taille actuelle du TBS? Car il ne faut pas confondre : la taille T1 des datafiles et la taille actuelle T2 du tbs qui peut aller jusqu'à T1. A noter que la vue DBA_TABLESPACE_USAGE_METRICS n'a pas d'unité en octets dans la doc Oracle donc on ne peut pas utiliser cette vue pour ce calcul, mais ce n'est pas grave car nous l'utilisons pour voir le taux d'occupation de celui-ci.

Doc Oracle

"DBA_TABLESPACE_USAGE_METRICS describes tablespace usage metrics for all types of tablespaces, including permanent, temporary, and undo tablespaces.
TABLESPACE_SIZE NUMBER Total size of the tablespace; ici on n'a pas d'unité, c'est dommage"

Avec DBMS_METADATA.GET_DDL on voit la taille max du ou des fichiers constitutifs du tbs. On peut aussi utiliser DBA_SEGMENTS pour calculer la taille réellement occupée dans le tbs par des objets comme les tables et les index. Ici, le tbs fait 0,28Go.
     SQL> select round(sum(BYTES)/(1024*1024*1024), 2) AS "Taille Go" from dba_segments where TABLESPACE_NAME = 'TEST01';
     Taille Go
     ----------
     ,28

Mais bon, connaître cette taille réelle du tbs n'est pas vraiment utile pour notre problème car ce qui nous intéresse c'est sa taille max.


============================================================================================
Augmenter la taille d'un tablespace
============================================================================================
Maintenant regardons avec la commande unix df s'il reste quelques gigas sur le file system du fichier du tbs. Ici il reste 21 Go; ATTENTION au % juste à côté du mot FREE, il est accolé à Used en réalité, pas à FREE! Donc ce qu'il faut lire ci-dessous c'est qu'il reste 21.50Go de libre sur 145Go (et non pas 21,5%) et que le fs est plein à 86%.
     SQL> ! df -g /u02/oradata
     Filesystem GB blocks Free %Used Iused %Iused Mounted on
     /dev/ddem2.1 145.50 21.50 86% 10587 1% /u02/oradata

J'augmente maintenant la taille du tablespace via son datafile: de façon arbitraire je la passe de 0,28Go à 1Go.
     SQL> alter database datafile '/u02/oradata/ZZSXM/TEST0101.DBF' resize 1G;
     Database altered.

Vérification : bingo, le tablespace n'est plus occupé qu'à 28%.
     SQL> SELECT TABLESPACE_NAME, TABLESPACE_SIZE, USED_SPACE, ROUND(USED_PERCENT, 2) FROM DBA_TABLESPACE_USAGE_METRICS WHERE TABLESPACE_NAME = 'TEST01';
     TABLESPACE_NAME TABLESPACE_SIZE USED_SPACE ROUND(USED_PERCENT,2)
     ------------------------------ --------------- ---------- ------
     TEST01 131072 36320 27,71



============================================================================================
Augmenter la taille d'un filesystem sous AIX Unix
============================================================================================
Nous venons de voir que quand un tablespace n’a plus d’espace, il suffit d’agrandir son ou un des ses datafiles. Le pb est que parfois ce datafile est sur un filesystem qui lui même n’a plus d’espace disque disponible... Dans ce cas il faut augmenter la taille du fs et là, c’est plus compliqué si vous êtes DBA Oracle et pas Admin système.

Prenons le cas d'un export datapump de la base XXXPROD qui fait 30Go.
     -> ls -l /u06/backup/XXXPROD/*.dmp
     -rw-rw---- 1 ora1120 dba 30247810048 Oct 02 14:28 /u06/backup/XXXPROD/expdp_XXXPROD.dmp

Il faut ensuite le copier sur le serveur de la base cible. Problème, il n’y a plus assez d’espace disponible dans le répertoire /u06/backup/xxxqlif : seulement 19Go de libre.
     # df -g /u06/backup/xxxqlif
     Filesystem GB blocks Free %Used Iused %IusedMounted on
     /dev/vlemc4.3 75.00 19.40 75% 12 1% /u06/backup/xxxqlif

En 2020 votre base Oracle est certainement dans une VM (Machine Virtuelle), ce qui signifie que les ressources que vous voyez sont en réalité des ressources allouées à la VM et non pas celles disponibles au niveau de la couche physique du serveur Unix, qui peut abriter plusieurs VM.

Il faut donc afficher les vraies ressources disponibles de votre SI.


Avec la commande df, on voit que le point de montage /u06/backup/xxxqlif est associé au file system /dev/vlemc4.3. Sous l'Unix AIX d'IBM, on utilise alors la commande lslv, pour Listing Logical Volume pour voir ces infos. Que voit-on? Que ce volume logique pointe vers un volume physique de nom emc_expvg1.
     # lslv vlemc4.3
     LOGICAL VOLUME: vlemc4.3 VOLUME GROUP: emc_expvg1
     LV IDENTIFIER: 00f8376500004c000000015b33976ada.3 PERMISSION: read/write
     VG STATE: active/complete LV STATE: opened/syncd
     TYPE: jfs2 WRITE VERIFY: off
     MAX LPs: 512 PP SIZE: 256 megabyte(s)
     COPIES: 1 SCHED POLICY: parallel
     LPs: 300 PPs: 300
     STALE PPs: 0 BB POLICY: relocatable
     INTER-POLICY: minimum RELOCATABLE: yes
     INTRA-POLICY: middle UPPER BOUND: 32
     MOUNT POINT: /u06/backup/xxxqlif LABEL: /u06/backup/xxxqlif
     MIRROR WRITE CONSISTENCY: on/ACTIVE
     EACH LP COPY ON A SEPARATE PV ?: yes
     SerializeIO ?: NO
     INFINITE RETRY: no

Maintenant on exécute la commande lsvg, pour Listing Volume Group, pour avoir enfin la taille de l'espace disque disponible. Et là il y a 14848 Mo de dispo, soit plus de 14 Go.
     # lsvg emc_expvg1
     VOLUME GROUP: emc_expvg1 VG IDENTIFIER: 00f8376500004c000000015b33976ada
     VG STATE: active PP SIZE: 256 megabyte(s)
     VG PERMISSION: read/write TOTAL PPs: 999 (255744 megabytes)
     MAX LVs: 256 FREE PPs: 58 (14848 megabytes)
     LVs: 5 USED PPs: 941 (240896 megabytes)
     OPEN LVs: 5 QUORUM: 2 (Enabled)
     TOTAL PVs: 1 VG DESCRIPTORS: 2
     STALE PVs: 0 STALE PPs: 0
     ACTIVE PVs: 1 AUTO ON: yes
     MAX PPs per VG: 32512
     MAX PPs per PV: 1016 MAX PVs: 32
     LTG size (Dynamic): 256 kilobyte(s) AUTO SYNC: no
     HOT SPARE: no BB POLICY: relocatable
     PV RESTRICTION: none INFINITE RETRY: no
     DISK BLOCK SIZE: 512 CRITICAL VG: no
     (ux10dwht@root) pwd: / SID:

Pour augmenter la taille directement du point de montage de notre VM, il suffit d'utiliser la commande Unix chfs, pour Change File System attributs. Ici, j'ajoute 12 Go.
     chfs -a size=+12G /u06/backup/xxxqlif

Pour voir si tout s'est bien passé, il faut relancer la commande df (pour info j'ai dû calculer de moi-même le résultat car j'avais oublié de copier le résultat de df et, le contenu de ma base ayant changé, je ne peux pas relancer cette commande, d'où le fait que j'ai mis des *** dans la colonne Iused).
     # df -g /u06/backup/xxxqlif
     Filesystem GB blocks Free %Used Iused %IusedMounted on
     /dev/vlemc4.3 87.00 31.40 64% ***% /u06/backup/xxxqlif


 
Attention, les commandes lsvl et lsvg semblent inconnues de Linux... alors tournez-vous vers Internet ou, mieux, vers votre admin système :-)