Changeset 2571100
- Timestamp:
- 07/23/2021 07:11:29 PM (4 years ago)
- Location:
- memcached
- Files:
-
- 1 deleted
- 4 edited
- 1 copied
-
branches/4.0.0 (deleted)
-
tags/4.0.0 (copied) (copied from memcached/trunk)
-
tags/4.0.0/object-cache.php (modified) (10 diffs)
-
tags/4.0.0/readme.txt (modified) (2 diffs)
-
trunk/object-cache.php (modified) (10 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
memcached/tags/4.0.0/object-cache.php
r2317338 r2571100 4 4 Plugin Name: Memcached 5 5 Description: Memcached backend for the WP Object Cache. 6 Version: 3.2.27 Plugin URI: http ://wordpress.org/extend/plugins/memcached/6 Version: 4.0.0 7 Plugin URI: https://wordpress.org/plugins/memcached/ 8 8 Author: Ryan Boren, Denis de Bernardy, Matt Martz, Andy Skelton 9 9 … … 55 55 function wp_cache_get( $key, $group = '', $force = false, &$found = null ) { 56 56 global $wp_object_cache; 57 58 $value = apply_filters( 'pre_wp_cache_get', false, $key, $group, $force ); 59 if ( false !== $value ) { 60 $found = true; 61 return $value; 62 } 57 63 58 64 return $wp_object_cache->get( $key, $group, $force, $found ); … … 116 122 var $no_mc_groups = array(); 117 123 118 var $cache = array(); 119 var $mc = array(); 120 var $stats = array(); 121 var $group_ops = array(); 122 124 var $cache = array(); 125 var $mc = array(); 126 var $default_mcs = array(); 127 var $stats = array(); 128 var $group_ops = array(); 129 130 var $flush_group = 'WP_Object_Cache'; 131 var $global_flush_group = 'WP_Object_Cache_global'; 132 var $flush_key = "flush_number_v4"; 133 var $old_flush_key = "flush_number"; 123 134 var $flush_number = array(); 124 135 var $global_flush_number = null; … … 268 279 } 269 280 281 // Gets number from all default servers, replicating if needed 282 function get_max_flush_number( $group ) { 283 $key = $this->key( $this->flush_key, $group ); 284 285 $values = array(); 286 $size = 19; // size of microsecond timestamp serialized 287 foreach ( $this->default_mcs as $i => $mc ) { 288 $flags = false; 289 $this->timer_start(); 290 $values[ $i ] = $mc->get( $key, $flags ); 291 $elapsed = $this->timer_stop(); 292 293 if ( empty( $values[ $i ] ) ) { 294 $this->group_ops_stats( 'get_flush_number', $key, $group, null, $elapsed, 'not_in_memcache' ); 295 } else { 296 $this->group_ops_stats( 'get_flush_number', $key, $group, $size, $elapsed, 'memcache' ); 297 } 298 } 299 300 $max = max( $values ); 301 302 if ( ! $max > 0 ) { 303 return false; 304 } 305 306 // Replicate to servers not having the max. 307 $expire = 0; 308 foreach ( $this->default_mcs as $i => $mc ) { 309 if ( $values[ $i ] < $max ) { 310 $this->timer_start(); 311 $mc->set( $key, $max, false, $expire ); 312 $elapsed = $this->timer_stop(); 313 $this->group_ops_stats( 'set_flush_number', $key, $group, $size, $elapsed, 'replication_repair' ); 314 } 315 } 316 317 return $max; 318 } 319 320 function set_flush_number( $value, $group ) { 321 $key = $this->key( $this->flush_key, $group ); 322 $expire = 0; 323 $size = 19; 324 foreach ( $this->default_mcs as $i => $mc ) { 325 $this->timer_start(); 326 $mc->set( $key, $value, false, $expire ); 327 $elapsed = $this->timer_stop(); 328 $this->group_ops_stats( 'set_flush_number', $key, $group, $size, $elapsed, 'replication' ); 329 } 330 } 331 332 function get_flush_number( $group ) { 333 $flush_number = $this->get_max_flush_number( $group ); 334 // What if there is no v4 flush number? 335 if ( empty( $flush_number ) ) { 336 // Look for the v3 flush number key. 337 $flush_number = intval( $this->get( $this->old_flush_key, $group ) ); 338 if ( !empty( $flush_number ) ) { 339 // Found v3 flush number. Upgrade to v4 with replication. 340 $this->set_flush_number( $flush_number, $group ); 341 // Delete v3 key so we can't later restore it and find stale keys. 342 } else { 343 // No flush number found anywhere. Make a new one. This flushes the cache. 344 $flush_number = $this->new_flush_number(); 345 $this->set_flush_number( $flush_number, $group ); 346 } 347 } 348 349 return $flush_number; 350 } 351 352 function get_global_flush_number() { 353 if ( ! isset( $this->global_flush_number ) ) { 354 $this->global_flush_number = $this->get_flush_number( $this->global_flush_group ); 355 } 356 return $this->global_flush_number; 357 } 358 359 function get_blog_flush_number() { 360 if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) { 361 $this->flush_number[ $this->blog_prefix ] = $this->get_flush_number( $this->flush_group ); 362 } 363 return $this->flush_number[ $this->blog_prefix ]; 364 } 365 270 366 function flush() { 271 367 // Do not use the memcached flush method. It acts on an … … 273 369 // Flush is also unusable in some setups, e.g. twemproxy. 274 370 // Instead, rotate the key prefix for the current site. 275 // Global keys are rotated when flushing on the main site. 371 // Global keys are rotated when flushing on any network's 372 // main site. 276 373 $this->cache = array(); 277 374 278 $this->rotate_site_keys(); 375 $flush_number = $this->new_flush_number(); 376 377 $this->rotate_site_keys( $flush_number ); 279 378 280 379 if ( is_main_site() ) { 281 $this->rotate_global_keys(); 282 } 283 } 284 285 function rotate_site_keys() { 286 $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache' ); 287 288 $this->flush_number[ $this->blog_prefix ] = $this->incr( 'flush_number', 1, 'WP_Object_Cache' ); 289 } 290 291 function rotate_global_keys() { 292 $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache_global' ); 293 294 $this->global_flush_number = $this->incr( 'flush_number', 1, 'WP_Object_Cache_global' ); 380 $this->rotate_global_keys( $flush_number ); 381 } 382 } 383 384 function rotate_site_keys( $flush_number = null ) { 385 if ( is_null( $flush_number ) ) { 386 $flush_number = $this->new_flush_number(); 387 } 388 389 $this->set_flush_number( $flush_number, $this->flush_group ); 390 391 $this->flush_number[ $this->blog_prefix ] = $flush_number; 392 } 393 394 function rotate_global_keys( $flush_number = null ) { 395 if ( is_null( $flush_number ) ) { 396 $flush_number = $this->new_flush_number(); 397 } 398 399 $this->set_flush_number( $flush_number, $this->global_flush_group ); 400 401 $this->global_flush_number = $flush_number; 402 } 403 404 function new_flush_number() { 405 return intval( microtime( true ) * 1e6 ); 295 406 } 296 407 … … 418 529 419 530 function flush_prefix( $group ) { 420 if ( 'WP_Object_Cache' === $group || 'WP_Object_Cache_global' === $group ) {531 if ( $group === $this->flush_group || $group === $this->global_flush_group ) { 421 532 // Never flush the flush numbers. 422 533 $number = '_'; 423 534 } elseif ( false !== array_search( $group, $this->global_groups ) ) { 424 if ( ! isset( $this->global_flush_number ) ) { 425 $this->global_flush_number = intval( $this->get( 'flush_number', 'WP_Object_Cache_global' ) ); 426 } 427 428 if ( 0 === $this->global_flush_number ) { 429 $this->rotate_global_keys(); 430 } 431 432 $number = $this->global_flush_number; 535 $number = $this->get_global_flush_number(); 433 536 } else { 434 if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) { 435 $this->flush_number[ $this->blog_prefix ] = intval( $this->get( 'flush_number', 'WP_Object_Cache' ) ); 436 } 437 438 if ( 0 === $this->flush_number[ $this->blog_prefix ] ) { 439 $this->rotate_site_keys(); 440 } 441 442 $number = $this->flush_number[ $this->blog_prefix ]; 443 } 444 537 $number = $this->get_blog_flush_number(); 538 } 445 539 return $number . ':'; 446 540 } … … 616 710 } 617 711 618 echo "<ul class='debug-menu-links' >\n";712 echo "<ul class='debug-menu-links' style='clear:left;font-size:14px;'>\n"; 619 713 $groups = array_keys( $this->group_ops ); 620 714 usort( $groups, 'strnatcasecmp' ); … … 755 849 $this->mc[ $bucket ] = new Memcache(); 756 850 757 foreach ( $servers as $ server ) {851 foreach ( $servers as $i => $server ) { 758 852 if ( 'unix://' == substr( $server, 0, 7 ) ) { 759 853 $node = $server; … … 775 869 $this->mc[ $bucket ]->addServer( $node, $port, true, 1, 1, 15, true, array( $this, 'failure_callback' ) ); 776 870 $this->mc[ $bucket ]->setCompressThreshold( 20000, 0.2 ); 871 872 // Prepare individual connections to servers in default bucket for flush_number redundancy 873 if ( 'default' === $bucket ) { 874 $this->default_mcs[ $i ] = new Memcache(); 875 $this->default_mcs[ $i ]->addServer( $node, $port, true, 1, 1, 15, true, array( $this, 'failure_callback' ) ); 876 } 777 877 } 778 878 } … … 827 927 828 928 /** 829 * Key format: key_salt:flush_ timer:table_prefix:key_name929 * Key format: key_salt:flush_number:table_prefix:key_name 830 930 * 831 * We want to strip the `key_salt:flush_ timer` part to not leak the memcached keys.832 * If `key_salt` is set we strip `'key_salt:flush_ timer`, otherwise just strip the `flush_timer` part.931 * We want to strip the `key_salt:flush_number` part to not leak the memcached keys. 932 * If `key_salt` is set we strip `'key_salt:flush_number`, otherwise just strip the `flush_number` part. 833 933 */ 834 934 function strip_memcached_keys( $keys ) { -
memcached/tags/4.0.0/readme.txt
r2317344 r2571100 3 3 Tags: cache, memcached 4 4 Requires at least: 5.3 5 Tested up to: 5. 4.16 Stable tag: 3.2.25 Tested up to: 5.8 6 Stable tag: 4.0.0 7 7 Requires PHP: 5.6.20 8 8 … … 84 84 == Changelog == 85 85 86 = 4.0.0 = 87 * Add preemptive filter pre_wp_cache_get 88 * Add flush_number replication to prevent accidental flush due to flush_number eviction, server rotation, etc. 89 86 90 = 3.2.2 = 87 91 * Remove filter, and base key stripping on presence of `key_salt` -
memcached/trunk/object-cache.php
r2317338 r2571100 4 4 Plugin Name: Memcached 5 5 Description: Memcached backend for the WP Object Cache. 6 Version: 3.2.27 Plugin URI: http ://wordpress.org/extend/plugins/memcached/6 Version: 4.0.0 7 Plugin URI: https://wordpress.org/plugins/memcached/ 8 8 Author: Ryan Boren, Denis de Bernardy, Matt Martz, Andy Skelton 9 9 … … 55 55 function wp_cache_get( $key, $group = '', $force = false, &$found = null ) { 56 56 global $wp_object_cache; 57 58 $value = apply_filters( 'pre_wp_cache_get', false, $key, $group, $force ); 59 if ( false !== $value ) { 60 $found = true; 61 return $value; 62 } 57 63 58 64 return $wp_object_cache->get( $key, $group, $force, $found ); … … 116 122 var $no_mc_groups = array(); 117 123 118 var $cache = array(); 119 var $mc = array(); 120 var $stats = array(); 121 var $group_ops = array(); 122 124 var $cache = array(); 125 var $mc = array(); 126 var $default_mcs = array(); 127 var $stats = array(); 128 var $group_ops = array(); 129 130 var $flush_group = 'WP_Object_Cache'; 131 var $global_flush_group = 'WP_Object_Cache_global'; 132 var $flush_key = "flush_number_v4"; 133 var $old_flush_key = "flush_number"; 123 134 var $flush_number = array(); 124 135 var $global_flush_number = null; … … 268 279 } 269 280 281 // Gets number from all default servers, replicating if needed 282 function get_max_flush_number( $group ) { 283 $key = $this->key( $this->flush_key, $group ); 284 285 $values = array(); 286 $size = 19; // size of microsecond timestamp serialized 287 foreach ( $this->default_mcs as $i => $mc ) { 288 $flags = false; 289 $this->timer_start(); 290 $values[ $i ] = $mc->get( $key, $flags ); 291 $elapsed = $this->timer_stop(); 292 293 if ( empty( $values[ $i ] ) ) { 294 $this->group_ops_stats( 'get_flush_number', $key, $group, null, $elapsed, 'not_in_memcache' ); 295 } else { 296 $this->group_ops_stats( 'get_flush_number', $key, $group, $size, $elapsed, 'memcache' ); 297 } 298 } 299 300 $max = max( $values ); 301 302 if ( ! $max > 0 ) { 303 return false; 304 } 305 306 // Replicate to servers not having the max. 307 $expire = 0; 308 foreach ( $this->default_mcs as $i => $mc ) { 309 if ( $values[ $i ] < $max ) { 310 $this->timer_start(); 311 $mc->set( $key, $max, false, $expire ); 312 $elapsed = $this->timer_stop(); 313 $this->group_ops_stats( 'set_flush_number', $key, $group, $size, $elapsed, 'replication_repair' ); 314 } 315 } 316 317 return $max; 318 } 319 320 function set_flush_number( $value, $group ) { 321 $key = $this->key( $this->flush_key, $group ); 322 $expire = 0; 323 $size = 19; 324 foreach ( $this->default_mcs as $i => $mc ) { 325 $this->timer_start(); 326 $mc->set( $key, $value, false, $expire ); 327 $elapsed = $this->timer_stop(); 328 $this->group_ops_stats( 'set_flush_number', $key, $group, $size, $elapsed, 'replication' ); 329 } 330 } 331 332 function get_flush_number( $group ) { 333 $flush_number = $this->get_max_flush_number( $group ); 334 // What if there is no v4 flush number? 335 if ( empty( $flush_number ) ) { 336 // Look for the v3 flush number key. 337 $flush_number = intval( $this->get( $this->old_flush_key, $group ) ); 338 if ( !empty( $flush_number ) ) { 339 // Found v3 flush number. Upgrade to v4 with replication. 340 $this->set_flush_number( $flush_number, $group ); 341 // Delete v3 key so we can't later restore it and find stale keys. 342 } else { 343 // No flush number found anywhere. Make a new one. This flushes the cache. 344 $flush_number = $this->new_flush_number(); 345 $this->set_flush_number( $flush_number, $group ); 346 } 347 } 348 349 return $flush_number; 350 } 351 352 function get_global_flush_number() { 353 if ( ! isset( $this->global_flush_number ) ) { 354 $this->global_flush_number = $this->get_flush_number( $this->global_flush_group ); 355 } 356 return $this->global_flush_number; 357 } 358 359 function get_blog_flush_number() { 360 if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) { 361 $this->flush_number[ $this->blog_prefix ] = $this->get_flush_number( $this->flush_group ); 362 } 363 return $this->flush_number[ $this->blog_prefix ]; 364 } 365 270 366 function flush() { 271 367 // Do not use the memcached flush method. It acts on an … … 273 369 // Flush is also unusable in some setups, e.g. twemproxy. 274 370 // Instead, rotate the key prefix for the current site. 275 // Global keys are rotated when flushing on the main site. 371 // Global keys are rotated when flushing on any network's 372 // main site. 276 373 $this->cache = array(); 277 374 278 $this->rotate_site_keys(); 375 $flush_number = $this->new_flush_number(); 376 377 $this->rotate_site_keys( $flush_number ); 279 378 280 379 if ( is_main_site() ) { 281 $this->rotate_global_keys(); 282 } 283 } 284 285 function rotate_site_keys() { 286 $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache' ); 287 288 $this->flush_number[ $this->blog_prefix ] = $this->incr( 'flush_number', 1, 'WP_Object_Cache' ); 289 } 290 291 function rotate_global_keys() { 292 $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache_global' ); 293 294 $this->global_flush_number = $this->incr( 'flush_number', 1, 'WP_Object_Cache_global' ); 380 $this->rotate_global_keys( $flush_number ); 381 } 382 } 383 384 function rotate_site_keys( $flush_number = null ) { 385 if ( is_null( $flush_number ) ) { 386 $flush_number = $this->new_flush_number(); 387 } 388 389 $this->set_flush_number( $flush_number, $this->flush_group ); 390 391 $this->flush_number[ $this->blog_prefix ] = $flush_number; 392 } 393 394 function rotate_global_keys( $flush_number = null ) { 395 if ( is_null( $flush_number ) ) { 396 $flush_number = $this->new_flush_number(); 397 } 398 399 $this->set_flush_number( $flush_number, $this->global_flush_group ); 400 401 $this->global_flush_number = $flush_number; 402 } 403 404 function new_flush_number() { 405 return intval( microtime( true ) * 1e6 ); 295 406 } 296 407 … … 418 529 419 530 function flush_prefix( $group ) { 420 if ( 'WP_Object_Cache' === $group || 'WP_Object_Cache_global' === $group ) {531 if ( $group === $this->flush_group || $group === $this->global_flush_group ) { 421 532 // Never flush the flush numbers. 422 533 $number = '_'; 423 534 } elseif ( false !== array_search( $group, $this->global_groups ) ) { 424 if ( ! isset( $this->global_flush_number ) ) { 425 $this->global_flush_number = intval( $this->get( 'flush_number', 'WP_Object_Cache_global' ) ); 426 } 427 428 if ( 0 === $this->global_flush_number ) { 429 $this->rotate_global_keys(); 430 } 431 432 $number = $this->global_flush_number; 535 $number = $this->get_global_flush_number(); 433 536 } else { 434 if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) { 435 $this->flush_number[ $this->blog_prefix ] = intval( $this->get( 'flush_number', 'WP_Object_Cache' ) ); 436 } 437 438 if ( 0 === $this->flush_number[ $this->blog_prefix ] ) { 439 $this->rotate_site_keys(); 440 } 441 442 $number = $this->flush_number[ $this->blog_prefix ]; 443 } 444 537 $number = $this->get_blog_flush_number(); 538 } 445 539 return $number . ':'; 446 540 } … … 616 710 } 617 711 618 echo "<ul class='debug-menu-links' >\n";712 echo "<ul class='debug-menu-links' style='clear:left;font-size:14px;'>\n"; 619 713 $groups = array_keys( $this->group_ops ); 620 714 usort( $groups, 'strnatcasecmp' ); … … 755 849 $this->mc[ $bucket ] = new Memcache(); 756 850 757 foreach ( $servers as $ server ) {851 foreach ( $servers as $i => $server ) { 758 852 if ( 'unix://' == substr( $server, 0, 7 ) ) { 759 853 $node = $server; … … 775 869 $this->mc[ $bucket ]->addServer( $node, $port, true, 1, 1, 15, true, array( $this, 'failure_callback' ) ); 776 870 $this->mc[ $bucket ]->setCompressThreshold( 20000, 0.2 ); 871 872 // Prepare individual connections to servers in default bucket for flush_number redundancy 873 if ( 'default' === $bucket ) { 874 $this->default_mcs[ $i ] = new Memcache(); 875 $this->default_mcs[ $i ]->addServer( $node, $port, true, 1, 1, 15, true, array( $this, 'failure_callback' ) ); 876 } 777 877 } 778 878 } … … 827 927 828 928 /** 829 * Key format: key_salt:flush_ timer:table_prefix:key_name929 * Key format: key_salt:flush_number:table_prefix:key_name 830 930 * 831 * We want to strip the `key_salt:flush_ timer` part to not leak the memcached keys.832 * If `key_salt` is set we strip `'key_salt:flush_ timer`, otherwise just strip the `flush_timer` part.931 * We want to strip the `key_salt:flush_number` part to not leak the memcached keys. 932 * If `key_salt` is set we strip `'key_salt:flush_number`, otherwise just strip the `flush_number` part. 833 933 */ 834 934 function strip_memcached_keys( $keys ) { -
memcached/trunk/readme.txt
r2317344 r2571100 3 3 Tags: cache, memcached 4 4 Requires at least: 5.3 5 Tested up to: 5. 4.16 Stable tag: 3.2.25 Tested up to: 5.8 6 Stable tag: 4.0.0 7 7 Requires PHP: 5.6.20 8 8 … … 84 84 == Changelog == 85 85 86 = 4.0.0 = 87 * Add preemptive filter pre_wp_cache_get 88 * Add flush_number replication to prevent accidental flush due to flush_number eviction, server rotation, etc. 89 86 90 = 3.2.2 = 87 91 * Remove filter, and base key stripping on presence of `key_salt`
Note: See TracChangeset
for help on using the changeset viewer.