MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Rafal Somla Date:December 21 2009 7:38am
Subject:bzr commit into mysql-6.0-backup branch (Rafal.Somla:2923) Bug#33019
View as plain text  
#At file:///ext/mysql/bzr/backup/bug33019/ based on revid:rafal.somla@stripped

 2923 Rafal Somla	2009-12-21
      Bug #33019 - Online backup process can consume too much processor time
      
      The problem is that BACKUP can enter a tight data pooling loop which
      consumes about 100% of CPU time if drv->get_data() calls are idle and
      produce no data.
      
      It is solved by counting consecutive idle iterations of the data 
      polling loop and inserting waits if this number exceeds a defined 
      threshold.
     @ sql/backup/data_backup.cc
        - Define the idle count threshold and idle wait constants.
        - Add Scheduler::m_idle_count member and initialize it with 0.
        - Update Scheduler::step() to insert waits and maintain idle iterations
          counter.

    modified:
      sql/backup/data_backup.cc
=== modified file 'sql/backup/data_backup.cc'
--- a/sql/backup/data_backup.cc	2009-12-19 15:23:03 +0000
+++ b/sql/backup/data_backup.cc	2009-12-21 07:38:02 +0000
@@ -26,6 +26,19 @@
 
  ***********************************************/
 
+/**
+  @brief Defines when a sleep should be inserted in the data reading loop.
+  
+  To avoid high CPU load, a wait will be inserted in the data reading loop
+  if more than @c WAIT_COUNT idle iterations have been made.
+*/ 
+#define WAIT_COUNT      10
+
+/**
+  @brief Duration in ms of the idle wait in the data reading loop.
+*/ 
+#define POLL_WAIT       50
+
 namespace backup {
 
 /**
@@ -297,12 +310,15 @@ private:
   */
   bool   m_vp_info_error;
 
+  /// Used to count consecutive idle iterations of the scheduler.
+  uint   m_idle_count;
+
   Scheduler(Output_stream &s, Logger &log)
     :init_count(0), prepare_count(0), finish_count(0),
     m_pumps(NULL), m_last(NULL), m_log(log),
     m_count(0), m_total(0), m_init_left(0), m_known_count(0),
     m_str(s), cancelled(FALSE),
-    m_failed_lock(NULL), m_vp_info_error(FALSE)
+    m_failed_lock(NULL), m_vp_info_error(FALSE), m_idle_count(0)
   {}
 
   void move_pump_to_end(const Pump_iterator&);
@@ -849,6 +865,13 @@ int Scheduler::step()
 
   DBUG_PRINT("backup_data",("polling %s", p->m_name));
 
+  // Insert a wait if number of idle iterations exceeds the threshold.
+  if (m_idle_count > WAIT_COUNT)
+  {
+    DBUG_PRINT("backu_data",("waiting %ud ms", POLL_WAIT));
+    my_sleep((POLL_WAIT)*1000UL);
+  }
+
   backup_state::value before_state= p->state;
 
   size_t howmuch;
@@ -871,6 +894,12 @@ int Scheduler::step()
       m_init_left -= howmuch;
   }
 
+  // Count consecutive iterations in which no data was sent from the driver.
+  if (howmuch == 0)
+    ++m_idle_count;
+  else
+    m_idle_count= 0;
+
   if (after_state != before_state)
   {
     switch (before_state) {


Attachment: [text/bzr-bundle] bzr/rafal.somla@sun.com-20091221073802-bb049clqu70rleme.bundle
Thread
bzr commit into mysql-6.0-backup branch (Rafal.Somla:2923) Bug#33019Rafal Somla21 Dec