Быстрое удаление пользователя Oracle

Оригинал: Drop User Fast (in parallel) но как-то раз столкнулся с тем, что ресурс был недоступен, потому решил продублировать сюда.

Удаление Оракловой схемы может занять о-очень много времени, если просто использовать «DROP USER yourmamuser CASCADE». Фишка в том, что таким способом объекты схемы удаляются последовательно.
Ниже прикреплён скрипт которым можно дропать схемы в Oracle через ПАРАЛЛЕЛЬНОЕ удаление всех объектов пользователя. Очень пригождается когда у нас в схемых овер-много (500к+) таблиц

Пошаговый мануал:
0. Укажите корректные переменные окружения
1. Распакуйте архив
2. Запустите скрипт «mk_dropusertabs.ksh <ПОЛЬЗОВАТЕЛЬ> <ПАРАЛЛЕЛЬНОСТЬ>«, где ПОЛЬЗОВАТЕЛЬ это имя схемы для удаления, а ПАРАЛЛЕЛЬНОСТЬ это степень параллельности которую хотим применить. Например, «./mk_dropusertabs.ksh yourmam 8» создаст 8 файлов с командами для удаления таблиц
3. Запустите скрипт «mk_dropuserviews.ksh <ПОЛЬЗОВАТЕЛЬ> <ПАРАЛЛЕЛЬНОСТЬ>» для создания файлов команд на удаление представлений
4. Запустите «dropusertabes.ksh <ПОЛЬЗОВАТЕЛЬ>»
5. Запустите «dropuserviews.ksh <ПОЛЬЗОВАТЕЛЬ>»
6. Дропните схему: «DROP USER <ПОЛЬЗОВАТЕЛЬ>;»

Скачать скрипт: dropuserfast

Чистим-чистим арклоги в FRA ASM Standby

Automatic Storage Management на стендбай сервере ругается, что Disk Group FRA is 90.358% used ?
Давайте почистим Fast Recovery Area.

Немного подхачим гуляющий по интернету скрипт и получим готовую к выполнению в RMAN команду для удаления применённых арклогов с учётом тредов. Минус 2 от максимального, т.к. бывали случаи, что стендбай ломался и требовал пару уже применённых логов. Выполнять строго на Standby:

select 'DELETE NOPROMPT ARCHIVELOG UNTIL SEQUENCE '|| (max(sequence#)-2)||' THREAD '||THREAD# ||';'
from v$archived_log
where applied = 'YES'
AND  RESETLOGS_TIME = (select MAX(RESETLOGS_TIME) from V$DATABASE_INCARNATION)
group by THREAD#;---

Чтобы быть уверенным, что особого отставания нет и адских гепов, посмотрим на PRIMARY

select max(SEQUENCE#),THREAD# from v$archived_log
where RESETLOGS_TIME = (select MAX(RESETLOGS_TIME) from V$DATABASE_INCARNATION)
group by THREAD#;

Получим что-то вроде этого:

DELETE NOPROMPT ARCHIVELOG UNTIL SEQUENCE 3786 THREAD 1;
DELETE NOPROMPT ARCHIVELOG UNTIL SEQUENCE 3571 THREAD 2;

Возможно, будет хорошим решением будет включение опции автоматического удаления накатившихся арклогов:

CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY;

Ожидания и реальность в статспэке. Statspack Idle Events

Если у вас нет Enterprise Edition с Diagnostic Pack, то юзать AWR у вас не получится, а вот Statspack поставить не только можно, но и нужно. Да, он всё ещё присутствует, но к сожалению, практически не развивается. Одна из самых важных секций ‘Top 5 Timed Events’ показывают только события переднего плана (foreground events), по крайней мере, должен показывать. Когда пользовательский процесс ожидает фоновый процесс (background) эта секция должна учитывать только фоновое ожидание, а не активность фоновых процессов, иначе мы получим удвоенный учёт. Фоновая активность включена в события ‘Idle’ (простаивание) чтобы быть исключенной из секции «топ 5». К сожалению, новые версии Oracle DB выпускаются с новыми типами ожидания, которые вы не найдёте в списке событий простоя StatsPack’а.

Например, вот ‘Top 5 Timed Events’ в период с 22:00 по 23:00 без активности приложения:

Top 5 Timed Events                                                    Avg %Total
~~~~~~~~~~~~~~~~~~                                                   wait   Call
Event                                            Waits    Time (s)   (ms)   Time
----------------------------------------- ------------ ----------- ------ ------
LGWR worker group idle                               6      22,049 ######   65.2
AQPC idle                                          120       3,602  30014   10.7
heartbeat redo informer                          3,568       3,601   1009   10.7
lreg timer                                       1,195       3,598   3011   10.6
direct path read                                31,221         466     15    1.4
-------------------------------------------------------------

Простой и таймеры занимают первые позиции. Прямое чтение с диска кажется минимальным. А использование ЦПУ вообще нет. Очевидно, что здесь, что-то не так.
Читать далее «Ожидания и реальность в статспэке. Statspack Idle Events»

QUICK KILL USER SESSION

Просто замените username на те, что нужны.
Just change username in section…

SELECT 'KILLING SESSION of LOUISE' FROM DUAL;
BEGIN
FOR r IN (select sid,serial# from v$session where username in ('LOUISE','MAM','PBB') )
LOOP
EXECUTE IMMEDIATE 'alter system kill session ''' || r.sid
|| ',' || r.serial# || '''';
END LOOP;
END;
/

Don’t forget to use upper case : UPPER(‘username’)

01555 и BLOB

Задача: полный экспорт БД.

Ну вот те раз!
"Job "SYSTEM"."SYS_EXPORT_FULL_01" completed with 1 error(s)
at Fri Nov 3 00:20:04 2017 elapsed 0 00:30:22"

Ar-r-r-r-r!!!

ORA-31693: Table data object "ARDOME"."XFER_HISTORY" failed to load/unload and is being skipped due to error:
ORA-02354: error in exporting/importing data
ORA-01555: snapshot too old: rollback segment number with name "" too small
ORA-22924: snapshot too old

Странно, не указана ссылка на табличное пространство UNDO, столкнулся с этим первый раз. Прошёлся по стандартной схеме:
0) Увеличение объёма UNDO и длительности UNDO_RETENTION

ORA-22924 — сигнализирует о проблемах с LOB

Вот что было предпринято, но не помогло:
1) alter table ARDOME.XFER_HISTORY modify lob (XFH_PAYLOAD) (pctversion 100);
2) alter table ARDOME.XFER_HISTORY modify lob(XFH_PAYLOAD) (retention);

Не помогло…

Есть вероятность того, что повреждены BLOB в этой таблице, для того, чтобы определить какие именно:

1) Создадим пустышку для хранения ROWID и кода ошибки ERR_NUM
SQL> create table corrupt_lobs (corrupt_rowid rowid, err_num number);

2) Найдём имя столбца который содержит LOB данные:
SQL> DESC ARDOME.XFER_HISTORY
———-
XFH_ID      NOT NULL NUMBER(10
XFH_PAYLOAD      BLOB
 

3) Выполним следующий блок:

declare
error_1578 exception;
error_1555 exception;
error_22922 exception;
pragma exception_init(error_1578,-1578);
pragma exception_init(error_1555,-1555);
pragma exception_init(error_22922,-22922);
num number;
begin
for cursor_lob in (select rowid r, &&lob_column from &table_owner..&table_with_lob) loop
begin
num := dbms_lob.instr (cursor_lob.&&lob_column, hextoraw ('889911')) ;
exception
when error_1578 then
insert into corrupt_lobs values (cursor_lob.r, 1578);
commit;
when error_1555 then
insert into corrupt_lobs values (cursor_lob.r, 1555);
commit;
when error_22922 then
insert into corrupt_lobs values (cursor_lob.r, 22922);
commit;
end;
end loop;
end;
/

Он у нас запросит и мы введём (имя столбца, имя владельца и имя таблицы):

Enter value for lob_column: XFH_PAYLOAD
Enter value for table_owner: ARDOME
Enter value for table_with_lob: XFER_HISTORY

4) После выполнения вышеописанной процедуры в созданной табличке мы можем найти (или не найти) ROWID повреждённых лоб:
select * from corrupted_lob_data;

У меня оказалось 3 строки:
corrupt_rowid     err_num
——————————-
AAAXd7AAKAAK5+oAAU    1555
AAAXd7AAKAAK5+oAAV    1555
AAAXd7AAKAAK5+oAAW   1555

В этой ситуации можно:
-восстановить эти LOB сегменты из физического бекапа;

-почистить (обнулить) повреждённые LOBы используя UPDATE:
update <owner>.<tablename>
set    <lob column> = empty_blob()
where  rowid in (select corrupted_rowid from   corrupted_lob_data);
commit;

В моей ситуации обошёлся тем, что выгрузил дамп БД без повреждённых строк:
expdp \"/as sysdba\" parfile=export_options.par

Содержимое export_options.par:
directory=DUMP_EXP
dumpfile=mamdb01_full.dmp
logfile=mamdb01_full.exp.log
full=y
query="where rowid not in ('AAAXd7AAKAAK5+oAAU', 'AAAXd7AAKAAK5+oAAV', 'AAAXd7AAKAAK5+oAAW')"

Высокое ожидание resmgr:cpu quantum с отключенным Resource Manager.

Дано:
Product Oracle Database — Standard Edition
Product Version 12.1.0.2
Operating System Microsoft Windows x64 (64-bit)
OS Version 2012 R2

По ссылке к описанию этого ожидания увидим, что оно относится только к Менеджеру Ресурсов:
«This event occurs when the resource manager is enabled and is throttling CPU consumption.» [«Это событие происходит тогда, когда менеджер ресурсов включен и он ограничивает потребление CPU»]

Но странность в том, что у нас Standard Edition и Resource Manager не должен быть активен, даже по определению:
«Resource Manager is a database feature that was introduced in Oracle 8i. It is only available with
Enterprise Edition.» [«Менеджер ресурсов это функционал БД который был представлен в Oracle 8i. Он доступен только в Корпоративной версии (Enterprise Edition)»] (Using Oracle Database Resource Manager)

Попытки принудительно его отключить, сообщают нам, что мы ничего не поделаем =(

SQL> alter system set resource_manager_plan='' scope=both;
alter system set resource_manager_plan='' scope=both
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-00439: feature not enabled: Database resource manager

Потому, MOS посоветовал диссоциировать менеджер ресурсов от всех окон Oracle Scheduler. Читать далее «Высокое ожидание resmgr:cpu quantum с отключенным Resource Manager.»

Vim for beginners

Изучение Vim — это инвестирование.

Редакторы командной строки могут быть страшной вещью для обучения и использования новичками и Vim возможно найстрашнейший из них– хотя на самом деле не должен. В нём много чего скрыто (гораздо больше, чем будет сказано в этом руководстве) и здесь рассмотрим основы настолько, что мы могли бы по крайней мере удобно редактировать файлы. Читать далее «Vim for beginners»

Drop и Create индекса на Primary key

Появилась задача — Drop и Create индекса на Primary key (Именно такое потенциальное решение, из всех других предложенных вариантов, остаётся для Internal error ORA 600 [kdsgrp1] по рекомендации MOS)

Alter table "ARDOME"."RUNDOWN_ROW" drop primary key
Error report -
SQL Error: ORA-02273: denna UNIQUE/PRIMARY KEY refereras från några främmande nycklar
02273. 00000 - "this unique/primary key is referenced by some foreign keys"
*Cause: Self-evident.
*Action: Remove all references to the key before the key is to be dropped.

I. Давайте определим имя PK при помощи представления DBA_CONSTRAINTS:

В нашем случае это таблица RUNDOWN_ROW в схеме ARDOME.
select CONSTRAINT_NAME from DBA_CONSTRAINTS
where OWNER like 'ARDOME' and Table_name like 'RUNDOWN_ROW'
and CONSTRAINT_TYPE='P'

Типы констрейнтов:

  • C (check constraint on a table)
  • P (primary key)
  • U (unique key)
  • R (referential integrity) — он же FK, который ссылаясь мешает удалить PK
  • V (with check option, on a view)
  • O (with read only, on a view)

Немного подшаманим и увидим информацию о FK на наш PK:
select * from DBA_CONSTRAINTS
where R_CONSTRAINT_NAME in (
select CONSTRAINT_NAME from DBA_CONSTRAINTS
where OWNER like 'ARDOME' and Table_name like 'RUNDOWN_ROW' and CONSTRAINT_TYPE='P')

Читать далее «Drop и Create индекса на Primary key»