← Toutes les erreurs expliquées

ORA-01653 : Unable to extend, l'écriture qui échoue

Par Omar Sall, DBA Oracle · publié le 30 septembre 2026 · sévérité dans Deynao : Vigilance

Oracle a voulu allonger une table d'une extension de plus, et le tablespace qui la contient n'a pas pu fournir un morceau d'espace contigu de cette taille, ni dans ses fichiers, ni en les faisant grandir. L'instruction qui écrivait échoue ; la base reste ouverte, les lectures continuent, et les écritures qui n'ont pas besoin de place dans ce tablespace aussi ; celles qui en ont besoin peuvent échouer à leur tour. La cause la plus fréquente est un tablespace arrivé au bout de ce qu'il peut grandir, mais ce n'est pas la seule : de l'espace libre peut exister sans convenir, et un pourcentage élevé n'est pas un danger tant que les fichiers peuvent encore grandir. Première chose à regarder : la marge d'extension du tablespace nommé dans le message, pas son pourcentage. Le premier contrôle est dans Vérifier.

Ce que vous voyez

En anglais

ORA-01653: unable to extend table <schéma>.<table> by <n> in tablespace <tablespace>

En français

ORA-01653: impossible d'étendre la table <schéma>.<table> de <n> dans le tablespace <tablespace>

Le message arrive dans la session qui écrivait : une application, un chargement, un traitement de nuit, un import. Il nomme trois choses : la table, avec son schéma ; le tablespace ; et un nombre. Ce nombre est une taille en blocs de la base, pas en octets : « by 128 » avec des blocs de 8 Ko, c'est une extension d'un mégaoctet qu'Oracle n'a pas pu placer, et « de 8192 », que l'on croise souvent, en fait soixante-quatre avec les mêmes blocs (page d'erreur officielle). Le portail du constructeur montre aujourd'hui une formulation plus récente, avec la taille en Ko, Mo ou Go et l'opération en cause, « unable to increase tablespace ... during insert or update on table ... » ; sur une base 21c, c'est la forme ci-dessus qui sort. Les codes voisins disent la même chose pour d'autres objets : ORA-01654 pour un index, ORA-01688 pour une partition de table, ORA-01691 pour une colonne LOB. ORA-01652 concerne un segment temporaire, mécanisme différent.

Pour une écriture ordinaire, le message revient au client. Il est consigné dans le journal d'alertes de l'instance quand l'instruction s'exécute en mode reprise, où la suspension est écrite dans le journal (voir Prévenir), et il peut y apparaître quand c'est un processus de la base elle-même qui n'a pas pu écrire.

Ce que ça veut dire

Une table vit dans un segment, fait d'extensions : des suites de blocs contigus dans les fichiers du tablespace (DBA_SEGMENTS). Quand le segment a besoin de place, Oracle lui alloue une extension de plus. Il lui faut, dans un des fichiers, un morceau libre d'un seul tenant de cette taille. S'il n'en trouve pas, il tente de faire grandir un fichier, par pas de NEXT jusqu'à MAXSIZE, si l'extension automatique est active (gestion des fichiers de données). Si aucun fichier ne peut grandir, c'est ce code.

Sur le terrain

La séquence typique : un chargement ou un traitement de nuit échoue, le message nomme une table et un tablespace, et la personne qui le reçoit n'est pas le DBA, qui n'est pas là. Deux fils francophones anciens racontent exactement cela : quelqu'un qui n'a ni les droits ni le diagnostic, et une réponse en une ligne, « ton tablespace est plein, c'est tout » (le fil). C'est vrai dans la majorité des cas, et c'est ce qui trompe dans les autres.

Quatre faux diagnostics fréquents :

Un dernier point, que les fils anciens montrent : « le nombre maximal d'extensions » est un autre code, ORA-01631. Ce n'est pas ici qu'il se cherche.

Vérifier

Les contrôles ci-dessous sont en lecture seule. Ils demandent SELECT sur DBA_TABLESPACES, DBA_DATA_FILES, DBA_FREE_SPACE, DBA_SEGMENTS, DBA_TABLESPACE_USAGE_METRICS, DBA_OUTSTANDING_ALERTS et V_$PARAMETER, accordés directement, sans rôle : c'est exactement ce que fait le script de privilèges de Deynao, et c'est vérifiable sur le compte de supervision dans USER_TAB_PRIVS. Exécutés sur une base 21c. Les vues lues sont documentées dès la version 11.2, la plus ancienne que Deynao supervise (DBA_DATA_FILES, DBA_FREE_SPACE, DBA_TABLESPACE_USAGE_METRICS, DBA_TABLESPACES, et DBA_SEGMENTS dans la liste des vues du guide d'administration 11.2) ; DBA_OUTSTANDING_ALERTS est décrite dès 11.1 dans la gestion des alertes de tablespace. Remplacez USERS par le tablespace nommé dans le message.

-- 1. Chaque tablespace permanent : occupé, taille actuelle, maximum atteignable, et la
--    marge d'extension ; le pourcentage sur la taille actuelle et sur le maximum
SELECT t.tablespace_name,
       ROUND(d.mb - NVL(f.mb, 0))                       AS occupe_mb,
       ROUND(d.mb)                                      AS taille_mb,
       ROUND(d.max_mb)                                  AS maximum_mb,
       ROUND((d.mb - NVL(f.mb, 0)) / d.mb * 100, 1)     AS pct_taille_actuelle,
       ROUND((d.mb - NVL(f.mb, 0)) / d.max_mb * 100, 1) AS pct_maximum,
       ROUND(d.max_mb - (d.mb - NVL(f.mb, 0)))          AS marge_mb
FROM dba_tablespaces t
JOIN (SELECT tablespace_name,
             SUM(bytes) / 1048576 AS mb,
             SUM(CASE WHEN autoextensible = 'YES'
                      THEN GREATEST(bytes, NVL(maxbytes, 0))
                      ELSE bytes END) / 1048576 AS max_mb
      FROM dba_data_files
      GROUP BY tablespace_name) d ON d.tablespace_name = t.tablespace_name
LEFT JOIN (SELECT tablespace_name, SUM(bytes) / 1048576 AS mb
           FROM dba_free_space
           GROUP BY tablespace_name) f ON f.tablespace_name = t.tablespace_name
WHERE t.contents = 'PERMANENT'
ORDER BY pct_maximum DESC;

Comment le lire. occupe_mb est la taille des fichiers moins leurs morceaux libres : ce que les segments tiennent, extensions vides d'un chargement annulé comprises. pct_taille_actuelle est le chiffre que la plupart des outils affichent ; pct_maximum et marge_mb sont ceux qui comptent. Une marge à zéro sous un pourcentage élevé, c'est le cas de cette erreur : les fichiers ne peuvent plus grandir. Une marge de plusieurs gigaoctets sous 97 %, c'est un tablespace qui va grandir tout seul, et il reste le disque à vérifier (contrôle 3). Un fichier sans extension automatique compte pour sa taille actuelle dans le maximum ; un fichier agrandi à la main au-delà de son plafond aussi, MAXSIZE ne bornant que l'extension automatique (clause AUTOEXTEND) : sans le GREATEST, sa marge sortirait négative. Une erreur ORA-00942 signifie que ce compte n'a pas accès à une des vues.

-- 2. Ce que les tables du tablespace demandent, face au plus grand morceau libre d'un
--    seul tenant : quand le premier dépasse le second, l'espace déjà alloué ne suffit plus,
--    quel que soit le total ; reste à savoir si un fichier peut grandir (contrôle 4)
SELECT s.owner,
       s.segment_name,
       s.extents,
       ROUND(s.next_extent / 1048576, 2) AS prochaine_extension_mb,
       ROUND(f.largest / 1048576, 2)     AS plus_grand_libre_mb,
       ROUND(f.total / 1048576, 2)       AS total_libre_mb,
       f.morceaux
FROM dba_segments s
LEFT JOIN (SELECT tablespace_name,
                  MAX(bytes) AS largest,
                  SUM(bytes) AS total,
                  COUNT(*)   AS morceaux
           FROM dba_free_space
           GROUP BY tablespace_name) f ON f.tablespace_name = s.tablespace_name
WHERE s.tablespace_name = 'USERS'
  AND s.segment_type = 'TABLE'
ORDER BY s.bytes DESC;

prochaine_extension_mb est la taille que le segment demandera la prochaine fois (DBA_SEGMENTS) ; si elle est vide, la base la choisira au moment de l'allocation. plus_grand_libre_mb est le plus gros morceau d'un seul tenant. Quand la première dépasse la seconde, l'espace déjà alloué ne peut plus servir, même avec un total_libre_mb confortable ; l'erreur tombe si, en plus, aucun fichier ne peut grandir (contrôle 4). La suite est à l'étape 2 d'Agir. Aucune ligne veut dire qu'aucune table ne vit dans ce tablespace ; les colonnes de morceaux vides, qu'il n'a plus aucun espace libre.

-- 3. Le pourcentage du constructeur, calculé sur le maximum atteignable, espace libre du
--    support de stockage compris : la vue qui tient compte du disque
SELECT m.tablespace_name,
       ROUND(m.used_space * t.block_size / 1048576)      AS occupe_mb,
       ROUND(m.tablespace_size * t.block_size / 1048576) AS maximum_mb,
       ROUND(m.used_percent, 2)                           AS pct_maximum
FROM dba_tablespace_usage_metrics m
JOIN dba_tablespaces t ON t.tablespace_name = m.tablespace_name
ORDER BY m.used_percent DESC;

La vue compte en blocs, et un tablespace peut avoir sa propre taille de bloc, différente de celle de la base (clause BLOCKSIZE, gestion des tablespaces) : la conversion prend celle de DBA_TABLESPACES, pas le paramètre de l'instance, et c'est aussi ce que fait Deynao. maximum_mb est ce que le tablespace peut atteindre en tenant compte de l'extension automatique et de l'espace libre du support de stockage (référence 21c, décrit ainsi depuis la référence 12.2 ; la référence 11.2 ne dit pas ce que la taille maximale intègre, à vérifier sur une base de cette version avant de s'y fier) : si ce chiffre est plus bas que maximum_mb du contrôle 1, c'est le disque qui bride, pas MAXSIZE. Sur la base de démonstration, SYSTEM y est à 0,86 %, le chiffre de plus haut arrondi autrement.

-- 4. Les fichiers du tablespace : extension automatique ou non, pas d'extension, plafond.
--    34 359 721 984 octets de plafond, c'est UNLIMITED sur la base de démonstration (blocs de 8 Ko)
SELECT file_id,
       file_name,
       ROUND(bytes / 1048576)    AS taille_mb,
       autoextensible,
       increment_by              AS pas_en_blocs,
       ROUND(maxbytes / 1048576) AS plafond_mb,
       maxblocks                 AS plafond_blocs
FROM dba_data_files
WHERE tablespace_name = 'USERS'
ORDER BY file_id;

increment_by est en blocs (DBA_DATA_FILES). Un fichier NO ne grandira pas, quel que soit le disque. Un plafond_blocs à 4 194 302, ce que UNLIMITED inscrit sur la base de démonstration, est le plafond d'un fichier smallfile à un bloc près, 32 Go en blocs de 8 Ko : un fichier arrivé là ne grandira plus, il en faut un de plus. Un fichier dont taille_mb dépasse plafond_mb a été agrandi à la main au-delà de son plafond, et ne grandira plus tout seul. Le chemin du fichier est celui qu'il faudra dans les commandes d'Agir.

-- 5. Les dix segments les plus gros du tablespace : qui a pris la place, et en combien
--    d'extensions ; un chargement annulé laisse des extensions vides
SELECT *
FROM (
    SELECT owner,
           segment_name,
           segment_type,
           ROUND(bytes / 1048576, 1) AS mb,
           extents
    FROM dba_segments
    WHERE tablespace_name = 'USERS'
    ORDER BY bytes DESC
)
WHERE ROWNUM <= 10;

Un segment volumineux, à beaucoup d'extensions, dont la table est presque vide, fait penser au chargement annulé sans le prouver : des suppressions massives laissent le même profil, un segment ne rendant pas ses extensions de lui-même (guide des concepts). Cette vue ne compte pas les lignes : NUM_ROWS dans DBA_TABLES le dit si les statistiques sont récentes, un COUNT sinon, coûteux sur une grosse table. Un index ou une colonne LOB en tête de liste désigne un autre objet que la table du message, et un autre code voisin la prochaine fois.

-- 6. Les alertes d'espace que la base a elle-même levées (85 % et 97 % par défaut sur une base
--    créée telle quelle), et si le mode reprise est activé au niveau système
SELECT 'alerte' AS quoi, object_name AS objet, reason AS detail
FROM dba_outstanding_alerts
WHERE UPPER(object_type) = 'TABLESPACE'
UNION ALL
SELECT 'resumable_timeout', name, value
FROM v$parameter
WHERE name = 'resumable_timeout';

La base surveille elle-même ses tablespaces gérés localement, à 85 % et 97 % par défaut sur une base créée telle quelle, et garde les alertes en cours dans DBA_OUTSTANDING_ALERTS (surveillance de la base, référence de la vue). Aucune ligne d'alerte veut dire qu'aucune n'est ouverte à cet instant, pas que les seuils sont en place : ils se règlent, et se désactivent, par DBMS_SERVER_ALERT, une base migrée depuis une version antérieure à 10g les a tous à zéro (gestion des alertes de tablespace, guide d'administration), et ils se lisent dans DBA_THRESHOLDS, avec un compte qui y a accès (référence de la vue). resumable_timeout à 0, sa valeur par défaut, veut dire que le mode reprise n'est pas activé pour tout le monde (référence du paramètre).

Agir

Dans l'ordre, et chaque étape peut suffire :

  1. Lire la marge avant d'ajouter quoi que ce soit (contrôle 1). Si les fichiers peuvent encore grandir de plusieurs gigaoctets, le tablespace n'est pas plein : c'est un morceau libre trop petit, un segment gonflé, ou le disque. Les étapes 2 et 3 disent les deux premiers ; le disque se lit au contrôle 3, et sur le serveur.
  2. Si l'extension ne tient dans aucun morceau libre (contrôle 2), il faut un morceau assez grand : libérer des petites zones éparses n'en fera pas une grande ; ce qui peut en faire une, c'est un segment qui rend d'un coup ses extensions vides (étape 3), sinon c'est de l'espace en plus (étape 4).
  3. Si un segment garde des extensions vides (contrôle 5), les lui reprendre avec la commande du cas, le repère haut décidant (voir Ce que ça veut dire) : DEALLOCATE UNUSED pour un chargement en chemin direct annulé ; SHRINK SPACE pour un chargement ordinaire annulé ou des suppressions massives, qui déplace des lignes et demande la gestion automatique de l'espace des segments et ROW MOVEMENT ; TRUNCATE si la table est vide (récupération d'espace). Exemples à adapter, jamais à copier tels quels :
ALTER TABLE app_paie.factures DEALLOCATE UNUSED;
ALTER TABLE app_paie.factures ENABLE ROW MOVEMENT;
ALTER TABLE app_paie.factures SHRINK SPACE;
  1. Donner de la place, par le fichier qui peut grandir ou par un fichier de plus. Agir sur un fichier existant passe par ALTER DATABASE, qui demande le privilège système du même nom ; ajouter un fichier passe par ALTER TABLESPACE, qui demande le sien (ALTER DATABASE, ALTER TABLESPACE). Les deux demandent de l'espace disque réel, sans quoi la commande échoue. Exemples à adapter :
ALTER DATABASE DATAFILE '/u02/oradata/orcl/users02.dbf'
  AUTOEXTEND ON NEXT 100M MAXSIZE 8G;
ALTER TABLESPACE users
  ADD DATAFILE '/u02/oradata/orcl/users03.dbf' SIZE 1G
  AUTOEXTEND ON NEXT 100M MAXSIZE 8G;

Un fichier smallfile arrivé à son plafond, 32 Go en blocs de 8 Ko, ne relève plus de MAXSIZE : ajouter un fichier. Un tablespace bigfile se redimensionne avec ALTER TABLESPACE ... RESIZE, puisqu'il n'a qu'un fichier (même référence).

  1. Pour un chargement long, le mode reprise : l'instruction se suspend au lieu d'échouer, le temps qu'on ajoute de l'espace, puis reprend seule, plusieurs fois s'il le faut (reprise des allocations d'espace). Ce n'est pas une garantie, et le guide le dit : la transaction suspendue garde toutes ses ressources transactionnelles tant qu'elle attend ; si l'espace n'est pas ajouté dans le délai, 7 200 secondes par défaut, l'instruction se réveille et renvoie l'erreur ; et la session doit avoir le privilège système RESUMABLE. Exemple à adapter, dans la session qui charge :
ALTER SESSION ENABLE RESUMABLE TIMEOUT 3600;

Votre DBA valide, adapte et décide : chaque fichier ajouté ou agrandi engage de l'espace disque qu'il faut avoir vérifié sur le serveur, et un plafond relevé partout ne supprime pas la limite, il la déplace vers le disque.

Prévenir

Trois mesures tiennent l'essentiel :

Ce qu'on ne fait pas : mettre MAXSIZE UNLIMITED partout et ne plus regarder. La limite ne disparaît pas, elle devient le disque, avec le plafond du fichier smallfile en chemin, 32 Go en blocs de 8 Ko (limites physiques), et un disque plein arrête tout le monde en même temps.

Deynao porte une règle sur ce sujet, « Tablespace critique », et elle ne se déclenche jamais sur un pourcentage seul : un tablespace est critique quand il est occupé à plus de 85 % et que ses fichiers ne peuvent plus gagner deux gigaoctets, ou ne peuvent plus grandir du tout ; un tablespace à plus de 95 % dont les fichiers peuvent encore grandir est seulement en surveillance. Les deux gigaoctets sont un seuil de Deynao, pas une recommandation du constructeur. Les règles et leurs temporisations sont publiées : règles d'alerte et temporisations.

Ce que Deynao en fait

Le domaine Capacité de Deynao lit à chaque collecte la taille, l'extension automatique et le plafond de chaque fichier de données, et ce que les segments occupent. Il juge chaque tablespace permanent sur deux chiffres à la fois : le pourcentage de ses fichiers actuels et la marge qui les sépare de leur plafond. Sur la base de démonstration de cette page, SYSTEM occupe 97,3 % de son fichier : un outil à pourcentage le classerait en alerte ; Deynao le met en surveillance, parce que son fichier peut encore grandir de près de trente-deux gigaoctets, et parce que SYSTEM et SYSAUX sont surveillés dès 85 % quoi qu'il arrive. Les recommandations qu'il affiche disent de quoi il s'agit : « Augmenter MAXSIZE » quand la marge descend sous 500 Mo, seuil du produit, « Activer autoextend ou étendre » quand un tablespace occupé n'a pas d'extension automatique, avec la mention d'un risque imminent de ce code, et un ton à part pour un tablespace système au-delà de 95 %, même avec de la marge. TEMP n'est pas jugé par cette règle : dans un tablespace temporaire, les extensions du segment de tri restent allouées une fois le tri fini, marquées libres et réutilisées, et le segment n'est libéré qu'à l'arrêt (gestion des tablespaces) ; des fichiers temporaires pleins ne sont donc pas en soi un incident, et leur saturation réelle a son propre code, ORA-01652.

La règle « Tablespace critique » émet une alerte critique, immédiate, dès qu'un tablespace est réellement à court d'espace extensible, avec le nombre de tablespaces concernés (règles d'alerte et temporisations). Sa limite est à dire : cette règle et le score de capacité mesurent la marge jusqu'au plafond des fichiers, pas l'espace libre du disque. Un fichier autorisé à grandir sur un disque plein échouera quand même. C'est la vue du constructeur, au contrôle 3, qui en tient compte, et c'est elle que l'écran d'état de la base affiche pour ses tablespaces les plus occupés. Dans la base de connaissances de Deynao, ce code est classé Vigilance : l'écriture a échoué, la base répond ; l'alerte structurée sur l'espace est celle de la Capacité, en amont de l'erreur, pas la lecture du code après coup. Quand c'est le disque qui a manqué, cette alerte n'a pas précédé l'erreur ; le chiffre qui l'annonçait est celui de la vue du constructeur, celle que l'écran d'état affiche pour les tablespaces les plus occupés.

Erreurs liées

Sources

Écrit par Omar Sall, DBA Oracle · publié le 30 septembre 2026 · deynao.fr/erreurs-oracle/ora-01653.html

Relu contre Deynao 1.0.3 le 30 septembre 2026 (empreinte de l'entrée de la base de connaissances : b89eaa24fa37). Les recommandations sont expliquées et priorisées, jamais exécutées par Deynao : votre DBA valide, adapte et décide.