Cardano-db-sync: Pengecualian karena unicode di testnet

Dibuat pada 19 Sep 2020  ·  15Komentar  ·  Sumber: input-output-hk/cardano-db-sync

Pada jaringan testnet , cardano-db-sync pada tags/5.0.0 dalam mode extended , melempar pengecualian pada blok 1816809 karena masalah penguraian/penanganan unicode. Itu tidak dapat disinkronkan melewati blok ini.

[db-sync-node:Info:234667] [2020-09-19 14:23:20.41 UTC] Starting chainSyncClient
[db-sync-node:Info:234667] [2020-09-19 14:23:20.48 UTC] Cardano.Db tip is at slot 6061839, block 1816809
[db-sync-node:Info:234672] [2020-09-19 14:23:20.48 UTC] Running DB thread
[db-sync-node:Info:234672] [2020-09-19 14:23:20.65 UTC] Rolling back to slot 6061839, hash 98414d12d1d1f05210dea6ce4082e1bcbbcfdf56343fd1cb44a8778c4c9ea57a
[db-sync-node:Info:234672] [2020-09-19 14:23:20.66 UTC] Deleting blocks numbered: []
[db-sync-node:Error:234672] [2020-09-19 14:23:21.03 UTC] runDBThread: DbInsertException "TxMetadata" (SqlError {sqlState = "22P05", sqlExecStatus = FatalError, sqlErrorMsg = "unsupported Unicode escape sequence", sqlErrorDetail = "\\u0000 cannot be converted to text.", sqlErrorHint = ""})
[db-sync-node:Error:234667] [2020-09-19 14:23:21.05 UTC] ChainSyncWithBlocksPtcl: DbInsertException "TxMetadata" (SqlError {sqlState = "22P05", sqlExecStatus = FatalError, sqlErrorMsg = "unsupported Unicode escape sequence", sqlErrorDetail = "\\u0000 cannot be converted to text.", sqlErrorHint = ""})
[db-sync-node.Subscription:Error:234663] [2020-09-19 14:23:21.05 UTC] [String "Application Exception: LocalAddress {getFilePath = \"/run/cardano-node/node.socket\"} DbInsertException \"TxMetadata\" (SqlError {sqlState = \"22P05\", sqlExecStatus = FatalError, sqlErrorMsg = \"unsupported Unicode escape sequence\", sqlErrorDetail = \"\\\\u0000 cannot be converted to text.\", sqlErrorHint = \"\"})",String "SubscriptionTrace"]
[db-sync-node.ErrorPolicy:Error:4] [2020-09-19 14:23:21.05 UTC] [String "ErrorPolicyUnhandledApplicationException (DbInsertException \"TxMetadata\" (SqlError {sqlState = \"22P05\", sqlExecStatus = FatalError, sqlErrorMsg = \"unsupported Unicode escape sequence\", sqlErrorDetail = \"\\\\u0000 cannot be converted to text.\", sqlErrorHint = \"\"}))",String "ErrorPolicyTrace",String "LocalAddress {getFilePath = \"/run/cardano-node/node.socket\"}"]

Komentar yang paling membantu

Ini tampilannya sekarang dengan perbaikan temp:

[db-sync-node:Info:37] [2020-09-22 10:19:09.66 UTC] insertShelleyBlock: epoch 84, slot 6060000, block 1816721, hash 3ec15354c53deae4eb26a206cc3185f799e80bd09393f279bce7e53a7d633144
[db-sync-node:Warning:37] [2020-09-22 10:19:24.08 UTC] insertTxMetadata: dropped due to a Unicode NUL character.
[db-sync-node:Warning:37] [2020-09-22 10:19:24.08 UTC] insertTxMetadata: dropped due to a Unicode NUL character.
[db-sync-node:Warning:37] [2020-09-22 10:19:24.10 UTC] insertTxMetadata: dropped due to a Unicode NUL character.
[db-sync-node:Warning:37] [2020-09-22 10:19:24.10 UTC] insertTxMetadata: dropped due to a Unicode NUL character.
[db-sync-node:Info:37] [2020-09-22 10:19:24.93 UTC] insertShelleyBlock: epoch 84, slot 6065000, block 1816973, hash 0ab0dd5c36c6eb480b8bbd05508be952c5ed8597a4e422af25bd80a905a9368d

Semua 15 komentar

Ini adalah nyeri BESAR di leher.

Metedata tx yang dimasukkan adalah

(1,S "\NUL\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX\ETX")

yang dikodekan sebagai JSON:

"\u0000\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003"

yang tentu saja bukan UTF8 yang valid dan karenanya database menolaknya.

Lebih buruk lagi, di atas dikodekan sebagai UTF8 oleh perpustakaan Haskell Text seperti yang ditunjukkan, tetapi PostgreSQL kemudian menolaknya.

Izinkan saya mengulangi betapa sakitnya SANGAT BESAR di leher ini.

String yang dimaksud didekodekan ke UTF8 oleh perpustakaan Haskell Text dan kemudian diteruskan ke Postgres yang melempar pengecualian SqlError . Saya telah mencoba menangkap pengecualian ini tetapi menangkap pengecualian sepertinya tidak berhasil.

Saya dapat menangkap dan mencatat pengecualian:

[db-sync-node:Warning:37] [2020-09-21 00:26:18.77 UTC] insertTxMetadata: Failed to insert (1,S "\NUL...\ETX")
SqlError {sqlState = "22P05", sqlExecStatus = FatalError, sqlErrorMsg
 = "unsupported Unicode escape sequence", sqlErrorDetail = "\\u0000 cannot be converted to text.", sqlErrorHint = ""}

tapi kemudian ada pengecualian kedua:

[db-sync-node:Error:37] [2020-09-21 00:26:18.77 UTC] runDBThread: SqlError {sqlState = "25P02", sqlExecStatus = FatalError, sqlErrorMsg = "current transaction is aborted, commands ignored until end of transaction
 block", sqlErrorDetail = "", sqlErrorHint = ""}

Ini menunjukkan bahwa saya perlu lebih memvalidasi JSON sebelum penyisipan.

Kami dapat menyimpan UTF8 yang tidak valid di PostgreSQL, tetapi hanya sebagai data bytea bukan sebagai jsonb dan jika kami menggunakan dukungan kueri JSON Postgres sebelumnya tidak akan tersedia.

Saya telah mencoba dekode UTF8 manual:

decodeUtf8IO :: ByteString -> IO (Either Text.UnicodeException Text)
decodeUtf8IO = try . evaluate . Text.decodeUtf8With Text.strictDecode

dan itu juga memiliki masalah yang sama.

Dari: https://stackoverflow.com/questions/31671634/handling-unicode-sequences-in-postgresql

Byte nol tidak legal dalam string PostgreSQL. Juga bukan titik kode nol.

Saat ini anggap ini karena cara Haskell/Persistent membuat serial ini untuk dikirim ke postgres. Saat ini mencoba untuk memvalidasi teori ini.

Aeson.encode sudah lolos dari karakter NUL ke \u0000 yang kemudian ditolak oleh Persisten.

Menemukan perbaikan yang rapi untuk ini tidak akan mudah.

Saya sedang mencari ini dan sepertinya properti ini berlaku:

  • "\u0000\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003" cukup valid sebagai UTF-8, karena UTF-8 mengizinkan \u0000 untuk diwakili secara langsung.
  • \u0000 tidak diperbolehkan untuk jsonb karena tidak dapat dikonversi ke text .

Satu-satunya solusi sementara untuk menyandikannya ke JSON, dan kemudian ke Text dan kemudian mendeteksi urutan karakter yang buruk dan menolak objek JSON jika berisi urutan yang buruk. Saya juga bertanya-tanya apakah \u0000 adalah satu-satunya urutan yang harus saya tolak,

Tidak bisakah Anda menyimpan dua kolom? byte, dan JSON ketika tidak mengandung karakter non-teks, sehingga siapa pun bebas menggunakan apa pun yang mereka butuhkan.

@erikd Pembatasan \u0000 dinyatakan dengan jelas di sini , bersama dengan semua aturan lain yang diikuti Postgres. Intinya: ada penolakan dan transformasi yang terjadi.

Untuk menghindari abstraksi yang bocor, nilai yang tepat (seperti yang diberikan oleh pengguna) harus disimpan. Ini kira-kira berarti gumpalan (= tidak ada struktur dalam DB) atau nilai string JSON yang entah bagaimana mempertahankan makna aslinya: misalnya nilai string yang disandikan base64 dalam DB (jadi memulihkan struktur dengan mengorbankan pemrosesan ekstra dalam aplikasi di untuk menerjemahkan dari base64 ke nilai aktual).

Perbaikan solusi sementara (hanya menjatuhkan objek metadata yang tidak dapat dimasukkan ke dalam Postgres) telah digabungkan ke master.

Ini tampilannya sekarang dengan perbaikan temp:

[db-sync-node:Info:37] [2020-09-22 10:19:09.66 UTC] insertShelleyBlock: epoch 84, slot 6060000, block 1816721, hash 3ec15354c53deae4eb26a206cc3185f799e80bd09393f279bce7e53a7d633144
[db-sync-node:Warning:37] [2020-09-22 10:19:24.08 UTC] insertTxMetadata: dropped due to a Unicode NUL character.
[db-sync-node:Warning:37] [2020-09-22 10:19:24.08 UTC] insertTxMetadata: dropped due to a Unicode NUL character.
[db-sync-node:Warning:37] [2020-09-22 10:19:24.10 UTC] insertTxMetadata: dropped due to a Unicode NUL character.
[db-sync-node:Warning:37] [2020-09-22 10:19:24.10 UTC] insertTxMetadata: dropped due to a Unicode NUL character.
[db-sync-node:Info:37] [2020-09-22 10:19:24.93 UTC] insertShelleyBlock: epoch 84, slot 6065000, block 1816973, hash 0ab0dd5c36c6eb480b8bbd05508be952c5ed8597a4e422af25bd80a905a9368d

Apakah buruh pelabuhan diperbaiki, dan apa versi yang diperbaiki

Ini tidak diperbaiki, tetapi 5.0.x (tetapi saya akan merekomendasikan 5.0.2 ) memiliki solusi yang menghindari masalah ini dengan menghapus tx_metadata berisi karakter Unicode NUL .

Apakah halaman ini membantu?
0 / 5 - 0 peringkat