2016-10-19 17:06:37 -04:00
< ? php
2016-10-21 19:04:04 -04:00
/**
* @ file include / dbclean . php
* @ brief The script is called from time to time to clean the database entries and remove orphaned data .
*/
2017-01-07 04:05:52 -05:00
2017-04-30 00:29:14 -04:00
use Friendica\Core\Config ;
2016-10-19 17:06:37 -04:00
2016-10-22 00:57:52 -04:00
function dbclean_run ( & $argv , & $argc ) {
2017-01-07 04:05:52 -05:00
if ( ! Config :: get ( 'system' , 'dbclean' , false )) {
2017-01-04 14:13:50 -05:00
return ;
}
2016-10-22 06:14:41 -04:00
if ( $argc == 2 ) {
$stage = intval ( $argv [ 1 ]);
} else {
$stage = 0 ;
}
2016-11-01 17:36:15 -04:00
2017-02-26 18:16:49 -05:00
if ( $stage == 0 ) {
2017-05-12 12:09:25 -04:00
for ( $i = 1 ; $i <= 7 ; $i ++ ) {
if ( ! Config :: get ( 'system' , 'finished-dbclean-' . $i )) {
proc_run ( PRIORITY_LOW , 'include/dbclean.php' , $i );
}
}
2016-11-01 17:36:15 -04:00
} else {
remove_orphans ( $stage );
}
2016-10-22 00:57:52 -04:00
}
2016-10-19 17:06:37 -04:00
2016-10-21 19:04:04 -04:00
/**
* @ brief Remove orphaned database entries
*/
2016-10-22 06:14:41 -04:00
function remove_orphans ( $stage = 0 ) {
global $db ;
2016-11-01 17:36:15 -04:00
$count = 0 ;
2017-02-26 18:16:49 -05:00
// We split the deletion in many small tasks
$limit = 1000 ;
2017-01-09 04:37:37 -05:00
2017-05-12 00:33:52 -04:00
if ( $stage == 1 ) {
2016-10-31 17:32:08 -04:00
logger ( " Deleting old global item entries from item table without user copy " );
2017-04-24 17:02:51 -04:00
$r = dba :: p ( " SELECT `id` FROM `item` WHERE `uid` = 0
2016-10-31 17:32:08 -04:00
AND NOT EXISTS ( SELECT `guid` FROM `item` AS `i` WHERE `item` . `guid` = `i` . `guid` AND `i` . `uid` != 0 )
2017-04-24 17:02:51 -04:00
AND `received` < UTC_TIMESTAMP () - INTERVAL 90 DAY LIMIT " .intval( $limit ));
$count = dba :: num_rows ( $r );
if ( $count > 0 ) {
2016-10-31 17:32:08 -04:00
logger ( " found global item orphans: " . $count );
2017-04-24 17:02:51 -04:00
while ( $orphan = dba :: fetch ( $r )) {
2017-05-11 16:13:45 -04:00
dba :: delete ( 'item' , array ( 'id' => $orphan [ " id " ]));
2016-10-31 17:32:08 -04:00
}
2017-05-11 16:13:45 -04:00
} else {
logger ( " No global item orphans found " );
2017-05-12 12:09:25 -04:00
// We will eventually set this value when we found a good way to delete these items in another way.
// Config::set('system', 'finished-dbclean-1', true);
2016-10-31 17:32:08 -04:00
}
2017-04-24 17:02:51 -04:00
dba :: close ( $r );
2017-05-11 16:13:45 -04:00
logger ( " Done deleting " . $count . " old global item entries from item table without user copy " );
2017-05-12 00:33:52 -04:00
} elseif ( $stage == 2 ) {
2016-10-31 17:32:08 -04:00
logger ( " Deleting items without parents " );
2017-04-24 17:02:51 -04:00
$r = dba :: p ( " SELECT `id` FROM `item` WHERE NOT EXISTS (SELECT `id` FROM `item` AS `i` WHERE `item`.`parent` = `i`.`id`) LIMIT " . intval ( $limit ));
$count = dba :: num_rows ( $r );
if ( $count > 0 ) {
2016-10-31 17:32:08 -04:00
logger ( " found item orphans without parents: " . $count );
2017-04-24 17:02:51 -04:00
while ( $orphan = dba :: fetch ( $r )) {
2017-05-11 16:13:45 -04:00
dba :: delete ( 'item' , array ( 'id' => $orphan [ " id " ]));
2016-10-31 17:32:08 -04:00
}
2017-05-11 16:13:45 -04:00
} else {
logger ( " No item orphans without parents found " );
2017-05-12 12:09:25 -04:00
Config :: set ( 'system' , 'finished-dbclean-2' , true );
2016-10-31 17:32:08 -04:00
}
2017-04-24 17:02:51 -04:00
dba :: close ( $r );
2017-05-11 16:13:45 -04:00
logger ( " Done deleting " . $count . " items without parents " );
2017-05-12 00:33:52 -04:00
} elseif ( $stage == 3 ) {
2016-10-22 06:14:41 -04:00
logger ( " Deleting orphaned data from thread table " );
2017-04-24 17:02:51 -04:00
$r = dba :: p ( " SELECT `iid` FROM `thread` WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`parent` = `thread`.`iid`) LIMIT " . intval ( $limit ));
$count = dba :: num_rows ( $r );
if ( $count > 0 ) {
2016-10-31 17:32:08 -04:00
logger ( " found thread orphans: " . $count );
2017-04-24 17:02:51 -04:00
while ( $orphan = dba :: fetch ( $r )) {
2017-05-11 16:13:45 -04:00
dba :: delete ( 'thread' , array ( 'iid' => $orphan [ " iid " ]));
2016-10-22 06:14:41 -04:00
}
2017-05-11 16:13:45 -04:00
} else {
logger ( " No thread orphans found " );
2017-05-12 12:09:25 -04:00
Config :: set ( 'system' , 'finished-dbclean-3' , true );
2016-10-22 06:14:41 -04:00
}
2017-05-11 16:13:45 -04:00
2017-04-24 17:02:51 -04:00
dba :: close ( $r );
2017-05-11 16:13:45 -04:00
logger ( " Done deleting " . $count . " orphaned data from thread table " );
2017-05-12 00:33:52 -04:00
} elseif ( $stage == 4 ) {
2016-10-22 06:14:41 -04:00
logger ( " Deleting orphaned data from notify table " );
2017-04-24 17:02:51 -04:00
$r = dba :: p ( " SELECT `iid` FROM `notify` WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `notify`.`iid`) LIMIT " . intval ( $limit ));
$count = dba :: num_rows ( $r );
if ( $count > 0 ) {
2016-10-31 17:32:08 -04:00
logger ( " found notify orphans: " . $count );
2017-04-24 17:02:51 -04:00
while ( $orphan = dba :: fetch ( $r )) {
2017-05-11 16:13:45 -04:00
dba :: delete ( 'notify' , array ( 'iid' => $orphan [ " iid " ]));
2016-10-22 06:14:41 -04:00
}
2017-05-11 16:13:45 -04:00
} else {
logger ( " No notify orphans found " );
2017-05-12 12:09:25 -04:00
Config :: set ( 'system' , 'finished-dbclean-4' , true );
2016-10-22 06:14:41 -04:00
}
2017-04-24 17:02:51 -04:00
dba :: close ( $r );
2017-05-11 16:13:45 -04:00
logger ( " Done deleting " . $count . " orphaned data from notify table " );
2017-05-12 00:33:52 -04:00
} elseif ( $stage == 5 ) {
2016-10-31 17:32:08 -04:00
logger ( " Deleting orphaned data from notify-threads table " );
2017-04-24 17:02:51 -04:00
$r = dba :: p ( " SELECT `id` FROM `notify-threads` WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`parent` = `notify-threads`.`master-parent-item`) LIMIT " . intval ( $limit ));
$count = dba :: num_rows ( $r );
if ( $count > 0 ) {
2016-10-31 17:32:08 -04:00
logger ( " found notify-threads orphans: " . $count );
2017-04-24 17:02:51 -04:00
while ( $orphan = dba :: fetch ( $r )) {
2017-05-11 16:13:45 -04:00
dba :: delete ( 'notify-threads' , array ( 'id' => $orphan [ " id " ]));
2016-10-31 17:32:08 -04:00
}
2017-05-11 16:13:45 -04:00
} else {
logger ( " No notify-threads orphans found " );
2017-05-12 12:09:25 -04:00
Config :: set ( 'system' , 'finished-dbclean-5' , true );
2016-10-31 17:32:08 -04:00
}
2017-04-24 17:02:51 -04:00
dba :: close ( $r );
2017-05-11 16:13:45 -04:00
logger ( " Done deleting " . $count . " orphaned data from notify-threads table " );
2017-05-12 00:33:52 -04:00
} elseif ( $stage == 6 ) {
2016-10-22 06:14:41 -04:00
logger ( " Deleting orphaned data from sign table " );
2017-04-24 17:02:51 -04:00
$r = dba :: p ( " SELECT `iid` FROM `sign` WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `sign`.`iid`) LIMIT " . intval ( $limit ));
$count = dba :: num_rows ( $r );
if ( $count > 0 ) {
2016-10-31 17:32:08 -04:00
logger ( " found sign orphans: " . $count );
2017-04-24 17:02:51 -04:00
while ( $orphan = dba :: fetch ( $r )) {
2017-05-11 16:13:45 -04:00
dba :: delete ( 'sign' , array ( 'iid' => $orphan [ " iid " ]));
2016-10-22 06:14:41 -04:00
}
2017-05-11 16:13:45 -04:00
} else {
logger ( " No sign orphans found " );
2017-05-12 12:09:25 -04:00
Config :: set ( 'system' , 'finished-dbclean-6' , true );
2016-10-22 06:14:41 -04:00
}
2017-04-24 17:02:51 -04:00
dba :: close ( $r );
2017-05-11 16:13:45 -04:00
logger ( " Done deleting " . $count . " orphaned data from sign table " );
2017-05-12 00:33:52 -04:00
} elseif ( $stage == 7 ) {
2016-10-22 06:14:41 -04:00
logger ( " Deleting orphaned data from term table " );
2017-04-24 17:02:51 -04:00
$r = dba :: p ( " SELECT `oid` FROM `term` WHERE NOT EXISTS (SELECT `id` FROM `item` WHERE `item`.`id` = `term`.`oid`) LIMIT " . intval ( $limit ));
$count = dba :: num_rows ( $r );
if ( $count > 0 ) {
2016-10-31 17:32:08 -04:00
logger ( " found term orphans: " . $count );
2017-04-24 17:02:51 -04:00
while ( $orphan = dba :: fetch ( $r )) {
2017-05-11 16:13:45 -04:00
dba :: delete ( 'term' , array ( 'oid' => $orphan [ " oid " ]));
2016-10-22 06:14:41 -04:00
}
2017-05-11 16:13:45 -04:00
} else {
logger ( " No term orphans found " );
2017-05-12 12:09:25 -04:00
Config :: set ( 'system' , 'finished-dbclean-7' , true );
2016-10-22 06:14:41 -04:00
}
2017-04-24 17:02:51 -04:00
dba :: close ( $r );
2017-05-11 16:13:45 -04:00
logger ( " Done deleting " . $count . " orphaned data from term table " );
2016-10-20 18:05:21 -04:00
}
2016-11-01 17:36:15 -04:00
// Call it again if not all entries were purged
2017-02-26 18:16:49 -05:00
if (( $stage != 0 ) AND ( $count > 0 )) {
2017-01-09 04:37:37 -05:00
proc_run ( PRIORITY_MEDIUM , 'include/dbclean.php' );
2016-11-01 17:36:15 -04:00
}
2016-10-19 17:06:37 -04:00
}