Hola Mario, me parece que hay un error en mi respuesta, repasando la documentación veo que un
alter table table_name move solo requiere de un lock tipo exclusive, es decir, mientras se está moviendo la tabla, las operaciones DML de otras sesiones estarán en espera, pero los SELECT tendrán respuesta inmediata con consistencia read-committed. Teniendo esto en cuenta, puede que sea mejor la opción 1, ya que de manera más simple, ofrece el mismo resultado y accesibilidad sobre los datos que la opción 3.
En resumen, los pasos y un ejemplo pueden ser:
1. Crear el nuevo tablespace.
2. Mover las tablas al nuevo tablespace
3. Rebuild de índices con la opción de moverlos a un nuevo tablespace.
4. Actualizar las estadísticas.
Código:
begin
for t in ( select owner, table_name
from dba_tables
where tablespace_name = 'tablespace_viejo' ) loop
--move de cada tabla.
--el comando varía para columnas tipo LOB y tablas particionadas.
--también soporta parallel.
execute immediate
'alter table '|| t.owner ||'.'|| t.table_name ||
' move tablespace tablespace_nuevo';
--para tener los datos disponibles en forma inmediata
--un rebuild de índices con estado unusable después de cada move
for i in ( select owner, index_name
from dba_indexes
where table_name = t.table_name
and table_owner = t.owner ) loop
--rebuild sobre el mismo tablespace
execute immediate
'alter index '|| i.owner ||'.'|| i.index_name ||' rebuild';
--o bien, rebuild y mover a un tablespace diferente
--execute immediate
--'alter index '|| i.owner ||'.'|| i.index_name ||
--' rebuild tablespace_nuevo';
end loop;
--y por cada move y rebuild,
--actualizar las estadísticas para el optimizador.
dbms_stats.gather_table_stats(t.owner, t.table_name);
end loop;
end;
/
Saludos