четверг, 10 сентября 2015 г.

Oracle. Перенос в другое табличное пространство

Наша система работает с базой данных Oracle. У Заказчика БД размещена на SSD-дисках, чтобы работало шустрее. Столкнулись с проблемой — кончилось место. Докупать SSD слишком дорого, нам выделили простые диски, на которые надо было частично переехать.

По итогам переезда мой коллега написал интересные заметки, которые я сюда и выкладываю Smile :)

При переносе таблицы или матвью в другое табличное пространство все индексы на этой таблице становятся UNUSABLE. Для того, чтобы вернуть их в стан валидных, надо сделать ребилд (см. ниже). Также могут невалидными стать процедуры, функции и пакеты. При необходимости можно им сделать compile.

Таблица или матвью

alter table tbl move tablespace new_tblspc;
alter materialized view mview move tablespace new_tblspc;

Партиционированная таблица

-- указать, где создавать новые партиции
alter table tbl modify default attributes tablespace new_tblspc;
-- перенести существующие партиции - получить набор запросов
select 'alter table '||table_name||' move partition '
||partition name||' tablespace new_tblspc;'
from user_tab_partitions where table_name = upper('tbl'
and tablespace_name = upper('old_tblspc');
Скопировать получившиеся запросы и выполнить. Для контроля выполнить ещё раз второй запрос, он должен вернуть пустой результат.
Для партиционированного матвью всё получилось как-то сложно. Легче оказалось его дропнуть и создать в новом табличном пространстве.

Индексы

-- посмотреть список невалидных индексов
select owner, index_name, status
from dba_indexes
where status not in ('VALID','N/A');
-- перестроение индекса
alter index idx_name rebuild;
-- перестроение индекса с переносом в другое табличное пространство
alter index idx_name rebuild tablespace new_tblspc;

Невалидные объекты

Посмотреть список невалидных объектов
select owner, object_type, object_name
from dba_objects
where status != 'VALID';
 
select 'alter '||object_type||' '||owner||'.'||object_name||' compile;'
from dba_objects
where status != 'VALID';
-- перекомпилировать пакет целиком
alter package pkg_name compile;
alter package pkg_name compile package;
-- только заголовок или только тело (понадобится последнее, скорее всего)
alter package pkg_name compile specification;
alter package pkg_name compile body;
alter package body pkg_name compile;
-- функция и процедура
alter function func_name compile;
alter procedure proc_name compile;
В принципе, oracle должен перекомпилировать это всё при запуске, но лучше сделать заранее. Если перекомпилировать заголовок пакета, то из-за этого могут стать невалидными другие объекты, которые данный пакет используют.

4 комментария:

  1. День добрый.
    А добавить еще один файл в табличное пространство?
    Или задача стояла именно освободить ssd?

    ОтветитьУдалить
  2. для компиляции инвалидных объектов это удобнее:

    EXECUTE UTL_RECOMP.RECOMP_PARALLEL(4);

    ОтветитьУдалить