Según tengo entendido, el hecho de que nuestra consulta esté esperando un bloqueo significa que siempre ha estado esperando un bloqueo y nunca ha cambiado nada.
Correcto: si ve que pg_stat_activity.waiting es "verdadero" para una TABLA DE ALTERACIÓN, eso seguramente significa que está esperando pacientemente el bloqueo ACCESS EXCLUSIVE en su tabla de destino y su verdadero trabajo (reescribiendo la tabla si es necesario, cambiando los catálogos) , reconstrucción de índices, etc.) aún no ha comenzado.
¿Es seguro para nosotros cancelar por completo nuestra consulta ALTER TABLE? ¿O es posible que la consulta ya haya modificado algo y cancelarla dejaría nuestra base de datos en algún estado intermedio?
Cancelar consultas (o, de manera equivalente, deshacer una transacción) en PostgreSQL no tiene ningún peligro de corrupción de la base de datos que podría haber sido asustado en ciertas otras bases de datos (por ejemplo, la advertencia aterradora al final de esta página). Es por eso que los que no son superusuarios son, en versiones recientes, libres de usar pg_cancel_backend()
y pg_terminate_backend()
eliminar sus propias consultas que se ejecutan en otros servidores; son seguros de usar sin preocuparse por la corrupción de la base de datos. Después de todo, PostgreSQL tiene que estar preparado para lidiar con cualquier proceso que se elimine, por ejemplo, SIGKILL del asesino OOM, el apagado del servidor, etc. Para eso está el registro WAL .
También es posible que haya visto que en PostgreSQL, es posible realizar la mayoría de los comandos DDL anidados dentro de una transacción (multi-declaración), por ejemplo
BEGIN;
ALTER TABLE foo ...;
ALTER TABLE bar ...;
-- more stuff
COMMIT; -- or ROLLBACK; if you've changed your mind
(Impresionante para asegurarse de que las migraciones de esquemas se realicen juntas o no). Sin embargo, usted dijo:
Nos hicieron no envolver los ALTER TABLE
en una transacción.
Eso está bien para un solo comando: de los documentos ,
PostgreSQL en realidad trata cada declaración SQL como ejecutada dentro de una transacción. Si no emite un comando BEGIN, cada instrucción individual tiene un BEGIN implícito y (si tiene éxito) COMMIT envuelto alrededor de él. Un grupo de declaraciones rodeadas por BEGIN y COMMIT a veces se denomina bloque de transacción.
Por lo tanto, cancelar eso ALTER TABLE
, ya sea a través de pg_cancel_backend()
un Ctrl-C emitido desde el indicador de control psql, tendrá un efecto similar al que hubiera hecho
BEGIN;
ALTER TABLE ... ;
ROLLBACK;
(aunque como es de esperar, cancelar eso costoso ALTER TABLE
puede salvar la base de datos de una gran cantidad de trabajo innecesario si de ROLLBACK
todos modos lo hará ).