Skip to content
Extraits de code Groupes Projets
Valider fd5111b9 rédigé par mattab's avatar mattab
Parcourir les fichiers

Refs #4186 Adding advisory locking before running the DELETE query

parent fe84dfa4
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -52,6 +52,31 @@ class ArchiveWriter ...@@ -52,6 +52,31 @@ class ArchiveWriter
$this->dateStart = $this->period->getDateStart(); $this->dateStart = $this->period->getDateStart();
} }
protected function getArchiveLockName()
{
$numericTable = $this->getTableNumeric();
$dbLockName = "allocateNewArchiveId.$numericTable";
return $dbLockName;
}
/**
* @return array
* @throws \Exception
*/
protected function acquireArchiveTableLock()
{
$dbLockName = $this->getArchiveLockName();
if (Db::getDbLock($dbLockName, $maxRetries = 30) === false) {
throw new Exception("allocateNewArchiveId: Cannot get named lock for table $numericTable.");
}
}
protected function releaseArchiveTableLock()
{
$dbLockName = $this->getArchiveLockName();
Db::releaseDbLock($dbLockName);
}
public function getIdArchive() public function getIdArchive()
{ {
if ($this->idArchive === false) { if ($this->idArchive === false) {
...@@ -87,14 +112,10 @@ class ArchiveWriter ...@@ -87,14 +112,10 @@ class ArchiveWriter
$numericTable = $this->getTableNumeric(); $numericTable = $this->getTableNumeric();
$idSite = $this->idSite; $idSite = $this->idSite;
$db = Db::get(); $this->acquireArchiveTableLock();
$locked = self::PREFIX_SQL_LOCK . Common::generateUniqId(); $locked = self::PREFIX_SQL_LOCK . Common::generateUniqId();
$date = date("Y-m-d H:i:s"); $date = date("Y-m-d H:i:s");
$dbLockName = "allocateNewArchiveId.$numericTable";
if (Db::getDbLock($dbLockName, $maxRetries = 30) === false) {
throw new Exception("allocateNewArchiveId: Cannot get named lock for table $numericTable.");
}
$insertSql = "INSERT INTO $numericTable " $insertSql = "INSERT INTO $numericTable "
. " SELECT ifnull(max(idarchive),0)+1, . " SELECT ifnull(max(idarchive),0)+1,
'" . $locked . "', '" . $locked . "',
...@@ -106,7 +127,7 @@ class ArchiveWriter ...@@ -106,7 +127,7 @@ class ArchiveWriter
0 " 0 "
. " FROM $numericTable as tb1"; . " FROM $numericTable as tb1";
try { // TODO: this is temporary, remove when deadlocking issue is fixed try { // TODO: this is temporary, remove when deadlocking issue is fixed
$db->exec($insertSql); Db::get()->exec($insertSql);
} catch (Exception $ex) { } catch (Exception $ex) {
if (Db::get()->isErrNo($ex, 1213)) { if (Db::get()->isErrNo($ex, 1213)) {
$deadlockInfo = \Piwik\Db::fetchAll("SHOW ENGINE INNODB STATUS"); $deadlockInfo = \Piwik\Db::fetchAll("SHOW ENGINE INNODB STATUS");
...@@ -114,9 +135,9 @@ class ArchiveWriter ...@@ -114,9 +135,9 @@ class ArchiveWriter
} }
throw $ex; throw $ex;
} }
Db::releaseDbLock($dbLockName); $this->releaseArchiveTableLock();
$selectIdSql = "SELECT idarchive FROM $numericTable WHERE name = ? LIMIT 1"; $selectIdSql = "SELECT idarchive FROM $numericTable WHERE name = ? LIMIT 1";
$id = $db->fetchOne($selectIdSql, $locked); $id = Db::get()->fetchOne($selectIdSql, $locked);
return $id; return $id;
} }
...@@ -155,11 +176,15 @@ class ArchiveWriter ...@@ -155,11 +176,15 @@ class ArchiveWriter
protected function deletePreviousArchiveStatus() protected function deletePreviousArchiveStatus()
{ {
// without advisory lock here, the DELETE would acquire Exclusive Lock
$this->acquireArchiveTableLock();
Db::query("DELETE FROM " . $this->getTableNumeric() . " Db::query("DELETE FROM " . $this->getTableNumeric() . "
WHERE idarchive = ? AND (name = '" . $this->doneFlag . "' OR name LIKE '" . self::PREFIX_SQL_LOCK . "%')", WHERE idarchive = ? AND (name = '" . $this->doneFlag . "' OR name LIKE '" . self::PREFIX_SQL_LOCK . "%')",
array($this->getIdArchive()) array($this->getIdArchive())
); );
$this->releaseArchiveTableLock();
} }
protected function logArchiveStatusAsFinal() protected function logArchiveStatusAsFinal()
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter