НАСТРОЙКА ВВОДА - ВЫВОДА ORACLE
ГЛАВА 22
----------------------------------------------------------------
НАСТРОЙКА ВВОДА-ВЫВОДА
Эта глава представляет Второй шаг процесса настройки: настройку
ввода-вывода. Здесь вы научитесь избегать узких мест
ввода-вывода, которые могут препятствовать ORACLE работать с
максимальной производительностью. В этой главе вы узнаете, как:
* сокращать соперничество за диск
* распределять память в блоках данных
* избегать динамического расределения пространства
Настройка ввода-вывода 22-1
----------------
Важность настройки ввода-вывода
Производительность многих программных приложений органически
лимитируется дисковым вводом-выводом. Зачастую приходится
приостанавливать работу процессора, пока не закончится операция
ввода-вывода. Такие приложения известны как "лимитированные
вводом-выводом". ORACLE спроектирован так, что его
производительность не обязательно лимитируется вводом-выводом.
Настройка ввода-вывода может помочь производительности, если
диск, содержащий базу данных, работает на пределе своей
загрузки. Однако такая настройка не может помочь
производительности в случаях, когда процессор вашего компьютера
работает на пределе своей загрузки.
Важно, чтобы настройка ввода-вывода осуществлялась после того,
как были учтены рекомендации, представленные в главе 21 данного
руководства, "Настройка определения памяти". Глава 21
показывает вам, как распределить память так, чтобы необходимость
в операциях ввода-вывода была минимальной. Когда вы достигнете
этого минимума, обратитесь к данной главе, чтобы организовать
необходимый ввод-вывод как можно более эффективно.
----------------
Сокращение соперничества за диск
В этой секции вы узнаете, как сократить соперничество за диск.
Обсуждаются следующие вопросы:
* что такое соперничество за диск
* как отслеживать активность диска
* как уменьшить активность диска
Что такое соперничество за диск?
--------------------------------
Соперничество за диск возникает, когда несколько процессов
одновременно пытаются обращаться к одному и тому же диску.
Большинство дисков имеют ограничения как на число одновременных
обращений, так и на количество данных, которые они могут
передавать за секунду. Когда достигаются эти лимиты, процессы
могут оказаться вынуждены ожидать доступа к диску.
Отслеживание активности диска
-----------------------------
Активность диска отражается:
* Статистиками файлового ввода-вывода ORACLE
* Статистиками операционной системы
ORACLE составляет свои файловые статистики, которые отражают
доступ к диску по файлам базы данных. Ваша операционная система
может также поддерживать статистики доступа к дискам для всех
файлов.
22-2 Руководство администратора
Отслеживание активности диска ORACLE
Исследуйте доступ к диску по файлам базы данных через
динамическую таблицу производительности V$FILESTAT. По
умолчанию эта таблица доступна только пользователю SYS, а также
пользователям, имеющим системную привилегию SELECT ANY TABLE,
таким как SYSTEM. Число обращений к диску для каждого файла
данных отражают следующие столбцы этой таблицы:
PHYRDS Значение этого столбца показывает число чтений
из каждого файла базы данных.
PHYWRTS Значение этого столбца показывает число записей
в каждый файл базы данных.
Отслеживайте эти значения за некоторый период времени, пока
работает ваше приложение, с помощью следующего запроса:
SELECT name, phyrds, phywrts
FROM v$datafile df, v$filestat fs
WHERE df.file# = fs.file#
Этот запрос также извлекает имя каждого файла данных из
динамической таблицы производительности V$DATAFILE. Вывод этого
запроса может выглядеть следующим образом:
NAME PHYRDS PHYWRTS
------------------------------------------- ---------- ---------
DISK$DEV20:[ORACLE.DB_ORA70}ORA_SYSTEM.DBS 7679 2735
DISK$DEV20:[ORACLE.DB_ORA70}ORA_SYSTEM1.DBS 32 546
Общее число операций ввода-вывода для одного диска вычисляется
как сумма значений PHYRDS и PHYWRTS для всех файлов базы данных,
управляемых инстанцией ORACLE на этом диске. Определите это
значение для каждого из ваших дисков. Определите также
интенсивность ввода-вывода для каждого диска, поделив общее
число операций ввода-вывода на интервал времени, в течение
которого была собрана эта статистика.
Отслеживание активности диска в операционной системе
Диски, содержащие файлы данных и файлы журнала повторения, могут
также содержать файлы, не относящиеся к ORACLE. Доступ к таким
файлам можно отслеживать только средствами операционной системы,
а не через таблицу V$FILESTAT. Такие средства описаны в
документации по вашей операционной системе; они также могут
упоминаться в вашем руководстве по инсталляции [IUG].
Используйте средства операционной системы, чтобы исследовать
общую активность ввода-вывода для ваших дисков. Постарайтесь
сократить общую интенсивность обращений к дискам, содержащим
файлы базы данных.
Настройка ввода-вывода 22-3
Распределение ввода-вывода
--------------------------
Рассмотрите статистики из таблицы V$FILESTAT и из средств вашей
операционной системы. Справьтесь в документации по
оборудованию, чтобы определить пределы загрузки ваших дисков.
Любой диск, работающий близко к своему пределу загрузки,
является потенциальным объектом для соперничества. Например, 40
или более запросов ввода-вывода в секунду - это слишком много
для большинства дисков на операционных системах VMS или UNIX.
Чтобы уменьшить активность перегруженного диска, переместите
один или несколько его наиболее интенсивно используемых файлов
на менее активный диск. Применяйте этот принцип к каждому из
ваших дисков, пока не добъетесь приблизительно одинаковой их
загрузки. Это называется распределением ввода-вывода.
Эта секция обсуждает рекомендации по распределению ввода-вывода:
* Разделить файлы данных и файлы журнала повторения по
разным дискам.
* Распределить, или "разрезать", данные таблицы по разным
дискам.
* Разделить таблицы и индексы по разным дискам.
* Сократить дисковый ввод-вывод, не связанный с ORACLE.
Разделение файлов данных и файлов журнала повторения
Процессы ORACLE постоянно обращаются к файлам данных и файлам
журнала повторения. Если эти файлы находятся на общих дисках,
существует тенденция к соперничеству за диск.
Помещайте каждый файл данных на отдельный диск. Тогда разные
процессы смогут обращаться к различным файлам одновременно без
соперничества.
Помещайте каждый набор файлов журнала повторения на отдельный
диск, не участвующий в других операциях. Файлы журнала
повторения пишутся процессом LGWR при подтверждении транзакции.
Информация в файл журнала записывается последовательно. Эта
последовательная запись может осуществляться намного быстрее,
если на этом диске нет других одновременных операций.
Выделение файлам журнала повторения специального отдельного
диска обычно гарантирует, что процесс LGWR работает ровно, не
требуя больше никакой настройки. Узкие места
производительности, связанные с LGWR, редки. Для информации о
настройке LGWR обратитесь к секции "Уменьшение соперничества за
замки буфера журнала повторения" на странице 23-9.
Заметим, что ЗЕРКАЛИЗАЦИЯ файлов журнала повторения, или
поддержание нескольких копий каждого файла журнала на разных
дисках, существенно не замедляет LGWR. LGWR пишет на каждый
диск параллельно, а потом ждет завершения каждой части этой
параллельной операции записи. Так как время, требуемое вашей
операционной системе для выполнения одной записи на диск, может
варьироваться, увеличение количества копий увеличивает
вероятность того, что одна из операций записи на диск в составе
параллельной записи продолжится дольше, чем в среднем.
Параллельная запись требует времени не больше, чем самая
продолжительная возможная одиночная запись. В вашей
операционной системе могут также иметь место некоторые накладные
расходы, ассоциированные с параллельной записью.
22-4 Руководство администратора
Выделение отдельных дисков и зеркализация файлов журнала
повторения - важные меры предосторожности. Выделение отдельных
дисков для файлов данных и файлов журнала гарантирует, что сразу
все файлы не будут потеряны в результате сбоя одиночного диска.
Зеркализация файлов журнала гарантирует, что каждый отдельный
файл журнала не будет потерян в результате сбоя одиночного
диска.
"Разрезание" данных таблицы
"Разрезание" - это практика разделения данных большой таблицы на
небольшие порции и размещение этих порций в отдельных файлах
данных на разных дисках. Это позволяет множественным процессам
обращаться к различным порциям таблицы одновременно без
соперничества за диск. "Разрезание" особенно удобно для
оптимизации произвольного доступа к таблицам, содержащим много
строк.
Чтобы создать "разрезанную" таблицу:
1. Создайте табличное пространство с помощью команды CREATE
TABLESPACE. Специфицируйте несколько файлов данных фразой
DATAFILE. Каждый из этих файлов должен быть на отдельном
диске.
CREATE TABLESPACE stripedtabspace
DATAFILE 'file_on_disk_1' SIZE 500K,
DATAFILE 'file_on_disk_2' SIZE 500K,
DATAFILE 'file_on_disk_3' SIZE 500K,
DATAFILE 'file_on_disk_4' SIZE 500K,
DATAFILE 'file_on_disk_5' SIZE 500K
2. Затем создайте таблицу с помощью команды CREATE TABLE.
Специфицируйте вновь созданное табличное пространство фразой
TABLESPACE.
Специфицируйте также размер экстентов таблицы с помощью фразы
STORAGE. Разместите каждый экстент в отдельном файле данных.
Экстенты таблицы должны быть несколько меньше файлов данных в
табличном пространстве, чтобы учесть накладные расходы.
Например:
CREATE TABLE stripedtab
( col_1 NUMBER(2),
col_2 VARCHAR(10) )
TABLESPACE stripedtabspace
STORAGE ( INITIAL 495K NEXT 495K
MINEXTENTS 5 PCTINCREASE 0 )
В результате этих шагов создана таблица STRIPEDTAB, которая
имеет 5 начальных экстентов размерами по 495K. Каждый экстент
занимает один из файлов данных, названных в фразе DATAFILE
предложения CREATE TABLESPACE. Все эти файлы находятся на
разных дисках. Эти пять экстентов распределяются сразу же,
поскольку MINEXTENTS равно 5. Для дополнительной информации о
параметре MINEXTENTS и других параметрах памяти обратитесь к
главе 8 "Управление объектами схемы" этого руководства.
Настройка ввода-вывода 22-5
Разделение таблиц и индексов
Поместите часто используемые структуры базы данных в отдельные
файлы данных на отдельных дисках. Чтобы сделать это, вы должны
знать, какие из структур вашей базы данных используются часто.
Например, отделите часто используемую таблицу от ее индекса.
Такое разделение распределит обращения к таблице и индексу по
разным дискам.
Выполните следующие шаги, чтобы разделить таблицу и ее индекс:
1. Создайте табличное пространство с помощью команды CREATE
TABLESPACE. Специфицируйте файл данных фразой DATAFILE:
CREATE TABLESPACE tabspace_1
DATAFILE 'file_on_disk_1'
2. Создайте таблицу с помощью команды CREATE TABLE.
Специфицируйте табличное пространство фразой TABLESPACE:
CREATE TABLE tab_1
( col_1 NUMBER(2),
col_2 VARCHAR(10) )
TABLESPACE tabspace_1
3. Создайте еще одно табличное пространство. Специфицируйте
файл данных на другом диске:
CREATE TABLESPACE tabspace_2
DATAFILE 'file_on_disk_2'
4. Создайте индекс. Специфицируйте новое табличное
пространство:
CREATE INDEX ind_1 ON tab_1 (col_1)
TABLESPACE tabspace_2
В результате этих шагов создана таблица TAB_1 в файле
FILE_ON_DISK_1, и индекс IND_1 в файле FILE_ON_DISK_2.
Устранение других дисковых операций
Если возможно, устраните ввод-вывод, не имеющий отношения к
ORACLE, на дисках, содержащих файлы базы данных. Эта мера
особенно полезна для оптимизации доступа к файлам журнала
повторения. Это не только уменьшит соперничество за диск, но
также позволит вам отслеживать всю активность на таких дисках
через динамическую таблицу производительности V$FILESTAT.
22-6 Руководство администратора
----------------
Распределение памяти в блоках данных
Данные таблиц в базе данных хранятся в блоках данных. В этой
секции вы узнаете, как распределять пространство внутри блоков
данных для лучшей производительности. Обсуждаются следующие
вопросы:
* как управлять памятью данных
* как хранить данные наиболее эффективно для вашего
приложения
Мигрирующие и сцепленные строки
-------------------------------
Если предложение UPDATE увеличивает объем данных в строке так,
что эта строка больше не умещается в своем блоке данных, то
ORACLE пытается найти другой блок, имеющий достаточно свободной
памяти, чтобы уместить целую строку. Если такой блок есть,
ORACLE перемещает всю строку в этот новый блок. Это называется
МИГРАЦИЕЙ СТРОКИ. Если строка слишком велика для всех доступных
блоков, то ORACLE расщепляет ее на несколько кусков, и сохраняет
каждый кусок в отдельном блоке. Это называется СЦЕПЛЕНИЕМ
строки. Сцепление строки может также осуществляться при ее
вставке.
Динамическое управление памятью данных, особенно миграция и
сцепление, наносит ущерб производительности:
* Предложения UPDATE, вызывающие миграцию и сцепление,
работают медленно.
* Запросы, выбирающие мигрировавшие или сцепленные строки,
должны выполнять больше ввода-вывода.
Вы можете идентифицировать мигрировавшие и сцепленные строки в
таблице или кластере с помощью команды ANALYZE с опцией LIST
CHAINED ROWS. Эта команда собирает информацию о каждой
мигрировавшей или сцепленной строке и помещает эту информацию в
указанную выходную таблицу. Определение типовой выходной
таблицы с именем CHAINED_ROWS содержится в скрипте SQL,
поставляемом на вашем дистрибутивном носителе. Общее имя этого
скрипта - UTLCHAIN.SQL, хотя его точное имя и местоположение
могут варьироваться в зависимости от вашей операционной системы.
Ваша собственная выходная таблица должна иметь такие же имена,
типы данных и размеры столбцов, что и таблица CHAINED_ROWS.
Настройка ввода-вывода 22-7
Чтобы уменьшить количество мигрировавших и сцепленных строк в
существующей таблице, выполните следующие шаги:
1. С помощью команды ANALYZE соберите информацию о мигрировавших
и сцепленных строках. Например:
ANALYZE
TABLE order_hist LIST CHAINED ROWS
2. Опросите выходную таблицу:
SELECT *
FROM chained_rows
WHERE table_name = 'ORDER_HIST'
OWNER_NAME TABLE_NAME CLUSTER_NAME HEAD_ROWID TIMESTAMP
---------- ---------- ------------ ------------------ ---------
SCOTT ORDER_HIST 0000186A.0003.0001 04-AUG-92
SCOTT ORDER_HIST 0000186A.0002.0001 04-AUG-92
SCOTT ORDER_HIST 0000186A.0001.0001 04-AUG-92
3. Если выходная таблица показывает, что у вас много
мигрировавших или сцепленных строк, выполните следующие шаги,
чтобы устранить миграцию строк:
a. Создайте промежуточную таблицу с теми же столбцами, что в
существующей таблице, и скопируйте в нее мигрировавшие и
сцепленные строки:
CREATE TABLE int_order_hist
AS SELECT *
FROM order_hist
WHERE ROWID IN
(SELECT head_rowid
FROM chained_rows
WHERE table_name = 'ORDER_HIST')
b. Удалите мигрировавшие и сцепленные строки из исходной
таблицы:
DELETE FROM order_hist
WHERE ROWID IN
(SELECT head_rowid
FROM chained_rows
WHERE table_name = 'ORDER_HIST')
c. Вставьте строки из промежуточной таблицы в исходную
таблицу:
INSERT INTO order_hist
SELECT *
FROM int_order_hist
d. Удалите промежуточную таблицу:
DROP TABLE int_order_history
22-8 Руководство администратора
4. Удалите информацию, собранную в выходной таблице на шаге 1:
DELETE FROM chained_rows
WHERE table_name = 'ORDER_HIST'
5. Снова выполните команду ANALYZE и опросите выходную таблицу.
6. Все строки, появившиеся в выходной таблице, - это сцепленные
строки. Вы можете устранить такие строки, увеличив ваш
размер блока данных. Может оказаться невозможным избежать
цепочек строк во всех ситуациях. Если ваша таблица имеет
столбцы LONG или длинные столбцы CHAR или VARCHAR2, сцепление
зачастую неизбежно.
----------------
Устранение динамического управления памятью
Когда создается объект, такой как таблица или сегмент отката,
для его данных распределяется пространство в базе данных,
называемое СЕГМЕНТОМ. Если последующие операции вызовут рост
данных и приведут к переполнению распределенной памяти, ORACLE
расширяет этот сегмент. Динамическое расширение памяти может
ухудшить производительность. Эта секция обсуждает следующие
вопросы:
* как обнаружить динамическое расширение
* как распределять достаточно памяти для ваших данных,
чтобы избежать динамического расширения
* как избежать динамического управления памятью в сегментах
отката
Обнаружение динамического расширения
------------------------------------
Динамическое расширение заставляет ORACLE выполнять предложения
SQL в дополнение к тем предложениям SQL, которые выдаются
пользовательскими процессами. Эти дополнительные предложения
SQL называются РЕКУРСИВНЫМИ ВЫЗОВАМИ, потому что ORACLE выдает
эти предложения сам. Рекурсивные вызовы генерируются также при
следующих действиях:
* промахах в кэше словаря данных
* возбуждении триггеров базы данных
* выполнении предложений определения данных (DDL)
* выполнении предложений SQL внутри хранимых процедур,
функций, пакетов и анонимных блоков PL/SQL
* срабатывании ограничений ссылочной целостности
Настройка ввода-вывода 22-9
Для исследования рекурсивных вызовов опросите динамическую
таблицу производительности V$SYSSTAT. По умолчанию эта таблица
доступна только пользователю SYS, а также пользователям, имеющим
системную привилегию SELECT ANY TABLE, таким как SYSTEM.
Отслеживайте эту статистику за некоторый период времени, пока
работает ваше приложение, с помощью следующего запроса:
SELECT name, value
FROM v$sysstat
WHERE name = 'recursive calls'
Вывод этого запроса может иметь следующий вид:
NAME VALUE
-------------------------------------------------- ----------
recursive calls 626681
Если ORACLE продолжает делать слишком много рекурсивных вызовов
по ходу выполнения вашего приложения, определите, какие из этих
рекурсивных вызовов инициированы действиями вашего приложения,
т.е. не имеют отношения к динамическому расширению. Если вы
обнаружите, что остальных рекурсивных вызовов, относящихся к
динамическому расширению, слишком много, вы можете попытаться
сократить их, распределяя экстенты большего размера.
Распределение экстентов
-----------------------
Чтобы устранить динамическое расширение, выполните следующие
шаги:
1. Определите максимальный размер вашего объекта. По поводу
формул, позволяющих предсказать количество памяти для
таблицы, обратитесь к главе 8 "Управление объектами схемы"
этого руководства.
2. Выберите значения параметров памяти так, чтобы ORACLE при
создании объекта распределил достаточное число экстентов для
размещения всех ваших данных.
Экстенты большего размера улучшают производительность по
следующим причинам:
* Так как блоки в каждом отдельном экстенте непрерывны,
один большой экстент более непрерывен, чем несколько
меньших экстентов. ORACLE может прочитать один большой
экстент с диска за меньшее число операций многоблочного
чтения, чем несколько экстентов меньшего размера.
* Сегменты большего размера менее подвержены вероятности
расширения.
Однако, поскольку большие экстенты требуют большего количества
непрерывных блоков, ORACLE может испытывать трудности при
отыскании для таких экстентов достаточного количества
непрерывной памяти. Чтобы определить, распределить ли несколько
больших сегментов или большее количество маленьких сегментов,
рассмотрите достоинства и недостатки каждого подхода в свете
ваших планов по росту и применению ваших таблиц.
22-10 Руководство администратора
Устранение динамического управления памятью в сегментах отката
--------------------------------------------------------------
Размер сегментов отката также может влиять на
производительность. Размер сегмента отката определяется
значениями параметров памяти этого сегмента отката. Ваши
сегменты отката должны быть достаточно большими, чтобы умещать
все записи отката для ваших транзакций. Как и для других
объектов, вы должны избегать динамического управления памятью в
сегментах отката.
Используйте команду SET TRANSACTION, чтобы назначать транзакции
сегментам отката соответствующего размера, базируясь на
рекомендациях следующих секций. Если вы явно не назначаете
транзакции сегмент отката, ORACLE выбирает для нее сегмент
отката произвольно. Если вы одновременно выполняете много копий
одного и того же приложения, позаботьтесь о том, чтобы не
назначать транзакции всех этих копий одному и тому же сегменту
отката. Это приведет к соперничеству за этот сегмент отката.
Отслеживайте также сжатие, или динамическое освобождение,
сегментов отката, которое базируется на параметре памяти
OPTIMAL. Для информации о том, как выбирать значение этого
параметра, отслеживать сжатие сегментов отката и соответственно
подбирать значение OPTIMAL, обратитесь к главе 9 "Управление
сегментами отката" этого руководства.
Пример
Следующее предложение назначает текущую транзакцию сегменту
отката OLTP_13:
SET TRANSACRION USE ROLLBACK SEGMENT oltp_13
Для длинных запросов
Назначайте большие сегменты отката таким транзакциям, которые
модифицируют данные, одновременно выбираемые длинными запросами.
Такие запросы могут требовать доступа к сегментам отката для
реконструирования согласованной по чтению версии
модифицированных данных. Эти сегменты отката должны быть
достатоно велики, чтобы умещать все записи отката для
соответствующих данных на все время выполнения длинного запроса.
Для длинных транзакций
Назначайте большие сегменты отката длинным транзакциям, которые
модифицируют большие количества данных. Большой сегмент отката
может улучшить производительность такой транзакции. Такие
транзакции генерируют большие записи отката. Если запись отката
не помещается в сегмент отката, ORACLE расширяет этот сегмент.
Динамическое расширение ухудшает производительность, и его
следует избегать по мере возможности.
Настройка ввода-вывода 22-11
Для интерактивных транзакций
Некоторые приложения выполняют интерактивную обработку
транзакций (OLTP). Приложения OLTP характеризуются частыми
одновременными транзакциями, каждая из которых модифицирует
небольшое количество данных. Назначайте транзакциям OLTP
небольшие сегменты отката, при условии, что их данные
одновременно не опрашиваются. Небольшие сегменты отката с
большей вероятностью будут поддерживаться в буферном кэше, где
доступ к ним очень быстр. Типичный сегмент отката для
транзакций OLTP может иметь два экстента размерами по 10K.
Чтобы лучше всего избежать соперничества, создайте много
сегментов отката, и назначайте каждую транзакцию своему сегменту
отката.