Aportado por Massimo Dal Zotto |
El fichero opcional data/pg_options contiene opciones de tiempo de ejecución utilizadas por el servidor para controlar los mensajes de seguimiento y otros parámetros ajustables de servidor. Lo que hace a este fichero interesante es el hecho de que es re-leido por un servidor qeu recibe una señal SIGHUP, haciendo así posible cambiar opciones de tiempo de ejecución sobre la marcha sin necesidad de rearrancar Postgres. Las opciones especificadas en este fichero pueden ser banderas de debugging utilizadas por el paquete de seguimiento (backend/utils/misc/trace.c) o parámetros numéricos que pueden ser usados por el servidor para controlar su comportamiento. Las nuevas opciones y parámetros deben ser definidos en backend/utils/misc/trace.c y backend/include/utils/trace.h.
Por ejemplo, supongamos que queremos añadir mensajes de seguimiento condicional y un parámetro numérico ajustable al código en el fichero foo.c. Todo lo que necesitamos hacer es añadir la constante TRACE_FOO y OPT_FOO_PARAM en backend/include/utils/trace.h:
/* file trace.h */ enum pg_option_enum { ... TRACE_FOO, /* trace foo functions */ OPT_FOO_PARAM, /* foo tunable parameter */ NUM_PG_OPTIONS /* must be the last item of enum */ }; |
/* file trace.c */ static char *opt_names[] = { ... "foo", /* trace foo functions */ "fooparam" /* foo tunable parameter */ }; |
/* file foo.c */ #include "trace.h" #define foo_param pg_options[OPT_FOO_PARAM] int foo_function(int x, int y) { TPRINTF(TRACE_FOO, "entering foo_function, foo_param=%d", foo_param); if (foo_param > 10) { do_more_foo(x, y); } } |
Los ficheros existentes que utilizan banderas de seguimiento privadas pueden cambiarse simplemente añadiendo el siguiente código:
#include "trace.h" /* int my_own_flag = 0; -- removed */ #define my_own_flag pg_options[OPT_MY_OWN_FLAG] |
Todas las pg_options son inicializadas a cero en el arranque del servidor. Si necesitamos un valor de defecto diferente necesitaremos añadir algún código de inicialización en el principio de PostgresMain. Ahora podemos fijar el parámetro foo_param y activar el seguimiento foo escribiendo valores en el fichero data/pg_options:
# file pg_options .... foo=1 fooparam=17 |
Las nuevas opciones serán leidas por todos los nuevos servidores conforme van arrancando. Para hacer efectivos los cambios para todos los servidores que están en funcionamiento, necesitaremos enviar un SIGHUP al postmaster. La señal será enviada automáticamente a todos los servidores. Podemos activar los cambios también para un servidor específico individual enviandole la señal SIGHUP directamente a él.
Las pg_options pueden también especificarse con el interruptor (switch) -T de Postgres:
postgres options -T "verbose=2,query,hostlookup-" |
Las funciones utilizadas para imprimir los errores y los mensajes de debug pueden hacer uso ahora de la facilidad sislog(2). Los mensajes impresos en stdout y stderr son preformatados con una marca horaria que contiene también la identificación del proceso del servidor:
#timestamp #pid #message 980127.17:52:14.173 [29271] StartTransactionCommand 980127.17:52:14.174 [29271] ProcessUtility: drop table t; 980127.17:52:14.186 [29271] SIIncNumEntries: table is 70% full 980127.17:52:14.186 [29286] Async_NotifyHandler 980127.17:52:14.186 [29286] Waking up sleeping backend process 980127.19:52:14.292 [29286] Async_NotifyFrontEnd 980127.19:52:14.413 [29286] Async_NotifyFrontEnd done 980127.19:52:14.466 [29286] Async_NotifyHandler done |
Este formato incrementa también la capacidad de leer los ficheros de mensajes y permite a las personas el conocimiento exacto de lo que cada servidor está haciendo y en qué momento. También hace más fácil escribir programas con awk o perl que revisen el rastro para detectar errores o problemas en la base de datos, o calcular estadisticas de tiempo de las transacciones.
Los mensajes impresos en el syslog utilizan la facilidad de rastro LOG_LOCAL0. El uso de syslog puede ser controlada con la pg_option syslog. Desgraciadamente, muchas funciones llaman directamente a printf() para imprimir sus mensajes en stdout o stderr y su salida no puede ser redirigida a syslog o tener indicaciones cronológicas en ella. Sería deseable que todas las llamadas a printf fueran reemplazadas con la macro PRINTF y la salida a stderr fuese cambiada para utilizar EPRINTF en su lugar, de modo que podamos controlar todas las salidas de un modo uniforme.
El nuevo mecanismo de las pg_options es más conveniente que definir nuevas opciones de switch en los servidores porque:
No tenemos que definir un switch diferente para cada idea que queramos controlar. Todas las opciones están definidas como palabras claves en un fichero externo almacenado en el directorio de datos.
No tenemos que rearrancar Postgres para cambiar el valor de alguna opción. Normalmente las opciones del servidor se especifican al postmaster y pasados a cada servidor cuando sea arrancado. Ahora son leidos de un fichero.
Podemos cambiar las opciones sobre la marcha mientras el servidor está corriendo. Podemos de este modo investigar algunos problemas activando los mensajes de seguimiento sólo cuando aparece el problema. Podemos también intentar diferentes valores de parámetros ajustables.
# comment option=integer_value # set value for option option # set option = 1 option+ # set option = 1 option- # set option = 0 |
Refierase al capítulo de la Guía del Administrador sobre las opciones de tiempo de ejecución para una lista completa de opciones soportadas actualmente.
Algo del código existente que utiliza variables privadas e interruptores de opciones se han cambiado para hacer uso de las posibilidades de las pg_options, fundamentalmente en postgres.c. Sería deseable modificar todo el codigo existente en este sentido, de modo que podamos hacer uso de muchos de los switches en la línea de comando de Postgres y poder tener más opciones ajustables con un lugar único para situar los valores de las opciones.