Files
php-doc-ru/reference/oci8/taf.xml
2024-07-09 00:14:57 +03:00

353 lines
18 KiB
XML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: f4c44b86948f70a7e89f582b500e2595452e00f0 Maintainer: rjhdby Status: ready -->
<!-- Reviewed: no -->
<chapter xml:id="oci8.taf" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Поддержка прозрачного для приложений восстановления после отказа (Transparent Application Failover или TAF) для OCI8</title>
<para>
TAF — функция базы данных Oracle, которая обеспечивает высокую доступность.
TAF помогает OCI8-приложениям PHP автоматически переподключаться
к предварительно настроенной базе данных при сбое подключения к базе данных
из-за сбоя экземпляра или сети.
</para>
<para>
В сконфигурированной системе базы данных Oracle TAF-обработка происходит, когда
PHP-приложение обнаруживает, что экземпляр базы данных не работает или недоступен.
Он устанавливает соединение с другим узлом в конфигурации
Oracle <link xlink:href="&url.oracle.taf.rac;">RAC</link>, базой данных горячего
резерва или самим экземпляром базы данных. Подробнее об OCI TAF
рассказывает краткое руководство <link xlink:href="&url.oracle.taf.ociguide;">Oracle
Call Interface Programmer's Guide</link>.
</para>
<para>
Callback-функцию приложения регистрируют функцией
<function>oci_register_taf_callback</function>. В процессе восстановления после
отказа исполнение приложения приостанавливается и вызывается зарегистрированная
callback-функция. Эта функция будет оповещать приложение о событиях
процесса восстановления. Если восстановление завершилось успешно, управление
возвращается приложению. Если восстановление завершилось неудачно, то очередные
обращения к базе данных завершаются с ошибкой, поскольку отсутствует подключение.
</para>
<para>
Когда соединение переходит к другой базе данных, обратный вызов может сбросить
любое необходимое состояние соединения, например, перевыполнить
необходимую команду ALTER SESSION, если для сервиса базы данных не включили параметр
-failover_restore.
</para>
<para>
Регистрацию callback-функции приложения удаляют вызовом функции <function>oci_unregister_taf_callback</function>.
</para>
<section>
<title>настройка TAF</title>
<para>
TAF настраивают на стороне PHP-модуля OCI8 или в конфигурации базы данных.
Если настроено и там, и там, предпочтение отдаётся настройкам на стороне базы данных.
</para>
<para>
Настроить TAF в PHP-модуле OCI8 (на стороне клиента) можно через параметр
FAILOVER_MODE в части CONNECT_DATA дескриптора соединения.
Подробнее о настройке TAF на стороне клиента рассказывает секция
«Настройка прозрачного переключения приложений при отказе» (Configuring Transparent Application Failover)
краткого руководства <link xlink:href="&url.oracle.taf.clientconfig;">
Oracle Database Net Services Administrator's Guide</link>.
</para>
<para>
Пример настройки TAF в файле tnsnames.ora для переподключения к той же самой БД:
</para>
<para>
<informalexample>
<screen>
<![CDATA[
ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = orclpdb1)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 20)
(DELAY = 15))))
]]>
</screen>
</informalexample>
</para>
<para>
TAF также настраивается на стороне базы данных путём изменения целевой службы
утилитой <link xlink:href="&url.oracle.taf.srvctl;">srvctl</link>
(для RAC) или через пакетную процедуру
<link xlink:href="&url.oracle.taf.dbmsservice;">
DBMS_SERVICE.MODIFY_SERVICE</link>
(для одиночных экземпляров баз данных).
</para>
</section>
<section>
<title>Callback-функции TAF в модуле OCI8</title>
<para>
Callback-функция TAF — функция приложения, которую можно зарегистрировать для вызова
во время аварийного переключения. При восстановлении соединения функция
вызывается несколько раз.
</para>
<para>
Первый раз функция запускается в момент обнаружения проблем с соединением.
Это позволяет приложению корректно подготовиться к задержке выполнения
на время восстановления после сбоя. Если восстановление завершилось успешно,
функция вызывается сразу после восстановления подключения. Этот запуск
приложение может использовать для пересинхронизации настроек сессии и оповещения
пользователя о восстановлении после сбоя. Если восстановление не удалось,
callback-функция запускается ещё раз, чтобы сообщить приложению,
что восстановление не произошло и соединение невозможно использовать.
</para>
<para>
Интерфейс callback-функции модуля TAF:
</para>
<methodsynopsis>
<type>int</type><methodname>userCallbackFn</methodname>
<methodparam><type>resource</type><parameter>connection</parameter></methodparam>
<methodparam><type>int</type><parameter>event</parameter></methodparam>
<methodparam><type>int</type><parameter>type</parameter></methodparam>
</methodsynopsis>
<para>
<variablelist>
<varlistentry>
<term><parameter>connection</parameter></term>
<listitem>
<para>
Идентификатор соединения Oracle, на котором функцией <function>oci_register_taf_callback</function>
зарегистрировали callback-функцию TAF.
Соединение недействительно, пока восстановление не завершится успешно.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>event</parameter></term>
<listitem>
<para>
Событие восстановления означает текущий статус восстановления.
</para>
<para>
<itemizedlist>
<listitem>
<para>
<constant>OCI_FO_BEGIN</constant> означает, что произошла потеря
соединения и процесс восстановления начат.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_END</constant> означает удачное восстановление соединения.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_ABORT</constant> означает, что восстановление завершилось
неудачно и попыток восстановления больше не будет.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_ERROR</constant> также означает, что восстановление
завершилось с ошибкой, но приложению даётся возможность обработать
ошибку и вернуть OCI_FO_RETRY для ещё одной попытки восстановления.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_REAUTH</constant> означает, что пользователь
Oracle был повторно аутентифицирован.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>type</parameter></term>
<listitem>
<para>
Тип восстановления после отказа. Это позволяет функции понять,
какой тип восстановления запрошен приложением. Допустимы такие значения:
</para>
<para>
<itemizedlist>
<listitem>
<para>
<constant>OCI_FO_SESSION</constant> означает, что пользователь
запросил только восстановление сессии. К примеру, если соединение пропало,
то будет создана новая сессия на резервном сервере. Этот тип восстановления
не будет пытаться восстановить запросы типа SELECT.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_SELECT</constant> означает, что запрошено восстановление
запросов SELECT. Это позволит использовать открытый курсор для
извлечения значений после восстановления.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>return value</parameter></term>
<listitem>
<para>
<itemizedlist>
<listitem>
<para>
<literal>0</literal> означает, что шаги восстановления после отказа должны
продолжаться нормально.
</para>
</listitem>
<listitem>
<para>
<constant>OCI_FO_RETRY</constant> означает, что необходимо попробовать
восстановиться ещё раз. В случае возникновения ошибки при переходе на новое соединение TAF
может повторить переход на другой ресурс. Обычно перед возвращением кода
OCI_FO_RETRY рекомендуется некоторое время подождать.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<example>
<title>Регистрация callback-функции TAF</title>
<programlisting role="php">
<![CDATA[
<?php
// Определяем callback-функцию в пространстве пользователя
class MyClass
{
public static $retry_count;
public static function TAFCallback($conn, $event, $type)
{
switch ($event) {
case OCI_FO_BEGIN:
printf(" Failing Over ... Please stand by\n");
printf(" Failover type was found to be %s \n",
(($type==OCI_FO_SESSION) ? "SESSION"
:(($type==OCI_FO_SELECT) ? "SELECT" : "UNKNOWN!")));
self::$retry_count = 0;
break;
case OCI_FO_ABORT:
// Приложение больше не может использовать базу данных
printf(" Восстановление невозможно.\n");
break;
case OCI_FO_END:
// Восстановление завершилось успешно. Оповестим пользователей, что была проблема.
printf(" Восстановление завершено ... восстанавливаю работу\n");
break;
case OCI_FO_REAUTH:
printf(" Пользователь переавторизован ... восстанавливаю работу\n");
// Заново выполняем все необходимые ALTER SESSION
// т.е. oci_parse($conn, ALTER SESSION …’) ;
break;
case OCI_FO_ERROR:
// Прекращаем попытки соединения, если их было более 20.
if (self::$retry_count >= 20)
return 0;
printf(" Ошибка восстановления. Повторная попытка через 10 секунд...\n");
sleep(10);
self::$retry_count++;
return OCI_FO_RETRY; // retry failover
break;
default:
printf("Неизвестное событие восстановления: %d.\n", $event);
break;
}
return 0;
}
}
$fn_name = 'MyClass::TAFCallback';
$conn = oci_connect('hr', 'welcome', 'orcl');
$sysconn = oci_connect('system', 'oracle', 'orcl');
// Используйте привилегированное соединение для создания SQL-запроса, который инициирует отработку отказа
$sql = <<< 'END'
select unique 'alter system disconnect session '''||sid||','||serial#||''''
from v$session_connect_info
where sid = sys_context('USERENV', 'SID')
END;
$s = oci_parse($conn, $sql);
oci_execute($s);
$r = oci_fetch_array($s);
$disconnectssql = $r[0];
oci_register_taf_callback($conn, $fn_name); // Зарегистрируйте TAFCallback для Oracle TAF
print "Разбор пользовательского запроса\n";
$sql = "select systimestamp from dual";
$stmt = oci_parse($conn, $sql);
// Например, если соединение было потеряно на этом шаге, функция oci_execute()
// определит это и запустит процедуру восстановления. В процессе восстановления
// функция oci_execute() будет вызывать зарегистрированную callback-функцию
// несколько раз. Если восстановление пройдёт успешно, callback-функция создаст новое соединение
// и выполнение функции oci_execute() продолжится в нормальном режиме.
// Настройки сессии могут быть сброшены в callback-функции.
// Если восстановление завершится неудачно, функция oci_execute() вернёт ошибку,
// поскольку будет отсутствовать соединение.
// Отключите пользователя, который инициирует аварийное переключение
print "Отключение пользователя\n";
$discsql = oci_parse($sysconn, $disconnectssql);
oci_execute($discsql);
print "Выполнение пользовательского запроса\n";
$e = oci_execute($stmt);
if (!$e) {
$m = oci_error($stmt);
trigger_error('Не удалось выполнить условие:'. $m['message'], E_USER_ERROR);
}
$row = oci_fetch_array($stmt);
print $row[0] . "\n";
// Выполняем другие SQL-запросы на новом подключении
// $stmt = oci_parse($conn, . . .);
?>
]]>
</programlisting>
</example>
</section>
<section>
&reftitle.seealso;
<simplelist>
<member><function>oci_register_taf_callback</function></member>
<member><function>oci_unregister_taf_callback</function></member>
</simplelist>
</section>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->