على شبكة 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\"}"]
هذا ألم شديد في الرقبة.
البيانات الوصفية 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
.
التعليق الأكثر فائدة
هكذا تبدو الآن مع الإصلاح المؤقت: