Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zerolab/8b2531599bff611942ae to your computer and use it in GitHub Desktop.
Save zerolab/8b2531599bff611942ae to your computer and use it in GitHub Desktop.
diff --git a/includes/database.mysqli.inc b/includes/database.mysqli.inc
index e208a66..e4eb6a5 100644
--- a/includes/database.mysqli.inc
+++ b/includes/database.mysqli.inc
@@ -133,34 +133,72 @@ function _db_query($query, $debug = 0, $slave = FALSE) {
$query = '/* '. $name .' : '. $bt[2]['function'] .' */ '. $query;
}
- $sent_to_slave = FALSE;
- if (isset($active_slave_db) && $slave) {
- $result = mysqli_query($active_slave_db, $query);
- $sent_to_slave = TRUE;
- }
- else {
- $result = mysqli_query($active_db, $query);
- }
+ $retry = 0;
+ do {
+ $sent_to_slave = FALSE;
+ if (isset($active_slave_db) && $slave) {
+ $result = mysqli_query($active_slave_db, $query);
+ $errno = mysqli_errno($active_slave_db);
+ $sent_to_slave = TRUE;
+ }
+ else {
+ $result = mysqli_query($active_db, $query);
+ $errno = mysqli_errno($active_db);
+ }
- if (variable_get('dev_query', 0)) {
- $query = $bt[2]['function'] ."\n". $query;
- list($usec, $sec) = explode(' ', microtime());
- $stop = (float)$usec + (float)$sec;
- $diff = $stop - $timer;
- $queries[] = array($query, $diff, $sent_to_slave);
- }
+ if (variable_get('dev_query', 0)) {
+ $query = $bt[2]['function'] ."\n". $query;
+ list($usec, $sec) = explode(' ', microtime());
+ $stop = (float)$usec + (float)$sec;
+ $diff = $stop - $timer;
+ $queries[] = array($query, $diff, $sent_to_slave);
+ }
+
+ // Handle transient errors.
+ // If we can handle this error, then increment the counter, so we run again. Otherwise
+ // use the default case to exit the while loop and return an error as per normal.
+ switch($errno) {
+ case 1153: // Got a packet bigger than "max_allowed_packet" bytes
+ // If the MySQL Server rejected the query because it's too big,
+ // writing the query to database watchdog will fail as well
+ // Truncate the query ...
+ $retry = 2;
+ $query = substr($query, 0, 100);
+ break;
+
+ case 1205: // Lock wait timeout exceeded; try restarting transaction
+ case 1213: // Deadlock found when trying to get lock; try restarting transaction
+ $retry++; // Increment counter.
+ break;
+
+ case 1614: // Transaction branch was rolled back: deadlock was detected
+ case 2013: // Lost connection to MySQL server during query
+ $retry++; // Increment counter.
+ if ($sent_to_slave) {
+ $slave = FALSE; // Retry on master.
+ }
+ break;
+
+ // If not an error we can handle (or not an error!) exit the loop.
+ // We cal deal with fall-out later, as errno is set.
+ default:
+ $retry = 2;
+ break;
+ }
+
+ if (!$sent_to_slave) {
+ $active_last_db = $active_db;
+ } else {
+ $active_last_db = $active_slave_db;
+ }
+ } while ($retry < 2);
- if (!$sent_to_slave) {
- $active_last_db = $active_db;
- } else {
- $active_last_db = $active_slave_db;
- }
if ($debug) {
print '<p>query: '. $query .'<br />error:'. mysqli_error($active_db) .'</p>';
}
- if (!mysqli_errno($active_last_db)) {
+ if (!$errno) {
return $result;
}
else {
diff --git a/includes/database.mysql.inc b/includes/database.mysql.inc
index acad975..f53daa5 100644
--- a/includes/database.mysql.inc
+++ b/includes/database.mysql.inc
@@ -134,34 +134,71 @@ function _db_query($query, $debug = 0, $slave = FALSE) {
$query = '/* '. $name .' : '. $bt[2]['function'] .' */ '. $query;
}
- $sent_to_slave = FALSE;
- if (isset($active_slave_db) && $slave) {
- $result = mysql_query($query, $active_slave_db);
- $sent_to_slave = TRUE;
- }
- else {
- $result = mysql_query($query, $active_db);
- }
+ $retry = 0;
+ do {
+ $sent_to_slave = FALSE;
+ if (isset($active_slave_db) && $slave) {
+ $result = mysql_query($query, $active_slave_db);
+ $errno = mysql_errno($active_slave_db);
+ $sent_to_slave = TRUE;
+ }
+ else {
+ $result = mysql_query($query, $active_db);
+ $errno = mysql_errno($active_db);
+ }
- if (variable_get('dev_query', 0)) {
- $query = $bt[2]['function'] ."\n". $query;
- list($usec, $sec) = explode(' ', microtime());
- $stop = (float)$usec + (float)$sec;
- $diff = $stop - $timer;
- $queries[] = array($query, $diff, $sent_to_slave);
- }
+ if (variable_get('dev_query', 0)) {
+ $query = $bt[2]['function'] ."\n". $query;
+ list($usec, $sec) = explode(' ', microtime());
+ $stop = (float)$usec + (float)$sec;
+ $diff = $stop - $timer;
+ $queries[] = array($query, $diff, $sent_to_slave);
+ }
- if (!$sent_to_slave) {
- $active_last_db = $active_db;
- } else {
- $active_last_db = $active_slave_db;
- }
+ // Handle transient errors.
+ // If we can handle this error, then increment the counter, so we run again. Otherwise
+ // use the default case to exit the while loop and return an error as per normal.
+ switch($errno) {
+ case 1153: // Got a packet bigger than "max_allowed_packet" bytes
+ // If the MySQL Server rejected the query because it's too big,
+ // writing the query to database watchdog will fail as well
+ // Truncate the query ...
+ $retry = 2;
+ $query = substr($query, 0, 100);
+ break;
+
+ case 1205: // Lock wait timeout exceeded; try restarting transaction
+ case 1213: // Deadlock found when trying to get lock; try restarting transaction
+ $retry++; // Increment counter.
+ break;
+
+ case 1614: // Transaction branch was rolled back: deadlock was detected
+ case 2013: // Lost connection to MySQL server during query
+ $retry++; // Increment counter.
+ if ($sent_to_slave) {
+ $slave = FALSE; // Retry on master.
+ }
+ break;
+
+ // If not an error we can handle (or not an error!) exit the loop.
+ // We cal deal with fall-out later, as errno is set.
+ default:
+ $retry = 2;
+ break;
+ }
+
+ if (!$sent_to_slave) {
+ $active_last_db = $active_db;
+ } else {
+ $active_last_db = $active_slave_db;
+ }
+ } while ($retry < 2);
if ($debug) {
print '<p>query: '. $query .'<br />error:'. mysql_error($active_db) .'</p>';
}
- if (!mysql_errno($active_last_db)) {
+ if (!$errno) {
return $result;
}
else {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment