sql >> Base de Datos >  >> RDS >> PostgreSQL

Mis extensiones favoritas de PostgreSQL:segunda parte

Esta es la segunda parte de mi blog "Mis extensiones de PostgreSQL favoritas", en la que les presenté dos extensiones de PostgreSQL, postgres_fdw y pg_partman. En esta parte exploraré tres más.

auditoríapg

La próxima extensión de interés de PostgreSQL tiene el propósito de satisfacer los requisitos de auditoría de varios organismos de certificación gubernamentales, financieros y de otro tipo, como ISO, BSI y FISCAM, etc. La función de registro estándar que ofrece PostgreSQL de forma nativa with log_statement =all es útil para monitorear, pero no brinda los detalles requeridos para cumplir o enfrentar la auditoría. La extensión pgAudit se enfoca en los detalles de lo que sucedió bajo el capó, mientras una base de datos satisfacía una solicitud de aplicación.

Una función de registro estándar proporcionada por PostgreSQL crea y actualiza una pista de auditoría o un registro de auditoría, que proporciona un registro detallado de auditoría de sesiones y/u objetos. La pista de auditoría creada por pgAudit puede tener un tamaño enorme dependiendo de la configuración de auditoría, por lo que se debe tener cuidado para decidir qué y cuánta auditoría se requiere de antemano. Una breve demostración en la siguiente sección muestra cómo se configura y se pone en uso pgAudit.

El seguimiento del registro se crea dentro del registro del clúster de la base de datos PostgreSQL que se encuentra en la ubicación PGDATA/log, pero los mensajes del registro de auditoría tienen el prefijo "AUDIT:" para distinguir entre los mensajes regulares de fondo de la base de datos y el registro de auditoría. registros.

Demostración

La documentación oficial de pgAudit explica que existe una versión separada de pgAudit para cada versión principal de PostgreSQL con el fin de admitir la nueva funcionalidad introducida en cada versión de PostgreSQL. La versión de PostgreSQL en esta demostración es la 11, por lo que la versión de pgAudit será de la rama 1.3.X. El pgaudit.log es el parámetro fundamental a configurar que controla qué clases de declaraciones se registrarán. Se puede configurar con un SET para un nivel de sesión o dentro del archivo postgresql.conf para que se aplique globalmente.

postgres=# set pgaudit.log = 'read, write, role, ddl, misc';

SET



cat $PGDATA/pgaudit.log

pgaudit.log = 'read, write, role, ddl, misc'



db_replica=# show pgaudit.log;

         pgaudit.log

------------------------------

 read, write, role, ddl, misc

(1 row)



2020-01-29 22:51:49.289 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,3,1,MISC,SHOW,,,show pgaudit.log;,<not logged>



db_replica=# create table t1 (f1 integer, f2 varchar);

CREATE TABLE



2020-01-29 22:52:08.327 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,4,1,DDL,CREATE TABLE,,,"create table t1 (f1 integer, f2 varchar);",<not logged>



db_replica=#  insert into t1 values (1,'one');

INSERT 0 1

db_replica=#  insert into t1 values (2,'two');

INSERT 0 1

db_replica=#  insert into t1 values (3,'three');

INSERT 0 1

2020-01-29 22:52:19.261 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,5,1,WRITE,INSERT,,,"insert into t1 values (1,'one');",<not logged>

20-01-29 22:52:38.145 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,6,1,WRITE,INSERT,,,"insert into t1 values (2,'two');",<not logged>

2020-01-29 22:52:44.988 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,7,1,WRITE,INSERT,,,"insert into t1 values (3,'three');",<not logged>



db_replica=# select * from t1 where f1 >= 2;

 f1 |  f2

----+-------

  2 | two

  3 | three

(2 rows)



2020-01-29 22:53:09.161 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,9,1,READ,SELECT,,,select * from t1 where f1 >= 2;,<not logged>



db_replica=# grant select on t1 to usr_replica;

GRANT



2020-01-29 22:54:25.283 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,13,1,ROLE,GRANT,,,grant select on t1 to usr_replica;,<not logged>



db_replica=# alter table t1 add f3 date;

ALTER TABLE



2020-01-29 22:55:17.440 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,23,1,DDL,ALTER TABLE,,,alter table t1 add f3 date;,<not logged>



db_replica=# checkpoint;

CHECKPOINT



2020-01-29 22:55:50.349 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,33,1,MISC,CHECKPOINT,,,checkpoint;,<not logged>



db_replica=# vacuum t1;

VACUUM



2020-01-29 22:56:03.007 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,34,1,MISC,VACUUM,,,vacuum t1;,<not logged>



db_replica=# show log_statement;

 log_statement

---------------

 none



2020-01-29 22:56:14.740 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,36,1,MISC,SHOW,,,show log_statement;,<not logged>

Las entradas de registro, como se muestra en la demostración anterior, solo se escriben en el archivo de registro de fondo del servidor cuando se establece el parámetro log_statement; sin embargo, en este caso no está configurado pero los mensajes de auditoría se escriben en virtud del parámetro pgaudit.log como se muestra en la demostración. Hay opciones más potentes disponibles para cumplir con todos los requisitos de auditoría de su base de datos dentro de PostgreSQL, que se pueden configurar siguiendo la documentación oficial de pgaudit aquí o en el repositorio de github.pg_repack

Esta es una extensión favorita entre muchos ingenieros de PostgreSQL que están directamente involucrados en la administración y el mantenimiento del estado general de un clúster de PostgreSQL. La razón de esto se discutirá un poco más adelante, pero esta extensión ofrece la funcionalidad para eliminar la sobrecarga de la base de datos dentro de una base de datos PostgreSQL, que es una de las preocupaciones persistentes entre los clústeres de bases de datos PostgreSQL muy grandes que requieren una reorganización de la base de datos.

Como una base de datos PostgreSQL se somete a ESCRITURAS constantes y pesadas (actualizaciones y eliminaciones), los datos antiguos se marcan como eliminados mientras se inserta la nueva versión de la fila, pero los datos antiguos en realidad no se borran de un bloque de datos Esto requiere una operación de mantenimiento periódico llamada vaciado, que es un procedimiento automatizado que se ejecuta en segundo plano y borra todas las filas "marcadas como eliminadas". Este proceso a veces se denomina recolección de basura en términos coloquiales.

El proceso de vaciado generalmente da paso a las operaciones de la base de datos durante los momentos de mayor actividad. La forma menos restrictiva de aspirar a favor de las operaciones de la base de datos da como resultado una gran cantidad de filas "marcadas como eliminadas" que hacen que las bases de datos crezcan desproporcionadamente, lo que se conoce como "inflación de la base de datos". Hay un proceso de vaciado contundente llamado VACUUM FULL, pero eso da como resultado la adquisición de un bloqueo exclusivo en el objeto de la base de datos que se está procesando, lo que detiene las operaciones de la base de datos en ese objeto.

pg_reempaquetar

Es por esta razón que pg_repack es un éxito entre los DBA e ingenieros de PostgreSQL, porque hace el trabajo de un proceso normal de limpieza pero ofrece una eficiencia de VACUUM FULL al no adquirir un bloqueo exclusivo en una base de datos. objeto, en resumen, funciona en línea. La documentación oficial aquí explica más sobre los otros métodos para reorganizar una base de datos, pero una demostración rápida como la que se muestra a continuación pondrá las cosas bajo la luz adecuada para una mejor comprensión. Existe el requisito de que la tabla de destino debe tener al menos una columna definida como CLAVE PRINCIPAL, que es una norma general en la mayoría de las configuraciones de bases de datos de producción.

Demostración

La demostración básica muestra la instalación y el uso de pg_repack en un entorno de prueba. Esta demostración utiliza la versión 1.4.5 de pg_repack, que es la última versión de esta extensión al momento de publicar este blog. Una tabla de demostración t1 inicialmente tiene 80000 filas que se someten a una operación masiva de eliminación, que elimina cada quinta fila de la tabla. Una ejecución de pg_repack muestra el tamaño de la tabla antes y después.

mydb=# CREATE EXTENSION pg_repack;

CREATE EXTENSION



mydb=# create table t1 (no integer primary key, f_name VARCHAR(20), l_name VARCHAR(20), d_o_b date);

CREATE TABLE

mydb=# insert into t1 (select generate_series(1,1000000,1),'a'||

mydb(# generate_series(1,1000000,1),'a'||generate_series(1000000,1,-1),

mydb(# cast( now() - '1 year'::interval * random()  as date ));

INSERT 0 1000000



mydb=# SELECT pg_size_pretty( pg_total_relation_size('t1'));

 pg_size_pretty

----------------

 71 MB

(1 row)



mydb=# CREATE or replace FUNCTION delete5() RETURNS void AS $$

mydb$# declare

mydb$# counter integer := 0;

mydb$# BEGIN

mydb$#

mydb$#  while counter <= 1000000

mydb$# loop

mydb$# delete from t1 where no=counter;

mydb$# counter := counter + 5;

mydb$# END LOOP;

mydb$# END;

mydb$# $$ LANGUAGE plpgsql;

CREATE FUNCTION

La función delete5 elimina 200000 filas de la tabla t1 usando un contador que incrementa 5 recuentos

mydb=# select delete5();

 delete5

------



(1 row)

mydb=# SELECT pg_size_pretty( pg_total_relation_size('t1'));

 pg_size_pretty

----------------

 71 MB

(1 row)



$ pg_repack -t t1 -N -n -d mydb -p 5433

INFO: Dry run enabled, not executing repack

INFO: repacking table "public.t1"



$ pg_repack -t t1 -n -d mydb -p 5433

INFO: repacking table "public.t1"



mydb=# SELECT pg_size_pretty( pg_total_relation_size('t1'));

 pg_size_pretty

----------------

 57 MB

(1 row)

Como se muestra arriba, el tamaño original de la tabla no cambia después de ejecutar la función delete5 , lo que muestra que las filas aún existen en la tabla. La ejecución de pg_repack borra las filas "marcadas como eliminadas" de la tabla t1, lo que reduce el tamaño de la tabla t1 a 57 MB. Otra cosa buena de pg_repack es una opción para la ejecución en seco con el indicador -N, mediante el cual puede verificar qué se ejecutará durante una ejecución real.

HipoPG

La próxima extensión interesante es idéntica a un concepto popular llamado índices invisibles entre los servidores de bases de datos propietarios. La extensión HypoPG le permite a un DBA ver el efecto de introducir un índice hipotético (que no existe) y si mejorará el rendimiento de una o más consultas, y de ahí el nombre HypoPG.

La creación de un índice hipotético no requiere ningún recurso de CPU o disco, sin embargo, consume la memoria privada de una conexión. Como el índice hipotético no se almacena en ninguna tabla del catálogo de la base de datos, no hay impacto de la sobrecarga de la tabla. Es por esta razón que no se puede usar un índice hipotético en una instrucción EXPLAIN ANALYZE, mientras que EXPLAIN simple es una buena manera de evaluar si una consulta problemática determinada utilizará un índice potencial. Aquí hay una demostración rápida para explicar cómo funciona HypoPG.

Demostración

Voy a crear una tabla que contenga 100 000 filas usando generate_series y ejecutaré un par de consultas simples para mostrar la diferencia en las estimaciones de costos con y sin índices hipotéticos.

olap=# CREATE EXTENSION hypopg;

CREATE EXTENSION



olap=# CREATE TABLE stock (id integer, line text);

CREATE TABLE



olap=# INSERT INTO stock SELECT i, 'line ' || i FROM generate_series(1, 100000) i;

INSERT 0 100000



olap=# ANALYZE STOCK;

ANALYZE



olap=#  EXPLAIN SELECT line FROM stock WHERE id = 1;

                       QUERY PLAN

---------------------------------------------------------

 Seq Scan on stock  (cost=0.00..1791.00 rows=1 width=10)

   Filter: (id = 1)

(2 rows)

olap=# SELECT * FROM hypopg_create_index('CREATE INDEX ON stock (id)') ;

 indexrelid |       indexname

------------+-----------------------

      25398 | <25398>btree_stock_id

(1 row)



olap=# EXPLAIN SELECT line FROM stock WHERE id = 1;

                                     QUERY PLAN

------------------------------------------------------------------------------------

 Index Scan using <25398>btree_stock_id on stock  (cost=0.04..8.06 rows=1 width=10)

   Index Cond: (id = 1)

(2 rows)



olap=# EXPLAIN ANALYZE SELECT line FROM stock WHERE id = 1;

                                             QUERY PLAN

----------------------------------------------------------------------------------------------------

 Seq Scan on stock  (cost=0.00..1791.00 rows=1 width=10) (actual time=0.028..41.877 rows=1 loops=1)

   Filter: (id = 1)

   Rows Removed by Filter: 99999

 Planning time: 0.057 ms

 Execution time: 41.902 ms

(5 rows)



olap=# SELECT indexname, pg_size_pretty(hypopg_relation_size(indexrelid))

olap-#   FROM hypopg_list_indexes() ;

       indexname       | pg_size_pretty

-----------------------+----------------

 <25398>btree_stock_id | 2544 kB

(1 row)



olap=# SELECT pg_size_pretty(pg_relation_size('stock'));

 pg_size_pretty

----------------

 4328 kB

(1 row)

La exposición anterior muestra cómo se puede reducir el costo total estimado de 1791 a 8,06 agregando un índice al campo "id" de la tabla para optimizar una consulta simple. También prueba que el índice no se usa realmente cuando la consulta se ejecuta con un EXPLAIN ANALYZE que ejecuta la consulta en tiempo real. También hay una forma de averiguar aproximadamente cuánto espacio en disco ocupa el índice utilizando la función hypopg_list_indexes de la extensión.

El HypoPG tiene algunas otras funciones para administrar índices hipotéticos y, además de eso, también ofrece una forma de averiguar si la partición de una tabla mejorará el rendimiento de las consultas que obtienen un gran conjunto de datos. Hay una opción de partición hipotética de la extensión HypoPG y se puede seguir más consultando la documentación oficial.

Conclusión

Como se indicó en la primera parte, PostgreSQL ha evolucionado a lo largo de los años para volverse más grande, mejor y más rápido con un rápido desarrollo tanto en el código fuente nativo como en las extensiones plug and play. Una versión de código abierto del nuevo PostgreSQL puede ser más adecuada para muchas tiendas de TI que ejecutan uno de los principales servidores de bases de datos propietarios, con el fin de reducir su CAPEX y OPEX de TI.

Hay muchas extensiones de PostgreSQL que ofrecen características que van desde el monitoreo hasta la alta disponibilidad y desde el escalado hasta el volcado de archivos de datos binarios en un formato legible por humanos. Se espera que las demostraciones anteriores hayan arrojado mucha luz sobre el máximo potencial y potencia de una base de datos PostgreSQL.