Cardano-db-sync: استثناء بسبب unicode على testnet

تم إنشاؤها على ١٩ سبتمبر ٢٠٢٠  ·  15تعليقات  ·  مصدر: input-output-hk/cardano-db-sync

على شبكة testnet ، تتسبب مزامنة cardano-db في tags/5.0.0 في وضع extended في طرح استثناءات على الكتلة 1816809 بسبب مشكلات تحليل / معالجة unicode. لا يمكن المزامنة بعد هذه الكتلة.

[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\"}"]

التعليق الأكثر فائدة

هكذا تبدو الآن مع الإصلاح المؤقت:

[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

ال 15 كومينتر

هذا ألم شديد في الرقبة.

البيانات الوصفية tx التي يتم إدراجها هي

(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")

الذي يتم ترميزه كـ 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"

وهو بالطبع غير صالح لـ UTF8 ومن ثم ترفضه قاعدة البيانات.

والأسوأ من ذلك ، أن ما ورد أعلاه تم ترميزه كـ UTF8 بواسطة مكتبة Haskell Text كما هو موضح ، لكن PostgreSQL يرفضه بعد ذلك.

اسمحوا لي أن أكرر ما هو هذا الألم الهائل في الرقبة.

تم فك تشفير السلسلة المعنية إلى UTF8 بواسطة مكتبة Haskell Text ثم تم تمريرها إلى Postgres التي تطرح استثناءً SqlError . لقد حاولت اللحاق بهذا الاستثناء ولكن يبدو أن اصطياد الاستثناء لا يعمل.

يمكنني التقاط وتسجيل الاستثناء:

[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 = ""}

ولكن هناك استثناء آخر:

[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 = ""}

يشير هذا إلى أنني بحاجة إلى التحقق من صحة JSON بشكل كامل قبل الإدراج.

يمكننا تخزين UTF8 غير صالح في PostgreSQL ، ولكن فقط على هيئة بيانات bytea وليس مثل jsonb وإذا ذهبنا إلى دعم استعلام Postgres السابق لن يكون متاحًا.

لقد جربت فك تشفير UTF8 يدويًا:

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

وهذا أيضًا له نفس المشكلة.

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

البايت الفارغ غير قانوني في سلسلة PostgreSQL. لا نقطة رمز الصفر.

أعتقد حاليًا أن هذا يرجع إلى الطريقة التي يسلسل بها Haskell / Persistent هذا لإرساله إلى postgres. تحاول حاليا التحقق من صحة هذه النظرية.

يهرب Aeson.encode بالفعل NUL char إلى \u0000 الذي يظل ثابتًا ثم يرفضه.

لن يكون التوصل إلى حل أنيق لهذا الأمر سهلاً.

كنت أبحث في هذا ويبدو أن هذه الخصائص تحمل:

  • "\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" صالح تمامًا مثل UTF-8 ، نظرًا لأن UTF-8 يسمح بتمثيل \u0000 مباشرة.
  • \u0000 غير مسموح به لـ jsonb لأنه لا يمكن تحويله إلى text .

الحل المؤقت الوحيد لترميزه إلى JSON ، ثم إلى Text ثم اكتشاف تسلسل الأحرف السيئة ورفض كائن JSON إذا كان يحتوي على التسلسل السيئ. أتساءل أيضًا عما إذا كان \u0000 هو التسلسل الوحيد الذي أحتاج إلى رفضه ،

ألا يمكنك تخزين عمودين؟ بايت ، و JSON عندما لا يحتوي على حرف غير نصي ، بحيث يكون لأي شخص الحرية في استخدام كل ما يحتاج إليه.

erikd تم \u0000 بوضوح هنا ، جنبًا إلى جنب مع جميع القواعد الأخرى التي تتبعها Postgres. الخلاصة: هناك رفضات وتحولات مستمرة.

لتجنب التجريد المتسرب ، يجب تخزين القيم الدقيقة (كما قدمها المستخدم). هذا يعني تقريبًا إما blob (= لا توجد بنية في DB) أو قيم سلسلة JSON تحافظ بطريقة ما على المعنى الأصلي: على سبيل المثال قيم السلسلة المشفرة base64 في قاعدة البيانات (لذا فإن استعادة البنية على حساب المعالجة الإضافية في التطبيق في من أجل الترجمة من base64 إلى القيمة الفعلية).

تم دمج إصلاح الحل المؤقت (ببساطة إسقاط كائنات البيانات الوصفية التي لا يمكن إدراجها في Postgres) للإتقان.

هكذا تبدو الآن مع الإصلاح المؤقت:

[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

ما إذا تم إصلاح عامل الإرساء ، وما هو الإصدار الذي تم إصلاحه

لم يتم إصلاحه ، ولكن 5.0.x (لكنني أوصي 5.0.2 ) به حل بديل يتجنب هذه المشكلة عن طريق إسقاط tx_metadata يحتوي على حرف Unicode NUL .

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات