Estoy rellenando una tabla PostgreSQL con ~ 11.000.000 filas que se han seleccionado anteriormente desde otra base de datos. Estoy usando Python y psycopg2. El proceso completo demora aproximadamente 1,5 horas en completarse. Sin embargo, después de ~ 30 minutos obtengo la excepción de "conexión cerrada inesperadamente". El código fuente es el siguiente:La conexión PostgreSQL se cierra inesperadamente al hacer una inserción grande
incursor = indb.cursor()
incursor.execute("SELECT ...")
indb.commit() # (1) close transaction
outcursor = outdb.cursor()
rows = 0
for (col1, col2, col3) in incursor: # incursor contains ~11.000.000 rows
outcursor.execute("INSERT ...", (col1, col2, col3)) # This fails after ~30 minutes
row += 1
if row % 100 == 0: # (2) Write data every 100 rows
outcursor.close()
outdb.commit()
outcursor = outdb.cursor()
incursor.close()
outcursor.close()
outdb.commit()
que inserta (1)
y (2)
después de los primeros intentos que fracasaron, en el supuesto de que una transacción abierta tiene un límite de tiempo superior de ~ 30 minutos o que un cursor tiene un límite superior de la espera inserciones. Parece que ninguna de estas suposiciones es verdadera y el error está en otra parte.
Ambas bases de datos se almacenan en una máquina VirtualBox que conecto mediante el reenvío de puertos desde el host. Ejecuto el programa en la máquina host.
Ambas bases de datos son solo para fines de prueba y no tienen otras conexiones que administrar. Tal vez tenga que volver a escribir el problema para evitar esto, pero necesito inserciones que consumen mucho tiempo en otros lugares (se ejecutan aproximadamente durante días), así que estoy muy preocupado por algunos límites de tiempo ocultos en psycopg2
o PostgreSQL.
Creo que el problema podría estar en la variable work_mem en la configuración. AFAIK esta variable establece la memoria máxima permitida para una conexión. Compruebe los registros que debería haber una entrada acerca de cuál es incorrecto – Voooza
Pero entonces la instrucción SELECT no funcionaría del todo, ¿no? Pero pierdo la conexión a 'outdb'. – WolfgangA
Utilice 'COPY' o transacciones más grandes. Ejecutar solo 100 registros en una sola transacción, le da alrededor de 110.000 transacciones para completar todo el trabajo. Una sola unidad de 7400rpm solo puede manejar 120 confirmaciones por segundo (a menos que se deba a caché, eso lo haría poco confiable). Su problema actual suena como un problema de red. –