سؤال

لقد قمت بتجميع التطبيقات التي تتطلب تعيين إحدى العقد على أنها العقد الرئيسية.يتم تعقب العقد العنقودية في جدول مع معرف العقدة, com.isMaster, lastTimestamp أعمدة.

ستحاول كل عقدة في المجموعة أن تصبح رئيسية كل عقدة X ثواني.لا يمكن أن تصبح العقدة رئيسية إلا في حالة حدوث ذلك

  • لا توجد العقد الرئيسية الأخرى
  • ال lastTimestamp على العقدة الرئيسية الحالية أقدم من 2*س

عند استيفاء أحد الشروط المذكورة أعلاه

  • العقدة الرئيسية الحالية com.isMaster ينبغي مسحها
  • العقدة الرئيسية الجديدة com.isMaster ينبغي تعيين
  • العقدة الرئيسية الجديدة lastTimestamp يجب ضبطه على الطابع الزمني "الآن".

ما هو أعزب عبارة SQL (محمولة) لتحقيق ما ورد أعلاه دون إمكانية أن تصبح عقدتان أو أكثر هي العقدة الرئيسية؟

هل كانت مفيدة؟

المحلول

ألا يتم التعامل مع هذا النوع من التنسيق عادةً بواسطة نظام إدارة قواعد البيانات (DBMS) نفسه، بدلاً من التطبيقات التي تعمل على نظام إدارة قواعد البيانات (DBMS)؟يمكنني أيضًا أن أتصور طرقًا للقيام بذلك في نظام إدارة قواعد البيانات (DBMS) الذي أعرفه، ولكن دون معرفة المزيد عن نظامك (من المفترض أنه يستخدم الأقراص المشتركة، بحيث ترى جميع العقد نفس البيانات؛من المفترض أن تكون هناك بروتوكولات قفل تمنع الوصول المتزامن إلى البيانات؛هل هي عملية مستخدم على العقدة الرئيسية تقوم بتحديث الطابع الزمني الأخير بشكل دوري)، فسيكون من الصعب تقديم المساعدة كثيرًا.وكما أشار جيمي لوف، ينبغي لنظام إدارة قواعد البيانات أن يسمح بعمليات متعددة لتنسيق الوصول إلى السجلات ذات الصلة - والسجل الرئيسي ذو الصلة هو السجل الرئيسي الحالي.

[تم تحريره:ربما كنت أقرأ الكثير في ذلك.

يجب أن تقوم عبارة UPDATE الفردية بإجراء تحديثات تفاضلية على صفين من الجدول، ويجب أن تفشل إذا كان من الممكن إجراء تحديث واحد فقط.أي أنه يجب عليه تغيير السجل الرئيسي الحالي ليصبح غير رئيسي وكذلك تغيير السجل الخاص به بحيث يصبح السيد.تتمثل إحدى المشكلات في كيفية قيام نظام إدارة قواعد البيانات (DBMS) بفرض القيد "قد يكون صف واحد فقط هو القيد الرئيسي".لنفترض أن هذا يعمل وأن العبارة ككل ستفشل إذا كانت هناك مشكلة - كما ينبغي.لماذا يحذف الأشخاص في كثير من الأحيان اسم الجدول، حتى عندما يقدمون أسماء الأعمدة؟حسنًا، اسم الجدول فيما يلي التحكم في الكتلة.يجب أن تعرف كل عقدة NodeID الخاصة بها بطريقة أو بأخرى؛لقد استخدمت {MyNodeID} للإشارة إلى المكان الذي يظهر فيه في SQL.

أنت بحاجة إلى تحديث منفصل لنبضات القلب:

 UPDATE ClusterControl
     SET lastTimestamp = CURRENT_TIMESTAMP
     WHERE NodeID = {MyNodeID};

قد يكون تحديث "الاستيلاء على الحالة الرئيسية":

UPDATE ClusterControl
    SET lastTimestamp = (CASE
                         WHEN NodeID = {MyNodeID} THEN CURRENT_TIMESTAMP
                         ELSE lastTimestamp END),
        isMaster      = (CASE
                         WHEN NodeID = {MyNodeId} THEN 'Y'
                         ELSE 'N' END)
    WHERE (NodeID  = {MyNodeID} AND isMaster = 'N') OR
          (NodeID != {MyNodeID} AND
           lastTimestamp < CURRENT_TIMESTAMP - INTERVAL '120' SECOND AND
           isMaster = 'Y'
          );

النظرية وراء تحديث "الاستيلاء على الحالة الرئيسية" هي (شرط SET):

  • يتم تعيين حقل lastTimestamp للرقم الرئيسي الجديد على الطابع الزمني الحالي، لكن الملف الرئيسي القديم لم يتغير.
  • يتم تغيير الحقل isMaster إلى "Y" للسيد الجديد وإلى "N" للسيد القديم.

النظرية وراء جملة WHERE هي:

  • قم بتغيير السجل الخاص بالعقدة الحالية فقط إذا لم تكن العقدة الرئيسية الحالية أو سجل العقدة الرئيسية الحالية عندما لا تكون هذه العقدة هي العقدة الحالية ويكون الطابع الزمني أكثر من 120 ثانية ("2 * X" في السؤال) قديم .

نظرًا لوجود قيد (ربما أسطوري) لضمان أن صفًا واحدًا فقط يحتوي على العلامة "Y"، فمن المفترض أن يفشل هذا كما هو مطلوب عندما يكون المعلم الرئيسي محدثًا.

SQL لم يتم اختبارها!

]

نصائح أخرى

يمكنني أن أتخيل حلاً لقاعدة بيانات Oracle ولكني لست متأكدًا من أنه سيكون محمولاً.لماذا يجب أن يكون هذا عبارة SQL محمولة واحدة؟تسمح معظم قواعد البيانات بقفل الجدول والمعاملات، مما يسمح لك بالقيام بهذا النوع من الأشياء في بيانات متعددة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top