Tabla de anulación de registros de PostgreSQL

Las tablas no registradas en Postgresql son una forma de evitar que tablas específicas generen información WAL (registro de escritura anticipada) agregando la palabra clave unlogged al comando de creación de tabla:

CREATE UNLOGGED TABLE testtable  (id int);

Cambie la tabla existente a una tabla sin marcar, luego vuelva a cambiar:

ALTER TABLE t1  SET UNLOGGED;   
ALTER TABLE t1  SET LOGGED;  

El uso de tablas UNLOGGED tiene los siguientes beneficios:

  • La cantidad de registros de wal se reduce, lo que ahorra archivos de registro de rehacer, ahorra una cierta cantidad de espacio y reduce la carga de trabajo de la copia de seguridad de wal.

  • El impacto del vacío se reduce, porque la acción del vacío también será escrita por el registro de pared.

  • Se ha mejorado la creación en paralelo de tablas grandes.

Desventajas de usar tablas UNLOGGED:

  • Las tablas se truncan en la conmutación por recuperación.

  • Las tablas que usan UNLOGGED solo son accesibles en el servidor maestro, no en las réplicas.

  • Las tablas que usan UNLOGGED no se pueden usar para la replicación lógica o la copia de seguridad física.

Luego, verifique que la tabla no registrada en Postgres no genere WAL y que la velocidad de actualización sea más rápida.

Primero, use la utilidad pgbench para crear una tabla de prueba, luego realice algunas actualizaciones. No solo veremos cuánto tiempo tomó la actualización, sino que también miraremos dentro del directorio pg_wal y veremos cuánto wal se creó. Para esta prueba, es importante desactivar el vacío automático y asegurarse de que no haya otros clientes conectados a la instancia.

# Ensure that autovacuum is (temporarily!) disabled:
$ psql -c 'alter system set autovacuum=off' -c 'select pg_reload_conf()'

# Generate a table with one million rows:
$ pgbench -i -s 10
dropping old tables...
creating tables...
generating data (client-side)...
1000000 of 1000000 tuples (100%) done (elapsed 1.25 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done in 3.60 s (drop tables 0.04 s, create tables 0.01 s,
  client-side generate 1.28 s, vacuum 1.81 s, primary keys 0.48 s).

## Update one million rows:
$ touch gregtest; time psql -c 'update pgbench_accounts set aid=aid'
UPDATE 1000000

real    0m5.592s
user    0m0.002s
sys     0m0.000s

## Determine how much WAL was generated by the above comamnd:
$ DD=$(psql -Atc 'show data_directory')
$ find $DD/pg_wal -newer gregtest -size 16M | wc -l | xargs echo 16* | bc
320

Use la herramienta de banco para admitir la especificación --unloged en tiempo de ejecución para crear tablas no registradas. Los demás pasos son iguales.

## pgbench can directly create its tables as unlogged:
$ pgbench -i -s 10 --unlogged
dropping old tables...
creating tables...
generating data (client-side)...
1000000 of 1000000 tuples (100%) done (elapsed 0.73 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done in 1.56 s (drop tables 0.03 s, create tables 0.03 s, client-side generate 0.80 s, vacuum 0.15 s, primary keys 0.20 s).

$ touch gregtest; time psql -c 'update pgbench_accounts set aid=aid'
UPDATE 1000000

real    0m3.173s
user    0m0.002s
sys     0m0.000s

$ find $DD/pg_wal -newer gregtest -size 16M | wc -l | xargs echo 16* | bc
16

Se puede ver que no solo la actualización se realiza el doble de rápido que antes, ¡sino que el tiempo de creación de la tabla y la cantidad de WAL generada también se han acortado!

Luego use la herramienta de banco para ejecutar durante 10 segundos, y puede encontrar que la diferencia en la cantidad de transacciones también es enorme.

$ pgbench -i -s 10
$ pgbench --time 10
pgbench (15.1)
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 10
query mode: simple
number of clients: 1
number of threads: 1
maximum number of tries: 1
duration: 10 s
number of transactions actually processed: 1680
number of failed transactions: 0 (0.000%)
latency average = 5.949 ms
initial connection time = 7.761 ms
tps = 168.087557 (without initial connection time)

tabla no registrada:

$ pgbench -i -s 10 --unlogged
$ pgbench -T 10
pgbench (15.1)
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 10
query mode: simple
number of clients: 1
number of threads: 1
maximum number of tries: 1
duration: 10 s
number of transactions actually processed: 4857
number of failed transactions: 0 (0.000%)
latency average = 2.059 ms
initial connection time = 2.522 ms
tps = 485.706168 (without initial connection time)

Aunque el rendimiento ha mejorado mucho, las tablas no registradas también tienen problemas ocultos:

las tablas no registradas en Postgres no son persistentes

Los datos en tablas no registradas son de corta duración y están fuera de la estricta protección de datos que normalmente proporciona Postgres. Por lo tanto, cuando el servidor se apaga de manera anormal, la tabla no registrada no se puede recuperar normalmente, porque los datos de wal no se registran, por lo que no se puede garantizar la integridad de los datos, por lo que la tabla se truncará aproximadamente. Tenga en cuenta que un simple reinicio no truncará la tabla:

$ pgbench -i -s 10 --unlogged
$ psql -Atc 'select count(*) from pgbench_accounts'
1000000

$ pg_ctl -D data restart
waiting for server to shut down.... done
server stopped
...
server started

$ psql -Atc 'select count(*) from pgbench_accounts'
1000000

Las tablas no registradas en Postgres no admiten la replicación de secuencias

Las tablas no registradas no se pueden replicar porque la replicación de transmisión (y el trasvase de registros para archivos WAL) usa la información del archivo WAL para actualizar las réplicas. Existen en la réplica, pero están vacíos e inaccesibles.

La tabla no registrada en Postgres no admite la copia de seguridad

Herramientas como pgBackRest excluyen las tablas temporales y no registradas de las copias de seguridad.

$ psql -c 'create table aaa as select 867 as id from generate_series(5,309)'
$ psql -c 'create unlogged table bbb as select 867 as id from generate_series(5,309)'
$ psql -c 'vacuum aaa, bbb'
$ AAA=$( psql -Atc "select pg_relation_filenode('aaa')" ) ## gives 980808
$ BBB=$( psql -Atc "select pg_relation_filenode('bbb')" ) ## gives 980811
$ pgbackrest --stanza=mydemo backup

$ grep -E "$AAA|$BBB" /var/log/pgbackrest/mydemo-backup.log | cut -d\( -f1 | sort -k7

2023-12-25 13:09:37.482 P02 DETAIL: backup file /home/greg/pg/15/data_replica/base/5/980808
2023-12-25 13:09:34.492 P02 DETAIL: backup file /home/greg/pg/15/data_replica/base/5/980808_fsm
2023-12-25 13:09:37.479 P02 DETAIL: backup file /home/greg/pg/15/data_replica/base/5/980808_vm
2023-12-25 13:09:40.658 P02 DETAIL: backup file /home/greg/pg/15/data_replica/base/5/980811_init

Finalmente, es más económico convertir de una tabla registrada a una tabla no registrada, tomando como ejemplo el banco:

$ pgbench -i -s 20
$ time psql -c 'alter table pgbench_accounts set unlogged'
ALTER TABLE

real    0m1.754s
user    0m0.000s
sys     0m0.004s

Pero viceversa costará mucho.

$ pgbench -i -s 10 --unlogged
$ time psql -c 'alter table pgbench_accounts set logged'
ALTER TABLE

real    0m16.601s
user    0m0.004s
sys     0m0.000s

Supongo que te gusta

Origin blog.csdn.net/hezhou876887962/article/details/129570226
Recomendado
Clasificación