it-swarm.asia

Bagaimana mengatasi kesalahan salin urutan byte UTF8 tidak valid pada pemulihan, ketika sumber database dikodekan dalam UTF8?

Saya diberi tugas untuk memigrasi database PostgreSQL 8.2.x ke server lain. Untuk melakukan ini, saya menggunakan pgAdmin 1.12.2 (pada Ubuntu 11,04 by the way) dan menggunakan Backup dan Restore menggunakan format kustom/kompres (.backup) dan pengkodean UTF8.

Database asli ada di UTF8, seperti:

-- Database: favela

-- DROP DATABASE favela;

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

Saya membuat database ini persis seperti ini di server tujuan. Tetapi ketika saya mengembalikan database dari file .backup menggunakan opsi Restore itu memberi saya beberapa kesalahan ini:

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

Ketika saya memeriksa catatan mana yang memicu kesalahan ini pada kenyataannya beberapa bidang varteks memiliki karakter diakritik seperti ç (digunakan dalam bahasa Portugis, misalnya, "caça"), dan ketika saya menghapusnya secara manual dari teks dalam catatan, kesalahan berlanjut ke catatan berikutnya. yang memiliki mereka - karena ketika salinan memiliki kesalahan itu berhenti memasukkan data pada tabel ini. Dan saya tidak ingin menggantinya secara manual satu per satu untuk mencapai ini.

Tapi ini agak aneh karena dengan UTF8 seharusnya tidak ada masalah seperti ini, kan?

Saya tidak tahu bagaimana mereka sampai di sana. Saya hanya memigrasi database, dan saya kira entah bagaimana database seperti di LATIN1 dan kemudian diubah menjadi UTF8.

Apakah ada cara untuk memeriksa apakah tabel/database memiliki urutan UTF8 yang tidak valid? Atau cara apa pun untuk memaksakan/mengubah karakter ini ke UFT8 jadi saya tidak mengalami masalah ketika saya menjalankan pengembalian?

Terima kasih sebelumnya.

17
pedrosanta

Menggali di internet, saya telah melihat bahwa ini adalah masalah yang cukup umum. Solusi umum adalah dengan menggunakan dump format teks biasa dan memberi makan melalui iconv untuk memperbaiki pengkodean.

Di Sini adalah informasi lebih lanjut tentang itu.

8
Richard

"Aku tidak tahu bagaimana mereka sampai di sana."

Itu bisa terjadi seperti yang dijelaskan di sini - walaupun ini menghasilkan kesalahan pada 8.4:

Jika Anda membuat tabel dengan jenis teks apa pun (mis. Teks, varchar (10), dll.), Maka Anda bisa menyisipkan urutan byte yang tidak valid ke dalam bidang tersebut menggunakan oktal escapes.

Misalnya, jika Anda memiliki database yang disandikan UTF8, Anda dapat melakukan:

=> CREATE TABLE foo (t TEXT);

=> INSERT INTO foo VALUES (E '\ 377');

Sekarang, jika Anda SALINAN tabel keluar, Anda tidak bisa SALINAN file yang dihasilkan kembali. Itu berarti cadangan pg_dump Anda tidak akan dapat mengembalikan. Satu-satunya cara untuk mendapatkan kembali data Anda adalah melepaskan diri dari nilai itu.

Ada posting bagus tentang hal ini blog luar biasa tentang masalah umum dan beberapa cara untuk mengatasinya

Saya tidak merekomendasikan menjalankan iconv secara membabi buta pada dump teks biasa karena dapat mengkonversi karakter yang valid (misalnya: karakter Cina) ke beberapa karakter lain. Lebih baik untuk menemukan karakter UTF8 yang tidak valid dengan menjalankan perintah di bawah ini.

grep -naxv '.*' plain_text_dump.sql

dan kemudian jalankan ikonv pada data tertentu. Periksa dokumen ini untuk penjelasan langkah demi langkah yang terperinci .

1
Nijil

Kemungkinan dengan encoding default yang digunakan di lingkungan Unix/Linux Anda. Untuk memeriksa pengkodean mana yang saat ini menjadi default, jalankan yang berikut:

$ echo $LANG
en_US

Dalam hal ini, kita dapat dengan jelas melihat bahwa itu bukan pengkodean UTF-8, yang menjadi sandaran perintah salin.

Jadi untuk memperbaikinya, kita cukup mengatur variabel LANG pada contoh sebagai berikut:

$ export LANG=en_US.UTF-8

Catatan: Ini hanya akan tersedia untuk sesi saat ini. Tambahkan ke ~/.bashrc atau yang serupa agar tersedia pada saat memulai sesi Shell di masa mendatang.

Referensi

1
arulraj.net

Saya mereferensikan tautan berikut yang memberi saya petunjuk untuk menentukan pengkodean sumber dan kemudian mengubahnya menjadi pengkodean UTF-8 yang diinginkan. Linux Check dan Change Encoding

$ file -bi cabot.sql
text/plain; charset=utf-16le
$ iconv -f utf-16le -t utf-8 -o converted.sql cabot.sql
$ file -bi converted.sql
text/plain; charset=utf-8
0
Biswajit Barman