34.2. Функции, описывающие текущее состояние подключения #
Эти функции могут использоваться для опроса состояния объекта, описывающего существующее подключение к базе данных.
Подсказка
Разработчики приложений на основе libpq должны тщательно поддерживать абстракцию PGconn
. Следует использовать функции доступа, описанные ниже, для получения содержимого PGconn
. Обращение напрямую к внутренним полям PGconn
, используя сведения из libpq-int.h
, не рекомендуется, поскольку они могут измениться в будущем.
Следующие функции возвращают значения параметров, которые были установлены в момент подключения. Эти значения не изменяются во время жизни соединения. Если используется строка соединения с несколькими узлами, значения PQhost
, PQport
и PQpass
могут меняться, если с тем же объектом PGconn
устанавливается новое соединение. Другие значения не меняются на протяжении жизни объекта PGconn
.
PQdb
#Возвращает имя базы данных, с которой установлено соединение.
char *PQdb(const PGconn *conn);
PQuser
#Возвращает имя пользователя, который установил соединение.
char *PQuser(const PGconn *conn);
PQpass
#Возвращает пароль, использованный для подключения.
char *PQpass(const PGconn *conn);
PQpass
возвратит либо пароль, указанный в параметрах подключения, либо пароль, полученный из файла паролей (в случае отсутствия первого). Во втором случае, если в параметрах подключения было указано несколько узлов, полагаться на результатPQpass
нельзя, пока соединение не будет установлено. Состояние подключения позволяет проверить функцияPQstatus
.PQhost
#Возвращает имя сервера для активного соединения. Это может быть имя узла, IP-адрес или путь к каталогу, если подключение установлено через сокет Unix. (Признаком подключения к сокету будет абсолютный путь, который начинается с
/
.)char *PQhost(const PGconn *conn);
Если в параметрах подключения был задан и
host
, иhostaddr
, функцияPQhost
выдаст содержимоеhost
. Если был задан толькоhostaddr
, возвращается это значение. Если в параметрах подключения было задано несколько узлов,PQhost
возвращает адрес узла, с которым фактически установлено соединение.PQhost
возвращаетNULL
, если аргументconn
равенNULL
. Иначе в случае ошибки при получении информации об узле (это возможно, если соединение не установлено до конца или произошла ошибка) она возвращает пустую строку.Если в параметрах подключения указаны несколько узлов, на результат
PQhost
нельзя полагаться, пока соединение не будет установлено. Проверить состояние соединения позволяет функцияPQstatus
.PQhostaddr
#Возвращает IP-адрес сервера для активного соединения. Это может быть адрес, в который разрешилось имя узла, или IP-адрес, переданный в параметре
hostaddr
.char *PQhostaddr(const PGconn *conn);
PQhostaddr
возвращаетNULL
, если аргументconn
равенNULL
. Иначе в случае ошибки при получении информации об узле (это возможно, если соединение не установлено до конца или произошла ошибка) она возвращает пустую строку.PQport
#Возвращает номер порта активного соединения.
char *PQport(const PGconn *conn);
Если в параметрах подключения было задано несколько портов,
PQport
возвращает порт, с которым фактически установлено соединение.PQport
возвращаетNULL
, если аргументconn
равенNULL
. Иначе в случае ошибки при получении информации о порте (это возможно, если соединение не установлено до конца или произошла ошибка) она возвращает пустую строку.Если в параметрах подключения указаны несколько портов, на результат
PQport
нельзя полагаться, пока соединение не будет установлено. Проверить состояние соединения позволяет функцияPQstatus
.PQtty
#Эта функция теперь ничего не делает, но необходима для обратной совместимости. Функция всегда возвращает пустую строку или
NULL
, если аргументconn
имеет значениеNULL
.char *PQtty(const PGconn *conn);
PQoptions
#Возвращает параметры командной строки, переданные в запросе на подключение.
char *PQoptions(const PGconn *conn);
Следующие функции возвращают данные статуса, который может измениться в процессе выполнения операций на объекте PGconn
.
PQstatus
#Возвращает состояние подключения.
ConnStatusType PQstatus(const PGconn *conn);
Статус может принимать одно из ряда значений. Однако только два из них видны извне процедуры асинхронного подключения:
CONNECTION_OK
иCONNECTION_BAD
. Успешное подключение к базе данных имеет статусCONNECTION_OK
. О неудачной попытке подключения сигнализирует статусCONNECTION_BAD
. Обычно статус OK остаётся таковым до вызоваPQfinish
, но в случае ошибки соединения статус может смениться наCONNECTION_BAD
преждевременно. В таком случае приложение может попытаться восстановить подключение, вызвавPQreset
.О других кодах состояния, которые могут выдать эти функции, можно узнать в описании
PQconnectStartParams
,PQconnectStart
иPQconnectPoll
.PQtransactionStatus
#Возвращает текущий статус сервера, отражающий процесс выполнения транзакций.
PGTransactionStatusType PQtransactionStatus(const PGconn *conn);
Статус может быть одним из
PQTRANS_IDLE
(в настоящее время не занят обработкой транзакции),PQTRANS_ACTIVE
(команда в процессе обработки),PQTRANS_INTRANS
(не выполняет работу, но находится в рамках действительной транзакции) илиPQTRANS_INERROR
(не выполняет работу, но находится в рамках транзакции, завершившейся сбоем). Статус принимает значениеPQTRANS_UNKNOWN
, если соединение не работает. Статус принимает значениеPQTRANS_ACTIVE
только тогда, когда запрос был отправлен серверу, но ещё не завершён.PQparameterStatus
#Отыскивает текущее значение параметра сервера.
const char *PQparameterStatus(const PGconn *conn, const char *paramName);
Значения определённых параметров сервер сообщает автоматически в начале процедуры подключения или тогда, когда их значения изменяются.
PQparameterStatus
можно использовать, чтобы запросить эти значения. Функция возвращает текущее значение параметра, если оно известно, илиNULL
, если параметр неизвестен.Параметры, об изменении которых сообщается в текущей версии:
application_name
is_superuser
client_encoding
scram_iterations
DateStyle
server_encoding
default_transaction_read_only
server_version
in_hot_standby
session_authorization
integer_datetimes
standard_conforming_strings
IntervalStyle
TimeZone
(
server_encoding
,TimeZone
иinteger_datetimes
не отслеживались до версии 8.0;standard_conforming_strings
не отслеживался до 8.1;IntervalStyle
— до версии 8.4;application_name
— до версии 9.0;default_transaction_read_only
иin_hot_standby
— до версии 14;scram_iterations
— до версии 16.) Обратите внимание, чтоserver_version
,server_encoding
иinteger_datetimes
не могут меняться после запуска сервера.Если для
standard_conforming_strings
не передано никакого значения, то приложения могут принять его равнымoff
. Это означает, что символы обратной косой черты в строковых литералах интерпретируются в качестве спецсимволов. Также, наличие этого параметра может рассматриваться как указание на то, что синтаксис escape-строк (E'...'
) является приемлемым.Хотя возвращаемый указатель объявлен со спецификатором
const
, фактически он указывает на изменяемое хранилище, связанное со структуройPGconn
. Не стоит рассчитывать на то, что указатель останется действительным при последующих запросах.PQprotocolVersion
#Запрашивает протокол, используемый между клиентом и сервером.
int PQprotocolVersion(const PGconn *conn);
Приложения могут использовать эту функцию, чтобы определить, поддерживаются ли опредёленные функциональные возможности. В настоящее время возможными значениями являются 3 (протокол версии 3.0) или ноль (проблемы в подключении). Версия протокола не будет изменяться после завершения процедуры подключения, но теоретически она могла бы измениться в процессе переподключения. Версия протокола 3.0 обычно используется при взаимодействии с серверами PostgreSQL версии 7.4 или более поздними.
PQserverVersion
#Возвращает целочисленное представление версии сервера.
int PQserverVersion(const PGconn *conn);
Приложения могут использовать эту функцию, чтобы определить версию сервера баз данных, к которому они подключены. Возвращаемое ей число получается в результате умножения номера основной версии на 10000 и добавления номера дополнительной версии. Например, для версии 10.1 будет выдано число 100001, а для версии 11.0 — 110000. Если соединение не работает, то возвращается ноль.
До версии 10 в PostgreSQL номера версий образовывались из трёх чисел, первые два из которых представляли основную версию. Для таких версий
PQserverVersion
отводит на каждое число по две цифры; например, для версии 9.1.5 будет выдано 90105, а для версии 9.2.0 — 90200.Таким образом, чтобы получить логический номер основной версии для определения доступности функциональности, приложения должны разделить результат
PQserverVersion
на 100, а не на 10000. Во всех сериях номера дополнительных (корректирующих) выпусков различаются только в двух последних цифрах.PQerrorMessage
#Возвращает сообщение об ошибке, наиболее недавно сгенерированное операцией, выполненной в рамках текущего подключения.
char *PQerrorMessage(const PGconn *conn);
Почти все функции библиотеки libpq в случае сбоя сформируют сообщение для
PQerrorMessage
. Обратите внимание, что по соглашениям, принятым в libpq, непустой результат функцииPQerrorMessage
может состоять из нескольких строк и будет включать завершающий символ новой строки. Вызывающая функция не должна освобождать память, на которую указывает возвращаемое значение, напрямую. Она будет освобождена, когда связанный с ней дескрипторPGconn
будет передан функцииPQfinish
. Не стоит ожидать, что результирующая строка останется той же самой при выполнении нескольких операций со структуройPGconn
.PQsocket
#Получает номер файлового дескриптора для сокета соединения с сервером. Действительный дескриптор будет больше или равен 0; значение -1 показывает, что в данный момент не открыто ни одного соединения с сервером. (Значение не изменится во время обычной работы, но может измениться во время установки или переустановки подключения.)
int PQsocket(const PGconn *conn);
PQbackendPID
#Возвращает ID (PID) серверного процесса, обрабатывающего это подключение.
int PQbackendPID(const PGconn *conn);
PID серверного процесса полезен для отладочных целей и для сопоставления с сообщениями команды
NOTIFY
(которые включают PID уведомляющего серверного процесса). Примите к сведению, что PID принадлежит процессу, выполняющемуся на узле сервера баз данных, а не на локальном узле.PQconnectionNeedsPassword
#Возвращает true (1), если метод аутентификации соединения требовал пароля, однако он не был предоставлен. Возвращает false (0), если пароль не требовался.
int PQconnectionNeedsPassword(const PGconn *conn);
Эту функцию можно применить после неудачной попытки подключения, чтобы решить, нужно ли предлагать пользователю ввести пароль.
PQconnectionUsedPassword
#Возвращает true (1), если метод аутентификации соединения использовал пароль. Возвращает false (0) в противном случае.
int PQconnectionUsedPassword(const PGconn *conn);
Эту функцию можно применить как после неудачной, так и после успешной попытки подключения, чтобы определить, требовал ли сервер предоставления пароля.
PQconnectionUsedGSSAPI
#Возвращает true (1), если метод аутентификации соединения использовал GSSAPI. Возвращает false (0) в противном случае.
int PQconnectionUsedGSSAPI(const PGconn *conn);
Эту функцию можно применить, чтобы определить, использовалась ли для подключения аутентификация GSSAPI.
Следующие функции возвращают информацию, относящуюся к SSL. Эта информация обычно не меняется после того, как подключение установлено.
PQsslInUse
#Возвращает true (1), если для текущего подключения используется SSL, и false (0) в противном случае.
int PQsslInUse(const PGconn *conn);
PQsslAttribute
#Возвращает связанную с SSL информацию о соединении.
const char *PQsslAttribute(const PGconn *conn, const char *attribute_name);
Список доступных атрибутов зависит от используемой библиотеки SSL и типа подключения. Если подключение не использует SSL или указанное имя атрибута неизвестно используемой библиотеке, возвращается NULL.
Обычно доступны следующие атрибуты:
library
Имя используемой реализации SSL. (В настоящее время поддерживается только
"OpenSSL"
)protocol
Применяемая версия SSL/TLS. Наиболее распространены варианты
"TLSv1"
,"TLSv1.1"
и"TLSv1.2"
, но реализация может возвращать и другие строки, если применяется какой-то другой протокол.key_bits
Число бит в ключе, используемом алгоритмом шифрования.
cipher
Краткое имя применяемого комплекта шифров, например:
"DHE-RSA-DES-CBC3-SHA"
. Эти имена могут быть разными в разных реализациях SSL.compression
Возвращает
on
, если используется сжатие SSL, илиoff
в противном случае.
В качестве исключения можно запросить атрибут
library
без подключения, передав NULL в качестве аргументаconn
. В результате будет выдано имя используемой по умолчанию библиотеки SSL, либо NULL, если библиотека libpq была скомпилирована без поддержки SSL. (В версиях PostgreSQL ниже 15, когда вconn
передавался NULL, результатом всегда был NULL. Отличить новую реализацию от старой в клиентских программах можно, проверив макросLIBPQ_HAS_SSL_LIBRARY_DETECTION
.)PQsslAttributeNames
#Возвращает массив имён доступных атрибутов SSL, которые могут использоваться в
PQsslAttribute()
. Завершается массив указателем NULL.const char * const * PQsslAttributeNames(const PGconn *conn);
Если
conn
равен NULL, возвращаются атрибуты, доступные для библиотеки SSL по умолчанию, или пустой список, если библиотека libpq была скомпилирована без поддержки SSL. При значенииconn
, отличном от NULL, возвращаются атрибуты, доступные для библиотеки SSL, используемой для соединения, или пустой список, если соединение не зашифровано.PQsslStruct
#Возвращает указатель на специфичный для реализации SSL объект, описывающий подключение. Если соединение не зашифровано или реализация SSL, используемая для подключения, не поддерживает запрошенный тип объекта, возвращается NULL.
void *PQsslStruct(const PGconn *conn, const char *struct_name);
Какие структуры можно получить, зависит от используемой реализации SSL. OpenSSL предоставляет одну структуру с именем
OpenSSL
и возвращает указатель на объектSSL
struct, описанный в OpenSSL. Для написания вызова этой функции можно воспользоваться кодом в следующих строках:#include <libpq-fe.h> #include <openssl/ssl.h> ... SSL *ssl; dbconn = PQconnectdb(...); ... ssl = PQsslStruct(dbconn, "OpenSSL"); if (ssl) { /* use OpenSSL functions to access ssl */ }
Эта структура может использоваться, чтобы сличить уровни шифрования, проверить сертификаты сервера и т. д. За информацией об этой структуре обратитесь к документации по OpenSSL.
PQgetssl
#Возвращает структуру SSL, использовавшуюся в соединении, или NULL, если SSL не используется.
void *PQgetssl(const PGconn *conn);
Эта функция равнозначна
PQsslStruct(conn, "OpenSSL")
. Её не следует применять в новых приложениях, так как возвращаемая структура специфична для OpenSSL и её нельзя будет получить с другой реализацией SSL. Чтобы проверить, использует ли подключение SSL, лучше вызватьPQsslInUse
, а чтобы получить свойства подключения —PQsslAttribute
.
F.3. auto_explain
The auto_explain
module provides a means for logging execution plans of slow statements automatically, without having to run EXPLAIN by hand. This is especially helpful for tracking down un-optimized queries in large applications.
The module provides no SQL-accessible functions. To use it, simply load it into the server. You can load it into an individual session:
LOAD 'auto_explain';
(You must be superuser to do that.) More typical usage is to preload it into some or all sessions by including auto_explain
in session_preload_libraries or shared_preload_libraries in postgresql.conf
. Then you can track unexpectedly slow queries no matter when they happen. Of course there is a price in overhead for that.
F.3.1. Configuration Parameters
There are several configuration parameters that control the behavior of auto_explain
. Note that the default behavior is to do nothing, so you must set at least auto_explain.log_min_duration
if you want any results.
-
auto_explain.log_min_duration
(integer
) auto_explain.log_min_duration
is the minimum statement execution time, in milliseconds, that will cause the statement's plan to be logged. Setting this to zero logs all plans. Minus-one (the default) disables logging of plans. For example, if you set it to250ms
then all statements that run 250ms or longer will be logged. Only superusers can change this setting.-
auto_explain.log_analyze
(boolean
) auto_explain.log_analyze
causesEXPLAIN ANALYZE
output, rather than justEXPLAIN
output, to be printed when an execution plan is logged. This parameter is off by default. Only superusers can change this setting.Note
When this parameter is on, per-plan-node timing occurs for all statements executed, whether or not they run long enough to actually get logged. This can have an extremely negative impact on performance. Turning off
auto_explain.log_timing
ameliorates the performance cost, at the price of obtaining less information.-
auto_explain.log_buffers
(boolean
) auto_explain.log_buffers
controls whether buffer usage statistics are printed when an execution plan is logged; it's equivalent to theBUFFERS
option ofEXPLAIN
. This parameter has no effect unlessauto_explain.log_analyze
is enabled. This parameter is off by default. Only superusers can change this setting.-
auto_explain.log_timing
(boolean
) auto_explain.log_timing
controls whether per-node timing information is printed when an execution plan is logged; it's equivalent to theTIMING
option ofEXPLAIN
. The overhead of repeatedly reading the system clock can slow down queries significantly on some systems, so it may be useful to set this parameter to off when only actual row counts, and not exact times, are needed. This parameter has no effect unlessauto_explain.log_analyze
is enabled. This parameter is on by default. Only superusers can change this setting.-
auto_explain.log_triggers
(boolean
) auto_explain.log_triggers
causes trigger execution statistics to be included when an execution plan is logged. This parameter has no effect unlessauto_explain.log_analyze
is enabled. This parameter is off by default. Only superusers can change this setting.-
auto_explain.log_verbose
(boolean
) auto_explain.log_verbose
controls whether verbose details are printed when an execution plan is logged; it's equivalent to theVERBOSE
option ofEXPLAIN
. This parameter is off by default. Only superusers can change this setting.-
auto_explain.log_format
(enum
) auto_explain.log_format
selects theEXPLAIN
output format to be used. The allowed values aretext
,xml
,json
, andyaml
. The default is text. Only superusers can change this setting.-
auto_explain.log_nested_statements
(boolean
) auto_explain.log_nested_statements
causes nested statements (statements executed inside a function) to be considered for logging. When it is off, only top-level query plans are logged. This parameter is off by default. Only superusers can change this setting.
In ordinary usage, these parameters are set in postgresql.conf
, although superusers can alter them on-the-fly within their own sessions. Typical usage might be:
# postgresql.conf session_preload_libraries = 'auto_explain' auto_explain.log_min_duration = '3s'
F.3.2. Example
postgres=# LOAD 'auto_explain'; postgres=# SET auto_explain.log_min_duration = 0; postgres=# SET auto_explain.log_analyze = true; postgres=# SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique;
This might produce log output such as:
LOG: duration: 3.651 ms plan: Query Text: SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; Aggregate (cost=16.79..16.80 rows=1 width=0) (actual time=3.626..3.627 rows=1 loops=1) -> Hash Join (cost=4.17..16.55 rows=92 width=0) (actual time=3.349..3.594 rows=92 loops=1) Hash Cond: (pg_class.oid = pg_index.indrelid) -> Seq Scan on pg_class (cost=0.00..9.55 rows=255 width=4) (actual time=0.016..0.140 rows=255 loops=1) -> Hash (cost=3.02..3.02 rows=92 width=4) (actual time=3.238..3.238 rows=92 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 4kB -> Seq Scan on pg_index (cost=0.00..3.02 rows=92 width=4) (actual time=0.008..3.187 rows=92 loops=1) Filter: indisunique
F.3.3. Author
Takahiro Itagaki <itagaki.takahiro@oss.ntt.co.jp>