ไม่มี NULLs แต่ลำดับไบต์ไม่ถูกต้องสำหรับการเข้ารหัส“ UTF8”: 0x00


12

ฉันใช้เวลา 8 ชั่วโมงที่ผ่านมาพยายามนำเข้าผลลัพธ์ของ 'mysqldump --compatible = postgresql' ลงใน PostgreSQL 8.4.9 และฉันได้อ่านอย่างน้อย 20 กระทู้ที่แตกต่างกันที่นี่และที่อื่น ๆ เกี่ยวกับปัญหาเฉพาะนี้แล้ว แต่ไม่พบ คำตอบที่ใช้งานได้จริงที่ทำงาน

ทิ้งข้อมูล MySQL 5.1.52:

mysqldump -u root -p --compatible=postgresql --no-create-info --no-create-db --default-character-set=utf8 --skip-lock-tables rt3 > foo

เซิร์ฟเวอร์ PostgreSQL 8.4.9 เป็นปลายทาง

กำลังโหลดข้อมูลด้วย 'psql -U rt_user -f foo' กำลังรายงาน (ส่วนใหญ่เป็นหนึ่งในตัวอย่าง):

psql:foo:29: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
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".

ตามข้อมูลต่อไปนี้ไม่มีอักขระ NULL (0x00) ในไฟล์อินพุต

database-dumps:rcf-temp1# sed 's/\x0/ /g' < foo > nonulls
database-dumps:rcf-temp1# sum foo nonulls
04730 2545610 foo
04730 2545610 nonulls
database-dumps:rcf-temp1# rm nonulls

ในทำนองเดียวกันการตรวจสอบอื่นด้วย Perl ไม่แสดง NULL:

database-dumps:rcf-temp1# perl -ne '/\000/ and print;' foo
database-dumps:rcf-temp1#

ในฐานะ "คำแนะนำ" ในข้อผิดพลาดที่กล่าวถึงฉันได้ลองทุกวิธีที่เป็นไปได้ในการตั้งค่า 'client_encoding' เป็น 'UTF8' และฉันประสบความสำเร็จ แต่ก็ไม่มีผลต่อการแก้ปัญหาของฉัน

database-dumps:rcf-temp1# psql -U rt_user --variable=client_encoding=utf-8 -c "SHOW client_encoding;" rt3
 client_encoding
-----------------
 UTF8
(1 row)

database-dumps:rcf-temp1#

สมบูรณ์แบบ แต่:

database-dumps:rcf-temp1# psql -U rt_user -f foo --variable=client_encoding=utf-8 rt3
...
psql:foo:29: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
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".
...

ยกเว้นคำตอบที่ถูกต้องของ "ตามที่ฮอยล์" ซึ่งน่าจะฟังและรู้ว่าฉันไม่สนใจที่จะรักษาตัวละครที่ไม่ใช่ ASCII สำหรับข้อมูลอ้างอิงที่ไม่ค่อยมีคุณมีคำแนะนำอะไร?

อัปเดต: ฉันได้รับข้อผิดพลาดเดียวกันกับไฟล์ดัมพ์รุ่น ASCII เท่านั้นในเวลานำเข้า เหลือเชื่อที่เหลือเชื่อ:

database-dumps:rcf-temp1# # convert any non-ASCII character to a space
database-dumps:rcf-temp1# perl -i.bk -pe 's/[^[:ascii:]]/ /g;' mysql5-dump.sql
database-dumps:rcf-temp1# sum mysql5-dump.sql mysql5-dump.sql.bk
41053 2545611 mysql5-dump.sql
50145 2545611 mysql5-dump.sql.bk
database-dumps:rcf-temp1# cmp mysql5-dump.sql mysql5-dump.sql.bk
mysql5-dump.sql mysql5-dump.sql.bk differ: byte 1304850, line 30
database-dumps:rcf-temp1# # GOOD!
database-dumps:rcf-temp1# psql -U postgres -f mysql5-dump.sql --variable=client_encoding=utf-8 rt3
...
INSERT 0 416
psql:mysql5-dump.sql:30: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
HINT:  This error can also happen if the byte sequence does not match the encod.
INSERT 0 455
INSERT 0 424
INSERT 0 483
INSERT 0 447
INSERT 0 503
psql:mysql5-dump.sql:36: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
HINT:  This error can also happen if the byte sequence does not match the encod.
INSERT 0 502
INSERT 0 507
INSERT 0 318
INSERT 0 284
psql:mysql5-dump.sql:41: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
HINT:  This error can also happen if the byte sequence does not match the encod.
INSERT 0 382
INSERT 0 419
INSERT 0 247
psql:mysql5-dump.sql:45: ERROR:  invalid byte sequence for encoding "UTF8": 0x00
HINT:  This error can also happen if the byte sequence does not match the encod.
INSERT 0 267
INSERT 0 348
^C

ตารางหนึ่งในคำถามถูกกำหนดเป็น:

                                        Table "public.attachments"
     Column      |            Type             |                        Modifie
-----------------+-----------------------------+--------------------------------
 id              | integer                     | not null default nextval('atta)
 transactionid   | integer                     | not null
 parent          | integer                     | not null default 0
 messageid       | character varying(160)      |
 subject         | character varying(255)      |
 filename        | character varying(255)      |
 contenttype     | character varying(80)       |
 contentencoding | character varying(80)       |
 content         | text                        |
 headers         | text                        |
 creator         | integer                     | not null default 0
 created         | timestamp without time zone |
Indexes:
    "attachments_pkey" PRIMARY KEY, btree (id)
    "attachments1" btree (parent)
    "attachments2" btree (transactionid)
    "attachments3" btree (parent, transactionid)

ฉันไม่มีเสรีภาพในการเปลี่ยนประเภทของส่วนใด ๆ ของ DB schema การทำเช่นนั้นมีแนวโน้มที่จะทำให้การอัพเกรดซอฟต์แวร์ในอนาคตฯลฯ

คอลัมน์ปัญหาที่อาจเกิดขึ้นคือ 'เนื้อหา' ของประเภท 'ข้อความ' (อาจเป็นรายการอื่นในตารางอื่นเช่นกัน) ดังที่ฉันทราบแล้วจากการวิจัยก่อนหน้านี้ PostgreSQL จะไม่อนุญาตให้ NULL เป็นค่า 'text' อย่างไรก็ตามโปรดดูข้างต้นว่าทั้ง sed และ Perl ไม่แสดงอักขระ NULL จากนั้นฉันจะดึงอักขระที่ไม่ใช่ ASCII ทั้งหมดออกจากไฟล์ดัมพ์ทั้งหมด แต่ยังคง barfs


2
บรรทัดที่ 29 ของไฟล์ดัมพ์ของคุณมีลักษณะเป็นอย่างไร head -29 foo | tail -1 | cat -vอาจมีการใช้งานที่คล้ายกัน
mu สั้นเกินไป

คำจำกัดความของตารางที่ได้รับผลกระทบคืออะไรและบรรทัดที่มีลักษณะอย่างไร
tscho

เป็นข้อมูล บริษัท 1MB ฉันเข้าใจว่าคุณอยู่ตรงไหนของหลักสูตร นี่คือจุดสิ้นสุดของแนวความคิดนั้น (โปรดอภัยภาษาฝรั่งเศสของฉันในตอนท้ายของส่วนสำคัญ / วาง): gist.github.com/1525788
jblaine

tscho: ตามที่ระบุไว้บรรทัดข้อผิดพลาดตัวอย่างนั้นเป็นหนึ่งในร้อยข้อผิดพลาดเหล่านี้
jblaine

คำตอบ:


3

ฟิลด์ตัวอักษร / ข้อความอย่างน้อยหนึ่งรายการอาจมี 0x00 สำหรับเนื้อหา

ลองทำสิ่งต่อไปนี้:

SELECT * FROM rt3 where some_text_field = 0x00 LIMIT 1;

หากสิ่งนี้ส่งคืนแถวเดียวให้ลองอัปเดตฟิลด์อักขระ / ข้อความเหล่านั้นด้วย:

UPDATE rt3 SET some_text_field = '' WHERE some_text_field = 0x00;

หลังจากนั้นให้ลอง MYSQLDUMP อื่น ... (และวิธีการนำเข้า PostgreSQL)


นี้ช่วยให้ฉันพบตัวละคร null จรจัดของฉัน colname LIKE concat('%', 0x00, '%')แต่ฉันจำเป็นในการใช้งาน พบพวกเขาในสาขาที่มีอาร์เรย์ PHP ต่อเนื่อง
cimmanon

5

ฉันมีปัญหาเดียวกันกับการใช้ MySQL เวอร์ชั่น 5.0.51 และ Postgres เวอร์ชัน 9.3.4.0 ฉันแก้ไข "ลำดับไบต์ที่ไม่ถูกต้องสำหรับการเข้ารหัส" UTF8 ": 0x00" ปัญหาหลังจากเห็นความคิดเห็นของ Daniel Véritéว่า "mysqldump ในโหมด postgresql จะถ่ายโอนข้อมูลเป็น null null เป็น \ 0 ในสตริงดังนั้นคุณอาจต้องการค้นหาลำดับของอักขระนั้น"

แน่นอนที่สุด grep ได้เปิดเผยตัวอักษร NULL

grep \\\\0 dump.sql

ฉันแทนที่ตัวอักษร NULL โดยใช้คำสั่งต่อไปนี้

sed -i BAK 's/\\0//g' dump.sql

Postgres สามารถโหลด dump.sql ได้สำเร็จ


4

คุณสามารถได้รับข้อผิดพลาดนี้โดยไม่มีไบต์ NULL หรืออักขระที่ไม่ใช่ ASCII ใด ๆ ในไฟล์ ตัวอย่างในฐานข้อมูล utf8:

select E'ab\0cd';

จะให้ผลผลิต:

ข้อผิดพลาด: ลำดับไบต์ไม่ถูกต้องสำหรับการเข้ารหัส "UTF8": 0x00 คำแนะนำ: ข้อผิดพลาดนี้อาจเกิดขึ้นได้หากลำดับไบต์ไม่ตรงกับการเข้ารหัสที่เซิร์ฟเวอร์คาดไว้ซึ่งควบคุมโดย "client_encoding"

mysqldump ในโหมด postgresql จะถ่ายโอนข้อมูล null เป็น \ 0 ในสตริงดังนั้นคุณอาจต้องการค้นหาลำดับของอักขระนั้น


0

ฉันจำปัญหานี้ได้ครึ่งหนึ่ง ฉันคิดว่าฉันจบการโยกย้ายสคีมาแล้วทิ้งข้อมูลเป็น csv และโหลดข้อมูลจากไฟล์ csv ฉันจำได้ว่าต้องอัปเดตไฟล์ csv (โดยใช้เครื่องมือ unix เช่น sed หรือ unixtodos) หรือใช้ open office calc (excell) เพื่อแก้ไขรายการบางอย่างที่มีข้อผิดพลาดในขั้นตอนการนำเข้า - อาจเป็นเรื่องง่ายเพียงเปิดและบันทึก ไฟล์.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.