Come risolvere gli errori di copia della sequenza di byte non validi UTF8 su un ripristino, quando il database di origine è codificato in UTF8?


17

Mi è stato affidato il compito di migrare un database PostgreSQL 8.2.x su un altro server. Per fare ciò sto usando pgAdmin 1.12.2 (su Ubuntu 11.04 tra l'altro) e usando il Backup e il Ripristino usando il formato personalizzato / comprimere (.backup) e la codifica UTF8.

Il database originale è in UTF8, in questo modo:

-- Database: favela

-- DROP DATABASE favela;

CREATE DATABASE favela
  WITH OWNER = favela
       ENCODING = 'UTF8'
       TABLESPACE = favela
       CONNECTION LIMIT = -1;

Sto creando questo database esattamente come questo sul server di destinazione. Ma quando ripristino il database dal file .backup usando l'opzione Ripristina mi dà alcuni di questi errori:

pg_restore: restoring data for table "arena"
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 2173; 0 35500 TABLE DATA arena favela
pg_restore: [archiver (db)] COPY failed: ERROR:  invalid byte sequence for encoding "UTF8": 0xe3a709
HINT:  This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
CONTEXT:  COPY arena, line 62

Quando controllo quale record ha innescato questo errore, in effetti alcuni campi vartext hanno caratteri diacritici come ç (usato in portoghese, ad esempio "caça"), e quando li rimuovo manualmente dal testo nei record l'errore passa al record successivo quello li ha - poiché quando la copia ha un errore smette di inserire dati in questa tabella. E non voglio sostituirli manualmente uno per uno per ottenere questo risultato.

Ma è un po 'strano perché con UTF8 non dovrebbe esserci questo tipo di problemi, giusto?

Non so come ci siano arrivati ​​in primo luogo. Sto solo migrando il database e suppongo che in qualche modo il database fosse come in LATIN1 e quindi sia stato erroneamente cambiato in UTF8.

Esiste un modo per verificare se una tabella / database ha sequenze UTF8 non valide? O un modo per imporre / riconvertire questi caratteri in UFT8 in modo da non incorrere in alcun problema quando eseguo il ripristino?

Grazie in anticipo.

Risposte:


8

Scavando su Internet, ho visto che questo è un problema piuttosto comune. La soluzione comune è quella di utilizzare il dump in formato testo normale e inviarlo tramite iconv per correggere la codifica.

Ecco maggiori informazioni a riguardo.


usa iconv per convertire in UTF-32 scartando simboli non validi e poi di nuovo in UTF-8, una conversione da UTF-8 a UTF-8 non catturerà tutti i punti di codice errato. (ad esempio surrogati orfani)
Jasen,

7

"In primo luogo non so come ci siano arrivati"

Potrebbe essere successo come descritto qui , sebbene ciò generi un errore su 8.4:

Se si crea una tabella con qualsiasi tipo di testo (ad esempio, text, varchar (10), ecc.), È possibile inserire una sequenza di byte non valida in quel campo utilizzando gli escape ottali.

Ad esempio, se si dispone di un database con codifica UTF8, è possibile eseguire:

=> CREA TABELLA foo (t TEXT);

=> INSERISCI IN VALORI (E '\ 377');

Ora, se COPIA la tabella, non puoi COPIARE nuovamente il file risultante. Ciò significa che i tuoi backup pg_dump non saranno in grado di ripristinare. L'unico modo per recuperare i tuoi dati è ripristinare il valore.

C'è un buon post su questo eccellente blog sulle questioni generali e su alcuni modi per affrontarle


1

È probabile con la codifica predefinita utilizzata nel tuo ambiente Unix / Linux. Per verificare quale codifica è attualmente quella predefinita, eseguire quanto segue:

$ echo $LANG
en_US

In questo caso, possiamo vedere chiaramente che non è una codifica UTF-8, quella su cui si basa il comando di copia.

Quindi, per risolvere questo problema, abbiamo semplicemente impostato la variabile LANG nell'esempio seguente:

$ export LANG=en_US.UTF-8

Nota: questo sarà disponibile solo per la sessione corrente. Aggiungilo a ~ / .bashrc o simile per renderlo disponibile all'avvio di qualsiasi futura sessione di shell.

Riferimento


1

Non consiglio di eseguire ciecamente iconv sul dump del testo normale perché potrebbe convertire caratteri validi (ad esempio: caratteri cinesi) in altri caratteri. È meglio trovare il carattere UTF8 non valido eseguendo il comando seguente.

grep -naxv '.*' plain_text_dump.sql

e quindi eseguire iconv sui dati particolari. Consulta questo documento per una spiegazione dettagliata dettagliata .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.