12 вариант 2 (954078), страница 24
Текст из файла (страница 24)
select name, gets, misses, sleeps, inunediate_gets, immediate_misses
from v$latch
where name in ('redo allocation', 'redo copy')
/
Информация о запросах wait находится слева, а о запросах immediate — справа. После выполнения этого оператора в качестве SYS или другого пользователя с доступом к представлениям V$ рассчитайте показатели конкуренции:
immediate contention = ( immediate_misses / (immediate_gets + immediate_misses) ) * 100
wait contention = ( misses / (gets + misses) ) * 100
Если любое из этих значений превышает 1, происходит конкуренция за эту защелку. Чтобы снизить конкуренцию за защелку распределения обновлений, сократите продолжительность времени захвата защелки любым процессом, уменьшив значение параметра LOG_SMALL_ENTRY_MAX_SIZE в файле параметров INIT.ORA. Чтобы снизить конкуренцию за защелку копирования обновлений, увеличьте число защелок, установив более высокое значение параметра LOG_SIMULTANEOUS_COPIES.
Контрольные точки
Контрольная точка — это событие, которое происходит в базе данных, когда информация из кэшей области SGA записывается на диск. Это происходит периодически в целях синхронизации базы данных и управляющих файлов с SGA. Дисковый ввод/вывод замедляет обработку, и это остается справедливым по отношению к контрольным точкам. База данных должна синхронизировать содержимое памяти и файлов данных, но слишком частая синхронизация может снизить общую производительность.
Контрольные точки обычно возникают либо через различные интервалы, которые DBA может контролировать, либо в результате определенных событий, которые DBA не может контролировать, либо когда DBA форсирует их выполнение.
Контрольные точки создаются на основе одного из двух интервалов: количественного или временного. Значение параметра LOG_CHECKPOINT_INTERVAL файла параметров INIT.ORA определяет число блоков обновлений, которые должны быть заполнены в процессе работы базы данных. При достижении этого значения возникает контрольная точка. Аналогичным образом контрольная точка возникает по истечении продолжительности времени с момента выполнения последней контрольной точки, указанной в параметре LOG_CHECKPOINT_TIMEOUT. Как правило, следует устанавливать значения этих показателей, позволяющие свести число контрольных точек к минимуму. Иными словами, установите значение LOG_CHECKPOINT_ INTERVAL на величину, превышающую размер самого большого журнала обновлений, a LOG_ CHECKPOINT_TIMEOUT установите равным нулю, что равносильно его отмене.
Контрольные точки продолжают выполняться при каждом останове базы данных (normal или immediate) или при каждом переключении журналов обновлений. Единственное, что можно сделать для настройки на этом уровне, — увеличить размер журналов обновлений, чтобы их переключение происходило реже.
Чтобы форсировать выполнение контрольной точки, выдайте следующую команду SQL:
alter system switch logfile;
Необходимость форсировать переключение журналов может возникнуть при их обслуживании, например при их перемещении с одного физического диска на другой.
Объекты базы данных
Настройка производительности не ограничивается проверкой буферных кэшей и корректировкой параметров в файле INIT.ORA. Необходимо также оптимизировать объекты базы данных. Это предусматривает контроль изменений состояния объектов, которые могут отрицательно повлиять на производительность, например, фрагментации. В отличие от проблем памяти и конкуренции, которые обычно продолжают проявляться, пока в базе данных не произойдут изменения, ключом к решению проблем большинства объектов базы данных является регулярная настройка.
Таблицы и индексы
Таблицы и индексы — это объекты базы данных, которые порождают больше всего проблем. В связи с тем что транзакции непрерывно извлекают и вставляют строки в таблицы и индексы базы данных, могут регулярно возникать такие проблемы, как разбиение, перемещение и динамическое расширение строк, а также фрагментация. Поскольку это происходит часто, большинство администраторов базы данных ожидают, пока эти проблемы не достигнут предела, или регулярно проводят обслуживание.
Перемещенные и фрагментированные строки
После того как RDBMS Oracle разместит информацию в какой-то строке, эта информация там и останется и будет использовать отведенное ей пространство, пока не возникнут изменения. Например, может быть выполнен такой оператор UPDATE, что после него строка уже не будет помещаться в одном блоке базы данных. RDBMS приступит к поиску свободного блока, в котором строка поместится. Найдя такой блок, она перенесет строку в новый блок базы данных. Это называется перемещением строки. С другой стороны, если одна строка базы данных станет слишком большой, чтобы ее можно было разместить в одном блоке базы данных, RDBMS Oracle расположит фрагменты этой строки по нескольким блокам базы данных. Это называется фрагментацией строки.
Перемещенные и фрагментированные строки уменьшают производительность операций ввода и вывода. Это связано с тем, что данные разбиты по нескольким блокам. Не имея возможности возвратить одну строку в одной операции ввода/вывода, база данных должна выполнить несколько операций чтения, чтобы вернуть одну строку. В зависимости от числа возвращаемых строк и числа фрагментированных или перемещенных строк, это может удвоить или даже утроить число операций чтения в процессе работы базы данных.
В Oracle предусмотрено инструментальное средство для обнаружения фрагментации и перемещения строк в базе данных. Команда analyze SQL, используемая в стоимостном оптимизаторе, отыскивает фрагментированные строки. Однако перед выполнением этого запроса необходимо выполнить сценарий utichain.sql, предусмотренный в базе данных. Команда analyze ищет таблицу под названием chained_rows, в которую записывает возвращаемую информацию. Этот запрос может быть выполнен только при наличии таблицы chained_rows. Эту таблицу создает сценарий utichain.sql:
SQL> @$ORACLE_HOME/rdbms/admin/utlchain
SQL> analyze table table_name list chained_rows;
Эту операцию необходимо выполнить для каждой таблицы, для которой нужно проверить фрагментацию или перемещение строк. Если в таблице chained_rows появятся какие-либо строки, их необходимо удалить. Чтобы удалить фрагментированные или перемещенные строки, выполните следующее:
1. Создайте копию таблицы, в которой возникли фрагментированные или перемещенные строки, и поместите их в новую таблицу.
create table new_table as select * from table where rowid in ( select head_rowid from chained_rows where table_name = 'TABLE' );
2. Удалите фрагментированные или перемещенные строки из первоначальной таблицы.
delete from table
where rowid in
( select head_rowid from chained_rows
where table_name = 'TABLE');
3. Перенесите строки из новой таблицы снова в первоначальную таблицу.
insert into table select * from new_table;
4. Уничтожьте новую таблицу.
drop table new_table;
Необходимо снова проанализировать таблицу. Оставшиеся строки являются фрагментированными, а исчезнувшие — перемещенными. Чтобы удалить фрагментированные строки, снова создайте эту таблицу с более высоким значением pctfree:
1. Выполните экспорт этой таблицы базы данных.
exp file=/tmp/filename compress=y indexes=y grants=y constraints=y tables=sample userid=user/password
2. Удалите текущую таблицу базы данных с помощью команды drop table.
3. Вновь создайте таблицу базы данных с более высоким значением pctfree.
create table sample ( first_column VARCHAR2(10), second_column VARCHAR2(10),…)
storage (initial 1024K next 1024K minextents 1 maxextents 249 pctfree 90) ;
4. Импортируйте данные во вновь созданную таблицу с помощью утилиты imp.
imp file=/tmp/filename full=y ignore=y userid=name/password
Снова проанализируйте таблицу. Если фрагментированные строки все еще существуют, может оказаться, что их невозможно устранить без повторного создания базы данных с новым размером блока базы данных. Иногда невозможно устранить всю фрагментацию строк из базы данных, особенно если в ней хранится информация в столбцах типа LONG или RAW.
Динамическое расширение
При создании каждой таблицы нужно определить, какой она должна иметь размер, как быстро она должна расти и как часто в ней будут изменяться данные. К сожалению, прогнозировать рост таблицы можно только на основе опыта и изучения тенденций роста. По этой причине приходится применять динамическое расширение.
При создании любого объекта базы данных устанавливается первоначальный размер. Информация вносится в таблицу или индекс до тех пор, пока в первоначально распределенном пространстве больше не останется места. Затем размер таблицы увеличивается на определенную величину. Это называется динамическим расширением
Выделение памяти основано на аргументах, переданных фразе storage команды create table или create index языка SQL. Если фраза storage не указана, используются параметры default storage в определении табличного пространства. Рассмотрим следующий оператор:
storage (initial x next у minextents a maxextents b pctincrease m)
Эти параметры определяют величину каждого расширения и предельный размер объекта. Чтобы определить начальный размер объекта базы данных, нужно умножить размер начального экстента initial на minextents. Когда количество данных в таблице и индексе превысит начальное распределение, будет распределен еще один экстент размером next. Этот процесс будет продолжаться, пока в табличном пространстве остается свободное место и не превышено число экстентов. Соблюдайте осторожность при установке значения PCTINCREASE — оно не должно быть слишком высоким. Используя параметр PCTINCREASE, следите на размерами следующих экстентов при возрастании таблицы или индекса. Эти параметры впоследствии можно всегда скорректировать.
Динамическое расширение отрицательно влияет на производительность базы данных; вырабатываются рекурсивные вызовы в результате запросов из словаря данных, которые в настоящее время еще не находятся в кэше. Для определения того, не происходит ли чрезмерное динамическое расширение, используйте следующий запрос:
select owner, segment_name, sum(extents)
from dba_segments
where segment__type in ('TABLE', 'INDEX')
group by owner, segment_name
order by owner, segment_name
/
Внимательно наблюдайте за экстентами, чтобы их число не приближалось к значению, установленному в maxextents. Необходимо время от времени вновь создавать таблицу с одним экстентом. Если только не была применена полосовая организация таблицы в виде нескольких экстентов, нужно тщательно следить за экстентами таблицы и поддерживать минимально возможное их число в целях максимального повышения производительности запросов на таблице. Для повторного создания таблицы выполните следующее:
1. Экспортируйте таблицу базы данных с помощью утилиты ехр. Не забудьте экспортировать индексы и ограничения.
ехр file=/tmp/filename compress=y indexes=y grants=y constraints=y tables=sample userid=user/password
2. Удалите таблицу базы данных с помощью команды drop table.
3. Вновь создайте таблицу с начальным экстентом, достаточно большим, чтобы вместить всю таблицу.
create table sample
( first_column VARCHAR2(10),
second_column VARCHAR2(10),…
)
storage (initial 50M next 1024K minextents 1 maxextents 249);
4. Импортируйте данные с помощью утилиты imp:
imp file=/tmp/filename full=y ignore=y userid=name/password
Работа с индексами намного проще. Выполните следующее:
1. Удалите индекс с помощью команды drop index.
2. Вновь создайте индекс с помощью команды create index. Следите за тем, чтобы начальный экстент был достаточно большим, чтобы вместить весь индекс.
Если вы не будете периодически (и правильно) переустанавливать размеры таблиц и индексов, таблица может достичь своих пределов, т.е. расшириться до размера, обусловленного параметром памяти maxextents. В такой ситуации выдайте следующую команду SQL:
alter table table_name (storage maxextents extent_size);
Максимальный экстент для объекта базы данных зависит от размера блока и от операционной системы Обратитесь к руководству Oracle Installation and Configuration Guide, чтобы определить установленные пределы. Не следя за максимальным расширением объекта базы данных и не контролируя надлежащим образом объекты базы данных, которые приближаются к предельным размерам, можно в результате вызвать останов производственной базы данных.
Фрагментация
Фрагментация табличных пространств, в которых находятся объекты базы данных, также приводит к снижению производительности. Первоначально табличные пространства распределяются как непрерывные участки памяти. Объекты базы данных тоже создаются в табличных пространствах как непрерывные участки памяти. Однако, по мере того как объекты выходят за пределы этих участков, они, как правило, занимают место, не смежное с предыдущими участками данных.
В процессе создания, уничтожения и расширения таблиц число сплошных участков свободного пространства увеличивается. Например, табличное пространство может иметь 1 Мб свободного пространства, но все оно будет состоять из участков по 1 Кб. Если вы выдадите команду create table с начальным экстентом 50 Кб, она не будет выполнена, поскольку не сможет распределить сплошной участок для создания таблицы. Это обычно встречается в тех условиях, когда часто происходит создание и удаление таблиц или индексов.
Чтобы проверить объем доступного свободного пространства и уровень фрагментации табличного пространства, выдайте следующий запрос:
select tablespace_name, sum(bytes), max(bytes), count(tablespace_name)
from dba_free_space
group by tablespace_name
order by tablespace_name
/
Результаты этого запроса покажут количество свободного места в табличном пространстве (sum), размер самого крупного непрерывного экстента (max), а также число экстентов свободного пространства, которое содержит табличное пространство (count). Если число сплошных участков больше 10—15, необходимо устранить фрагментацию табличного пространства следующим образом: