• Hi, I’ve run into two issues with delete_transient() when redis-cache is active:

    1. delete_transient never returns true anymore even if a transient is/was present (not sure if deletion from the object cache is taking place at all, see #2).
    2. On set_transient the transient is stored in the database (why? is redis-cache doing that?) but on delete_transient the transient is not deleted from the database.

    I should note: This issue occurs on a subsite on a multisite installation. Is this a known issue or is this happening only on this installation?

Viewing 14 replies - 1 through 14 (of 14 total)
  • Plugin Author Till Krüss

    (@tillkruess)

    You can read the source code of the *_transient() methods, it’s got little to do with this plugin.

    https://developer.wordpress.org/reference/functions/set_transient/#source

    Thread Starter Rolf Allard van Hagen

    (@ravanh)

    That’s exactly what I was looking at. I assume that when redis-cache is active and wp_using_ext_object_cache() is true, this applies:

    if ( wp_using_ext_object_cache() || wp_installing() ) {
    $result = wp_cache_set( $transient, $value, 'transient', $expiration );
    }

    calling wp_cache_set() which uses the redis-cache method, not the else part of set_transient() which uses add_option() to store transient and timeout to the database…

    But… to my surprise I find that transients still appear in the database, right after set_transient is run. Where / when is this happening? Is redis-cache not doing that? If not, is it WordPress itself or something else on my installation?

    I should maybe explain more about the issue I’m facing with this:

    I’ve got a small implementation that stores external API queries with set_transient() for an hour to prevent the API being consulted too often and to improve load times. The implementation also has an admin method that will call delete_transient() to allow “flushing” the cached data before expiry, with an admin notice if any stored transient data was successfully deleted.

    function delete_my_plugin_data( $transient ) {
    $result = delete_transient( $transient );

    if ( $result ) {
    wp_admin_notice( 'Success!', [ 'type' => 'success' ] );
    } else {
    wp_admin_notice( 'Not found!', [ 'type' => 'error' ] );
    }
    }

    This works perfectly without Redis Object Cache activated. But with Redis Object Cache is active, delete_transient() does not delete the transient data anymore. At least not from the database. And $result is always false.

    To fix this, I had to add an extra routine to delete the transient from the database:

    function delete_my_plugin_data( $transient ) {
    $result = delete_transient( $transient );

    // When an object cache is active, make sure the DB entry is deleted as well.
    if ( wp_using_ext_object_cache() ) {
    $result = delete_option( '_transient_' . $transient );
    if ( $result ) {
    delete_option( '_transient_timeout_' . $transient );
    }
    }

    if ( $result ) {
    wp_admin_notice( 'Success!', [ 'type' => 'success' ] );
    } else {
    wp_admin_notice( 'Not found!', [ 'type' => 'error' ] );
    }
    }

    Is it normal that I should do this “double” routine to delete a transient when redis-cache is used?

    Thank you for your insights 🙂

    Plugin Author Till Krüss

    (@tillkruess)

    After running wp transient delete --all, and navigating around the site a little bit, do Transients still show up in the database?

    You shouldn’t need alter your code, I’ll take a look at this.

    Plugin Author Till Krüss

    (@tillkruess)

    I just tested delete_transient() against Redis Object Cache as well as Object Cache Pro (both using PhpRedis) and both return true once and then false as expected. Must be something with your particular WordPress setup.

    I’d check what wp_cache_delete() returns inside delete_transient().

    Thread Starter Rolf Allard van Hagen

    (@ravanh)

    Initially, after my wp transient delete --all transients did not show up anymore but then I did a Purge cache from the Object cache admin bar menu and right after that, the transients start appearing in the database again.

    $ wp --path=/xxx/xxx/htdocs --url=ecranvillage.net transient delete --all
    Success: 153 transients deleted from the database.
    Warning: Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.

    Thread Starter Rolf Allard van Hagen

    (@ravanh)

    Please note: this is a multisite. It is in fact a multi-network with https://fr.wordpress.org/plugins/wp-multi-network/ … Could this be causing a conflict?

    Plugin Author Till Krüss

    (@tillkruess)

    You probably have to call wp transient delete --all --network instead.

    Make sure you’re not using WP_REDIS_GRACEFUL.

    Thread Starter Rolf Allard van Hagen

    (@ravanh)

    Wanted to limit the test to one network subsite, but I’ll try with –network and let you know 🙂

    (WP_REDIS_GRACEFUL is not set in wp-config.php, could it be anywhere else?)

    Thread Starter Rolf Allard van Hagen

    (@ravanh)

    Somehow, with the –network flag it does not look like sub-site transients are deleted from the DB, not even the main site ones. Maybe only network transients (wherever they are stored) ?

    $ wp transient delete --all --network
    PHP Warning: Undefined array key "HTTP_HOST" in phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1335) : eval()'d code on line 64
    PHP Warning: Undefined array key "HTTP_HOST" in /var/www/xxx/htdocs/wp-includes/ms-settings.php on line 57
    Warning: Undefined array key "HTTP_HOST" in /var/www/xxx/htdocs/wp-includes/ms-settings.php on line 57
    Success: 101 transients deleted from the database.
    Warning: Transients are stored in an external object cache, and this command only deletes those stored in the database. You must flush the cache to delete all transients.
    Thread Starter Rolf Allard van Hagen

    (@ravanh)

    So to confirm:

    1. with wp --url=ecranvillage.net transient delete --all the transients get deleted from the database but remain in the redis object cache as expected;
    2. running delete_transient from admin will not delete a transient from the redis object cache (and returns false);
    3. only clearing the full object cache from admin will get rid of all the transients;
    4. after clearing the redis object cache, transients will start appearing in the database again;
    5. points 2 and 4 are not supposed to happen, meaning there is some conflict on my network installation.

    Could there be any reason outside of the WP install (like missing PHP modules or server settings) that could explain this? If not, I’ll have to do some thorough debugging :/

    Thread Starter Rolf Allard van Hagen

    (@ravanh)

    My diagnostics:

    Status: Connecté
    Client: PhpRedis (v5.3.7)
    Drop-in: Valid
    Disabled: No
    Ping: 1
    Errors: []
    PhpRedis: 5.3.7
    Relay: Not loaded
    Predis: 2.1.2
    Credis: Not loaded
    PHP Version: 8.3.6
    Plugin Version: 2.5.4
    Redis Version: 7.0.15
    Multisite: Yes
    Metrics: Enabled
    Metrics recorded: 5055
    Filesystem: Writable
    Global Prefix: ""
    Blog Prefix: 1
    Timeout: 1
    Read Timeout: 1
    Retry Interval:
    WP_REDIS_SCHEME: "unix"
    WP_REDIS_PATH: "/var/run/redis/redis.sock"
    WP_REDIS_DATABASE: 0
    WP_REDIS_PREFIX: "xx.x:"
    WP_CACHE_KEY_SALT: "xx.x:"
    WP_REDIS_PLUGIN_PATH: "/var/www/xxx/htdocs/wp-content/plugins/redis-cache"
    Global Groups: [
    "blog-details",
    "blog-id-cache",
    "blog-lookup",
    "global-posts",
    "networks",
    "rss",
    "sites",
    "site-details",
    "site-lookup",
    "site-options",
    "site-transient",
    "users",
    "useremail",
    "userlogins",
    "usermeta",
    "user_meta",
    "userslugs",
    "redis-cache",
    "blog_meta",
    "image_editor",
    "network-queries",
    "site-queries",
    "theme_files",
    "translation_files",
    "user-queries"
    ]
    Ignored Groups: [
    "counts",
    "plugins",
    "theme_json",
    "themes"
    ]
    Unflushable Groups: []
    Groups Types: {
    "blog-details": "global",
    "blog-id-cache": "global",
    "blog-lookup": "global",
    "global-posts": "global",
    "networks": "global",
    "rss": "global",
    "sites": "global",
    "site-details": "global",
    "site-lookup": "global",
    "site-options": "global",
    "site-transient": "global",
    "users": "global",
    "useremail": "global",
    "userlogins": "global",
    "usermeta": "global",
    "user_meta": "global",
    "userslugs": "global",
    "redis-cache": "global",
    "blog_meta": "global",
    "image_editor": "global",
    "network-queries": "global",
    "site-queries": "global",
    "theme_files": "global",
    "translation_files": "global",
    "user-queries": "global",
    "counts": "ignored",
    "plugins": "ignored",
    "theme_json": "ignored",
    "themes": "ignored"
    }
    Drop-ins: [
    "Anti-Splog (Spammed Notice and Splog Review Form) v by WPMU DEV",
    "Redis Object Cache Drop-In v2.5.4 by Till Krüss"
    ]
    Thread Starter Rolf Allard van Hagen

    (@ravanh)

    Just wondering… for a multisite, should I make WP_REDIS_PREFIX dynamic? Something like:

    define( 'WP_REDIS_PREFIX', $_SERVER['HTTP_HOST'] );
    Plugin Author Till Krüss

    (@tillkruess)

    You’ll have to debug this why 2 and 4 are happening, since I can’t replicate it.

    Thread Starter Rolf Allard van Hagen

    (@ravanh)

    I found the conflict. It was legacy code from a few years back put in place to work around an issue with transients in the W3 Total Cache Object Cache module at the time. Long since moved away from W3TC, the old work-around remained in place, causing this conflict with Redis Object Cache.

    Removing the old work-around, fixed everything.

    My sincerest apologies for having bothered you with this. And many many thanks for your time and thoughts, and for the excellent plugin 🙂

Viewing 14 replies - 1 through 14 (of 14 total)
  • You must be logged in to reply to this topic.