Декабрь 2005

Рекомендации по программированию в версии 6.0
Oracle TimesTen™ In-Memory Database.

(Oracle TimesTen™ In-Memory Database
Recommended Programming Practices for Release 6.0)


Источник: сайт корпорации Oracle, раздел TimesTen, август 2005,
http://www.oracle.com/technology/products/timesten/pdf/wp/timesten60_good_practices.pdf

[От редакции OM/RE: Этот документ входит в комплект документации по Oracle TimesTen™ In-Memory Database. В виду его большого объема в данной публикации приводится перевод только главы 3 "Максимизация стабильности". Для того, чтобы читатели имели представление о структуре, содержании и объеме всего текста специально переведено оглавление документа полностью.
Если наши читатели проявят интерес к данной тематике, мы продолжим перевод и публикацию фрагментов документации.
]

Проектирование TimesTen-приложения, имеющего наибольшую устойчивость и производительность

Содержание

  1. Обзор
    • Технология
      • “TimesTen-Приложение” или “приложение с прямыми связями”
      • “TimesTen-приложение в архитектуре клиент/сервер”
    • Пользователям C++: О применении TTClasses
  2. Максимизация производительности
    • Информация о производительности в документации по TimesTen
    • Общие рекомендации по влиянию на производительность
      • Работа приложений с прямыми связями, критичных к производительности
      • Проверка синтаксиса всех SQL-предложений, выполняемая заранее
      • Управление частотой записи на диск
      • Создание правильных индексов для запросов
      • Использование “showplan”, чтобы проверить правильность использования индекса для запроса
      • Корректное переключение autocommit off и commit
      • Сравнение производительности C/C++ (ODBC) и Java (JDBC)
      • Быстрая загрузка данных (большого объема) с последующим созданием индексов
      • Использование TTClasses вместо OLEDB, ADO или промежуточного ПО третьих фирм
    • Настройка производительности для нескольких CPU
    • Использование пулов соединений
    • Увеличение параллелизма базы данных
    • Своевременное закрытие курсоров
    • Как избежать больших delete-предложений
    • О “DELETE FIRST NumRows
    • Как сократить излишне продолжительные транзакции
  3. Максимизация стабильности
    • Максимизация стабильности
      • Документация по TimesTen
    • Краткий курс по архитектуре TimesTen и восстановлению сборки данных
    • Как избежать неожиданного отказа приложения
      • TimesTen-приложения всегда следует отсоединять
      • Как избежать использования “kill –9” для TimesTen-приложений
    • Резервное копирование
    • Контрольные точки
    • Другие полезные методики
    • Проверка кодов возврата ODBC-функций и их обработка
    • Обработка ошибок нарушения целостности базы данных
    • Обработка блокировок deadlock и lock timeout vВосстановление с заполненного диска
  4. Репликация и XLA
    • Репликация
    • Использование DSN-имени как префикса в названии файла
    • Создание двух контрольных точек перед дублированием
    • В конфигурации репликации следует (вручную) указывать номера портов
    • Наблюдение за репликацией
    • Взаимодействие SEQUENCE с репликацией и избежание сбоя
    • Об XLA
    • Использование Persistent XLA
    • Постоянное наблюдение за XLA
    • Улучшение производительности XLA
  5. Индекс


Глава 3. “Максимизация стабильности”

В этом разделе внимание уделено способам написания кода приложения, позволяющим увеличить живучесть и стабильность, то есть сделать так, чтобы приложение оставалось присоединенным к сборке данных (data storage) и “живым”, насколько это возможно.

Документация по TimesTen

Существующая документация по TimesTen содержит много информации о разработке высокоустойчивых приложений. Заинтересованные читатели могут обратиться к главам Transaction Management and Recovery, TimesTen Built-In Procedures и Diagnostics, Errors and Warnings.

Краткий курс по архитектуре TimesTen и восстановлению сборки данных

TimesTen использует сегменты разделяемой памяти для хранения в памяти содержимого базы данных. Когда приложение присоединяется к базе данных TimesTen, оно отображает сегмент разделяемой памяти, выделенной под базу данных, в своем адресном пространстве. Использование разделяемой памяти позволяет нескольким процессам присоединяться к единственному образу базы данных. В традиционных приложениях, которые используют разделяемую память, от стабильности каждого процесса, присоединенного к разделяемой памяти, может сильно зависеть структура разделяемой памяти. Нестабильное приложение часто приводит к порче разделяемой памяти и сбою приложения. Это случается, когда приложение внезапно прекращает работу (например, в результате выполнения команды “kill -9”) во время обновления разделяемой памяти. При этом разделяемая память может остаться в состоянии противоречивости, то есть, со структурой данных, обновленной только частично.

TimesTen избегает этих проблем, благодаря использованию технологии Micrologging™, которая защищает любые приложения от внезапного сбоя даже при использовании разделяемой памяти. Если во время изменения разделяемой памяти в TimesTen произошел сбой приложения, TimesTen может определить этот момент и “откатить” разделяемую память к непротиворечивому и корректному состоянию.

Хотя TimesTen может восстановиться после внезапного сбоя приложения, этот процесс занимает ресурсы, которые лучше было бы потратить на выполнение приложений. Чтобы избежать этих издержек, при разработке приложения следует выполнить несколько простых шагов.

Как избежать неожиданного отказа приложения

Нижеследующие советы могут помочь при разработке TimesTen-приложения.

TimesTen-приложения всегда следует отсоединять

Существует множество причин, по которым может произойти останов приложения. Это может быть вызов exit() или abort() или множество видов завершения main(); другая причина – получение сигнала. Если процесс получил необработанный сигнал, он прекращается, что может повлечь за собой нарушение целостности хранимых данных. Перед завершением приложение должно откатить все активные транзакции и закрыть все соединения с базой данных TimesTen.

По этой причине в приложениях на C и C++, которые используют TimesTen, следует предусматривать обработчики сигналов, перехватывающие все сигналы этому приложению от других процессов. Лучше всего сделать это через специальный тред обработки сигналов. Некоторые приложения используют сигналы для взаимодействия между процессами; поэтому полученный сигнал не обязательно означает, что процесс должен быть прекращен.

В Java для этой же цели могут использоваться “shutdown hooks”. Демонстрационные модули, которые поставляются вместе с TimesTen, показывают, как в общем случае надлежащим образом использовать сигналы. Один из хороших примеров показан в “ttCGmonitor” (monitor.cpp). Демонстрационные модули на Java, расположенные в директории “Tutorial”, показывают соответственно, как использовать “shutdown hooks”.

Как избежать использования “kill –9” для TimesTen-приложений

Сигнал SIGKILL (в Windows это эквивалент использования кнопки “Завершить процесс” из диспетчера задач) не может быть обработан процессом. Вместо этого “kill –9” прерывает целевой процесс еще до того, как он что-либо сделает.

Поэтому для TimesTen-приложения не рекомендуется выполнять команду “kill –9”.

Приложение и систему следует проектировать так, чтобы команда “kill –9” никогда не потребовалась в промышленной эксплуатации. Это вообще хорошее правило.

Резервное копирование

Как и для всех баз данных, необходимо периодическое выполнение резервного копирования, чтобы обеспечить целостность данных. Выполнение резервного копирования и сохранение копий на переносном устройстве или на вторичном наборе постоянно смонтированных устройств уменьшает вероятность потери данных, если что-то случится с оборудованием, на котором установлена база данных, например, откажет жесткий диск.

Утилита TimesTen, называемая ttBackup, позволяет легко выполнить резервное копирование базы данных. Резервное копирование может выполняться в пакетном режиме одновременно с обычными операциями базы данных. Во время резервного копирования не возникает блокировок, что позволяет сделать этот процесс весьма эффективным.

Контрольные точки

Периодические контрольные точки - это важная часть функционирования базы данных TimesTen. Настройка частоты порождения контрольных точек может быть полезна некоторым приложениям. TimesTen создает на диске два полных снимка содержимого базы данных. Эти снимки называются “checkpoints” (контрольные точки). Периодически TimesTen будет автоматически обновлять на диске эти контрольные точки, чтобы синхронизировать их с текущим содержимым базы данных. Этот процесс выполняется в фоновом режиме, асинхронно и без участия приложения. Периодические контрольные точки важны по двум основным причинам:

  1. Контрольные точки позволяют TimesTen освободить место в журнале транзакций. В результате удаления устаревших файлов журнала транзакций диск не будет переполнен, а обеспечит Times-Ten возможность успешного продолжения работы, (см. раздел “Восстановление с заполненного диска” о важных вопросах контроля дискового пространства).
  2. Тот же самый процесс удаления журналов сокращает также время восстановления сборки данных в случае сбоя системы. Это происходит потому, что время, требуемое TimesTen для загрузки сборки данных в память, пропорционально количеству журналов на диске. По умолчанию TimesTen делает контрольные точки базы данных каждые 600 секунд (10 минут), или через заполнение очередных 64 мегабайтов журнала, в зависимости от того, какое из этих событий наступит быстрее. Этот режим может быть изменен, если необходимо использование таких атрибутов хранения данных, как CkptFrequency и CkptLogVolume.

Другие полезные методики

Проверка кодов возврата ODBC-функций и их обработка

При использовании ODBC необходимо проверять коды возврата всех ODBC-функций. Если обнаружены замечания или ошибки, то приложение должно обработать их соответствующим образом. Некоторые из особо важных ошибок, которые будут появляться, описаны в следующих двух разделах.

Полный список кодов ошибок и обозначений, которые TimesTen использует для описания этих кодов, находится в файле: install_dir/include/tt_errCode.h.

Краткое описание способов обработки ошибок в приложении для общего случая можно найти в разделе “Обработка ошибок в TimesTen-приложениях и восстановление ” в документе “Управление транзакциями и Восстановление”.

При использовании JDBC (Java) и TTClasses (C++) исключения будут отбраковываться для большинства ошибочных условий, связанных с базой данных. Эти ошибки должны быть обработаны в соответствующих блоках try/catch.

Обработка ошибок нарушения целостности базы данных

Как и любая база данных, TimesTen может стать недоступной. Приложения должны обрабатывать случаи, когда база данных, к которой они присоединены, неожиданно “портится”.

Базы данных могут стать недоступными по нескольким причинам. Администратор может прекратить работу экземпляра TimesTen. Критическая ошибка аппаратного обеспечения может повлиять на базу данных. Или в редких случаях TimesTen не сможет использовать Micro Logging для отката изменений, выполненных приложением, которое отказало. В этом случае TimesTen признает базу данных “недействительной” и потребует, чтобы все приложения прекратили ее использование.

Существует два кода ошибок TimesTen, которые показывают, что приложение присоединено к сборке данных с нарушением целостности: 846 (tt_ErrBadConnect) и 994 (tt_ErrDrtyByte). Когда приложение получит любой из этих кодов ошибок, оно должно откатить все начавшиеся транзакции, а затем отсоединиться, а для продолжением процесса соединиться повторно. Простую, но эффективную реализацию обработки ошибок нарушения целостности сборки данных можно найти в исходном коде C++ для ttMonitor (имя файла: monitor.cpp), который поставляется вместе с TimesTen.

Обработка блокировок deadlock и lock timeout

Deadlock (“мертвая” блокировка) и lock timeout (тайм-аут - блокировка по истечению времени) в общем случае следует обрабатывать похожими способами, однако они часто возникают по разным причинам. Блокировка deadlock возникает, когда две транзакции одновременно обращаются к одним и тем же ресурсам, и каждая из них держит ресурс, который требуется другой. Единственный способ продолжения работы после возникновения deadlock – это выбрать “жертву” и передать этой транзакции сообщение о deadlock-ошибке. В TimesTen код deadlock-ошибки 6002 (tt_ErrDeadlockVictim). Блокировка lock timeout возникает, когда две транзакции одновременно обращаются к одним и тем же ресурсам, и одна из них не может захватить ресурс за заданный промежуток времени. Для обоих случаев существует одинаковое решение, когда одна из транзакций продолжается долго без выполнения фиксации (commit), таким образом, удерживая блокировки продолжительное время. Надо предотвращать попытки блокировки ресурсов, заблокированных этой долгой транзакцией, другими транзакциями. Транзакция, которая не может заблокировать ресурс, получит код ошибки TimesTen 6003 (tt_ErrTimeoutVictim).

Плохо спроектированные приложения могут легко попасть в ситуацию deadlock. Например, если несколько тредов часто пытаются модифицировать один и тот же набор строк одновременно, может легко возникнуть deadlock. Утилита ttXactAdmin в TimesTen - это хороший инструмент для диагностики проблем, связанных с параллелизмом в базе данных. Для получения информации о ttXactAdmin, ознакомьтесь, пожалуйста, с описанием, имеющимся в разделе документации TimesTen Utilities.

TimesTen предоставляет разработчикам приложений несколько полезных воможностей, которые могут использоваться для уменьшения проблем, связанных с параллелизмом в базе данных. Это:

  • Работа в TimesTen на уровне изоляции READ_COMMITTED обеспечивает “неблокирующее чтение” (“nonblocking reads”), когда тот, кто читает, не блокирует того, кто пишет, а тот, кто пишет, не блокирует того, кто читает.
  • SQL-предложение SELECT... FOR UPDATE полезно для организации параллелизма, когда приложение выполняет SELECT, а затем немедленно хочет выполнить UPDATE над выбранной строкой (-ами).

Более подробная информацию об этих SQL-предложениях находится в секции по “SELECT” и “UPDATE” в документации по TimesTen API и “SQL Reference Guide”.

Восстановление при заполненном диске

Восстановление при заполненном диске может быть сложным и беспорядочным. Когда диск, содержащий журналы транзакций TimesTen, заполняется (из-за редких контрольных точек, или, возможно, из-за сбоя репликации или XLA), сохранение данных может стать некорректным (см. выше) и соединения не смогут автоматически восстановиться, так как больше нет места для записи последующих журналов.

В общем, когда журналы транзакций TimesTen полностью заполнят диск, необходимо (как-нибудь) освободить часть дискового пространства, затем подсоединиться к сборке данных и сразу же создать пару контрольных точек (для удаления ненужных журналов, которые там скопились).

Еще раз обратите внимание, что если репликация и/или XLA явились причиной увеличения журнала транзакций и полного заполнения диска, то сначала необходимо стереть репликационные и/или XLA-метки, а затем можно будет успешно удалить журналы транзакций с помощью контрольных точек.

E-mail this page