#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#33019 | Rafal Somla | 21 Dec |