
إطار اختبار صحة المعاملات المستند إلى Jepsen لـ DuckDB، يكتشف شذوذ العزل مثل انتهاكات G2-item و SSI عبر أعباء العمل العشوائية ومدقق Elle.
اختبارات Jepsen لقاعدة بيانات DuckDB. يتم تشغيلها محليًا، بدلاً من عنقود بعيد. يقوم الاختبار بتشغيل مجموعة من العمليات المحلية التي تفتح ملف DuckDB محليًا، وتتفاعل معها عبر STDIN/STDOUT.
هذا نموذج أولي مبكر. يتم تشغيله، وتنفيذ المعاملات، والتحقق من صحتها، والإبلاغ عن الأخطاء، لكنني لست متأكدًا مما إذا كانت هذه الأخطاء حقيقية.
ستحتاج إلى JDK (الإصدار 21 أو أحدث)، Git، Gnuplot، Graphviz، بالإضافة إلى Leiningen. على عكس معظم اختبارات Jepsen، يعمل هذا الاختبار محليًا بالكامل؛ لا تحتاج إلى عنقود من الأجهزة، مفاتيح SSH، إلخ.
sudo apt install openjdk leiningen gnuplot graphviz
brew install openjdk leiningen gnuplot graphviz
لتشغيل اختبار، جرب:
lein run test
توفر DuckDB (على ما أعتقد) عزل اللقطة القوي (Strong SI) بشكل افتراضي، وهذا ما يتحقق منه الاختبار. لكنها تسمح بـ G2-item، وهو انتهاك لـ Repeatable Read. لتوضيح ذلك، جرب:
lein run test --time-limit 10 --expected-consistency-model serializable --max-writes-per-key 8
نطلب الاختبار لمدة عشر ثوانٍ، للبحث عن انتهاكات لقابلية التسلسل (Serializability)، ولتوليد أمثلة صغيرة قابلة للقراءة، نكتب فقط 8 عناصر لكل مفتاح. يجب أن تتوفر أمثلة على G2-item في store/latest/elle/G2-item.
هناك عدة خيارات ضبط متاحة. المساعدة حول الخيارات المختلفة متاحة من خلال lein run test --help.
تُكتب نتائج الاختبار إلى store/<test-name>/<date>/، ويتم إنشاء رابط رمزي لها كـ store/latest. كل دليل اختبار من هذه الأدلة مكتفي بذاته؛ يمكنك نسخه، ضغطه، تحليل واحد لاحقًا، حذفه، وهكذا. يمكنك أيضًا تشغيل خادم ويب لتصفح النتائج.
lein run serve
يتوفر REPL؛ راجع lein repl.
توجد أداة الاختبار في هذا الدليل؛ ملف مشروعها هو project.clj، ومصدرها في src/، وهكذا.
تقوم أداة الاختبار بتشغيل برنامج منفصل، هو "العقدة المحلية"، الذي يضم مكتبة DuckDB وينفذ المعاملات ضدها. تقوم أداة الاختبار بتوليد معاملات عشوائية لعبء عمل معين، وتقديمها عبر HTTP إلى العقدة المحلية، وتسجيل نتائج تلك المعاملات، والتحقق في النهاية من وجود حالات شذوذ مختلفة في المعاملات. نحن نبحث عن عزل اللقطة القوي (Strong Snapshot Isolation)، باستخدام أداة التحقق Elle (https://github.com/jepsen-io/elle).
تحتوي العقدة المحلية على خادم HTTP صغير يستقبل المعاملات المجردة (مثل "قراءة المفتاح x، ثم تعيين y إلى 5") من أداة الاختبار، ويترجمها إلى معاملات تُنفذ ضد برنامج تشغيل DuckDB JDBC.
يمكننا حقن نوع واحد من الأعطال: قتل العمليات.
لدينا عبءا عمل.
الأول، الإلحاق (append)، يقوم بتنفيذ معاملات تلحق أعدادًا صحيحة فريدة بالقوائم، وتقرأ محتويات تلك القوائم. تعيش كل قائمة في صف واحد، موزع عبر عدة جداول. يتم التعرف على القوائم بواسطة المفتاح الأساسي أو مفتاح ثانوي غير مفهرس. يتم ترميز القوائم إما كحقول نصية أو كقوائم INTEGER{] في DuckDB. يتم التعديل إما باستخدام INSERT ON CONFLICT UPDATE أو MERGE INTO.
الثاني، سجل المفتاح الأجنبي (fkey-register)، يقوم بقراءة وكتابة سجلات الأعداد الصحيحة. في DuckDB، نخزن هذه السجلات في جدولين. جدول منطقي يربط المفاتيح بمعرفات مادية، مع مفتاح أجنبي. جدول مادي يربط المعرفات المادية بالقيم. نستخدم JOIN بسيط بين الاثنين للقراءة. تتم الكتابة إما بتحديث الصف المادي، أو بإنشاء صف مادي جديد وتغيير المؤشر المنطقي إليه. لقد قمت بتشغيل هذا العبء اليوم للتو؛ إنه يعمل، لكنه ليس مصقولًا بعد.
حقوق الطبع والنشر © 2026 شركة Jepens, LLC
هذا البرنامج والمواد المصاحبة متاحة بموجب شروط رخصة Eclipse Public License 2.0 المتاحة على https://www.eclipse.org/legal/epl-2.0.
قد يتوفر كود المصدر هذا أيضًا بموجب التراخيص الثانوية التالية عند استيفاء شروط هذا التوفر المنصوص عليها في Eclipse Public License، الإصدار 2.0: رخصة GNU العامة العامة كما نشرتها مؤسسة البرمجيات الحرة، إما الإصدار 2 من الرخصة، أو (حسب اختيارك) أي إصدار لاحق، مع استثناء GNU Classpath المتاح على https://www.gnu.org/software/classpath/license.html.