¿Cómo resolver los errores de copia de secuencia de bytes no válidos UTF8 en una restauración, cuando la base de datos de origen está codificada en UTF8?

17

Me dieron la tarea de migrar una base de datos PostgreSQL 8.2.x a otro servidor. Para hacer esto, estoy usando el pgAdmin 1.12.2 (en Ubuntu 11.04, por cierto) y el Respaldo y Restauración usando el formato personalizado / comprimido (.backup) y la codificación UTF8.

La base de datos original está en UTF8, así:

-- Database: favela

-- DROP DATABASE favela;

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

Estoy creando esta base de datos exactamente como esta en el servidor de destino. Pero cuando restauro la base de datos desde el archivo .backup usando la opción Restaurar, me da algunos de estos errores:

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

Cuando verifico qué registro desencadenó este error, de hecho, algunos campos de vartexto tienen caracteres diacríticos como ç (usado en portugués, por ejemplo, "caça"), y cuando los elimino manualmente del texto en los registros, el error pasa al siguiente registro eso los tiene, ya que cuando la copia tiene un error, deja de insertar datos en esta tabla. Y no quiero reemplazarlos manualmente uno por uno para lograr esto.

Pero es un poco extraño porque con UTF8 no debería haber este tipo de problemas, ¿verdad?

No sé cómo llegaron allí en primer lugar. Solo estoy migrando la base de datos, y supongo que de alguna manera la base de datos era como en LATIN1 y luego se cambió incorrectamente a UTF8.

¿Hay alguna forma de verificar si una tabla / base de datos tiene secuencias UTF8 no válidas? ¿O alguna forma de imponer / reconvertir estos caracteres en UFT8 para que no tenga ningún problema cuando ejecuto la restauración?

Gracias por adelantado.

pedrosanta
fuente

Respuestas:

8

Excavando en internet, he visto que este es un problema bastante común. La solución común es usar el volcado de formato de texto plano y alimentarlo a través de iconv para corregir la codificación.

Aquí hay más información sobre eso.

Ricardo
fuente
use iconv para convertir a UTF-32 descartando símbolos inválidos y luego de vuelta a UTF-8, una conversión de UTF-8 a UTF-8 no detectará todos los puntos de código incorrectos. (por ejemplo, sustitutos huérfanos)
Jasen
7

"No sé cómo llegaron allí en primer lugar"

Podría haber sucedido como se describe aquí , aunque esto genera un error en 8.4:

Si crea una tabla con cualquier tipo de texto (es decir, texto, varchar (10), etc.), puede insertar una secuencia de bytes no válida en ese campo utilizando escapes octales.

Por ejemplo, si tiene una base de datos codificada en UTF8, puede hacer:

=> CREAR TABLA foo (t TEXTO);

=> INSERTAR EN LOS VALORES foo (E '\ 377');

Ahora, si COPIE la tabla, no puede COPIAR el archivo resultante nuevamente. Eso significa que sus copias de seguridad pg_dump no podrán restaurarse. La única forma de recuperar sus datos es volver a escapar de ese valor.

Hay una buena publicación en este excelente blog sobre los problemas generales y algunas formas de tratarlos.

Jack Douglas
fuente
1

Es probable que tenga la codificación predeterminada utilizada en su entorno Unix / Linux. Para verificar qué codificación es actualmente la predeterminada, ejecute lo siguiente:

$ echo $LANG
en_US

En este caso, podemos ver claramente que no es una codificación UTF-8, en la que se basa el comando de copia.

Entonces, para solucionar esto, solo establecemos la variable LANG en el siguiente ejemplo:

$ export LANG=en_US.UTF-8

Nota: Esto solo estará disponible para la sesión actual. Agréguelo a ~ / .bashrc o similar para tenerlo disponible al inicio de cualquier futura sesión de shell.

Referencia

arulraj.net
fuente
1

No recomiendo ejecutar iconv a ciegas en el volcado de texto sin formato porque puede convertir caracteres válidos (por ejemplo: caracteres chinos) a otros caracteres. Es mejor encontrar el carácter UTF8 no válido ejecutando el siguiente comando.

grep -naxv '.*' plain_text_dump.sql

y luego ejecute iconv en los datos particulares. Consulte este documento para obtener una explicación detallada paso a paso .

Nijil
fuente