12c Nouvelles opérations online

On a vu une opération online sur les fichiers: 12c: déplacer un datafile online et la 12c amène plusieurs nouvelles opérations sur les tables qui peuvent être faites online.

Commençons par celles qui ne nécessitent pas le mot clé ‘ONLINE’ et qui sont donc possible en Standard Edition: on peut rendre un index visible/invisible sans poser de verrou DML.

Et les opérations qui peuvent se faire avec ‘ONLINE’ en Enterprise Edition:

ALTER INDEX ... UNUSABLE ONLINE;
DROP INDEX ... ONLINE;
ALTER TABLE ... DROP CONSTRAINT ... ONLINE;
ALTER TABLE ... SET UNUSED(...) ONLINE;
ALTER TABLE ... MOVE PARTITION ... ONLINE;

Le MOVE d’une table non partitionnée ne prends pas le ‘ONLINE’, mais on pouvait déjà le faire avec dbms_redefinition.

Les exemples avec les modes de verrous exacts posés par ces opérations dans la demo.

La plupart de ces opérations posent seulement un Row-S et c’est vraiment online puisque seulement les DDL exclusifs sont bloqués/bloquants.
Mais certaines posent un Row-X qui peuvent être bloqués par des opérations DML (cas de la foreign key non indexée).

12c: Indexer les mêmes colonnes avec différents types d’index

La 11g avait apporté les index invisibles: on peut créer des index qui sont maintenus, mais ne sont pas utilisés par les requêtes. Pour pouvoir les tester par exemple.
Mais il était toujours impossible de tester un différent type d’index sur des colonnes déjà indexées (pour le passer en bitmap, en reverse, le compresser,…).
L’erreur était:

ORA-01408:  such column list already indexed
Cause:  A CREATE INDEX statement specified a column that is already indexed. A single column may be indexed only once. Additional indexes may be created on the column if it is used as a portion of a concatenated index, that is, if the index consists of multiple columns.
Action: Do not attempt to re-index the column, as it is unnecessary. To create a concatenated key, specify one or more additional columns in the CREATE INDEX statement.

En 12c, cette restriction est levée dans le cas où l’index que l’on crée est invisible.
Par exemple, je n’ai pas d’erreur en exécutant ceci:

create unique index TEST1 on TEST(num) ;
create unique index TEST2 on TEST(num) reverse invisible;

On a donc 2 index sur les mêmes colonnes. Ils sont maintenus (donc utilisables) mais un seul n’est utilisé: celui qui est visible.
Il est facile de passer de l’un à l’autre en changeant leur visibilité: c’est une opération online (pas de verrou).

Deux gros avantage:

  • créer un index peut être long. On peut le faire online, mais le fait de devoir supprimer l’ancien avant nous laissait un certain temps dans index.
  • si on ne le crée pas online, la création du nouvel index peut être très rapide car elle utilise l’ancien.

On a donc le choix: maximiser la disponibilité de l’application en le créant online, ou minimiser le temps de création de l’index.

Si l’index supporte une contrainte d’intégrité, c’est un peu plus complexe.
Le détail dans la demo
avec une introduction sur de nouvelles opérations online apportées par la 12c (drop index et drop constraint).

12c: déplacer un datafile online

Jusqu’en 11g pour déplacer un datafile (pour le mettre sur un autre filesystem) il fallait:

  • mettre le tablespace offline
  • copier le(s) fichier(s) à partir de l’OS
  • faire ALTER DATABASE RENAME FILE … TO …

Pour diminuer le downtime, il est aussi possible de faire la copie sans mettre le tablespace offline, seulement en BEGIN BACKUP. Puis il n’y aura qu’à le mettre offline que pendant le recovery.

En 12c, plus de problème. Il suffit de faire : ALTER DATABASE MOVE DATAFILE … TO …;

C’est une opération totalement online, sans aucun verrou, et très peu d’overhead: simplement pendant que Oracle fait la copie de fichier, les process qui veulent y accéder en écriture écriront à la fois dans l’ancien fichier et le nouveau.
Et ils liront uniquement l’ancien jusqu’à ce que la copie soit terminée.
Une fois que la copie est terminée, ils liront uniquement le nouveau fichier. Et l’ancien fichier sera supprimé sauf si on a précisé KEEP.

La demo montre les statistiques de session lors d’une activité sur un tablespace en cours de move.

On voit cette double écriture dans ‘physical write total bytes’. Par contre, on ne voit jamais les fichiers en double (et ils ont le même file_id), sauf si in regarde au niveau de l’OS.
L’opération ne modifie que le controlfile, c’est donc indépendant sur des bases en DataGuard, et ce n’est pas concerné par flashback database.

Dans l’alert.log on voit au début de l’opération:

Moving datafile /tmp/TESTMOVE1.dbf (2) to /tmp/TESTMOVE2.dbf

A partir de ce moment la session crée le fichier secondaire et signale aux autres session qu’elles doivent écrire en double vers ce fichier aussi.
Puis la copie commence (‘db file sequential read’ et ‘db file single write’ par i/o de 1MB)

puis lorsque tous les blocs sont copiés, on voit:

Move operation committed for file /tmp/TESTMOVE2.dbf

les session peuvent alors ne travailler que sur le deuxième fichier. Puis l’ancien fichier est supprimé.

Completed: alter database move datafile '/tmp/TESTMOVE1.dbf' to '/tmp/TESTMOVE2.dbf'

Oracle a introduit ça pour pouvoir déplacer des partitions vers un storage moins cher au lieu de purger/archiver.
Mais c’est aussi une solution pour passer en ASM sans arrêt de la base, ou pour n’importe quel changement de filesystem.
En ASM, pas besoin de cela: on a l’équivalent en rajoutant le nouveau disque et en supprimant l’ancien.