Como Daniel Vérité mencionó, no parece haber una solución genérica. Al cargar datos en una tabla desde un archivo, se puede usar la siguiente técnica para obtener el progreso de la carga.
COPY barra de progreso de la consola de comandos
Crea una mesa vacía.
CREATE TABLE mytest (n int);
Cree un archivo de datos con 10 millones de líneas para cargar en la tabla.
$ seq 10000000 > /tmp/data.txt
Cargue datos del archivo en la tabla y muestre una barra de progreso.
$ pv /tmp/data.txt | psql -c "COPY mytest FROM STDIN;"
Manifestación
Como funciona esto
Mediante el uso de la opción STDIN de comandos de copia, podemos alimentar los datos para la operación de copia desde otro proceso. El comando pv generará un archivo y hará un seguimiento de su progreso mostrando una barra de progreso, ETA, el tiempo total transcurrido y la velocidad de transferencia de datos.
Barra de progreso gráfica del comando COPY
Usando la misma técnica general, podríamos mostrar una barra de progreso en una aplicación gráfica o una aplicación basada en la web. Usando python, por ejemplo, el módulo psycopg2 le permite llamar al comando copiar con un objeto de archivo de su elección. Luego puede realizar un seguimiento de la cantidad de su objeto de archivo que se ha leído y mostrar una barra de progreso.
pv
comando antes, y no estaba instalado en mi servidor Debian por defecto, pero está en el repositorio. La descripción dice que "pv (Pipe Viewer) se puede insertar en cualquier canalización normal entre dos procesos para dar una indicación visual de qué tan rápido pasan los datos". Un comando muy útil!No parece haber un método genérico compatible, pero hay algunos trucos que se pueden usar en contextos limitados para evaluar el progreso de una consulta individual. Éstos son algunos de ellos.
Secuencias
Cuando una consulta SELECT o UPDATE incluye alguna
nextval(sequence_name)
, o un INSERT tiene una columna de destino con unnextval
valor predeterminado, el valor de secuencia actual se puede consultar repetidamente en otra sesión conSELECT sequence_name.last_value
. Funciona porque las secuencias no están delimitadas por transacciones. Cuando el plan de ejecución es tal que la secuencia se incrementa linealmente durante la consulta, puede usarse como un indicador de progreso.pgstattuple
El módulo contrib pgstattuple proporciona funciones que pueden ver directamente las páginas de datos. Parece que cuando las tuplas se insertan en una tabla vacía y aún no se confirman, se cuentan en el
dead_tuple_count
campo desde lapgstattuple
función.Demostración con 9.1: crea una tabla vacía
Insertemos 10M filas en él:
En otra sesión, verifique pgstattuple cada segundo durante la inserción:
Resultados:
Vuelve a 0 cuando finaliza la inserción (todas las tuplas se vuelven visibles y vivas).
Este truco también se puede usar cuando la tabla no se ha creado recientemente, pero
dead_tuple_count
es probable que la inicial tenga un valor distinto de cero y también puede cambiar simultáneamente si está ocurriendo otra actividad de escritura como el vacío automático (¿presumiblemente? ¿No está seguro de qué nivel de concurrencia a esperar con autovacuum).Sin embargo, no se puede usar si la tabla es creada por la declaración misma (
CREATE TABLE ... AS SELECT
oSELECT * INTO newtable
), ya que la creación se transa. La solución alternativa sería crear la tabla sin filas (agregarLIMIT 0
) y completarla en la próxima transacción.Tenga en cuenta que
pgstattuple
no es gratis: escanea toda la tabla en cada llamada. También se limita a los superusuarios.Contador personalizado
En el blog de Pavel Stehule, proporciona una función de contador implementada en C que genera AVISOS en un número específico de ejecuciones. Debe combinar la función con la consulta de alguna manera para permitir que el ejecutor la llame. Los avisos se envían durante la consulta y no necesitan una sesión separada, solo un cliente SQL que los muestre (
psql
siendo el candidato obvio).Ejemplo de INSERT INTO reelaborado para generar avisos:
Pregunta relacionada sobre stackoverflow, para funciones:
cómo informar el progreso de la función PostgreSQL de larga duración al cliente
Opciones de futuro?
A partir de mayo de 2017, hay un parche prometedor enviado a la comunidad de desarrolladores: [PATCH v2] Comando de progreso para monitorear la progresión de consultas SQL de larga ejecución
que podría terminar como una solución genérica en PostgreSQL 11 o posterior. Los usuarios que desean participar en las funciones de trabajo en progreso pueden aplicar la última versión del parche y probar el
PROGRESS
comando propuesto .fuente
Hasta que la funcionalidad del informe de progreso no se extienda, como @AmirAliAkbari mencionó en su respuesta, aquí hay una solución alternativa a nivel de sistema operativo.
Esto funciona solo en Linux, pero probablemente haya soluciones similares fácilmente buscables para cualquier sistema operativo.
La ventaja más grande y también la desventaja de PostgreSQL, que todos sus backends son procesos simples de un solo subproceso, utilizando
lseek()
,read()
ywrite()
para manipular sus archivos de la tabla, mientras que están interactuando en el MEM y los bloqueos compartidos.Esto da como resultado que todos sus procesos de back-end estén trabajando siempre en una sola consulta, que se puede encontrar fácilmente, y fácilmente
strace
d.Primero, puede ver el PID de fondo desde
SELECT * FROM pg_stat_activity;
:La tercera columna es el pid. En PostgreSQL, es lo mismo que el proceso de Linux pid del backend.
A continuación, puede dividirlo, por ejemplo, mediante un
strace -p 20019 -s 8192
: (-s 8192
es útil porque postgresql funciona con bloques largos de 8192 bytes).Los significados:
sendto
Ocurre si el servidor responde algo a un cliente. En el ejemplo, responde el resultado de unaINSERT
consulta.recvfrom
sucede si el servidor obtiene algo de un cliente. Normalmente es una consulta nueva, en el ejemplo, otra másINSERT
.lseek
sucede si el backend cambia de posición en un archivo de tabla.read
sucede si el backend lee un bloque desde un archivo de tabla.write
sucede si el backend escribe un bloque en un archivo de tabla.En el caso de
read
ywrite
, también puede ver el contenido de ese bloque en la tabla. Puede ayudar mucho entender, qué está haciendo y dónde está.En el caso de
recvfrom
, puede ver la consulta real que tiene el backend.fuente
Como se dijo en otras respuestas, actualmente no existe una forma directa de informar el progreso en general.
Sin embargo, a partir de 9.6, cada vez que
VACUUM
se ejecute, lapg_stat_progress_vacuum
vista contendrá una fila para cada backend (incluidos los procesos de trabajo de vacío automático) que se está aspirando actualmente. Sepg_stat_progress_vacuum
pueden encontrar más detalles sobre la documentación: 27.4 Informes de progreso .fuente