Skip to content

Instantly share code, notes, and snippets.

@diosmosis
Created March 5, 2015 01:37
Show Gist options
  • Save diosmosis/a6b9cc61ff08bbe9bab5 to your computer and use it in GitHub Desktop.
Save diosmosis/a6b9cc61ff08bbe9bab5 to your computer and use it in GitHub Desktop.
command to force purges on archive tables for 2.11.2
<?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\Plugins\CoreAdminHome\Commands;
use Piwik\Archive;
use Piwik\DataAccess\ArchivePurger;
use Piwik\DataAccess\ArchiveTableCreator;
use Piwik\DataAccess\InvalidatedReports;
use Piwik\Date;
use Piwik\Db;
use Piwik\Plugin\ConsoleCommand;
use Piwik\Plugins\SitesManager\API as SitesManagerAPI;
use Piwik\Timer;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* TODO
*/
class PurgeOldArchiveData extends ConsoleCommand
{
const ALL_DATES_STRING = 'all';
/**
* @var ArchivePurger
*/
private $archivePurger;
public function __construct(ArchivePurger $archivePurger = null)
{
parent::__construct();
$this->archivePurger = $archivePurger ?: new ArchivePurger();
}
protected function configure()
{
$this->setName('core:purge-old-archive-data');
$this->setDescription('Purges old and invalid archive data from archive tables.');
$this->addArgument("dates", InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
"The months of the archive tables to purge data from. By default, only deletes from the current month. Use '" . self::ALL_DATES_STRING. "' for all dates.",
array(Date::today()->toString()));
$this->addOption('exclude-outdated', null, InputOption::VALUE_NONE, "Do not purge outdated archive data.");
$this->addOption('exclude-invalidated', null, InputOption::VALUE_NONE, "Do not purge invalidated archive data.");
$this->addOption('skip-optimize-tables', null, InputOption::VALUE_NONE, "Do not run OPTIMIZE TABLES query on affected archive tables.");
$this->setHelp("By default old and invalidated archives are purged. Custom ranges are also purged with outdated archives.\n\n"
. "Note: archive purging is done during scheduled task execution, so under normal circumstances, you should not need to "
. "run this command manually.");
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$self = $this;
$dates = $this->getDatesToPurgeFor($input);
$excludeOutdated = $input->getOption('exclude-outdated');
if ($excludeOutdated) {
$output->writeln("Skipping purge outdated archive data.");
} else {
$this->trickPurgerIntoForcingPurge();
foreach ($dates as $date) {
$message = sprintf("Purging outdated archives for %s...", $date->toString('Y_m'));
$this->performTimedPurging($output, $message, function () use ($date, $self) {
$self->archivePurger->purgeOutdatedArchives($date);
});
}
}
$excludeInvalidated = $input->getOption('exclude-invalidated');
if ($excludeInvalidated) {
$output->writeln("Skipping purge invalidated archive data.");
} else {
$self->addAllSitesAndDatesToPurgeList($dates); // hack to get invalidated archives to purge no matter what
$this->performTimedPurging($output, "Purging invalidated archives...", function () use ($self) {
$self->archivePurger->purgeInvalidatedArchives();
});
}
$skipOptimizeTables = $input->getOption('skip-optimize-tables');
if ($skipOptimizeTables) {
$output->writeln("Skipping OPTIMIZE TABLES.");
} else {
$this->optimizeArchiveTables($output, $dates);
}
}
/**
* @param InputInterface $input
* @return Date[]
*/
private function getDatesToPurgeFor(InputInterface $input)
{
$dates = array();
$dateSpecifier = $input->getArgument('dates');
if (count($dateSpecifier) === 1
&& reset($dateSpecifier) == self::ALL_DATES_STRING
) {
foreach (ArchiveTableCreator::getTablesArchivesInstalled() as $table) {
$tableDate = ArchiveTableCreator::getDateFromTableName($table);
list($year, $month) = explode('_', $tableDate);
$dates[] = Date::factory($year . '-' . $month . '-' . '01');
}
} else {
foreach ($dateSpecifier as $date) {
$dates[] = Date::factory($date);
}
}
return $dates;
}
private function performTimedPurging(OutputInterface $output, $startMessage, $callback)
{
$timer = new Timer();
$output->write($startMessage);
$callback();
$output->writeln("Done. <comment>[" . $timer->__toString() . "]</comment>");
}
/**
* @param Date[] $dates
*/
private function addAllSitesAndDatesToPurgeList($dates)
{
$sitesId = SitesManagerAPI::getInstance()->getAllSitesId();
$yearMonths = array();
foreach ($dates as $date) {
$yearMonths[] = $date->toString('Y_m');
}
$invalidatedReportsList = new InvalidatedReports();
$invalidatedReportsList->addSitesToPurgeForYearMonths($sitesId, $yearMonths);
}
private function trickPurgerIntoForcingPurge()
{
$_GET['trigger'] = 'archivephp';
}
/**
* @param Date[] $dates
*/
private function optimizeArchiveTables(OutputInterface $output, $dates)
{
$output->writeln("Optimizing archive tables...");
foreach ($dates as $date) {
$numericTable = ArchiveTableCreator::getNumericTable($date);
$this->performTimedPurging($output, "Optimizing table $numericTable...", function () use ($numericTable) {
Db::optimizeTables($numericTable);
});
$blobTable = ArchiveTableCreator::getBlobTable($date);
$this->performTimedPurging($output, "Optimizing table $blobTable...", function () use ($blobTable) {
Db::optimizeTables($blobTable);
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment