|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
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.
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;
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.
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!
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.
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: 0Se 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).
|
||||||||||||||||||||||||||||||||||||||
Comments and Corrections are welcome. Suggestions and contributions of items are also welcome. Send them in!. Copyright A. Elein Mustain 2003, 2004,2005 |