Sto compilando una tabella PostgreSQL con ~ 11.000.000 di righe che sono state selezionate in precedenza da un altro database. Sto usando Python e psycopg2. L'intero processo richiede circa 1,5 ore per essere completato. Tuttavia, dopo ~ 30 minuti ottengo l'eccezione "connessione chiusa in modo imprevisto". Il codice sorgente è simile al seguente:La connessione PostgreSQL si chiude in modo imprevisto quando si esegue un inserto 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()
ho inserito (1)
e (2)
dopo i primi tentativi non riusciti, partendo dal presupposto che una transazione aperta ha un limite di tempo superiore di circa 30 minuti o che un cursore ha un limite massimo di attesa inserti. Sembra che nessuno di questi presupposti sia vero e l'errore si trova altrove.
Entrambi i database sono memorizzati su una macchina VirtualBox che collego tramite port forwarding dall'host. Eseguo il programma sulla macchina host.
Entrambi i database sono solo a scopo di test e non hanno altre connessioni da gestire. Forse dovrò riscrivere il problema per aggirare questo problema, ma ho bisogno di inserimenti molto dispendiosi in termini di tempo altrove (in esecuzione approssimativamente per giorni) quindi sono molto preoccupato per alcuni limiti di tempo nascosti in psycopg2
o PostgreSQL.
I problema potrebbe essere nella variabile work_mem nella configurazione. AFAIK questa variabile imposta la memoria massima consentita per una connessione. Controllare i registri ci dovrebbe essere una voce su cosa è sbagliato – Voooza
Ma poi l'istruzione SELECT non avrebbe funzionato affatto, non è vero? Ma ho perso la connessione a 'outdb'. – WolfgangA
Utilizzare 'COPY' o transazioni più grandi. Eseguendo solo 100 record all'interno di una singola transazione, ne ottieni circa 110.000 transazioni per completare l'intero lavoro. Una singola unità 7400rpm può gestire solo 120 commit al secondo (a meno che non si trovi a causa della cache, ciò renderebbe inaffidabile). Il tuo problema attuale sembra un problema di rete. –