pg_options

Nota

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 */
};
   
y una línea correspondiente en backend/utils/misc/trace.c:
/* file trace.c */
static char *opt_names[] = {
    ...
    "foo",            		/* trace foo functions */
    "fooparam"         		/* foo tunable parameter */
};
   
Las opciones se deben especificar en los dos ficheros exáctamente en el mismo orden. En los ficheros fuente foo podemos ahora hacer referencia a las nuevas banderas con:
/* 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:

El formato de las pg_options es como sigue:
# comment
option=integer_value  # set value for option
option                # set option = 1
option+               # set option = 1
option-               # set option = 0
   
Notese que keyword puede también ser una abreviatura del nombre de opción definida en backend/utils/misc/trace.c.

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.