Функции управления подключением к базе данных

Следующие функции имеют дело с установкой подключения к внутреннему серверу QHB. У прикладной программы может быть открыто несколько подключений к серверу одновременно. (Одна из причин этого состоит в том, чтобы иметь доступ к нескольким базам данных.) Каждое подключение представляется объектом PGconn, получаемым из функции PQconnectdb, PQconnectdbParams или PQsetdbLogin. Обратите внимание, что эти функции всегда будут возвращать непустой указатель на объект, возможно, за исключением случая, когда свободной памяти так мало, что ее не удастся выделить даже для объекта PGconn. Прежде чем передавать запросы через объект подключения, нужно вызвать функцию PQstatus для проверки возвращаемого значения при успешном подключении.

ПРЕДУПРЕЖДЕНИЕ!
Если к базе данных, в которой не был внедрен шаблон безопасного использования схем, имеют доступ недоверенные пользователи, начинайте каждый сеанс с удаления общедоступных для записи схем из пути поиска (search_path). Для этого можно установить в ключевом слове-параметре options значение -csearch_path=. Или, как вариант, выполнить PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)") после подключения. Это касается не только libpq, но и всех остальных интерфейсов для выполнения произвольных команд SQL.

ПРЕДУПРЕЖДЕНИЕ!
В системе Unix клонирование процесса с открытыми подключениями libpq может привести к непредсказуемым результатам, так как родительский и дочерний процессы совместно используют одни и те же сокеты и ресурсы операционной системы. По этой причине подобная практика не рекомендуется, хотя вызов exec из дочернего процесса для загрузки нового исполняемого файла является безопасным.

PQconnectdbParams

Создает новое подключение к серверу баз данных.

PGconn *PQconnectdbParams(const char * const *keywords,
                          const char * const *values,
                          int expand_dbname);

Эта функция открывает новое подключение к базе данных, используя параметры, взятые из двух массивов, завершающихся значением NULL. Первый из них, keywords, определяется как массив строк, каждая из которых является ключевым словом. Второй, values, дает значение для каждого ключевого слова. В отличие от описываемой ниже функции PQsetdbLogin, ее набор параметров можно расширить без изменения сигнатуры функции, поэтому при разработке новых приложений предпочтительнее использовать эту функцию (или ее неблокирующиеся аналоги PQconnectStartParams и PQconnectPoll).

Распознаваемые в настоящее время ключевые слова-параметры перечислены в подразделе Ключевые слова-параметры.

Передаваемые массивы могут быть пустыми, чтобы использовались все параметры по умолчанию, или содержать одно или несколько значений параметров. Они должны быть одинаковой длины. Обработка остановится на первой записи NULL в массиве keywords. При этом если запись в values, связанная с отличной от NULL записью в keywords, содержит NULL или пустую строку, эта запись игнорируется, а обработка продолжается, переходя к следующей паре записей массивов.

Когда expand_dbname имеет ненулевое значение, значение первого ключевого слова dbname проверяется на предмет, не является ли оно строкой подключения. Если это так, она «разворачивается» в отдельные параметры подключения, извлеченные из этой строки. Значение считается строкой подключения, а не просто именем базы данных, если оно содержит знак равенства (=) или начинается с обозначения схемы URI. (Более подробно форматы строки подключения описываются в подразделе Строки подключения.) Таким способом обрабатывается только первое вхождение dbname; все последующие параметры dbname обрабатываются как просто имя базы данных.

Обычно массивы параметров обрабатываются от начала к концу. Если какое-либо ключевое слово повторяется, используется его последнее значение (отличное от NULL и не пустое). Это правило применяется, в частности, когда ключевое слово, найденное в строке подключения, конфликтует с тем, которое задано в массиве keywords. Таким образом, программист может сам решать, будут ли записи в массиве переопределять значения, взятые из строки подключения, или наоборот. Записи массива, предшествующие развернутой записи dbname, могут быть переопределены полями строки подключения, которые, в свою очередь, переопределяются записями массива, следующими после dbname (но, опять же, только если эти записи предоставляют непустые значения).

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

PQconnectdb

Создает новое подключение к серверу баз данных.

PGconn *PQconnectdb(const char *conninfo);

Эта функция открывает новое подключение к базе данных, используя параметры, взятые из строки conninfo.

Передаваемая строка может быть пустой, чтобы использовались все параметры по умолчанию, либо содержать одно или несколько значений параметров, разделенных пробелами, или URI. Подробную информацию см. в подразделе Строки подключения.

PQsetdbLogin

Создает новое подключение к серверу баз данных.

PGconn *PQsetdbLogin(const char *pghost,
                     const char *pgport,
                     const char *pgoptions,
                     const char *pgtty,
                     const char *dbName,
                     const char *login,
                     const char *pwd);

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

Если параметр dbName содержит знак = или имеет допустимый префикс URI для подключения, то он воспринимается как строка conninfo точно таким же образом, как если бы он был передан функции PQconnectdb, а затем оставшиеся параметры применяются, как указано для функции PQconnectdbParams.

Параметр pgtty больше не применяется, и любое переданное ему значение будет игнорироваться.

PQsetdb

Создает новое подключение к серверу баз данных.

PGconn *PQsetdb(char *pghost,
                char *pgport,
                char *pgoptions,
                char *pgtty,
                char *dbName);

Это макрос, вызывающий функцию PQsetdbLogin с пустыми указателями вместо параметров login и pwd. Предоставляется в целях обратной совместимости с очень старыми программами.

PQconnectStartParams
PQconnectStart
PQconnectPoll

Создают подключение к серверу баз данных неблокирующим способом.

PGconn *PQconnectStartParams(const char * const *keywords,
                             const char * const *values,
                             int expand_dbname);

PGconn *PQconnectStart(const char *conninfo);

PostgresPollingStatusType PQconnectPoll(PGconn *conn);

Эти три функции используются для открытия подключения к серверу баз данных таким образом, чтобы поток исполнения вашего приложения не блокировался в процессе во время удаленной операции ввода/вывода. Смысл этого подхода в том, чтобы ожидание завершения операций ввода/вывода могло происходить в основном цикле приложения, а не внутри функции PQconnectdbParams или PQconnectdb, и благодаря этому приложение могло управлять этой операцией параллельно с другой работой.

С функцией PQconnectStartParams подключение к базе данных производится с использованием параметров, взятых из массивов keywords и values, и управляется expand_dbname, как описано выше для функции PQconnectdbParams.

С функцией PQconnectStart, подключение к базе данных производится с использованием параметров, взятых из строки conninfo, как описано выше для функции PQconnectdb.

Ни PQconnectStartParams, ни PQconnectStart, ни PQconnectPoll не заблокируются, пока соблюдается ряд ограничений:

  • Параметр hostaddr должен использоваться соответствующим образом, чтобы предотвратить выполнение запросов DNS. Подробную информацию по этому параметру см. в подразделе Ключевые слова-параметры.

  • Если вы вызываете функцию PQtrace, позаботьтесь о том, чтобы объект-поток, в который производится трассировка, не заблокировался.

  • Перед вызовом функции PQconnectPoll следует позаботиться о том, чтобы сокет находился в соответствующем состоянии, как описывается ниже.

Чтобы начать неблокирующий запрос на подключение, вызовите PQconnectStart или PQconnectdbParams. Если результат равен NULL, значит libpq не смогла выделить память для новой структуры PGconn. В противном случае возвращается допустимый указатель PGconn (хотя он еще не представляет рабочее подключение к базе данных). Затем вызовите PQstatus(conn). Если результатом является CONNECTION_BAD, значит попытка подключения уже провалилась, скорее всего, из-за недопустимых параметров подключения.

Если вызов PQconnectStart или PQconnectStartParams успешен, следующим шагом нужно опросить libpq, чтобы она могла продолжить процедуру подключения. Воспользуйтесь PQsocket(conn) для получения дескриптора сокета, лежащего в основе подключения к базе данных. (Внимание: не стоит полагать, что этот сокет остается неизменным от вызова к вызову PQconnectPoll.) Организуйте цикл таким образом: если PQconnectPoll(conn) при последнем вызове вернула PGRES_POLLING_READING, ожидайте, пока сокет не будет готов для чтения (что показывает select(), poll() или похожая системная функция). Затем снова вызовите PQconnectPoll(conn). Если же PQconnectPoll(conn) при последнем вызове вернула PGRES_POLLING_WRITING, ожидайте, пока сокет не будет готов для записи, а затем снова вызовите PQconnectPoll(conn). На первой итерации, т. е. когда вы еще не вызвали PQconnectPoll, реализуйте то же поведение, как если бы она вернула PGRES_POLLING_WRITING. Продолжайте этот цикл, пока PQconnectPoll(conn) не вернет PGRES_POLLING_FAILED, показывая, что процедура подключения окончилась неудачей, или PGRES_POLLING_OK, показывая, что соединение было успешно установлено.

В любое время в процессе подключения его состояние можно проверить, вызвав функцию PQstatus. Если этот вызов возвращает CONNECTION_BAD, значит процедура подключения окончилась неудачей; если же вызов возвращает CONNECTION_OK, значит соединение установлено. Оба эти состояния одинаково определяются на основе возвращаемого значения функции PQconnectPoll, описанной выше. Кроме того, во время асинхронной процедуры подключения (и только во время нее) могут встречаться и другие состояния. Они показывают текущую стадию процедуры подключения и могут быть полезны, например, для предоставления обратной связи пользователю. Вот эти состояния:

CONNECTION_STARTED
Ожидание установки соединения.

CONNECTION_MADE
Соединение установлено; ожидание отправки.

CONNECTION_AWAITING_RESPONSE
Ожидание ответа от сервера.

CONNECTION_AUTH_OK
Получена аутентификация; ожидание завершения запуска серверной части.

CONNECTION_SSL_STARTUP
Согласование шифрования SSL.

CONNECTION_SETENV
Согласование значений параметров, зависящих от среды.

CONNECTION_CHECK_WRITABLE
Проверка того, может ли соединение обрабатывать пишущие транзакции.

CONNECTION_CONSUME
Прочтение всех оставшихся ответных сообщений через соединение.

Обратите внимание, что, хотя эти константы и сохранятся (для поддержания совместимости), приложение никогда не должно полагаться на то, что они появятся в определенном порядке или вообще появятся, или что состояние всегда будет одним из этих документированных значений. Приложение может сделать что-то вроде этого:

switch(PQstatus(conn))
{
        case CONNECTION_STARTED:
            feedback = "Connecting...";
            break;

        case CONNECTION_MADE:
            feedback = "Connected to server...";
            break;
.
.
.
        default:
            feedback = "Connecting...";
}

При использовании PQconnectPoll параметр подключения connect_timeout игнорируется; именно приложение должно решать, не истекло ли чрезмерно много времени. В противном случае цикл с вызовом PQconnectStart и последующим вызовом PQconnectPoll равнозначны вызову функции PQconnectdb.

Обратите внимание, что когда функция PQconnectStart или PQconnectdbParams возвращает непустой указатель, то, закончив его использование, следует вызвать функцию PQfinish, чтобы освободить эту структуру и все связанные с ней блоки памяти. Это нужно сделать, даже если попытка подключения провалилась или прекратилась.

PQconndefaults

Возвращает значения по умолчанию для параметров подключения.

PQconninfoOption *PQconndefaults(void);

typedef struct
{
    char   *keyword;   /* Ключевое слово этого параметра */
    char   *envvar;    /* Имя резервной переменной среды */
    char   *compiled;  /* Скомпилированное резервное значение по умолчанию */
    char   *val;       /* Текущее значение параметра или NULL */
    char   *label;     /* Метка этого поля в диалоге подключения */
    char   *dispchar;  /* Показывает, как отображать это поле
                          в диалоге подключения. Значения следующие:
                          ""        Отображать введенное значение как есть
                          "*"       Поле пароля — скрывать значение
                          "D"       Параметр отладки — не показывать по умолчанию */
    int     dispsize;  /* Размер поля в символах для диалога */
} PQconninfoOption;

Возвращает массив параметров подключения. Его можно использовать для определения всех возможных параметров функции PQconnectdb и их текущих значений по умолчанию. Возвращаемое значение указывает на массив структур PQconninfoOption, который заканчивается записью, имеющей пустой указатель keyword. Если память выделить не удалось, возвращается пустой указатель. Обратите внимание, что текущие значения по умолчанию (поля val) будут зависеть от переменных среды и другого контекста. Отсутствующий или недействительный файл служб будет молча игнорироваться. Вызывающие функции должны рассматривать данные параметров подключения как доступные только для чтения.

После обработки массива параметров освободите память, передав его функции PQconninfoFree. Если этого не сделать, то при каждом вызове функции PQconndefaults будет теряться небольшой объем памяти.

PQconninfo

Возвращает параметры подключения, используемые активным соединением.

PQconninfoOption *PQconninfo(PGconn *conn);

Возвращает массив параметров подключения. Его можно использовать для определения всех возможных параметров функции PQconnectdb и значений, которые использовались для подключения к серверу. Возвращаемое значение указывает на массив структур PQconninfoOption, который заканчивается записью, имеющей пустой указатель keyword. Все примечания, приведенные выше для функции PQconndefaults, применимы также и к результату функции PQconninfo.

PQconninfoParse

Возвращает синтаксически проанализированные параметры подключения из предоставленной строки подключения.

PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);

Синтаксически анализирует строку подключения и возвращает результирующие параметры в виде массива или возвращает NULL, если при анализе строки подключения возникает. Эту функцию можно использовать для извлечения параметров функции PQconnectdb из предоставленной строки подключения. Возвращаемое значение указывает на массив структур PQconninfoOption, который заканчивается записью, имеющей пустой указатель keyword.

Все допустимые параметры будут присутствовать в результирующем массиве, но для всех параметров, отсутствующих в строке подключения, PQconninfoOption будет иметь в поле val значение NULL; значения по умолчанию не подставляются.

Если поле errmsg не равно NULL, то в случае успеха в поле *errmsg устанавливается NULL, а в противном случае — выделенная malloc строка с сообщением об ошибке, объясняющем проблему. (Также возможен вариант, когда в поле *errmsg устанавливается NULL, и при этом функция возвращает NULL; это указывает на нехватку памяти.)

После обработки массива параметров освободите память, передав его функции PQconninfoFree. Если этого не сделать, то при каждом вызове функции PQconninfoParse будет теряться небольшой объем памяти. В свою очередь, если произошла ошибка и поле errmsg не равно NULL, обязательно освободите память со строкой сообщения об ошибке, воспользовавшись функцией PQfreemem.

PQfinish

Закрывает соединение с сервером. Также освобождает память, используемую объектом PGconn.

void PQfinish(PGconn *conn);

Обратите внимание, что даже если попытка подключения к серверу провалилась (как показывает функция PQstatus), приложение все равно должно вызвать PQfinish, чтобы освободить память, используемую объектом PGconn. Указатель PGconn не должен использоваться повторно после того, как была вызвана функция PQfinish.

PQreset

Переустанавливает канал связи с сервером.

void PQreset(PGconn *conn);

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

PQresetStart
PQresetPoll

Переустанавливает канал связи с сервером неблокирующим способом.

int PQresetStart(PGconn *conn);

PostgresPollingStatusType PQresetPoll(PGconn *conn);

Эти функции закроют соединение с сервером и попытаются установить новое подключение, используя все те же параметры, что использовались раньше. Это может быть полезно для восстановления после ошибки при потере работающего соединения с сервером. Они отличаются от функции PQreset (см. выше) тем, что действуют неблокирующим способом. На эти функции наложены те же ограничения, что и на PQconnectStartParams, PQconnectStart и PQconnectPoll.

Чтобы запустить переподключение, вызовите функцию PQresetStart. Если она вернет 0, значит переподключение не удалось. Если же она вернет 1, опросите результат переподключения, используя функцию PQresetPoll точно таким же образом, как если бы вы проводили подключение с помощью функции PQconnectPoll.

PQpingParams

Функция PQpingParams отображает состояние сервера. Она принимает параметры подключения, идентичные параметрам описанной выше функции PQconnectdbParams. Чтобы получить состояние сервера, нет необходимости предоставлять корректные значения имени пользователя, пароля или имени базы данных; однако если будут предоставлены некорректные значения, сервер запротоколирует в журнал провалившуюся попытку подключения.

PGPing PQpingParams(const char * const *keywords,
                    const char * const *values,
                    int expand_dbname);

Эта функция возвращает одно из следующих значений:

PQPING_OK
Сервер работает и предположительно принимает подключения.

PQPING_REJECT
Сервер работает, но находится в состоянии, не допускающем подключения (запуск, завершение работы или восстановление после сбоя).

PQPING_NO_RESPONSE
С сервером невозможно связаться. Это может указывать на то, что сервер не запущен, или что-то не так с заданными параметрами подключения (например, неверный номер порта), или имеется проблема сетевого соединения (например, брандмауэр блокирует запрос на подключение).

PQPING_NO_ATTEMPT
Попытка связаться с сервером не проводилась, потому что предоставленные параметры были очевидно неправильными или имела места какая-то проблема на стороне клиента (например, нехватка памяти).

PQping

Функция PQping отображает состояние сервера. Она принимает параметры подключения, идентичные параметрам описанной выше функции PQconnectdb. Чтобы получить состояние сервера, нет необходимости предоставлять корректные значения имени пользователя, пароля или имени базы данных; однако если будут предоставлены некорректные значения, сервер запротоколирует в журнал провалившуюся попытку подключения.

PGPing PQping(const char *conninfo);

Возвращаемые значения такие же, как и для функции PQpingParams.

PQsetSSLKeyPassHook_OpenSSL

Функция PQsetSSLKeyPassHook_OpenSSL позволяет приложению переопределить имеющуюся в libpq стандартную обработку файлов с зашифрованными ключами клиентских сертификатов, использующую sslpassword или интерактивное приглашение.

void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook);

Приложение передает указатель функции обратного вызова с сигнатурой:

int callback_fn(char *buf, int size, PGconn *conn);

которую libpq потом будет вызывать вместо своего стандартного обработчика PQdefaultSSLKeyPassHook_OpenSSL. Эта функция обратного вызова должна идентифицировать пароль для ключа и скопировать его в результирующий буфер buf размера size. Строка в buf должна завершаться NULL. Функция обратного вызова должна вернуть длину пароля, сохраненного в buf, не считая завершающего NULL. В случае неудачи она должна установить buf[0] = '\0' и вернуть 0. В качестве примера см. реализацию PQdefaultSSLKeyPassHook_OpenSSL в исходном коде libpq.

Если пользователь задал местоположение ключа явно, то при вызове функции обратного вызова его путь будет передан в conn->sslkey. Это поле будет пустым, если используется путь к ключу по умолчанию. Что касается ключей, специфичных для криптомодулей, именно реализации криптомодулей должны решать, использовать ли функцию-обработчик паролей OpenSSL или определить собственный обработчик.

Обработчик приложения может предпочесть делегировать необрабатываемые им случаи функции PQdefaultSSLKeyPassHook_OpenSSL, или сначала вызвать ее и попытаться предпринять что-то еще, если она возвратит 0, или полностью ее переопределить.

Эта функция обратного вызова не должна нарушать нормальную последовательность выполнения, выбрасывая исключения, вызывая longjmp(...) и т. п. Она должна завершиться нормально.

PQgetSSLKeyPassHook_OpenSSL

Функция PQgetSSLKeyPassHook_OpenSSL возвращает текущий обработчик пароля для ключа клиентского сертификата или NULL, если таковой не был установлен.

PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL(void);


Строки подключения

Ряд функций libpq синтаксически анализируют заданную пользователем строку для получения параметров подключения. Существует два принятых формата для этих строк: простые строки ключ/значение и URI. В целом, строки URI соответствуют RFC 3986, за исключением того, что в них допускаются строки подключения с несколькими хостами, как подробно описано ниже.


Строки подключения вида «ключ/значение»

В формате ключ/значение установка каждого параметра происходит в форме ключ = значение, с пробелами между параметрами. Пробелы вокруг знака равенства являются необязательными. Чтобы записать пустое значение или значение с пробелами, нужно заключить его в апострофы, например, keyword = 'a value'. Апострофы и обратные слэши внутри значения следует экранировать обратным слэшем, т. е. \' и \\.

Пример:

host=localhost port=5432 dbname=mydb connect_timeout=10

Распознаваемые ключевые слова-параметры перечислены в подразделе Ключевые слова-параметры.


URI подключения

Общая форма URI подключения:

qhb://[указание_пользователя@][указание_хоста][/имя_бд][?указание_параметра]

где указание_пользователя:

пользователь[:пароль]

и указание_хоста:

[хост][:порт][,...]

и указание_параметра:

имя=значение[&...]

В качестве обозначения схемы URI используется qhb://. Все остальные части URI являются необязательными. Следующие примеры иллюстрируют допустимый синтаксис URI:

qhb://
qhb://localhost
qhb://localhost:5433
qhb://localhost/mydb
qhb://user@localhost
qhb://user:secret@localhost
qhb://other@localhost/otherdb?connect_timeout=10&application_name=myapp
qhb://host1:123,host2:456/somedb?target_session_attrs=any&application_name=myapp

Значения, которые обычно фигурируют в иерархической части URI, также можно задать в именованных параметрах. Например:

qhb:///mydb?host=localhost&port=5433

Все именованные параметры должны соответствовать ключевым словам, перечисленным в подразделе Ключевые слова-параметры, за исключением того, что для совместимости с URI подключения JDBC вхождения ssl=true заменяются на sslmode=require.

Если URI подключения содержит в какой-либо из частей символы со специальным значением, он должен кодироваться в формате с процентами. Вот пример, где знак равенства (=) заменяется на %3D, а знак пробела — на %20:

qhb://user@localhost:5433/mydb?options=-c%20synchronous_commit%3Doff

Часть строки с хостом можно представить либо именем хоста, либо IP-адресом. Чтобы задать адрес IPv6, нужно заключить его в квадратные скобки:

qhb://[2001:db8::1234]/database

Часть строки с хостом интерпретируется в соответствии с описанием параметра host. В частности, если часть строки с хостом пуста или выглядит как абсолютный путь, выбирается соединение через сокеты домена Unix; в противном случае инициируется подключение по TCP/IP. Однако обратите внимание, что слэш в иерархической части URI является зарезервированным символом. Поэтому чтобы задать нестандартный каталог сокета домена Unix, нужно либо опустить в URI часть с хостом и задать сервер в именованном параметре, либо закодировать путь в этой части процентами:

qhb:///dbname?host=/var/lib/qhb
qhb://%2Fvar%2Flib%2Fqhb/dbname

В одном URI можно задать несколько компонентов хостов, каждый с необязательным компонентом порта. URI вида qhb://host1:port1,host2:port2,host3:port3/ равнозначен строке подключения вида host=host1,host2,host3 port=port1,port2,port3. Как описывается ниже, все хосты будут перебираться по очереди, пока не будет установлено соединение.


Указание нескольких хостов

В строке подключения можно указать несколько хостов, и тогда клиент будет пытаться подключиться к ним в заданном порядке. В формате ключ/значение параметры host, hostaddr и port принимают списки значений, разделенных запятыми. В каждом указанном параметре должно быть задано одинаковое число элементов, чтобы, например, первый элемент hostaddr соответствовал имени первого хоста, второй — имени второго хоста и т. д. В порядке исключения, если указывается только один элемент port, он применяется ко всем хостам.

В формате URI подключения в компоненте host можно перечислить несколько пар host:port, разделенных запятыми.

В любом формате одно имя хоста может переводиться в несколько сетевых адресов. Типичным примером этого является хост, имеющий как адрес IPv4, так и адрес IPv6.

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

При использовании файла паролей можно задать разные пароли для разных хостов. Все остальные параметры подключения являются одинаковыми для всех хостов в списке; например, невозможно задать для разных хостов разные имена пользователей.



Ключевые слова-параметры

В настоящее время распознаются следующие ключевые слова-параметры:

host

Имя хоста для подключения. Если имя хоста выглядит как абсолютный путь, оно задает связь через домен Unix, а не через TCP/IP; значение является именем каталога, в котором хранится файл сокета. (В системах Unix абсолютный путь начинается со слэша.) Если имя хоста начинается с @, оно воспринимается как сокет домена Unix в абстрактном пространстве имен (в настоящее время поддерживается в Linux). Поведение по умолчанию, когда параметр host не задан или пуст, заключается в подключении к сокету домена Unix в /tmp (или в том каталоге сокетов, который был указан при сборке QHB). На машинах без сокетов домена Unix по умолчанию выполняется подключение к localhost.

Также принимается список имен хостов, разделенных запятыми, и тогда все эти имена перебираются по порядку; для пустых элементов списка выбирается поведение по умолчанию, описанное выше. Подробную информацию см. в подразделе Указание нескольких хостов.

hostaddr

Числовой IP-адрес хоста для подключения. Он должен иметь стандартный формат адресов IPv4, например 172.28.40.9. Если ваша машина поддерживает IPv6, можно использовать и такие адреса. Когда в этом параметре задается непустая строка, всегда используется связь через TCP/IP. Если этот параметр не задан, соответствующий IP-адрес будет взят из значения host — или, если в host задан IP-адрес, это значение будет использоваться напрямую.

Использование hostaddr позволяет приложению обойтись без розыска имени хоста, что может быть важно для приложений с временными ограничениями. Однако имя хоста требуется для методов аутентификации GSSAPI или SSPI, а также для проверки сертификатов SSL в режиме verify-full. Применяются следующие правила:

  • Если host задается без hostaddr, ищется имя хоста. (При использовании функции PQconnectPoll поиск производится, когда PQconnectPoll впервые изучает имя этого хоста, и это может надолго заблокировать PQconnectPoll.)

  • Если hostaddr задается без host, значение hostaddr дает сетевой адрес сервера. Если для метода аутентификации требуется имя хоста, попытка подключения провалится.

  • Если задаются и host, и hostaddr, значение hostaddr дает сетевой адрес сервера. Значение host игнорируется, за исключением случаев, когда его требует метод аутентификации, и тогда оно будет использоваться как имя хоста.

Обратите внимание, что аутентификация, вероятно, завершится неудачей, если host не является именем сервера с сетевым адресом hostaddr. Кроме того, когда задаются и host, и hostaddr, то значение host используется для идентификации подключения в файле паролей (см. раздел [Файл паролей]).

Также принимается список значений hostaddr, разделенных запятыми, и тогда все хосты в этом списке перебираются по порядку. Вместо пустого элемента списка используется имя соответствующего хоста или, если оно тоже пустое, имя хоста по умолчанию. Подробную информацию см. в подразделе Указание нескольких хостов.

В отсутствие имени и адреса хоста libpq произведет подключение, используя локальный сокет домена Unix, а на машинах без сокетов домена Unix попытается подключиться к localhost.

port

Номер порта для подключения на хосте сервера или расширение имени файла сокета для подключений через домен Unix. Если в параметрах host или hostaddr указано несколько хостов, в этом параметре может задаваться список разделенных запятыми портов той же длины, что и список хостов, или может задаваться один номер порта для всех хостов. Пустая строка или пустой элемент в списке через запятую задают номер порта по умолчанию, установленный при сборке QHB.

dbname

Имя базы данных. По умолчанию будет совпадать с именем пользователя. В определенных контекстах это значение проверяется на соответствие расширенным форматам; более подробную информацию см. в подразделе Строки подключения.

user

Имя пользователя QHB, под которым будет производиться подключение. По умолчанию будет совпадать с тем именем пользователя в операционной системе, от лица которого выполняется приложение.

password

Пароль, который будет использоваться, если сервер потребует аутентификацию по паролю.

passfile

Задает имя файла, используемого для хранения паролей (см. раздел [Файл паролей]). По умолчанию это ~/.pgpass. (Если этот файл не существует, это не будет ошибкой.)

channel_binding

Этот параметр управляет использованием связывания каналов клиентом. Значение require означает, что соединение должно задействовать связывание каналов, prefer — что клиент выберет связывание каналов, если оно доступно, а disable предотвращает использование связывания каналов. Если QHB компилируется с поддержкой SSL значением по умолчанию будет prefer, в противном случае — disable.

Связывание каналов — это метод, позволяющий серверу подтвердить свою подлинность клиенту. Он поддерживается только для подключений поверх SSL с серверами QHB, использующими метод аутентификации SCRAM.

connect_timeout

Максимальное время ожидания подключения в секундах (записывается в виде десятичного целого числа, например 10). Ноль, отрицательное или не заданное значение означают бесконечное ожидание. Минимально допустимое время ожидания составляет 2 секунды, поэтому значение 1 интерпретируется как 2. Это время ожидания применяется по отдельности для каждого имени хоста или IP-адреса. Например, если задать два хоста и установить в connect_timeout значение 5, для каждого хоста время ожидания при отсутствии подключения истечет через 5 секунд, так что общее время, затраченное на ожидание подключения, может составить до 10 секунд.

client_encoding

Здесь устанавливается параметр конфигурации client_encoding для данного подключения. Помимо значений, принимаемых соответствующим параметром сервера, можно использовать значение auto, чтобы определить верную кодировку на основе текущей локали на стороне клиента (в системах Unix это переменная среды LC_CTYPE).

options

Задает параметры командной строки для передачи серверу при установлении соединения. Например, значение -c geqo=off установит для параметра сеанса geqo значение off. Пробелы в этой строки считаются разделяющими аргументы командной строки, если только они не экранированы обратным слэшем (\); чтобы отобразить собственно обратный слэш, нужно написать \\. Более подробное описание доступных параметров см. в главе Конфигурация сервера.

application_name

Задает значение для параметра конфигурации application_name.

fallback_application_name

Задает альтернативное значение для параметра конфигурации application_name. Это значение будет использоваться, если для параметра application_name не было задано никакого значения посредством параметра подключения или переменной среды PGAPPNAME. Указание альтернативного имени полезно для типовых служебных программ, желающих установить имя приложения по умолчанию, но позволяющих пользователю переопределить его.

keepalives

Определяет, будут ли использоваться keepalive-сообщения протокола TCP на стороне клиента. Значение 1 (по умолчанию) означает, что использование включено, но его можно изменить на 0 (выключено), если keepalive-сообщения не нужны. Этот параметр игнорируется для соединений, установленных через сокет домена Unix.

keepalives_idle

Управляет продолжительностью периода бездействия (в секундах), по истечении которого TCP должен отправить keepalive-сообщение на сервер. При нулевом значении используется системное значение по умолчанию. Этот параметр игнорируется для соединений, установленных через сокет домена Unix, или при отключенных keepalive-сообщениях. Он поддерживается только в системах, где доступен TCP_KEEPIDLE или равнозначный ему параметр сокета; в других системах он не оказывает никакого эффекта.

keepalives_interval

Управляет продолжительностью периода бездействия (в секундах), по истечении которого keepalive-сообщение TCP, получение которого не подтверждено сервером, следует отправить повторно. При нулевом значении используется системное значение по умолчанию. Этот параметр игнорируется для соединений, установленных через сокет домена Unix, или при отключенных keepalive-сообщениях. Он поддерживается только в системах, где доступен TCP_KEEPINTVL или равнозначный ему параметр сокета; в других системах он не оказывает никакого эффекта.

keepalives_count

Определяет количество keepalive-сообщений TCP, которые могут быть потеряны, прежде чем соединение клиента с сервером будет признано неработающим. При нулевом значении используется системное значение по умолчанию. Этот параметр игнорируется для соединений, установленных через сокет домена Unix, или при отключенных keepalive- сообщениях. Он поддерживается только в системах, где доступен TCP_KEEPCNT или равнозначный ему параметр сокета; в других системах он не оказывает никакого эффекта.

tcp_user_timeout

Управляет продолжительностью периода (в миллисекундах), в течение которого отправляемые данные могут оставаться неподтвержденными, прежде чем соединение будет принудительно закрыто. При нулевом значении используется системное значение по умолчанию. Этот параметр игнорируется для соединений, установленных через сокет домена Unix. Он поддерживается только в системах, где доступен параметр сокета TCP_USER_TIMEOUT; в других системах он не оказывает никакого эффекта.

replication

Этот параметр определяет, должно ли соединение использовать протокол репликации вместо обычного протокола. Этот вариант внутренне используют соединения репликации QHB и средства вроде qhb_basebackup, но его также могут применять сторонние приложения. Описание протокола репликации см. в разделе Протокол потоковой репликации.

Поддерживаются следующие значения, без учета регистра:

  • true, on, yes, 1
    Подключение производится в режиме физической репликации.

  • database
    Подключение производится в режиме логической репликации, с базой данных, заданной в параметре dbname.

  • false, off, no, 0
    Подключение производится в обычном режиме, что является поведением по умолчанию.

В режиме физической или логической репликации может использоваться только протокол простых запросов.

gssencmode

Этот параметр определяет, будет ли согласовываться с сервером защищенное GSS подключение по TCP/IP, и если да, то в какой очередности. Всего существует три режима:

  • disable
    пытаться установить только соединение без шифрования GSSAPI

  • prefer (по умолчанию)
    если присутствуют учетные данные GSSAPI (т. е. имеются в кэше учетных данных), сначала попытаться установить зашифрованное GSSAPI соединение; если это не получится или учетных данных нет, попытаться установить соединение без шифрования GSSAPI. Это значение по умолчанию, если QHB была скомпилирована с поддержкой GSSAPI.

  • require
    пытаться установить только зашифрованное GSSAPI соединение

Параметр gssencmode игнорируется при подключении через сокет домена Unix. Если QHB компилируется без поддержки GSSAPI, использование режима require вызовет ошибку, тогда как prefer будет принят, но на самом деле libpq не будет пытаться установить зашифрованное GSSAPI соединение.

sslmode

Этот параметр определяет, будет ли согласовываться с сервером защищенное SSL подключение по TCP/IP, и если да, то в какой очередности. Всего существует шесть режимов:

  • disable
    пытаться установить только соединение без использования SSL

  • allow
    сначала попытаться установить соединение без использования SSL; если это не получится, попытаться установить соединение SSL

  • prefer (по умолчанию)
    сначала попытаться установить соединение SSL; если это не получится, попытаться установить соединение без использования SSL

  • require
    пытаться установить только соединение SSL. Если присутствует файл корневого центра сертификации (CA), проверить сертификат тем же способом, как если бы был задан режим verify-ca

  • verify-ca
    пытаться установить только соединение SSL и проверить, что сертификат сервера был выпущен доверенным CA

  • verify-full
    пытаться установить только соединение SSL, проверить, что сертификат сервера был выпущен доверенным CA и что имя хоста запрошенного сервера соответствует указанному в сертификате

Подробное описание того, как работают эти режимы, см. в разделе [Поддержка SSL].

Параметр sslmode игнорируется при подключении через сокет домена Unix. Если QHB компилируется без поддержки SSL, использование режимов require, verify-ca или verify-full вызовет ошибку, тогда как режимы allow и prefer будут приняты, но на самом деле libpq не будет пытаться установить соединение SSL.

Обратите внимание, что если возможно шифрование GSSAPI, оно будет предпочитаться шифрованию SSL вне зависимости от значения параметра sslmode. Чтобы принудительно использовать шифрование SSL в среде с рабочей инфраструктурой GSSAPI (например, на сервере Kerberos), нужно дополнительно установить в параметре gssencmode значение disable.

requiressl

Этот параметр считается устаревшим; рекомендуется вместо него установить sslmode.

При значении 1 требуется соединение SSL с сервером (это равнозначно значению require в sslmode). Тогда libpq откажется подключаться, если сервер не принимает соединений SSL. При значении 0 (по умолчанию) libpq будет согласовывать тип соединения с сервером (равнозначно значению prefer в sslmode). Этот параметр доступен, только если QHB компилируется с поддержкой SSL.

sslcompression

При значении 1 данные, передаваемые через соединения SSL, будут сжиматься. При значении 0 сжатие будет выключено. Значение по умолчанию — 0. Этот параметр игнорируется, если соединение SSL не установлено.

В настоящее время сжатие SSL считается небезопасным, и использовать его уже не рекомендуется. В OpenSSL 1.1.0 сжатие отключено по умолчанию, а во многих дистрибутивах операционных систем оно отключается и с более ранними версиями, поэтому включение этого параметра не окажет никакого влияния, если сервер не принимает сжатие. В QHB сжатие полностью отключено на сервере.

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

sslcert

Этот параметр задает имя файла для SSL-сертификата клиента, заменяющего файл по умолчанию ~/.qhb/qhb.crt. Этот параметр игнорируется, если соединение SSL не установлено.

sslkey

Этот параметр задает расположение секретного ключа, используемого для клиентского сертификата. Он может задать либо имя файла, который будет использоваться вместо имени по умолчанию ~/.qhb/qhb.key, либо ключ, полученный из внешнего «криптомодуля» (криптомодули — это загружаемые модули OpenSSL). Спецификация внешнего криптомодуля должна состоять из имени криптомодуля и специфичного для криптомодуля идентификатора ключа, разделенных двоеточием. Этот параметр игнорируется, если соединение SSL не установлено.

sslpassword

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

Любое непустое значение, заданное для этого параметра, подавляет вывод приглашения OpenSSL Enter PEM pass phrase: (введите пароль для PEM:), которое по умолчанию будет выводиться, если в libpq передается зашифрованный ключ клиентского сертификата.

Если ключ не зашифрован, этот параметр игнорируется. Параметр не действует на ключи, заданные криптомодулями OpenSSL, если только модуль не пользуется механизмом для приглашений обработчика паролей OpenSSL.

Для этого параметра не существует равнозначной переменной среды, а также нет средства его поиска в .pgpass. Его можно использовать в определении подключения в служебном файле. Пользователям, тяготеющим к более сложным способам, следует рассмотреть возможность использования криптомодулей и инструментов OpenSSL, например PKCS#11 или криптографических USB-устройств.

sslrootcert

Этот параметр задает имя файла, содержащего SSL-сертификат(ы) центра сертификации (CA). Если такой файл существует, сертификат сервера будет проверен на предмет подписания одним из этих центров. Имя по умолчанию — ~/.qhb/root.crt.

sslcrl

Этот параметр задает имя файла со списком отозванных SSL-сертификатов сервера (CRL). Сертификаты, перечисленные в этом файле, если таковой существует, будут отвергаться при попытке установить подлинность сертификата сервера. Если ни sslcrl, ни sslcrldir не установлены, используется файл ~/.qhb/root.crl.

sslcrldir

Этот параметр задает имя каталога со списком отозванных SSL-сертификатов сервера (CRL). Сертификаты, перечисленные в этом каталоге, если таковой существует, будут отвергаться при попытке установить подлинность сертификата сервера.

Этот каталог нужно подготовить с помощью команды OpenSSL openssl rehash или c_rehash. Подробную информацию см. в документации OpenSSL.

Параметр sslcrl и sslcrldir можно указывать вместе.

sslsni

При значении 1 (по умолчанию) libpq включает расширение TLS «Server Name Indication» (указание имени сервера, SNI) для соединений с шифрованием SSL. При установке в этом параметре значения 0 это расширение выключается.

Указание имени сервера может использоваться прокси-серверами с поддержкой SSL для маршрутизации соединений без необходимости расшифровывания потока SSL. (Обратите внимание, что для этого необходим прокси-сервер, распознающий протокол взаимной идентификации QHB, а не просто любой прокси-сервер SSL.) Однако SNI заставляет имя целевого хоста передаваться по сети в открытом виде, что в некоторых случаях может быть нежелательно.

requirepeer

Этот параметр задает имя пользователя операционной системы для сервера, например, requirepeer=qhb. При установке соединения через сокет домена Unix, если этот параметр установлен, клиент проверяет в начале подключения, что серверный процесс запущен от имени указанного пользователя; если это не так, соединение прерывается с ошибкой. Этот параметр можно использовать для обеспечения аутентификации сервера, схожей с той, которая доступна с SSL-сертификатами при соединениях по TCP/IP. (Обратите внимание, что если сокет домена Unix находится в каталоге /tmp или ином расположении, запись в котором разрешена всем пользователям, любой пользователь может запустить там прослушивающий сервер. Используйте этот параметр, чтобы гарантировать, что вы подключены к серверу, запущенному доверенным пользователем.) Этот параметр поддерживается только на платформах, для которых реализован метод аутентификации peer; см. раздел Аутентификация peer.

ssl_min_protocol_version

Этот параметр задает минимальную версию протокола SSL/TLS, допустимую для этого соединения. Допустимые значения: TLSv1, TLSv1.1, TLSv1.2 и TLSv1.3. Набор поддерживаемых протоколов зависит от используемой версии OpenSSL; более старые версии не поддерживают самые последние версии протоколов. Если значение не задано, минимальная версия по умолчанию — TLSv1.2, что удовлетворяет передовым рекомендациям индустрии на момент написания этой документации.

ssl_max_protocol_version

Этот параметр задает максимальную версию протокола SSL/TLS, допустимую для этого соединения. Допустимые значения: TLSv1, TLSv1.1, TLSv1.2 и TLSv1.3. Набор поддерживаемых протоколов зависит от используемой версии OpenSSL; более старые версии не поддерживают самые последние версии протоколов. Если значение не задано, этот параметр игнорируется, и при подключении будет использоваться верхняя граница, определенная сервером (если она установлена). Установка максимальной версии протокола полезна в основном для тестирования или если у какого-то компонента возникают затруднения при работе с новым протоколом.

krbsrvname

Имя службы Kerberos для использования при аутентификации с GSSAPI. Чтобы аутентификация Kerberos прошла успешно, оно должно соответствовать имени службы, заданному в конфигурации сервера. (См. также раздел Аутентификация GSSAPI.) По умолчанию обычно устанавливается имя qhb, но это можно изменить при сборке QHB посредством параметра --with-krb-srvnam скрипта configure. В большинстве сред никогда не возникает необходимости менять этот параметр. Некоторым реализациям Kerberos может потребоваться другое имя службы.

service

Имя службы, используемое для задания дополнительных параметров. Оно задает имя службы в файле pg_service.conf, где хранятся дополнительные параметры подключения. Это позволяет приложениям указывать только имя службы, так как параметры подключения могут поддерживаться централизованно. См. раздел Файл подключений служб.

target_session_attrs

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

  • any (по умолчанию)
    любое успешное подключение приемлемо

  • read-write
    сеанс должен по умолчанию принимать транзакции чтения-записи (то есть сервер не должен находиться в режиме горячего резерва, а параметр default_transaction_read_only должен иметь значение off (выключен))

  • read-only
    сеанс не должен по умолчанию принимать транзакции чтения-записи (противоположный случай)

  • primary
    сервер не должен находиться в режиме горячего резерва

  • standby
    сервер должен находиться в режиме горячего резерва

  • prefer-standby
    сначала попытаться найти резервный сервер, но если ни один из перечисленных хостов таковым не является, попробовать снова в режиме any