настройка TAF
PHP Manual
PHP Manual»OCI8»Поддержка прозрачного для приложений восстановления после отказа (Transparent Application Failover или TAF) для OCI8

Поддержка прозрачного для приложений восстановления после отказа (Transparent Application Failover или TAF) для OCI8

TAF — функция базы данных Oracle, которая обеспечивает высокую доступность. TAF помогает OCI8-приложениям PHP автоматически переподключаться к предварительно настроенной базе данных при сбое подключения к базе данных из-за сбоя экземпляра или сети.

В сконфигурированной системе базы данных Oracle TAF-обработка происходит, когда PHP-приложение обнаруживает, что экземпляр базы данных не работает или недоступен. Он устанавливает соединение с другим узлом в конфигурации Oracle » RAC, базой данных горячего резерва или самим экземпляром базы данных. Подробнее об OCI TAF рассказывает краткое руководство » Oracle Call Interface Programmer's Guide.

Callback-функцию приложения регистрируют функцией oci_register_taf_callback(). В процессе восстановления после отказа исполнение приложения приостанавливается и вызывается зарегистрированная callback-функция. Эта функция будет оповещать приложение о событиях процесса восстановления. Если восстановление завершилось успешно, управление возвращается приложению. Если восстановление завершилось неудачно, то очередные обращения к базе данных завершаются с ошибкой, поскольку отсутствует подключение.

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

Регистрацию callback-функции приложения удаляют вызовом функции oci_unregister_taf_callback().

TAF настраивают на стороне PHP-модуля OCI8 или в конфигурации базы данных. Если настроено и там, и там, предпочтение отдаётся настройкам на стороне базы данных.

Настроить TAF в PHP-модуле OCI8 (на стороне клиента) можно через параметр FAILOVER_MODE в части CONNECT_DATA дескриптора соединения. Подробнее о настройке TAF на стороне клиента рассказывает секция «Настройка прозрачного переключения приложений при отказе» (Configuring Transparent Application Failover) краткого руководства »  Oracle Database Net Services Administrator's Guide.

Пример настройки TAF в файле tnsnames.ora для переподключения к той же самой БД:

    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))))

TAF также настраивается на стороне базы данных путём изменения целевой службы утилитой » srvctl (для RAC) или через пакетную процедуру »  DBMS_SERVICE.MODIFY_SERVICE (для одиночных экземпляров баз данных).

Callback-функция TAF — функция приложения, которую можно зарегистрировать для вызова во время аварийного переключения. При восстановлении соединения функция вызывается несколько раз.

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

Интерфейс callback-функции модуля TAF:

function userCallbackFn(resource $connection, int $event, int $type): int

connection

Идентификатор соединения Oracle, на котором функцией oci_register_taf_callback() зарегистрировали callback-функцию TAF. Соединение недействительно, пока восстановление не завершится успешно.

event

Событие восстановления означает текущий статус восстановления.

  • OCI_FO_BEGIN означает, что произошла потеря соединения и процесс восстановления начат.

  • OCI_FO_END означает удачное восстановление соединения.

  • OCI_FO_ABORT означает, что восстановление завершилось неудачно и попыток восстановления больше не будет.

  • OCI_FO_ERROR также означает, что восстановление завершилось с ошибкой, но приложению даётся возможность обработать ошибку и вернуть OCI_FO_RETRY для ещё одной попытки восстановления.

  • OCI_FO_REAUTH означает, что пользователь Oracle был повторно аутентифицирован.

type

Тип восстановления после отказа. Это позволяет функции понять, какой тип восстановления запрошен приложением. Допустимы такие значения:

  • OCI_FO_SESSION означает, что пользователь запросил только восстановление сессии. К примеру, если соединение пропало, то будет создана новая сессия на резервном сервере. Этот тип восстановления не будет пытаться восстановить запросы типа SELECT.

  • OCI_FO_SELECT означает, что запрошено восстановление запросов SELECT. Это позволит использовать открытый курсор для извлечения значений после восстановления.

return value

  • 0 означает, что шаги восстановления после отказа должны продолжаться нормально.

  • OCI_FO_RETRY означает, что необходимо попробовать восстановиться ещё раз. В случае возникновения ошибки при переходе на новое соединение TAF может повторить переход на другой ресурс. Обычно перед возвращением кода OCI_FO_RETRY рекомендуется некоторое время подождать.

Пример #1 Регистрация callback-функции TAF

<?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,  . . .);

?>
To Top