Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Old records are not being removed #1056

Open
kasparsd opened this issue Mar 19, 2020 · 6 comments · Fixed by #1159 · May be fixed by #1236
Open

Old records are not being removed #1056

kasparsd opened this issue Mar 19, 2020 · 6 comments · Fixed by #1159 · May be fixed by #1236
Assignees
Labels

Comments

@kasparsd
Copy link
Contributor

kasparsd commented Mar 19, 2020

From https://wordpress.org/support/topic/old-records-are-not-being-removed/

I have a few sites with the Stream plugin installed. I just noticed that none of them are removing old records. I have the “Keep Records for” setting set to 30, but with records going back more than a year. They aren’t being removed. Any idea why that would happen and how to resolve it?

Duplicate reports:

@lkraav
Copy link
Contributor

lkraav commented Apr 22, 2020

I can confirm, this is happening on one of our client site as well. Oldest records available are now from 2016. This site was not intended to have an eternal memory.

@kopepasah kopepasah self-assigned this Jun 15, 2020
@kopepasah
Copy link
Contributor

I am starting review of this today and will carve out some time to investigate/fix this week.

@kopepasah
Copy link
Contributor

@kasparsd did you do any research into how the cron schedules run for deleting the logs. WordPress Cron is notorious for missing events without a dedicated native cron to trigger WordPress Cron. I have a suspicion this may be related to these records not being removed and posted a question in the WordPress support forum topic related to this issue.

@kasparsd
Copy link
Contributor Author

kasparsd commented Jul 8, 2020

@kopepasah The method used for deleting the older logs is defined here:

public function purge_scheduled_action() {
global $wpdb;
// Don't purge when in Network Admin unless Stream is network activated.
if (
is_multisite()
&&
is_network_admin()
&&
! $this->plugin->is_network_activated()
) {
return;
}
if ( is_multisite() && $this->plugin->is_network_activated() ) {
$options = (array) get_site_option( 'wp_stream_network', array() );
} else {
$options = (array) get_option( 'wp_stream', array() );
}
if ( ! empty( $options['general_keep_records_indefinitely'] ) || ! isset( $options['general_records_ttl'] ) ) {
return;
}
$days = $options['general_records_ttl'];
$timezone = new DateTimeZone( 'UTC' );
$date = new DateTime( 'now', $timezone );
$date->sub( DateInterval::createFromDateString( "$days days" ) );
$where = $wpdb->prepare( ' AND `stream`.`created` < %s', $date->format( 'Y-m-d H:i:s' ) );
// Multisite but NOT network activated, only purge the current blog.
if ( is_multisite() && ! $this->plugin->is_network_activated() ) {
$where .= $wpdb->prepare( ' AND `blog_id` = %d', get_current_blog_id() );
}
$wpdb->query(
"DELETE `stream`, `meta`
FROM {$wpdb->stream} AS `stream`
LEFT JOIN {$wpdb->streammeta} AS `meta`
ON `meta`.`record_id` = `stream`.`ID`
WHERE 1=1 {$where};" // @codingStandardsIgnoreLine $where already prepared
);
}

Notice that it has several conditionals which can stop the deletion from happening. I haven't verified if all of them work as expected.

The wp_stream_auto_purge action is scheduled here to run twice per day:

public function purge_schedule_setup() {
if ( ! wp_next_scheduled( 'wp_stream_auto_purge' ) ) {
wp_schedule_event( time(), 'twicedaily', 'wp_stream_auto_purge' );
}
}

There is also a test case for this method and it appears to be passing:

public function test_purge_scheduled_action() {
// Set the TTL to one day
if ( is_multisite() && is_plugin_active_for_network( $this->plugin->locations['plugin'] ) ) {
$options = (array) get_site_option( 'wp_stream_network', array() );
$options['general_records_ttl'] = '1';
update_site_option( 'wp_stream_network', $options );
} else {
$options = (array) get_option( 'wp_stream', array() );
$options['general_records_ttl'] = '1';
update_option( 'wp_stream', $options );
}
global $wpdb;
// Create (two day old) dummy records
$stream_data = $this->dummy_stream_data();
$stream_data['created'] = gmdate( 'Y-m-d h:i:s', strtotime( '2 days ago' ) );
$wpdb->insert( $wpdb->stream, $stream_data );
$stream_id = $wpdb->insert_id;
$this->assertNotFalse( $stream_id );
// Create dummy meta
$meta_data = $this->dummy_meta_data( $stream_id );
$wpdb->insert( $wpdb->streammeta, $meta_data );
$meta_id = $wpdb->insert_id;
$this->assertNotFalse( $meta_id );
// Purge old records and meta
$this->admin->purge_scheduled_action();
// Check if the old records have been cleared
$stream_results = $wpdb->get_row( "SELECT * FROM {$wpdb->stream} WHERE ID = $stream_id" );
$this->assertEmpty( $stream_results );
// Check if the old meta has been cleared
$meta_results = $wpdb->get_row( "SELECT * FROM {$wpdb->streammeta} WHERE meta_id = $meta_id" );
$this->assertEmpty( $meta_results );
}

@codepuncher
Copy link

codepuncher commented Aug 6, 2020

@kasparsd @kopepasah I have done some testing and I can see that the plugin options are empty on my environments.

$options = (array) get_option( 'wp_stream', array() );

This is an empty array as the wp_stream option is not saved to the database.

After changing the values in the plugin settings and saving multiple times, it does update them and I can then run wp cron event run wp_stream_auto_purge with succession.

Whilst the event could run to completion on some environments and entries are removed, it does not work for a site that has 5,883,474 entries (294,174 pages) as it times out.

user@hostname:~/public/current$ wp cron event run wp_stream_auto_purge
WordPress database error Lock wait timeout exceeded; try restarting transaction for query DELETE `stream`, `meta`
                        FROM wp_stream AS `stream`
                        LEFT JOIN wp_stream_meta AS `meta`
                        ON `meta`.`record_id` = `stream`.`ID`
                        WHERE 1=1  AND `stream`.`created` < '2020-07-06 17:01:33'; made by include('phar:///usr/local/bin/wp/php/boot-phar.php'), include('phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/wp-cli.php'), WP_CLI\bootstrap, WP_CLI\Bootstrap\LaunchRunner->process, WP_CLI\Runner->start, WP_CLI\Runner->run_command_and_exit, WP_CLI\Runner->run_command, WP_CLI\Dispatcher\Subcommand->invoke, call_user_func, WP_CLI\Dispatcher\CommandFactory::WP_CLI\Dispatcher\{closure}, call_user_func, Cron_Event_Command->run, Cron_Event_Command::run_event, do_action_ref_array('wp_stream_auto_purge'), WP_Hook->do_action, WP_Hook->apply_filters, WP_Stream\Admin->purge_scheduled_action
Executed the cron event 'wp_stream_auto_purge' in 51.741s.

@kasparsd
Copy link
Contributor Author

Reopening since #1159 has been reverted.

@kasparsd kasparsd reopened this Feb 12, 2021
@kidunot89 kidunot89 linked a pull request Feb 22, 2021 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment