Options, Meta APIs: Prevent delete_expired_transients() from deleting site transients across networks - #13288
Conversation
… site transients across networks In multisite environments, site transients and their timeout entries are stored in the global `wp_sitemeta` table, separated by `site_id` (the network ID). The DELETE query in `delete_expired_transients()` joined the transient value row (`a`) and the timeout row (`b`) solely by matching `b.meta_key` with `a.meta_key`, without verifying that both rows belong to the same network. As a result, an expired site transient on one network would delete an unexpired site transient with the same key on another network, leaving behind an orphaned timeout row. This commit adds `AND b.site_id = a.site_id` to qualify the join in `delete_expired_transients()`, ensuring deletions only occur within the same network. Props robbsie, adamgreenwell, wprashed. Fixes #65969.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
Ticket
Trac ticket: https://core.trac.wordpress.org/ticket/65969
Description
In multisite environments, site transients and their timeout entries are stored in the global
wp_sitemetatable, separated bysite_id(representing the network ID).The multisite cleanup query in
delete_expired_transients()previously joined the transient value row (a) and timeout row (b) purely by matchingb.meta_keywitha.meta_key:Because
b.site_id = a.site_idwas not required, an expired site transient on one network would match an unexpired site transient with the same key on a different network and delete it fromwp_sitemeta, leaving an orphaned timeout row behind on the victim network.This PR adds
AND b.site_id = a.site_idto ensure the cleanup is properly scoped within the same network.Testing Instructions
phpunit -c tests/phpunit/multisite.xml --filter test_delete_expired_transients_does_not_cross_networksUse of AI Tools
AI assistance: Yes
Tool(s): Google Antigravity
Model(s): Gemini
Used for: Analyzing the cross-network multi-table delete issue, writing the multisite unit test, and applying the network qualification join condition.