
Июнь 2005
Профессионалу администратору
Аруп Нанда
Oracle Database 10g: 20 наиболее
привлекательных для АБД возможностей (Oracle Database 10g: The Top 20
Features for DBAs by Arup Nanda) Часть IХ
Источник: журнал Oracle Magazine, OTN Technical Articles
(
http://www.oracle.com/oramag/webcolumns/windex.html), http://otn.oracle.com/pub/articles/10gdba/index.html
В течение 20 недель Arup Nanda, “Лучший АБД 2003 года” по
версии журнала Oracle Magazine, рассказывал о наиболее, по его мнению,
привлекательных для администраторов баз данных возможностях Oracle Database
10g.
[От редакции OM/RE: мы завершаем публикацию
переводов этих заметно окрашенных индивидуальной авторской интонацией небольших
по объему заметок, но удивительно емких по содержанию и точных по существу
рассматриваемых вопроcов. В каждом выпуске журнала предполагалось по две-три
“недели” , и весь цикл заметок Arup Nanda уложился в нашем журнале примерно за год. В этот последний раз мы предлагаем вниманию читателей "Неделю 19"
и "Неделю 20". Но, будем надеяться, что наш автор выполнит обещание и напишет новую серию своих "недель", о чем говорится в послесловии от редакции OM/RE ]
План публикаций
Неделя
17
Планировщик
(Scheduler)
Источник: http://www.oracle.com/technology/pub/articles/10gdba/week19_10gdba.html
Вы устали от громоздкого ручного управления интервалами, предлагаемого пакетом dbms_job, и нуждаетесь в новой системе планирования в базе данных? Ответ содержится в самой базе данных.
Некоторые АБД интенсивно используют пакет dbms_job для того, чтобы выполнять в фоновом режиме какие-либо работы в базе данных (database jobs), управлять временем и интервалами выполнения, сообщать об отказах, и еще для много другого. Однако, я почему-то подозреваю, что большинство из АБД этого не делают.
Ограниченность этого пакета состоит в том, что он может обращаться только с фрагментами PL/SQL-кода, то есть, только с анонимными PL/SQL-блоками и хранимыми программными модулями. Он ничего не может обработать вне базы данных, например, выполнить командный файл операционной системы или исполняемую программу. Чтобы все-таки добиться этого, нужно применить утилиту планирования операционной системы, например, cron в Unix или AT-команда в Windows. Или же можно использовать некий сторонний инструмент (third-party tool), который может быть даже расширит эти функциональные возможности, обеспечив графический пользовательский интерфейс.
Но даже в существующем виде dbms_job имеет значительное преимущество перед этими альтернативами: он проявляет активность только, когда база данных запущена и функционирует. Если база данных остановлена, работы не выполняются. Инструмент же вне базы данных должен вручную проверить, запущена ли база данных, а это может быть сложным делом. Другое преимущество состоит в том, что dbms_job является внутренним пакетом в базе данных; следовательно, к нему можно обратиться, используя какую-нибудь утилиту доступа к базе данных, например, SQL*Plus.
Oracle Database Oracle10g предлагает лучшую во всех мирах функциональность Scheduler (Планировщик): это - утилита планирования работ, находящаяся внутри базы данных, достаточно мощная, чтобы обращаться со всеми типами работ, а не только фрагментами PL/SQL-кода, которая поможет вам создавать работы (jobs), как с, так и без ассоциированных программ и/или расписаний. Самое приятное, что эта утилита приходит к вам вместе с базой данных без доплаты. В этой статье мы рассмотрим, как она работает.
Создание работ, не связанных с программами
Общее представление, вероятно, лучше всего представить на примерах. Предположим, что вы создали shell-скрипт (скрипт оболочки), чтобы переместить заархивированные журналы в другую файловую систему, как показано ниже:
/home/arup/dbtools/move_arcs.sh
Мы можем сразу специфицировать выполнимую OS-программу, предварительно не создавая ее как программу.
begin
dbms_scheduler.create_job
(
job_name => 'ARC_MOVE_2',
schedule_name => 'EVERY_30_MINS',
job_type => 'EXECUTABLE',
job_action => '/home/arup/dbtools/move_arcs.sh',
enabled => true,
comments => 'Move Archived Logs to a Different Directory'
);
end;
/
Точно так же можно создать работу без именованного расписания (named schedule).
begin
dbms_scheduler.create_job
(
job_name => 'ARC_MOVE_3',
job_type => 'EXECUTABLE',
job_action => '/home/arup/dbtools/move_arcs.sh',
repeat_interval => 'FREQ=MINUTELY; INTERVAL=30',
enabled => true,
comments => 'Move Archived Logs to a Different Directory'
);
end;
/
Первое преимущество Scheduler над dbms_job довольно ясно следует из нашего начального примера: способность вызывать OS-утилиты и программы, а не только программные PL/SQL-модули. Эта возможность делает Планировщик наиболее универсальным инструментом управления работами при управлении базой данных Oracle и прописанными в ней работами. Однако, может быть вы заметили еще одно, сравнимое по важности преимущество: возможность определять интервалы на естественном языке. Обратите внимание, что в вышеупомянутом примере мы захотели, чтобы наша программа выполнялась каждые 30 минут; и поэтому параметр REPEAT_INTERVAL определен простым выражением на почти английском (а не на PL/SQL) языке:
'FREQ=MINUTELY; INTERVAL=30'
Более сложный пример показывает это преимущество даже еще лучше. Предположим, что ваши промышленные приложения обретают наибольшую активность в 7:00AM и 3:00PM. Для сбора системной статистики вы применяете пакет Statspack и хотите, чтобы он выполнялся только в 7:00AM и 3:00PM с понедельника и до пятницы. Если для создания работы применяется пакет DBMS_JOB.SUBMIT, то параметр NEXT_DATE будет выглядеть примерно следующим образом:
DECODE
(
SIGN
(
15 - TO_CHAR(SYSDATE,'HH24')
),
1,
TRUNC(SYSDATE)+15/24,
TRUNC
(
SYSDATE +
DECODE
(
TO_CHAR(SYSDATE,'D'), 6, 3, 1
)
)
+7/24
)
Просто ли понять этот код? Не очевидно.
Теперь давайте посмотрим на создание эквивалентной работы в DBMS_SCHEDULER. Параметр REPEAT_INTERVAL задается просто как:
'FREQ=DAILY; BYDAY=MON,TUE,WED,THU,FRI; BYHOUR=7,15'
Кроме того, значение этого параметра может содержать последовательность интервалов, некоторые из которых могут быть очень заковыристыми. Приведем некоторые примеры:
- в прошлое воскресенье каждого месяца:
FREQ=MONTHLY; BYDAY=-1SUN
- каждая третья пятница месяца:
FREQ=MONTHLY; BYDAY=3FRI
- каждую секунду в пятницу с конца месяца, не с начала:
FREQ=MONTHLY; BYDAY=-2FRI
Знаки "минус" перед числами указывают подсчет с конца, а не с начала.
А что надо сделать, если бы вы захотели проверить правильность интервальных установок? Вот было бы хорошо увидеть различные даты, созданные прямо из календаря! Хорошо, вы можете предварительно увидеть вычисленные последующие даты, использовав процедуру EVALUATE_CALENDAR_STRING. Вспомним первый пример - выполнение Statspack каждый день понедельника до пятницы в 7:00AM и 3:00PM - вы можете проверить точность установки интервальной строки следующим образом:
set serveroutput on size 999999
declare
L_start_date TIMESTAMP;
l_next_date TIMESTAMP;
l_return_date TIMESTAMP;
begin
l_start_date := trunc(SYSTIMESTAMP);
l_return_date := l_start_date;
for ctr in 1..10 loop
dbms_scheduler.evaluate_calendar_string(
'FREQ=DAILY; BYDAY=MON,TUE,WED,THU,FRI; BYHOUR=7,15',
l_start_date, l_return_date, l_next_date
);
dbms_output.put_line('Next Run on: ' ||
to_char(l_next_date,'mm/dd/yyyy hh24:mi:ss')
);
l_return_date := l_next_date;
end loop;
end;
/
Листинг вывода таков:
Next Run on: 03/22/2004 07:00:00
Next Run on: 03/22/2004 15:00:00
Next Run on: 03/23/2004 07:00:00
Next Run on: 03/23/2004 15:00:00
Next Run on: 03/24/2004 07:00:00
Next Run on: 03/24/2004 15:00:00
Next Run on: 03/25/2004 07:00:00
Next Run on: 03/25/2004 15:00:00
Next Run on: 03/26/2004 07:00:00
Next Run on: 03/26/2004 15:00:00
Это подтверждает, что ваш параметр установлен правильно.
Привязка работ к программам
В вышеупомянутом случае вы создавали работу, независимую от какой-либо программы. Теперь давайте создадим конструкцию (one), которая обратится к утилите операционной системы или программе-планировщику, определяющей, сколько раз нечто (something) должно выполниться, и затем вторым действием создадим работу.
Сначала вы должны дать знать базе данных, что ваш скрипт является программой, которая используется в работе. Чтобы создавать такую программу, вы должны иметь привилегию CREATE JOB.
begin
dbms_scheduler.create_program
(
program_name => 'MOVE_ARCS',
program_type => 'EXECUTABLE',
program_action => '/home/arup/dbtools/move_arcs.sh',
enabled => TRUE,
comments => 'Moving Archived Logs to Staging Directory'
);
end;
/
Выше вы создали именованный программный модуль, определили его как выполняемую программу и отметили, что это вызываемый программный модуль.
Затем вы создаете именованное расписание, называемое EVERY_30_MINS, которое запускается каждые 30 минут. Это можно сделать так:
begin
dbms_scheduler.create_schedule
(
schedule_name => 'EVERY_30_MINS',
repeat_interval => 'FREQ=MINUTELY; INTERVAL=30',
comments => 'Every 30-mins'
);
end;
/
Теперь, когда программа и расписание созданы, можно привязать программу к расписанию, чтобы создать работу.
begin
dbms_scheduler.create_job
(
job_name => 'ARC_MOVE',
program_name => 'MOVE_ARCS',
schedule_name => 'EVERY_30_MINS',
comments => 'Move Archived Logs to a Different Directory',
enabled => TRUE
);
end;
/
Это создаст работу, которая запускается каждые 30 минут, которая выполняет shell-скрипт move_arcs.sh. И все это будет выполнено средствами Scheduler, встроенного в базу данных, поэтому нет никакой потребности в cron- или AT- утилитах.
Классы, планы и окна
Изюминкой достоинств хорошей системы планирования работ является ее возможность обеспечения расположения работ по приоритетам. Например, совокупность статистических работ внезапно наплывает на окно высокой OLTP-нагрузки, что сказывается на общей производительности. Чтобы гарантировать, что совокупность статистических работ не затронет ресурсы, требуемые для OLTP, надо воспользоваться классами работ (job classes), ресурсными планами (resource plans) и окнами Планировщика (Scheduler Windows).
Например, при определении работы ее можно сделать элементом класса работ, который соотносится с группой пользовательских ресурсов при распределении ресурсов. Чтобы сделать это, сначала нужно определить вызываемую группу пользовательских ресурсов, скажем, OLTP_GROUP.
begin
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.create_consumer_group (
consumer_group => 'oltp_group',
comment => 'OLTP Activity Group'
);
dbms_resource_manager.submit_pending_area();
end;
/
Затем нам надо создать ресурсный план (resource plan).
begin
dbms_resource_manager.clear_pending_area();
dbms_resource_manager.create_pending_area();
dbms_resource_manager.create_plan
('OLTP_PLAN', 'OLTP Database Activity Plan');
dbms_resource_manager.create_plan_directive(
plan => 'OLTP_PLAN',
group_or_subplan => 'OLTP_GROUP',
comment => 'This is the OLTP Plan',
cpu_p1 => 80, cpu_p2 => NULL, cpu_p3 => NULL, cpu_p4 => NULL,
cpu_p5 => NULL, cpu_p6 => NULL, cpu_p7 => NULL, cpu_p8 => NULL,
parallel_degree_limit_p1 => 4,
active_sess_pool_p1 => NULL,
queueing_p1 => NULL,
switch_group => 'OTHER_GROUPS',
switch_time => 10,
switch_estimate => true,
max_est_exec_time => 10,
undo_pool => 500,
max_idle_time => NULL,
max_idle_blocker_time => NULL,
switch_time_in_call => NULL
);
dbms_resource_manager.create_plan_directive(
plan => 'OLTP_PLAN',
group_or_subplan => 'OTHER_GROUPS',
comment => NULL,
cpu_p1 => 20, cpu_p2 => NULL, cpu_p3 => NULL, cpu_p4 => NULL,
cpu_p5 => NULL, cpu_p6 => NULL, cpu_p7 => NULL, cpu_p8 => NULL,
parallel_degree_limit_p1 => 0,
active_sess_pool_p1 => 0,
queueing_p1 => 0,
switch_group => NULL,
switch_time => NULL,
switch_estimate => false,
max_est_exec_time => 0,
undo_pool => 10,
max_idle_time => NULL,
max_idle_blocker_time => NULL,
switch_time_in_call => NULL
);
dbms_resource_manager.submit_pending_area();
end;
/
И, наконец, вы создаете класс работ (job class), который соотносится с созданной ранее группой пользовательских ресурсов.
begin
dbms_scheduler.create_job_class(
job_class_name => 'OLTP_JOBS',
logging_level => DBMS_SCHEDULER.LOGGING_FULL,
log_history => 45,
resource_consumer_group => 'OLTP_GROUP',
comments => 'OLTP Related Jobs'
);
end;
/
Давайте посмотрим на некоторые параметры в этом запросе. Параметр LOGGING_LEVEL устанавливает, сколько журнальных данных собирается для этого класса работ. Значение LOGGING_FULL указывает, что все действия в работах этого класса - создание (creation), удаление (deletion), выполнение (run), изменение (alteration) и так далее - будут зарегистрированы в журналах. Данные о журналах могут быть получены из представления DBA_SCHEDULER_JOB_LOG и доступны в течение 45 дней, как определено в параметре LOG_HISTORY (по умолчанию это значение равно 30 дням). Также определена группа пользовательских ресурсов, связанная с этим классом. Данные о классах работ приводятся в представлении DBA_SCHEDULER_JOB_CLASSES.
При создании работы можно произвольно связать класс с группой. Например, когда создается работа COLLECT_STATS, которая, выполняя сохраненную процедуру collect_opt_stats (), собирает статистику оптимизатора, можно определить:
begin
dbms_scheduler.create_job
(
job_name => 'COLLECT_STATS',
job_type => 'STORED_PROCEDURE',
job_action => 'collect_opt_stats',
job_class => 'OLTP_JOBS',
repeat_interval => 'FREQ=WEEKLY; INTERVAL=1',
enabled => true,
comments => 'Collect Optimizer Stats'
);
end;
/
Эта команда поместит недавно созданную работу в класс OLTP_JOBS, который в свою очередь управляется ресурсным планом OLTP_GROUP, который определяет ограничение на время центрального процессора, которое может быть выделено процессу, а также максимальное число выполнений, прежде чем совершится переключение к другой группе, а также группу, на которую происходит переключение, и так далее. Любая работа, определенная в этом классе, директивно управляется тем же самым ресурсным планом. Эта возможность особенно полезна для того, чтобы разграничить различные типы работ по потреблению ресурсов системы.
Scheduler Window (окно планировщика) – это выделенный интервал времени (time frame – временной кадр, фрейм), связанный с ресурсным планом, используемый для активизирования этого плана и, таким образом, поддерживающий различные приоритеты работ по временным интервалам. Например, некоторые работы, типа пакетных программ (batch programs), обновляющие базы данных для поддержки решений в реальном масштабе времени, нуждаются в высоком приоритете днем, а ночью могут выполняться с низким приоритетом (или напротив). Вы можете реализовать такое расписание, определив различные ресурсные планы, а затем активизировав их, используя механизм Scheduler Windows.
Мониторинг
После того, как работа запущена, можно контролировать ее состояние, используя представление DBA_SCHEDULER_JOB_LOG, где столбец STATUS показывает текущее состояние работы. Если он показывает FAILED, более детально выяснить причину неудачи можно из представления DBA_SCHEDULER_JOB_RUN_DETAILS.
Администрирование
Итак, мы обсудили приемы создания нескольких типов объектов: программы, расписания, работы и классы работ. Но что надо сделать, если вы захотите изменить некоторых из них, чтобы привести их в соответствие с изменившимися потребностями? Да, это можно сделать, используя API, предлагаемые пакетом DBMS_SCHEDULER.
На домашней странице Enterprise Manager 10g в закладке Database надо кликнуть по ссылке Administration (Администрирование). Этим будет вызван Administration Screen (Экран Администрирования), показанный на рисунке 1. Все задачи, имеющие отношение к Scheduler (Планировщику), будут найдены под заголовком "Scheduler" в правом нижнем угле, очерченным на рисунке красным эллипсом.
Рисунок 1: Административная страница
Все задачи, связанные с планировщиком, такие как: создание, удаление и управление работами, могут быть легко совершены при использовании гиперссылки задачи на этой странице. Давайте посмотрим на некоторые из этих задач. Мы создали все эти задачи ранее, так что щелчок по закладке Jobs вызовет экран, подобной представленному на рисунке 2.
Рисунок 2: Спланированные работы
Если кликнуть по работе COLLECT_STATS, это позволит вам изменить ее атрибуты. Экран, показанный на рисунке 3, вызывается, когда нажимается кнопка "Job Name".
Рисунок 3: Параметры работы
Как Вы можете видеть, можно изменить параметры работы, а также расписание и опции, кликая по соответствующим закладкам табуляции. После того, как все изменения произведены, надо нажать кнопку "Apply", чтобы сделать эти изменения постоянными. Перед выполнением этого, можно щелкнуть по кнопке "Show SQL", что покажет точное SQL-предложение, которое будет исполнено. Таким способом вам предоставляется возможность узнать, какие работы происходят за сценой. Более того, это SQL-предложение можно сохранить в скрипте и выполнить позже или сохранить как шаблон для будущих надобностей.
Заключение
Scheduler (Планировщик) в Oracle Database 10g - это гигантский шаг вперед по сравнению с изначальным интерфейсом пакета dbms_job. Более подробная информация об этих и других, более расширенных возможностях находится в Главе 25 Chapter 25 руководства “ Oracle Database Administrator's Guide”.
Неделя
20
Лучшее на последок
(Best of the Rest)
Источник: http://www.oracle.com/technology/pub/articles/10gdba/week20_10gdba.html
Автоматическое накопление статистики, гарантированное сохранение Undo-данных, простое и более защищенное шифрование – эти и многие другие, всегда требуемые АБД возможности теперь имеют место в Oracle Database 10g.
Поздравляю! Это - заключительная неделя нашего удивительного путешествия по самым важным новым возможностям АБД в Oracle Database 10g. В предыдущих девятнадцати статьях я попытался рассмотреть все инструментальные средства, подсказки и методы, которые обладают той фундаментальной привлекательностью: что выполнение наших работ становится проще и приносит большее удовлетворение.
Если какая-то возможность имела "звездное" ("star") качество, но не слишком помогала мне, как администратору базы данных, ей не было места в этом списке. Но и в этом случае даже двадцати статей недостаточно, чтобы рассказать обо всем, что способен предложить Oracle 10g , мне, наверно, не хватило бы и еще ста таких заметок. Итак, в этой последней статье этой серии я расскажу лишь о нескольких из многочисленных новых особенностей Oracle 10g, которые заслуживают быть упомянутыми.
А не устарела ли ваша статистика? Этого допускать нельзя
Как большинство из вас знает, Rules-Based Optimizer (RBO - Оптимизатор на основе синтаксических правил) наконец-то перестал поддерживаться, начиная с Oracle 10g. В ожидании этого долгожданного события многие вычислительные центры, применявшие базы данных Oracle9i, перешли на использование Cost Based Optimizer (CBO - Оптимизатор на основе стоимости), чтобы войти в контур поддержки и использовать в своих интересах расширенные возможности, как-то: перезапись запросов (query rewrite) и отсечение секций (partition pruning). Проблемой, однако, является статистика или, скорее, ее отсутствие.
Поскольку CBO, чтобы создать оптимальные пути выполнения запросов, зависит от точных (или разумно точных) статистических данных, АБД должны гарантировать, что статистические данные собираются регулярно, что порождает еще один контрольный список (checklist) регламентных работ. До 10g по различным причинам этот процесс мог быть бесполезным. Это противоречие восходит к теории, что CBO имеет "собственное мнение", которое означает поведение, как будто он изменяет по своему разумению пути выполнения запросов!
Многие из этих мучений были разрешены, и можно отдохнуть в 10g, в котором статистика может быть собрана автоматически. В Oracle9i можно было проверить, значительно ли изменились данные в таблице, включив опцию мониторинга таблицы (ALTER TABLE ... MONITORING), а затем проверив представление DBA_TAB_MODIFICATIONS для таких таблиц.
В 10g предложение MONITORING отсутствует. Вместо него статистические данные собираются автоматически, если параметр инициализации STATISTIC_LEVEL установлен в значение TYPICAL или ALL. (По умолчанию задано TYPICAL, так что автоматический сбор статистики допускается изначально.) Oracle Database 10g имеет в своем составе GATHER_STATS_JOB, предопределенную работу Планировщика (о Scheduler (Планировщик) вы узнали на предыдущей “Неделе 19” <http://www.oracle.com/technology/pub/articles/10gdba/week19_10gdba.html>), которая активизируется в соответствии со значением параметра STATISTIC_LEVEL.
Коллекционирование статистики - довольно ресурсоемкий процесс, так что следует гарантировать, что это не затронет нормальную производительность базы данных. В 10g можно автоматически сделать так: специальная группа пользовательских ресурсов по имени AUTO_TASK_CONSUMER_GROUP предопределенно доступна для автоматически выполняемых задач типа сбора статистики. Эта группа пользователей отличается тем, что приоритет работ по сбору статистики ниже заданной по умолчанию группы пользователей, и, следовательно, уменьшен или устранен риск заполонить машину автоматическими задачами.
Но что произойдет, если вы установите параметр STATISTIC_LEVEL в TYPICAL, но не пожелаете выполнять автоматический сбор статистики? Это просто, только отключите работу Scheduler, выдав следующую инструкцию:
BEGIN
DBMS_SCHEDULER.DISABLE('GATHER_STATS_JOB');
END;
Но почему Вам понадобилось это сделать? Существует многообразие разумных причин, одной из которых является то обстоятельство, что хотя большинство строк таблицы изменилось, их распределение, возможно, не изменилось, что является обычным случаем в хранилищах данных. В этом случае надо стремиться не собирать статистику заново, а только многократно использовать старую статистику. Другая причина может состоять в том, что Вы используете обмен секций (partition exchange), чтобы обновить материализованное представление (MV - materialized view), и не хотите собирать статистику по MV, поскольку статистика по обмениваемой таблице будет также импортирована. Более того, можно исключить некоторые таблицы из автоматической работы по сбору статистики, устраняя, тем самым, надобность в отключении работы в целом.
Хронология Статистики
Одним из осложнений, которые могут произойти в процессе коллекционирования статистики оптимизатора, является изменение планов выполнения, то есть, старые работы по оптимизации - прекрасны, пока не собраны [свежие] статистические данные, после чего эти запросы внезапно искажаются из-за плохих планов, сгенерированных на недавно собранной статистикой. Это – не такая уж нечастая проблема.
Чтобы оградиться от таких напастей, статистическая коллекция сохраняет существующую статистику перед сбором новых данных. В случае возникновения проблем всегда можно вернуться к старой статистике или, с другой стороны, исследовать различия между ними, чтобы выработать решение проблемы.
Например, давайте представим, что 31 мая в 10:00PM был выполнен сбор статистики по таблице REVENUE и что последующие запросы стали выполняться ужасно. Старые статистические данные, которые были сохранены Oracle, можно отыскать, задав:
begin
dbms_stats.restore_table_stats (
'ARUP',
'REVENUE',
'31-MAY-04 10.00.00.000000000 PM -04:00');
end;
Эта команда отменит собранную в 10:00PM 31 мая статистику, которая задается типом данных (datatype) TIMESTAMP. Вы только немедленно отменили изменения, сделанные в соответствии с новой программой сбора статистики.
Длительность периода, в течение которого можно восстановить [статистику], определятся параметром сохранения (retention). Чтобы проверить текущее сохранение, используйте запрос:
SQL> select DBMS_STATS.GET_STATS_HISTORY_RETENTION from dual;
GET_STATS_HISTORY_RETENTION
---------------------------
31
что в данном случае показывает, что в течение 31 дня статистик может быть сохранена, но это не гарантируется. Чтобы выяснить точные дату и время, на которые простираются статистические данные, надо воспользоваться запросом:
SQL> select DBMS_STATS.GET_STATS_HISTORY_AVAILABILITY from dual;
GET_STATS_HISTORY_AVAILABILITY
---------------------------------------------------------------------
17-MAY-04 03.21.33.594053000 PM -04:00
который показывает, что самая старая доступная дата [восстановления] статистики - 17 мая 3:21AM.
Вы можете задать периоду сохранения различную длительность, выполнив встроенную функцию. Например, чтобы установить его длительность на 45 дней, введите команду:
execute DBMS_STATS.ALTER_STATS_HISTORY_RETENTION (45)
Гарантируемое Undo-сохранение
Автоматическое Undo-сохранение, представленное в Oracle9i, имело существенную поддержку для сокращения случаев страшных ошибок ORA-1555 "Snapshot Too Old" ("Снимок слишком старый"). Но эти ошибки все-таки еще появлялись, хотя в значительно уменьшенном количестве. Почему?
Чтобы отвечать на этот вопрос, вы должны понять, как работает undo-сегмент. Когда в Oracle изменяет данные, немедленно изменяются блоки в кэше (в SGA), а предыдущие образы сохраняются в undo-сегментах. Когда фиксируется (commit) транзакция, старые образы [в undo-сегменте] больше не нужны, и, следовательно, они могут повторно использоваться. Если активная транзакция использует все пространство undo-сегмента, Oracle пытается повторно использовать самый старый участок сегмента (этот процесс известен как "wrapping" ("свертка"), что показывается в столбце WRAPS в представлении V$ROLLSTAT). Однако, в некоторых случаях, особенно в долго выполняющих транзакциях сегмент будет расширяться, чтобы предоставить место для активных транзакций, как показано в столбце EXTENDS в представлении V$ROLLSTAT. Если запрос, чтобы создать согласованное представление данных, нуждается в данных из того участка undo-сегмента, который уже был повторно использован, запрос аварийно заканчивается с ошибкой ORA-1555. [Прим. главного редактора OM/RE А.Бачина: я не берусь критиковать нашего автора, авторитетного эксперта в области администрирования базами данных Oracle, но хочу предостеречь не столь продвинутых АБД, что механизм отката (использование undo- или rollback- сегментов, ранее употреблявшийся эквивалентный термин) изложен, на мой взгляд, несколько поверхностно.]
Параметр инициализации UNDO_RETENTION_PERIOD определяет, как долго (в секундах) должны быть сохранены undo-данные отмены. Определяя время, Oracle гарантировал, что старые undo-участки не используются повторно, если они были изменены в пределах периода undo-сохранения, даже если они неактивны. Такой подход снизил вероятность случайного повторного использования неактивного участка более поздним запросом и, следовательно, и шансы возникновения ошибок ORA-1555.
Однако, хотя UNDO_RETENTION_PERIOD определяет, сколь долго undo-данные могут сохраниться, это не является гарантией. Когда сегменты не могут более расширяться, самый старый неактивный участок используется повторно, чтобы удовлетворить текущую транзакцию. Поэтому некоторые долго выполняющиеся запросы, несвязанные с транзакцией, изменяющей данные, когда доходят до таких участков, могут отказать и выдать ошибку ORA-1555.
Эта проблема решена в 10g: когда создается табличное undo-пространство, то теперь можно определить "guarantee" ("гарантированное") undo-сохранение. Приведем пример:
CREATE UNDO TABLESPACE UNDO_TS1
DATAFILE '/u01/oradata/proddb01/undo_ts1_01.dbf'
SIZE 1024M
RETENTION GUARANTEE;
Обратите внимание на последнее предложение, которое заставляет табличное undo- пространство гарантировать сохранение неистекших (unexpired) undo-участков. Существующие табличные undo-пространства могут быть также сделаны гарантированными, применяя команду ALTER, как показано в предложении:
ALTER TABLESPACE UNDO_TS2 RETENTION GUARANTEE;
Но что надо сделать, если Вы не хотите гарантировать сохранение (вариант Oracle9i)? Тогда поступите так:
ALTER TABLESPACE UNDO_TS2 RETENTION NOGUARANTEE;
Вы можете проверить, что табличное пространство гарантирует undo-сохранение:
SELECT RETENTION
FROM DBA_TABLESPACES
WHERE TABLESPACE_NAME = 'UNDO_TS1';
Сквозная трассировка
Общий подход к диагностированию проблем производительности состоит в том, чтобы дать возможность механизму sql_trace трассировать запросы базы данных и затем анализировать вывод, используя позже инструмент типа утилиты tkprof. Однако, этот подход имеет серьезное ограничение в базах данных с серверами, работающими в разделяемом режиме (shared server). В этой конфигурации возникает несколько разделяемых серверных процессов, которые обслуживают пользовательские запросы. Когда пользователь BILL соединяется с базой данных, диспетчер передает подключение к доступному разделяемому серверу. Если ни один из них не доступен, создается новый разделяемый серверный процесс. Если сессия стартует трассировку, трассироваться будут запросы, обслуживаемые процессом разделяемого сервера.
Теперь предположим, что сессия BILL переходит в простой, а сессия LORA становится активной. В этой точке разделяемый сервер, первоначально обслуживающий BILL, назначается сессии LORA. В этой точке трассовая информация исходит не от сессии BILL, а от сессии LORA. Когда сессия LORA становится неактивной, этому разделяемому серверу может быть назначена еще какая-то другая активная сессия, которая будет поставлять полностью отличную информацию.
В 10g эту проблему эффективно разрешили с помощью сквозной (end-to-end) трассировки. В этом случае трассовые данные отождествляются не только сессией, но и опознаваемым именем, например, идентификатором клиента. Для этой цели применяется новый пакет DBMS_MONITOR.
Например, Вы хотите проследить все сессии с идентификатором account_update. Чтобы установить трассировку, надо выполнить:
exec DBMS_MONITOR.CLIENT_ID_TRACE_ENABLE('account_update');
Эта команда включает трассировку во всех сессиях с идентификатором account_update. Когда BILL соединяется с базой данных, он может выполнить следующее предложение, чтобы установить идентификатор клиента:
exec DBMS_SESSION.SET_IDENTIFIER ('account_update')
Трассировка активна в сессиях с идентификатором account_update, так что вышеупомянутая сессия будет оттрассирована, и в назначенной пользовательской дамп-директории будет сгенерирован файл трассировки. Если другой пользователь соединяется с базой данных и устанавливает свой идентификатор клиента тоже как account_update, эта сессия также будет автоматически оттрассирована, без задействования в коде какой-либо команды. Все сессии с идентификатором клиента account_update будут трассироваться, пока не будет заблокирована трассировка:
exec DBMS_MONITOR.CLIENT_ID_TRACE_ENABLE('account_update');
Результирующие файлы трассировки могут быть проанализированы утилитой tkprof. Однако, каждая сессия производит отличный от других трассовый файл. Для всесторонней диагностики проблемы нас должен интересовать объединенный трассовый файл, а не индивидуальные. Как нам получить это?
Легко. Воспользуемся инструментом, называемым trcsess, и извлечем информацию, соответствующую идентификатору клиента account_update, из каждого файла, который можно обработать tkprof. В вышеупомянутом случае надо войти в назначенную пользовательскую дамп-директорию и выполнить:
trcsess output=account_update_trc.txt clientid=account_update *
Эта команда создает файл, называемый account_update_trc.txt, подобный обычному трассовому файлу, но который содержит данные только тех сессий, которые имеют идентификатор клиента account_update. Этот файл может быть обработан утилитой tkprof, чтобы получить проанализированный вывод.
Сравните этот подход с предыдущим, более трудным методом собирания трассовой информации. Кроме того, допускается включение (enable) и отключение (disable) трассировки некоторой переменной типа идентификатора клиента, без запроса alter session set sql_trace = true от этой сессии. Другая процедура в том же самом пакете, SERV_MOD_ACT_TRACE_ENABLE может включить трассировку в других комбинациях, например, для определенного сервиса, модуля или действия, которое может быть установлено пакетом dbms_application_info.
Использование базы данных
Любой представитель отдела продаж Oracle подтвердит, что секционирование - опция экстра-стоимости, и соответственно его стоимости, стоит задаться вопросом, используют ли пользователи когда-либо эту опцию, и если да, то, как часто.
Вместо того чтобы полагаться на ответы от пользователей, спросите базу данных. Automatic Workload Repository (Автоматический Репозиторий Рабочей нагрузки), представленный в “Неделе 6” http://www.oracle.com/technology/pub/articles/10gdba/week6_10gdba.html, собирает хотя бы однажды в неделю информацию об использовании всех установленных возможностей.
Два очень важных обзора отображают образ использования базы данных. Один, DBA_HIGH_WATER_MARK_STATISTICS, показывает максимальные значения каждой из возможностей, используемых в существующей базе данных. Приведем пример его вывода.
NAME HIGHWATER LAST_VALUE DESCRIPTION
--------------- ---------- ---------- ----------------------------------------------------------
USER_TABLES 401 401 Number of User Tables
(Число пользовательских таблиц)
SEGMENT_SIZE 1237319680 1237319680 Size of Largest Segment (Bytes)
(Размер наибольшего сегмента (байты))
PART_TABLES 12 0 Maximum Number of Partitions belonging to an User Table
(Макc. число секций, принадлежащих польз. таблице)
PART_INDEXES 12 0 Maximum Number of Partitions belonging to an User Index
(Макс. число секций, принадлежащих польз. индексу)
USER_INDEXES 832 832 Number of User Indexes
(Число пользовательских индексов)
SESSIONS 19 17 Maximum Number of Concurrent Sessions seen in the database
(Макс. число параллельных сессий, замеченных в базе данных)
DB_SIZE 7940079616 7940079616 Maximum Size of the Database (Bytes)
(Макс. размер базы данных (байты))
DATAFILES 6 6 Maximum Number of Datafiles
(Макс. число файлов данных)
TABLESPACES 7 7 Maximum Number of Tablespaces
(Макс. число табличных пространств)
CPU_COUNT 4 4 Maximum Number of CPUs
(Макс. число центральных процессоров)
QUERY_LENGTH 1176 1176 Maximum Query Length
(Макс. длина запроса)
Как Вы можете видеть, это представление показывает несколько значимых разрезов данных об использовании базы данных, как-то: всего пользователи создали 12 разделенных таблиц, но ни одна сейчас не используется (LAST_VALUE = 0). Эта информация не зависит от остановок (shutdowns) базы данных и может оказаться очень полезной при планировании операций типа перемещения к другому хосту.
Однако, приведенный выше обзор все же не ответил на все наши вопросы. Он сказал, что когда-либо создавалось не более 12 секционированных таблиц, но не в прошлый раз, когда эта опция использовалась. Другое представление, DBA_FEATURE_USAGE_STATISTICS, который показывает использованию различных возможностей базы данных, может ответить на тот вопрос. Здесь в вертикальном формате представлены данные об использовании опции секционирования.
DBID : 4133493568
NAME : Partitioning
VERSION : 10.1.0.1.0
DETECTED_USAGES : 12
TOTAL_SAMPLES : 12
CURRENTLY_USED : FALSE
FIRST_USAGE_DATE : 16-oct-2003 13:27:10
LAST_USAGE_DATE : 16-dec-2003 21:20:58
AUX_COUNT :
FEATURE_INFO :
LAST_SAMPLE_DATE : 23-dec-2003 21:20:58
LAST_SAMPLE_PERIOD : 615836
SAMPLE_INTERVAL : 604800
DESCRIPTION : Oracle Partitioning option is being used -
there is at least one partitioned object created.
(Опция Oracle Partitioning используется -
имеется не менее одного когда-либо
созданного секционированного объекта )
Как показано в этих представлениях, возможность секционирования сейчас в базе данных не используется (столбец CURRENTLY_USED есть FALSE), и в прошлый раз к этой опции обращались в 9:20PM 16 декабря 2003. Примерная выборка делалась каждые 604 800 секунд или 7 дней, как показано в столбце SAMPLE_INTERVAL. Столбец LAST_SAMPLE_DATE показывает, когда в прошлый раз эта возможность использовалась.
В дополнение к интерфейсу командной строки утилита Enterprise Manager 10g также показывает эту информацию. В EM войдите в закладку Administration и кликните по ссылке "Database Usage Statistics" ("Статистика использования базы данных”) под Configuration Management (“Управление Конфигурацией”). (См. рисунки 1 и 2.)
Рисунок 1: Страница статистики использования базы данных
Рисунок 2: Статистика использования базы данных; детализация опции
Простое и более защищенное шифрование
Помните пакет DBMS_OBFUSCATION_TOOLKIT (DOTK)? Это был единственный доступный метод выполнить шифрование (encryption) в базе данных в Oracle9i и ниже. В свое время этот пакет был достаточен для большинства баз данных, подобно большинству программ безопасности, но он быстро стал неэффективным против искушенных хакерских нападений, использующих очень тонкую информацию. Известно, что отсутствовала поддержка функциональных возможностей Advanced Encryption Standard (AES - Улучшенный стандарт шифрования), более мощного преемника прежнего Digital Encryption Standard (DES – Стандарт цифрового шифрования) и Triple DES (DES3 - Тройной стандарт шифрования данных).
В 10g внедрен более сложный аппарат шифрования пакет DBMS_CRYPTO. Этот встроенный пакет в дополнение к расширению существующих функций и процедур предлагает все функциональные возможности, недостающие в DOTK. Например, DBMS_CRYPTO может шифровать в новом 256 битовом AES алгоритме. Функция ENCRYPT (которая также перегружается как процедура) применяет несколько параметров:
|
Параметр |
Описание |
|
SRC |
Ввод, который будет зашифрован. Это должны быть данные типа RAW. Любой другой тип данных должен быть конвертирован. Например, символьная переменная l_inp конвертируется:
utl_i18n.string_to_raw (p_in_val, 'AL32UTF8');
Поскольку строка должна быть преобразована в RAW, используются набор символов AL32UTF8 и новый пакет по имени UTL_IL8N. В отличие от DOTK, DBMS_CRYPTO не принимает символьные переменные как параметры. Еще надо обратить внимание, что теперь не надо применять дополнительные символы, чтобы делать длину кратной 16, как это было в пакете DOTK. Функция (или процедура) выполняет это дополнение автоматически. |
|
KEY |
Здесь определен ключ шифрования. Ключ должен иметь соответствующую длину, основанную на используемом алгоритме. |
|
TYP |
Тип шифрования и используемого дополнения определяется в этом параметре. Например, если бы Вы хотите использовать 256-битовый AES-алгоритм, Cipher Block Chaining (сцепление блоков шифртекста) и дополнение PKCS#5, вы должны использовать встроенные константы как показано ниже:
typ => dbms_cryptio.encrypt_aes256 +
dbms_cryptio.chain_cbc +
dbms_cryptio.pad_pkcs5 |
Функция ENCRYPT возвращает зашифрованное значение в данных типа RAW, которые могут быть конвертированы в строки, используя:
utl_i18n.raw_to_char (l_enc_val, 'AL32UTF8')
что является обратным действием по преобразованию к RAW.
Противоположное шифрованию действие дешифрования обеспечивается функцией (или перегружаемой процедурой) DECRYPT, которая применяет аналогичные параметры. Используя этот новый пакет, вы можете формировать сложные модели безопасности в ваших приложениях базы данных.
Заключение
Как я упоминал ранее, невозможно охватить все новые особенности, востребованные АБД в Oracle Database 10g, но я сделал попытку в течение этих двадцати недель представить на ваш суд свой выбор важнейших лакомых кусочков. Я надеюсь, что для вас эта серия статей была действительно информативной и полезной. Еще раз прошу, пожалуйста, не стесняйтесь предлагать ваши комментарии и не забывайте писать мне, что позволит мне узнать, какие возможности оказались для вас самыми полезными.
От редакции “Oracle Magazine/Русское издание”:
Вот мы и прощаемся с великолепной серией статей Аруп Нанда “Oracle Database 10g:
20 наиболее привлекательных для АБД возможностей”, посвященной самым интересным новым особенностям с точки зрения администратора базы данных Oracle Database 10g.
На языке оригинала эта 20-недельная серия была опубликована довольно давно, и русский перевод м.б. несколько затянулся.
Но все-таки хорошо, что эта серия появилась на русском языке. Своеобразный стиль, язык, м |