1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\DataAccess;
use Exception;
use Piwik\ArchiveProcessor\Rules;
use Piwik\Config;
use Piwik\Date;
use Piwik\Db;
use Piwik\Log;
use Piwik\Piwik;
/**
*
* This class purges two types of archives:
*
* (1) Deletes invalidated archives (from ArchiveInvalidator)
*
* (2) Deletes outdated archives (the temporary or errored archives)
*
*
* @package Piwik\DataAccess
*/
class ArchivePurger
{
public static function purgeInvalidatedArchives()
{
$store = new InvalidatedReports();
$idSitesByYearMonth = $store->getSitesByYearMonthArchiveToPurge();
foreach ($idSitesByYearMonth as $yearMonth => $idSites) {
if(empty($idSites)) {
continue;
}
$date = Date::factory(str_replace('_', '-', $yearMonth) . '-01');
$numericTable = ArchiveTableCreator::getNumericTable($date);
$archiveIds = self::getModel()->getInvalidatedArchiveIdsSafeToDelete($numericTable, $idSites);
if (count($archiveIds) == 0) {
continue;
}
self::deleteArchiveIds($date, $archiveIds);
$store->markSiteIdsHaveBeenPurged($idSites, $yearMonth);
}
}
/**
* Removes the outdated archives for the given month.
* (meaning they are marked with a done flag of ArchiveWriter::DONE_OK_TEMPORARY or ArchiveWriter::DONE_ERROR)
*
* @param Date $dateStart Only the month will be used
*/
public static function purgeOutdatedArchives(Date $dateStart)
{
$purgeArchivesOlderThan = Rules::shouldPurgeOutdatedArchives($dateStart);
if (!$purgeArchivesOlderThan) {
return;
}
$idArchivesToDelete = self::getOutdatedArchiveIds($dateStart, $purgeArchivesOlderThan);
if (!empty($idArchivesToDelete)) {
self::deleteArchiveIds($dateStart, $idArchivesToDelete);
}
self::deleteArchivesWithPeriodRange($dateStart);
Log::debug("Purging temporary archives: done [ purged archives older than %s in %s ] [Deleted IDs: %s]",
$purgeArchivesOlderThan,
$dateStart->toString("Y-m"),
implode(',', $idArchivesToDelete));
}
protected static function getOutdatedArchiveIds(Date $date, $purgeArchivesOlderThan)
{
$archiveTable = ArchiveTableCreator::getNumericTable($date);
$result = self::getModel()->getTemporaryArchivesOlderThan($archiveTable, $purgeArchivesOlderThan);
$idArchivesToDelete = array();
if (!empty($result)) {
foreach ($result as $row) {
$idArchivesToDelete[] = $row['idarchive'];
}
}
return $idArchivesToDelete;
}
/**
* Deleting "Custom Date Range" reports after 1 day, since they can be re-processed and would take up un-necessary space.
*
* @param $date Date
*/
protected static function deleteArchivesWithPeriodRange(Date $date)
{
$numericTable = ArchiveTableCreator::getNumericTable($date);
$blobTable = ArchiveTableCreator::getBlobTable($date);
$daysRangesValid = Config::getInstance()->General['purge_date_range_archives_after_X_days'];
$pastDate = Date::factory('today')->subDay($daysRangesValid)->getDateTime();
self::getModel()->deleteArchivesWithPeriod($numericTable, $blobTable, Piwik::$idPeriods['range'], $pastDate);
Log::debug("Purging Custom Range archives: done [ purged archives older than %s from %s / blob ]",
$pastDate, $numericTable);
}
/**
* Deletes by batches Archive IDs in the specified month,
*
* @param Date $date
* @param $idArchivesToDelete
*/
protected static function deleteArchiveIds(Date $date, $idArchivesToDelete)
{
$batches = array_chunk($idArchivesToDelete, 1000);
$numericTable = ArchiveTableCreator::getNumericTable($date);
$blobTable = ArchiveTableCreator::getBlobTable($date);
foreach ($batches as $idsToDelete) {
self::getModel()->deleteArchiveIds($numericTable, $blobTable, $idsToDelete);
}
}
private static function getModel()
{
return new Model();
}
}
|