โดยทั่วไปแล้วอะไรคือจุดประสงค์ของตาราง Semaphore ของ Drupal DB


9

ฉันเข้าใจวัตถุประสงค์ของ semaphores ในการเขียนโปรแกรม IPC แต่ฉันไม่พบคำอธิบายที่ดี - หรือคำอธิบายใด ๆ เกี่ยวกับวัตถุประสงค์ของตารางนี้

คำตอบ:


11

ตารางสัญญาณที่ใช้จากกลไกการล็อคการดำเนินการโดยค่าเริ่มต้นจาก Drupal ไม่แตกต่างจากกลไกการล็อคปกติที่เห็นในการเขียนโปรแกรม: ค่าใช้เพื่อตรวจสอบการดำเนินการที่กำลังดำเนินการอยู่เพื่อหลีกเลี่ยงความขัดแย้งหรือสภาพการแข่งขัน ความแตกต่างคือปกติล็อคเป็นไฟล์ในขณะที่ Drupal ใช้แถวในฐานข้อมูล

อันที่จริงกลไกการล็อคมีฟังก์ชั่นในการรับล็อค ( lock_acquire()) หรือรอการปลดล็อค ( lock_wait()) ในทั้งสองกรณีฐานข้อมูลสัญญาณจะใช้

// lock_acquire()
// Optimistically try to acquire the lock, then retry once if it fails.
// The first time through the loop cannot be a retry.
$retry = FALSE;
// We always want to do this code at least once.
do {
  try {
    db_insert('semaphore')
      ->fields(array(
        'name' => $name,
        'value' => _lock_id(),
        'expire' => $expire,
      ))
      ->execute();
    // We track all acquired locks in the global variable.
    $locks[$name] = TRUE;
    // We never need to try again.
    $retry = FALSE;
  }
  catch (PDOException $e) {
    // Suppress the error. If this is our first pass through the loop,
    // then $retry is FALSE. In this case, the insert must have failed
    // meaning some other request acquired the lock but did not release it.
    // We decide whether to retry by checking lock_may_be_available()
    // Since this will break the lock in case it is expired.
    $retry = $retry ? FALSE : lock_may_be_available($name);
  }
  //lock_may_be_available()
  $lock = db_query('SELECT expire, value FROM {semaphore} WHERE name = :name', array(':name' => $name))->fetchAssoc();
  if (!$lock) {
    return TRUE;
  }
  $expire = (float) $lock['expire'];
  $now = microtime(TRUE);
  if ($now > $expire) {
    // We check two conditions to prevent a race condition where another
    // request acquired the lock and set a new expire time. We add a small
    // number to $expire to avoid errors with float to string conversion.
    return (bool) db_delete('semaphore')
      ->condition('name', $name)
      ->condition('value', $lock['value'])
      ->condition('expire', 0.0001 + $expire, '<=')
      ->execute();
  }
  return FALSE;

ใน Drupal ผู้ใช้ที่แตกต่างกันสามารถร้องขอหน้าเดียวกันซึ่งหมายความว่าเธรดที่แตกต่างกันหรือกระบวนการสามารถรันรหัสเดียวกันในเวลาเดียวกัน สิ่งนี้อาจทำให้เกิดปัญหาเมื่อมีการอัปเดตตารางฐานข้อมูล การใช้การล็อกเป็นวิธีหนึ่งในการหลีกเลี่ยงปัญหานี้อาจทำให้เกิดปัญหา

เหตุผลที่ใช้ตารางฐานข้อมูลคือ Drupal ต้องการให้เอ็นจิ้นฐานข้อมูลทำงาน ใช้ตารางฐานข้อมูลสำหรับกลไกการล็อคเป็นวิธีการลดความต้องการ กลไกการล็อคสามารถใช้งานได้โดยใช้ส่วนขยาย APCu ด้วยและถ้าฉันจำได้อย่างถูกต้องก็มีโมดูลที่ทำเช่นนั้น


คำตอบที่ยอดเยี่ยม แต่เพื่อให้ชัดเจนตารางเซมาฟอร์แยกจากกลไกการล็อกเนทีฟในเอ็นจิน DB ซึ่งเป็นของตัวเอง (เช่น mysql)
Mike

2
ตารางสัญญาณจะถูกสร้างและใช้งานโดย Drupal มันไม่ได้ใช้จากโปรแกรมฐานข้อมูล
kiamlaluno

6

คำตอบจาก @kiamlaluno นั้นสมบูรณ์และสมบูรณ์แบบ แต่ฉันคิดว่ามันมุ่งเน้นไปที่การอธิบาย (เก่ง) แนวคิด / การใช้งานการล็อคฐานข้อมูลโดยใช้ semaphores ของ drupal

ฉันจะหันไปใกล้ OP:

วัตถุประสงค์ของตารางสัญญาณคือ (ตามที่อธิบายไว้ในคำอธิบายการสร้างตารางสัญญาณ):

ตารางสำหรับการเก็บเซมาฟอร์, ล็อค, แฟล็ก, และอื่น ๆ ที่ไม่สามารถจัดเก็บเป็นตัวแปร Drupal ได้เนื่องจากจะต้องไม่ถูกแคช

ดังนั้นจุดประสงค์ของตารางนั้นเป็นมากกว่าเพียงแค่กลไกการล็อคฐานข้อมูล (จนถึงตอนนี้ฉันสามารถเข้าใจได้จากความคิดเห็นนั้น) และยังระบุถึงข้อกำหนดทางเทคนิคของการหลีกเลี่ยงการแคชตัวแปร

หมายเหตุ: จะมีความสุขที่ได้รับการแก้ไขโดยคนที่มีความเชี่ยวชาญในหัวข้อนี้มากขึ้นถ้าฉันทำผิด ไชโย!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.