varlena
varlena
PostgreSQL Training,
Consulting & Support
General Bits
By A. Elein Mustain


27-Oct-2003 Edición: 49

Archives | General Tidbits | Google General Bits | Docs | Castellano | Português | Subscriptions | Notifications

General Bits General Bits es una publicación periódica escrita con información desde la lista de PostgreSQL, pgsql-general.
Para saber más sobre pgsql-general y PostgreSQL, visite www.PostgreSQL.org.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Llevando la cuenta de la cantidad de filas
[GENERAL] create triggers 20-Oct-2003

Se necesita un trigger para actualizar la cantidad de filas en una tabla, la cual es importante para la aplicación. count(*) es, por naturaleza, demasiado lento.

La manera de implementar un contador de filas correcto es a través de un trigger en la tabla que necesita ser contabilizada. El trigger incrementará o decrementará el contador en insert o delete.

Hay algunos detalles interesantes respecto de la implementación del conteo de filas. El primero es que la función de conteo pueda funcionar tanto para inserciones y eliminaciones y con cualquier tabla, usando la información disponible a través del mecanismo de triggers en plpgsql. El segundo es la inicialización de la tabla de cuentas.

Suponga que tiene la tabla mitabla y que define la tabla cuenta_filas para almacenar el conteo de varias tablas.

	CREATE TABLE mitabla (
		nombre  text NOT NULL,
		descripcion text,
		PRIMARY KEY (nombre));

	CREATE TABLE cuenta_filas (
		nombre_tabla  text NOT NULL,
		filas_totales  bigint,
		PRIMARY KEY (nombre_tabla));

Muchas personas están familiarizadas con el uso de las variables OLD y NEW en funciones de triggers, pero hay unas cuantas variables informacionales disponibles.

NombreSignificado
TG_NAMENombre del trigger
TG_WHENBEFORE o AFTER
TG_LEVELROW o STATEMENT
TG_OPINSERT, UPDATE o DELETE
TG_RELIDOID de la tabla donde está definido el trigger
TG_RELNAMENombre de la tabla donde está definido el trigger
TG_NARGSNúmero de argumentos en la fila que se está actualizando
TG_ARGV[]Arreglo de texto con los tipos de dato de la fila
Tenga presente que los triggers por cada sentencia (statement) están disponibles sólo a partir de 7.4.

La función de trigger cuenta_filas() usa TG_OP y TG_RELNAME. TG_OP indica si la operación es un DELETE o un INSERT, y TG_RELNAME se usa para almacenar la cuenta en la tabla cuenta_filas según el nombre de la tabla. La definición de esta función es:

	CREATE OR REPLACE FUNCTION cuenta_filas()
	RETURNS TRIGGER AS
	'
	   BEGIN
	      IF TG_OP = ''INSERT'' THEN
	         UPDATE cuenta_filas
	            SET filas_totales = filas_totales + 1
	            WHERE nombre_tabla = TG_RELNAME;
	      ELSIF TG_OP = ''DELETE'' THEN
	         UPDATE cuenta_filas
	            SET filas_totales = filas_totales - 1
	            WHERE nombre_tabla = TG_RELNAME;
	      END IF;
	      RETURN NULL;
	   END;
	' LANGUAGE plpgsql;

Hay varias maneras en las que las variables TG pueden usarse para escribir triggers genéricos. Pueden tomarse distintos cursos de acción basados en la definición exacta del trigger. Los datos en la fila modificada se pueden encontrar en las variables NEW y OLD, y se pueden obtener sus tipos de datos si fuera necesario tomar distintas acciones basándose en el tipo de dato.

Ahora veremos lo que se necesita para inicializar el trigger. Si la función de trigger y las tablas se definen en la misma transacción, entonces no es necesario inicializar. Sin embargo, en la mayoría de los casos la funcionalidad de conteo de filas se agregará a una tabla existente, y por lo tanto debe definirse el conteo inicial.

La inicialización debe hacerse en una sola transacción. La tabla objetivo debe estar bloqueada para impedir actualizaciones durante esta inicialización; luego se crea el trigger y la cuenta de filas se inicializa con el conteo real, tomado desde la tabla. Una vez que la transacción de inicialización se compromete, el contador está operacional. ¡No olvide verificar que funciona correctamente!

	BEGIN;
	   -- Asegúrese que no se pueden agregar filas hasta que esté
	   -- completo
	   LOCK TABLE mitabla IN SHARE ROW EXCLUSIVE MODE;
	
	   create TRIGGER cuenta_filas
	      AFTER INSERT OR DELETE on mitabla
	      FOR EACH ROW EXECUTE PROCEDURE cuenta_filas();

	   -- Inicializar el contador
	   DELETE FROM cuenta_filas WHERE nombre_tabla = 'mitabla';

	   INSERT INTO cuenta_filas (nombre_tabla, filas_totales)
	   VALUES  ('mitabla',  (SELECT COUNT(*) FROM mitabla));

	COMMIT;

	--
	-- Verificación
	--
	insert into mitabla values ('abaco','matematicas');
	insert into mitabla values ('abeja','insecto');
	select * from rowcount;
	insert into mitabla values ('perro','mascota');
	insert into mitabla values ('catedral','construccion');
	select * from cuenta_filas;
	select * from mitabla;
	delete from mitabla where name='abaco';
	select * from cuenta_filas;
	select * from mitabla;

Contribuyeron: Ling Xiaoyu cdu_lx at yahoo.com Oliver Elphick olly at lfix.co.uk elein at varlena.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Breve Descripción de los Mecanismos de ErServer
eRServer 23-Oct-2003

Andrew Sullivan ha escrito una buena guía de los mecanismos de eRServer. Esto no es un COMO (How-to), sino una descripción de lo que ocurre cuando el servidor está correctamente configurado.

Es una guía muy útil para comprender los mecanismos de la solución de replicación, de modo de poder utilizarlo de la manera más beneficiosa posible.

La guía puede ser accedida a través de Tidbits o directamente.

Contribuyó: andrew at libertyrms.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

7.4 Beta 5
[GENERAL] PostgreSQL v7.4 Beta5 Available for Testing 22-Oct-2003

El Beta 5 de PostgreSQL v7.4 ha sido liberado. Se invita a todas las personas que estén evaluando las versiones de prueba a probar esta nueva versión. Hay paquetes Debian en la sección experimental del archivo Debian.

NOTA Esta versión requiere initdb.

La decisión de sacar Beta 5 se tomó debido a las correcciones de errores que requirieron initdb. Cuando ocurren cambios de esa naturaleza, no es razonable liberar una versión sin un ciclo beta.

¡Esperamos ansiosamente las nuevas características y documentación que estarán disponibles en RC1!

Contribuyó: Marc G. Fournier scrappy at postgresql.org

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Informes de ports para 7.4
[HACKERS] Call for port reports 25-Oct-2003

En las últimas 24 horas, cerca de 22 plataformas han sido certificadas con PostgreSQL v7.4. La lista actualizada está disponible en el sitio de Bruce.

Bruce y Peter Eisentraut definieron y corrigieron problemas muy rápidamente, y varios otros ayudaron a acelerar este proceso, así como la gente involucrada en construir y verificar las pruebas de regresión en sus plataformas.

Conociendo la magnitud del esfuerzo que esto toma en un ambiente comercial, estoy muy impresionada con la cooperación, rapidez y buena voluntad involucrada en este proceso.

Contribuyeron: Bruce Momjian pgman at candle.pha.pa.us, Adam Witney awitney at sghms.ac.uk, Peter Eisentraut peter_e at gmx.net, Marko Karppinen marko at karppinen.fi, Larry Rosenman ler at lerctr.org, Kevin Brown kevin at sysexperts.com, Rod Taylor rbt at rbt.ca, Robert Treat xzilla at users.sourceforge.net, Christopher Browne cbbrowne at libertyrms.info, Alvaro Herrera alvherre at dcc.uchile.cl, Kurt Roeckx Q at ping.be, Noèl Köthe noel at debian.org, Hans-Jürgen Schönig hs at cybertec.at, Dave Page dpage at vale-housing.co.uk, Andrew Dunstan andrew at dunslane.net, Johan Henselmans johan at netsense.nl

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Afinamiento de entrada/salida en Linux para VACUUM
[GENERAL] VACUUM degrades performance significantly. Database 15-Oct-2003

Una discusión sobre degradación de la velocidad de las consultas durante VACUUM dio pie a una solución de afinamiento de Linux. Es común que las consultas se ralenticen durante vacuum; sin embargo, el caso en particular mostraba un retardo excesivo. Las mediciones iniciales mostraron que una consulta que normalmente se ejecuta en 25.52 milisegundos tomaba 2290.22 milisegundos durante vacuum.

El análisis inicial se centró en velocidad de CPU; sin embargo, especulación posterior sugirió que la máquina estaba acotada por el sistema de I/O. Si el sistema está cerca del punto de saturación de I/O, vacuum puede hacerla pasar de este límite.

El uso de discos IDE puede afectar esto. Todos parecen estar de acuerdo en que los discos SCSI se comportan mejor; sin embargo, mucha gente prefiere la opción IDE, más económica.

Se sugirió llevar a cabo un análisis usando vmstat, poniendo particular atención en las columnas bi/bo, para determinar si efectivamente había problemas de I/O.

La solución llevó a la configuración del sistema usando el utilitario de Linux elvtune. Este utilitario permite afinar el algoritmo del ascensor de los discos (disk I/O elevator) en Linux, el cual reordena las peticiones de lectura/escritura a disco de acuerdo a los sectores de disco, con el fin de reducir los movimientos de cabezales. Varias personas reportaron valores muy diferentes de elvtune.

   Instalación RH9.0
   /dev/sda7 elevator ID           5
           read_latency:           64
           write_latency:          8192
           max_bomb_segments:      6

   El valor por omisión en RH 8.0 es:
   /dev/hda1 elevator ID           0
           read_latency:           2048
           write_latency:          8192
           max_bomb_segments:      0 

   En Debian 2.4.23-pre4 es:
   /dev/hdg elevator ID            3
           read_latency:           128
           write_latency:          512
           max_bomb_segments:      0
Se sugirió que max_bomb_segments había sido deshabilitado y que siempre debería ser cero debido a ciertas ineficiencias en el algoritmo ascensor. Sin embargo, no se encontró documentación sobre este cambio.

El campo read_latency cambió entre 2.4.18 y 2.4.20, lo cual explica las diferencias en ese campo entre RH8 y RH9.

   Los valores de 2.4.18 de latencia son:
      read_latency:          8192
      write_latency:        16384

   En 2.4.20 son:
      read_latency:          64
      write_latency:        8192

Un poco de experimentación con la consulta problemática original y diferentes valores de read_latency mostró mejoras a medida que read_latency se disminuía a 64, pero empeoró un poco después de eso:

   elvtune -r 2048 -w 8192 /dev/hdc (estándar Redhat 9):
    Total runtime: 2290.22 msec

   elvtune -r 128 -w 8192 /dev/hdc:
    Total runtime: 450.46 msec

   elvtune -r 64 -w 8192 /dev/hdc:
    Total runtime: 206.14 msec

   elvtune -r 32 -w 8192 /dev/hdc:
    Total runtime: 210.75 msec

   elvtune -r 8 -w 8192 /dev/hdc:
    Total runtime: 338.18 msec

   elvtune -r 1 -w 8192 /dev/hdc:
    Total runtime: 390.55 msec

Hay una explicación muy interesante del algoritmo ascensor en http://strasbourg.linuxfr.org/jl3/features-2.3-1.html (en inglés).

Contribuyeron: Stephen jleelim at xxxxxx.com, Tom Lane tgl at sss.pgh.pa.us, Vivek Khera khera at kcilink.com, Shridhar Daithankar shridhar_daithankar at persistent.co.in, Greg Stark gsstark at mit.edu, Matthew T. O'Connor matthew at zeut.net, Dann Corbit DCorbit at connx.com, Gaetano Mendola mendola at bigfoot.com, Jeff threshar at torgo.978.org, scott.marlowe scott.marlowe at ihs.com


Comments and Corrections are welcome. Suggestions and contributions of items are also welcome. Send them in!.
Copyright A. Elein Mustain 2003, 2004,2005

Google
Search General Bits & varlena.com Search WWW