diff options
author | Thomas Steur <tsteur@users.noreply.github.com> | 2020-03-05 06:40:33 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-05 06:40:33 +0300 |
commit | 6a3fc7d70e231f5b50f1df56c3741cd4c9535fdc (patch) | |
tree | 4d2a5b443db90641aa47c1bfff66234de69a7722 /core | |
parent | 0fd0b3039b23524e5959c2243a25fe2ff53db175 (diff) |
Try to prevent a deadlock when writing options (#15666)
Diffstat (limited to 'core')
-rw-r--r-- | core/Archive/ArchiveInvalidator.php | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/core/Archive/ArchiveInvalidator.php b/core/Archive/ArchiveInvalidator.php index 8ead0f8a65..68274c9857 100644 --- a/core/Archive/ArchiveInvalidator.php +++ b/core/Archive/ArchiveInvalidator.php @@ -78,11 +78,12 @@ class ArchiveInvalidator // we do not really have to get the value first. we could simply always try to call set() and it would update or // insert the record if needed but we do not want to lock the table (especially since there are still some // MyISAM installations) - $values = Option::getLike($this->rememberArchivedReportIdStart . '%'); + $values = Option::getLike('%' . $this->rememberArchivedReportIdStart . '%'); $all = []; foreach ($values as $name => $value) { - $suffix = substr($name, strlen($this->rememberArchivedReportIdStart)); + $suffix = substr($name, strpos($name, $this->rememberArchivedReportIdStart)); + $suffix = str_replace($this->rememberArchivedReportIdStart, '', $suffix); list($idSite, $dateStr) = explode('_', $suffix); $all[$idSite][$dateStr] = $value; @@ -102,7 +103,7 @@ class ArchiveInvalidator // we do not really have to get the value first. we could simply always try to call set() and it would update or // insert the record if needed but we do not want to lock the table (especially since there are still some // MyISAM installations) - $value = Option::getLike($key . '%'); + $value = Option::getLike('%' . $key . '%'); } // getLike() returns an empty array rather than 'false' @@ -117,6 +118,7 @@ class ArchiveInvalidator $mykey = $this->buildRememberArchivedReportIdProcessSafe($idSite, $date->toString()); Option::set($mykey, '1'); Cache::clearCacheGeneral(); + return $mykey; } } @@ -134,11 +136,12 @@ class ArchiveInvalidator public function getRememberedArchivedReportsThatShouldBeInvalidated() { - $reports = Option::getLike($this->rememberArchivedReportIdStart . '%_%'); + $reports = Option::getLike('%' . $this->rememberArchivedReportIdStart . '%_%'); $sitesPerDay = array(); foreach ($reports as $report => $value) { + $report = substr($report, strpos($report, $this->rememberArchivedReportIdStart)); $report = str_replace($this->rememberArchivedReportIdStart, '', $report); $report = explode('_', $report); $siteId = (int) $report[0]; @@ -170,14 +173,16 @@ class ArchiveInvalidator // This version is multi process safe on the insert of a new date to invalidate. private function buildRememberArchivedReportIdProcessSafe($idSite, $date) { - $id = $this->buildRememberArchivedReportIdForSiteAndDate($idSite, $date); + $id = Common::getRandomString(4, 'abcdefghijklmnoprstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ') . '_'; + $id .= $this->buildRememberArchivedReportIdForSiteAndDate($idSite, $date); $id .= '_' . Common::getProcessId(); + return $id; } public function forgetRememberedArchivedReportsToInvalidateForSite($idSite) { - $id = $this->buildRememberArchivedReportIdForSite($idSite) . '_%'; + $id = $this->buildRememberArchivedReportIdForSite($idSite); $this->deleteOptionLike($id); Cache::clearCacheGeneral(); } @@ -201,7 +206,7 @@ class ArchiveInvalidator { // we're not using deleteLike since it maybe could cause deadlocks see https://github.com/matomo-org/matomo/issues/15545 // we want to reduce number of rows scanned and only delete specific primary key - $keys = Option::getLike($id . '%'); + $keys = Option::getLike('%' . $id . '%'); if (empty($keys)) { return; |