Table of Contents |
---|
Info |
---|
This article is in English Working with the DB Dumps |
Для работы с дампами БД следует пользоваться специальным скриптом dump.sh
, который располагается, как правило, в директории /opt/hydra/oracle/scripts
. Скрипт обязательно следует вызвать под пользователем oracle с инициализированным окружением. Инициализировать окружение для пользователя oracle с помощью sudo можно выполнить следующим образом:
...
language | bash |
---|
...
устанавливается при помощи deb пакета hydra-utils.
Этот пакет совместим с операционными системами Debian 9
и ниже. Для операционной системы Oracle Linux необходимо использовать отдельный Docker-
контейнер.
У скрипта для работы с дампами БД существуют следующие варианты запуска:
- export — снятие дампа. Дамп снимается в директорию для дампов, установленную в БД (как правило, это
/var/oradata/dumps
). - drop — очистка. Перед очисткой следует обязательно убедиться, что БД не является промышленной.
- import — загрузка дампа в БД. Перед загрузкой дампа обязательно следует выполнить очистку. Дамп поднимается из директории для дампов, установленной в БД (как правило, это
/var/oradata/dumps
). После импортирования флаг «Признак промышленной базы данных» сбрасывается.
...
- -i — название БД
- -o — название схемы
- -p — пароль пользователя AIS_NET
- -f — название дампа (файла с дампом)
- -s — отказ от предупреждающего сообщения при очистке БД
Пример использования dump.sh при нативной установке hydra-utils
При установке hydra-utils скрипт снятия дампов устанавливаются в следующую директорию - /opt/hydra/oracle/scripts
. Скрипт обязательно следует вызвать под пользователем oracle с инициализированным окружением. Инициализировать окружение для пользователя oracle с помощью sudo можно выполнить следующим образом:
Code Block | ||
---|---|---|
| ||
sudo -u oracle -i |
Пример вызова скрипта для переноса дампа БД с hydra на hydra2:
Снятие дампа с hydra:
Code Block language bash /opt/hydra/oracle/scripts/dump.sh -i hydra -p password -f hydra_dump export
Очистка hydra2:
Code Block language bash /opt/hydra/oracle/scripts/dump.sh -i hydra2 -p password drop
Поднятие дампа на hydra2:
Code Block language bash /opt/hydra/oracle/scripts/dump.sh -i hydra2 -p password -f hydra_dump import
Во время импорта дампа в новую базу возможны ошибки следующего вида:
Code Block language text Failing sql is: GRANT SELECT ON "AIS_NET"."SR_V_GOOD_SERVS" TO "NET_GOODS" ORA-39083: Object type OBJECT_GRANT failed to create with error: ORA-01917: user or role 'NET_GOODS' does not exist
Эти ошибки не являются критичными, т.к. скрипт экспорта выгружает только схему AIS_NET. Отсутствующие роли создаются в БД отдельным скриптом в завершающей части импорта.
Работа с дампами при помощи hydra-utils в Docker
Использование контейнера Docker
возможно только для операционных систем с ядром Linux
версии 4 или выше.
Алгоритм установки hydra-utils
следующий:
Создать директории для конфигурационных файлов
Code Block language text sudo mkdir /etc/hydra/hydra-utils
Создать
docker-compose.yml
в новой директории:
Для СУБД Oracle 11 необходимо использовать следующийdocker-compose.yml
:Code Block language bash title /etc/hydra/hydra-utils/docker-compose.yml version: '3.7' services: hydra-utils: container_name: hydra-utils image: docker.dl.latera.ru:5000/hydra-utils:11g network_mode: "host" environment: - TZ=${TZ} - ORACLE_HOME=${ORACLE_HOME} volumes: - /u01/app/oracle/product/11g:/u01/app/oracle/product/11g:ro - /u01/app/oracle/product/11g/network/admin/tnsnames.ora:/app/tnsnames.ora:ro
Для Oracle 19:Code Block language bash title /etc/hydra/hydra-utils/docker-compose.yml version: '3.7' services: hydra-utils: container_name: hydra-utils image: docker.dl.latera.ru:5000/hydra-utils:latest network_mode: "host" environment: - TZ=${TZ} volumes: - /u01/app/oracle/product/19c/network/admin/tnsnames.ora:/app/tnsnames.ora
TZ
- временная зона сервера. Значение переменной окружения может быть задано вручную, либо в/etc/environment
. Например:Code Block language bash title Значение переменной TZ TZ="Asia/Krasnoyarsk"
ORACLE_HOME
- каталог с установленным Oracle. Задано в/etc/environment
.После создания файлов конфигурации необходимо перейти в директорию и установить образ:
Code Block language bash title Установка образа контейнера cd /etc/hydra/hydra-utils/ sudo docker-compose pull
Пример вызова скриптов из контейнера для переноса дампа БД с hydra
на hydra2
(для Oracle 19 вместо hydra-utils нужно вызывать hydra-utils-19с)
):
Снятие дампа с hydra:
Code Block language bash sudo docker-compose -f /etc/hydra/hydra-utils/docker-compose.yml run --rm hydra-utils dump.sh -i hydra -p password -f hydra_dump export
Очистка hydra2:
Code Block language bash sudo docker-compose -f /etc/hydra/hydra-utils/docker-compose.yml run --rm hydra-utils dump.sh -i hydra2 -p password drop
Поднятие дампа на hydra2:
Code Block language bash sudo docker-compose -f /etc/hydra/hydra-utils/docker-compose.yml run --rm hydra-utils dump.sh -i hydra2 -p password -f hydra_dump import
Warning | ||
---|---|---|
| ||
В ходе снятия дампа не должны выполняться DDL выражения, в том числе TRUNCATE и очистка очередей, иначе снятие дампа завершится с ошибкой |
Note | ||
---|---|---|
| ||
Так как процедура снятия резервных копий с помощью утилиты expdp (скрипт |
...
Note | ||
---|---|---|
| ||
После выполнения поднятия дампа необходимо проверить лог импорта (файл с суффиксом _impdp.log в каталоге с дампом) на наличие ошибок |
Note | ||
---|---|---|
| ||
При копировании дампа на внешнее хранилище необходимо копировать и лог экспорта (файл с суффиксом _expdp.log в каталоге с дампом) |
Note | |||||
---|---|---|---|---|---|
| |||||
Новые профили пользователей, отличные Полный список команд для получения DDL кастомных профилей можно получить при помощи следующего SQL запроса:
Для их автоматического резервирования рекомендуется использовать RMAN бекапы. |
Отменить процесс экспорта/импорта дампа можно с помощью CTRL-C
и команды kill_job
:
Code Block |
---|
... . . exported "AIS_NET"."SS_JOB_LOGS" 635.2 MB 1550063 rows . . exported "AIS_NET"."SD_PROCESSING_REQUESTS_T" 563.8 MB 7204 rows . . exported "AIS_NET"."SD_MV_DOCUMENTS" 479.7 MB 3247473 rows ^C Export> kill_job Are you sure you wish to stop this job ([yes]/no): yes |
Note | ||
---|---|---|
| ||
Импорт дампа может завершиться следующей ошибкой: |
Code Block |
---|
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options
SP2-0734: unknown command beginning "-- ======..." - rest of line ignored.
DECLARE
*
ERROR at line 1:
ORA-04063: package body "AIS_NET.SS_IMP_DUMP_PKG" has errors
ORA-06508: PL/SQL: could not find program unit being called:
"AIS_NET.SS_IMP_DUMP_PKG"
ORA-06512: at line 3
ORA-06512: at line 16
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options |
В таком случае необходимо проверить выполнилась ли первая часть импорта, а именно: impdp. Если с этим все хорошо, то скорее всего проблема с синонимами в исходных пакетах.
Проверить это можно в net_Imp_Dump.sql той версии Гидры, дамп которой импортировался. Проблемная часть может выглядеть следующим образом:
Code Block |
---|
PROCEDURE RESET_JOB_STATES
IS
BEGIN
UPDATE SS_JOBS
SET N_JOB_STATE_ID = CONST.JOB_STATE_Waiting
WHERE N_JOB_STATE_ID IN (CONST.JOB_STATE_Running, CONST.JOB_STATE_ToStart)
AND C_FL_TEMPLATE = 'N'
AND C_ACTIVE = 'Y';
END RESET_JOB_STATES;
|
Ее необходимо исправить следующим образом (Заменить CONST на SS_CONTSTANTS_PKG_S)
Code Block |
---|
PROCEDURE RESET_JOB_STATES
IS
BEGIN
UPDATE SS_JOBS
SET N_JOB_STATE_ID = SS_CONTSTANTS_PKG_S.JOB_STATE_Waiting
WHERE N_JOB_STATE_ID IN (SS_CONTSTANTS_PKG_S.JOB_STATE_Running, SS_CONTSTANTS_PKG_S.JOB_STATE_ToStart)
AND C_FL_TEMPLATE = 'N'
AND C_ACTIVE = 'Y';
END RESET_JOB_STATES; |
После этого прогоняем исправленный пакет на БД, на которой импортировался дамп. Сделать это можно прогнав этот пакет в SQL Developer, или создав файл net_Imp_Dump.sql с исправленным скриптом, после чего прогнать его под Oracle:
Code Block | ||
---|---|---|
| ||
#Использовать вместо hydra2 наименование того инстанса, на котором импортировался дамп
sudo -u oracle -i sqlplus ais_net@hydra2 @net_Imp_Dump.sql |
После этого осталось завершить работу используемого ранее dump.sh, для этого необходимо прогнать следующе SQL скрипты:
Code Block | ||
---|---|---|
| ||
#Использовать вместо hydra2 наименование того инстанса, на котором импортировался дамп
sudo -u oracle -i sqlplus ais_net@hydra2 @/opt/hydra/oracle/sql/Alter_Dump.sql;
sudo -u oracle -i sqlplus ais_net@hydra2 @/opt/hydra/oracle/sql/Activate_After_Logon_Trigger.sql
sudo -u oracle -i sqlplus ais_net@hydra2 @/opt/hydra/oracle/sql/Remove_Job_Queue_Processes.sql
sudo -u oracle -i sqlplus ais_net@hydra2 @/opt/hydra/oracle/sql/ReInit_Consts.sql
sudo -u oracle -i sqlplus ais_net@hydra2 @/opt/hydra/oracle/sql/Setup_Grants.sql
sudo -u oracle -i sqlplus ais_net@hydra2 @/opt/hydra/oracle/sql/Unset_Prom_DB_Flag.sql
sudo -u oracle -i sqlplus ais_net@hydra2 @/opt/hydra/oracle/sql/Drop_Deny_Logon_Trigger.sql
sudo -u oracle -i sqlplus ais_net@hydra2 @/opt/hydra/oracle/sql/Activate_Before_DDL_Trigger.sql |
Ранее эта проблема возникала в AIS-3790 и AIS-6293, на проверку этого пакета создана внутренняя заявка:
Jira | ||||||
---|---|---|---|---|---|---|
|
Действия после поднятия дампа
Note |
---|
Выполнять под пользователем БД |
Контроль невалидных объектов
После поднятия дампа необходимо убедиться что в базе данных нет невалидных объектов.
Для этого необходимо выполнить скрипт компилляции
Code Block | ||
---|---|---|
| ||
DECLARE
ch_AlterTypes VARCHAR2(1) := 'N';
num_MaxRetries NUMBER := 0;
num_Counter NUMBER := 0;
--
num_Retries NUMBER;
PROCEDURE TRY_TO_ALTER_TYPE(
vch_VC_TYPE_NAME IN ALL_OBJECTS.OBJECT_NAME%TYPE)
IS
num_Count NUMBER;
BEGIN
SELECT COUNT(*)
INTO num_Count
FROM ALL_OBJECTS
WHERE OBJECT_NAME = vch_VC_TYPE_NAME
AND OBJECT_TYPE = 'TYPE';
IF num_Count > 0 THEN
EXECUTE IMMEDIATE 'ALTER TYPE "' || vch_VC_TYPE_NAME || '" COMPILE';
END IF;
END TRY_TO_ALTER_TYPE;
BEGIN
IF ch_AlterTypes = 'Y' THEN
TRY_TO_ALTER_TYPE('equipment_bind');
TRY_TO_ALTER_TYPE('equipment_binds');
TRY_TO_ALTER_TYPE('HYDRA_ANYDATA');
TRY_TO_ALTER_TYPE('HYDRA_ANYDATA_TABLE');
TRY_TO_ALTER_TYPE('application_context');
TRY_TO_ALTER_TYPE('deferred_task');
TRY_TO_ALTER_TYPE('command_result');
TRY_TO_ALTER_TYPE('command_results');
TRY_TO_ALTER_TYPE('command');
TRY_TO_ALTER_TYPE('commands');
TRY_TO_ALTER_TYPE('profile_attribute');
TRY_TO_ALTER_TYPE('profile_attributes');
TRY_TO_ALTER_TYPE('profile');
TRY_TO_ALTER_TYPE('profiles');
TRY_TO_ALTER_TYPE('sys_msg_line');
TRY_TO_ALTER_TYPE('sys_msg_lines');
TRY_TO_ALTER_TYPE('system_message');
TRY_TO_ALTER_TYPE('system_messages');
TRY_TO_ALTER_TYPE('service');
TRY_TO_ALTER_TYPE('services_list');
TRY_TO_ALTER_TYPE('account_services');
TRY_TO_ALTER_TYPE('LOG_MESSAGE');
END IF;
-- Выбираем список объектов
FOR rl_Object IN (
SELECT OWNER,
OBJECT_NAME,
OBJECT_TYPE
FROM ALL_OBJECTS A
WHERE OBJECT_TYPE IN ('PACKAGE', 'PACKAGE BODY', 'TRIGGER', 'VIEW')
AND OWNER = 'AIS_NET'
AND STATUS = 'INVALID'
ORDER BY OBJECT_TYPE, OBJECT_NAME)
-- Движение по списку
LOOP
num_Retries := 0;
num_Counter := num_Counter + 1;
<<retry>>
-- Компилим объект
BEGIN
-- Разные команды для пакетов ХП и остальных типов объектов
IF rl_Object.OBJECT_TYPE = 'PACKAGE BODY' THEN
EXECUTE IMMEDIATE 'ALTER PACKAGE "' || rl_Object.OWNER || '"."' || rl_Object.OBJECT_NAME || '" COMPILE BODY';
ELSE
EXECUTE IMMEDIATE 'ALTER ' || rl_Object.OBJECT_TYPE || ' "' || rl_Object.OWNER || '"."' || rl_Object.OBJECT_NAME || '" COMPILE';
END IF;
EXCEPTION WHEN others THEN
IF num_Retries < num_MaxRetries THEN
num_Retries := num_Retries + 1;
GOTO Retry;
ELSE
DBMS_OUTPUT.PUT_LINE('Ошибка: '|| rl_Object.OBJECT_TYPE || ' ' || rl_Object.OWNER || '.' || rl_Object.OBJECT_NAME);
END IF;
END;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Total processed: ' || num_Counter);
IF ch_AlterTypes = 'Y' THEN
SYS.FIX_HYDRA_OBJECT_TYPES;
END IF;
END;
/ |
И проверить наличие невалидных объектов
Code Block | ||
---|---|---|
| ||
SELECT OWNER,
OBJECT_NAME,
OBJECT_TYPE
FROM ALL_OBJECTS A
WHERE OBJECT_TYPE IN ('PACKAGE', 'PACKAGE BODY', 'TRIGGER', 'VIEW')
AND OWNER = 'AIS_NET'
AND STATUS = 'INVALID'
ORDER BY OBJECT_TYPE, OBJECT_NAME; |
В случае, если в базе есть невалидные объекты, это может быть вызвано дефектом СУБД Oracle Bug 18881811 - Data Pump Import of Wrapped PLSQL Corrupts the Body
Для устранения дефекта необходимо применить Oracle патч и повторить действия по разворачиванию дампа.
Исключением могут быть пакеты с префиксом MI_ — ядро приложения миграции (если данные объекты не используются).
Анализ БД
Перед началом использования БД необходимо выполнить полный анализ БД.
Для этого необходимо выполнить скрипт, приведенный ниже.
Следует учесть что анализ БД может занимать весьма продолжительное время, поэтому рекомендуется выполнять его напрямую на сервере из sqlplus с использованием оконного менеджера, например screen (это позволит скрипту доработать даже в случае неожиданного обрыва связи с компьютером администратора)
Code Block | ||
---|---|---|
| ||
DECLARE
num_N_JOB_ID NUMBER := -101;
--
ch_Invalidate SS_PARVALUES.C_FLAG_VALUE%TYPE;
ch_StaleOnly SS_PARVALUES.C_FLAG_VALUE%TYPE;
num_AnalyzePercent SS_PARVALUES.N_VALUE%TYPE;
BEGIN
DBMS_STATS.SET_GLOBAL_PREFS('NO_INVALIDATE', 'FALSE');
-- Сохранение текущих параметров
num_AnalyzePercent := SS_PARS_PKG_S.GET_N_VALUE_BY_CODE(
vch_VC_CODE => 'PAR_JobAnalyzeSchema_AnalyzePercent',
num_N_JOB_ID => num_N_JOB_ID);
ch_StaleOnly := SS_PARS_PKG_S.GET_C_FLAG_VALUE_BY_CODE(
vch_VC_CODE => 'PAR_JobAnalyzeSchema_StaleOnly',
num_N_JOB_ID => num_N_JOB_ID);
ch_Invalidate := SS_PARS_PKG_S.GET_C_FLAG_VALUE_BY_CODE(
vch_VC_CODE => 'PAR_JobAnalyzeSchema_InvalidateCursors',
num_N_JOB_ID => num_N_JOB_ID);
-- Установка нужных параметров
SS_PARS_PKG.SS_PARVALUES_PUT(
num_N_PAR_ID => SS_PARS_PKG_S.GET_PAR_ID_BY_CODE(
vch_VC_CODE => 'PAR_JobAnalyzeSchema_AnalyzePercent',
num_N_JOB_ID => num_N_JOB_ID),
num_N_SUBJECT_ID => NULL,
num_N_APPLICATION_ID => NULL,
num_N_VALUE => 100,
num_N_JOB_ID => num_N_JOB_ID);
SS_PARS_PKG.SS_PARVALUES_PUT(
num_N_PAR_ID => SS_PARS_PKG_S.GET_PAR_ID_BY_CODE(
vch_VC_CODE => 'PAR_JobAnalyzeSchema_StaleOnly',
num_N_JOB_ID => num_N_JOB_ID),
num_N_SUBJECT_ID => NULL,
num_N_APPLICATION_ID => NULL,
ch_C_FLAG_VALUE => 'N',
num_N_JOB_ID => num_N_JOB_ID);
SS_PARS_PKG.SS_PARVALUES_PUT(
num_N_PAR_ID => SS_PARS_PKG_S.GET_PAR_ID_BY_CODE(
vch_VC_CODE => 'PAR_JobAnalyzeSchema_InvalidateCursors',
num_N_JOB_ID => num_N_JOB_ID),
num_N_SUBJECT_ID => NULL,
num_N_APPLICATION_ID => NULL,
ch_C_FLAG_VALUE => 'Y',
num_N_JOB_ID => num_N_JOB_ID);
COMMIT;
-- Подготовка к выполнению задания вручную
SS_JOBS_PKG.MANUAL_START_JOB(num_N_JOB_ID);
-- Выполнение задания в текущей сессии
SS_JOBS_PKG.RUN_JOB(
num_N_JOB_ID => num_N_JOB_ID,
ch_C_REASON => 'M');
DBMS_STATS.SET_GLOBAL_PREFS('NO_INVALIDATE', 'DBMS_STATS.AUTO_INVALIDATE');
-- Возврат сохраненных параметров
SS_PARS_PKG.SS_PARVALUES_PUT(
num_N_PAR_ID => SS_PARS_PKG_S.GET_PAR_ID_BY_CODE(
vch_VC_CODE => 'PAR_JobAnalyzeSchema_AnalyzePercent',
num_N_JOB_ID => num_N_JOB_ID),
num_N_SUBJECT_ID => NULL,
num_N_APPLICATION_ID => NULL,
num_N_VALUE => num_AnalyzePercent,
num_N_JOB_ID => num_N_JOB_ID);
SS_PARS_PKG.SS_PARVALUES_PUT(
num_N_PAR_ID => SS_PARS_PKG_S.GET_PAR_ID_BY_CODE(
vch_VC_CODE => 'PAR_JobAnalyzeSchema_StaleOnly',
num_N_JOB_ID => num_N_JOB_ID),
num_N_SUBJECT_ID => NULL,
num_N_APPLICATION_ID => NULL,
ch_C_FLAG_VALUE => ch_StaleOnly,
num_N_JOB_ID => num_N_JOB_ID);
SS_PARS_PKG.SS_PARVALUES_PUT(
num_N_PAR_ID => SS_PARS_PKG_S.GET_PAR_ID_BY_CODE(
vch_VC_CODE => 'PAR_JobAnalyzeSchema_InvalidateCursors',
num_N_JOB_ID => num_N_JOB_ID),
num_N_SUBJECT_ID => NULL,
num_N_APPLICATION_ID => NULL,
ch_C_FLAG_VALUE => ch_Invalidate,
num_N_JOB_ID => num_N_JOB_ID);
COMMIT;
END;
/ |