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