diff options
author | sergiocarlos <carloschilazo@gmail.com> | 2015-12-08 18:32:49 -0600 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2016-05-28 23:40:07 -0700 |
commit | 6895d23e48c6359402066a74c812b3f14be05100 (patch) | |
tree | 4eecbe1d9fd15fac04239464f46d2363a72bb427 | |
parent | 1b13a586624e8e315f23a482691c9bfb3ab36d9b (diff) | |
download | memcached-6895d23e48c6359402066a74c812b3f14be05100.tar.gz |
Implement get_expired stats
-rw-r--r-- | doc/protocol.txt | 2 | ||||
-rw-r--r-- | items.c | 9 | ||||
-rw-r--r-- | items.h | 4 | ||||
-rw-r--r-- | memcached.c | 22 | ||||
-rw-r--r-- | memcached.h | 6 | ||||
-rwxr-xr-x | t/stats.t | 17 | ||||
-rw-r--r-- | thread.c | 10 |
7 files changed, 46 insertions, 24 deletions
diff --git a/doc/protocol.txt b/doc/protocol.txt index 7e72508..eaa3b16 100644 --- a/doc/protocol.txt +++ b/doc/protocol.txt @@ -542,6 +542,8 @@ integers separated by a colon (treat this as a floating point number). | | | and found present | | get_misses | 64u | Number of items that have been requested | | | | and not found | +| get_expired | 64u | Number of items that have been requested | +| | | but had already expired. | | delete_misses | 64u | Number of deletions reqs for missing keys | | delete_hits | 64u | Number of deletion reqs resulting in | | | | an item being removed. | @@ -659,7 +659,7 @@ void item_stats_sizes(ADD_STAT add_stats, void *c) { } /** wrapper around assoc_find which does the lazy expiration logic */ -item *do_item_get(const char *key, const size_t nkey, const uint32_t hv) { +item *do_item_get(const char *key, const size_t nkey, const uint32_t hv, conn *c) { item *it = assoc_find(key, nkey, hv); if (it != NULL) { refcount_incr(&it->refcount); @@ -711,6 +711,9 @@ item *do_item_get(const char *key, const size_t nkey, const uint32_t hv) { do_item_unlink(it, hv); do_item_remove(it); it = NULL; + pthread_mutex_lock(&c->thread->stats.mutex); + c->thread->stats.get_expired++; + pthread_mutex_unlock(&c->thread->stats.mutex); if (was_found) { fprintf(stderr, " -nuked by expire"); } @@ -727,8 +730,8 @@ item *do_item_get(const char *key, const size_t nkey, const uint32_t hv) { } item *do_item_touch(const char *key, size_t nkey, uint32_t exptime, - const uint32_t hv) { - item *it = do_item_get(key, nkey, hv); + const uint32_t hv, conn *c) { + item *it = do_item_get(key, nkey, hv, c); if (it != NULL) { it->exptime = exptime; } @@ -23,8 +23,8 @@ void item_stats_totals(ADD_STAT add_stats, void *c); /*@null@*/ void item_stats_sizes(ADD_STAT add_stats, void *c); -item *do_item_get(const char *key, const size_t nkey, const uint32_t hv); -item *do_item_touch(const char *key, const size_t nkey, uint32_t exptime, const uint32_t hv); +item *do_item_get(const char *key, const size_t nkey, const uint32_t hv, conn *c); +item *do_item_touch(const char *key, const size_t nkey, uint32_t exptime, const uint32_t hv, conn *c); void item_stats_reset(void); extern pthread_mutex_t lru_locks[POWER_LARGEST]; diff --git a/memcached.c b/memcached.c index 07f8ab5..eb5ffd3 100644 --- a/memcached.c +++ b/memcached.c @@ -179,6 +179,7 @@ static rel_time_t realtime(const time_t exptime) { static void stats_init(void) { stats.curr_items = stats.total_items = stats.curr_conns = stats.total_conns = stats.conn_structs = 0; stats.get_cmds = stats.set_cmds = stats.get_hits = stats.get_misses = stats.evictions = stats.reclaimed = 0; + stats.get_expired = 0; stats.touch_cmds = stats.touch_misses = stats.touch_hits = stats.rejected_conns = 0; stats.malloc_fails = 0; stats.curr_bytes = stats.listen_disabled_num = 0; @@ -1296,9 +1297,9 @@ static void process_bin_get_or_touch(conn *c) { protocol_binary_request_touch *t = binary_get_request(c); time_t exptime = ntohl(t->message.body.expiration); - it = item_touch(key, nkey, realtime(exptime)); + it = item_touch(key, nkey, realtime(exptime), c); } else { - it = item_get(key, nkey); + it = item_get(key, nkey, c); } if (it) { @@ -2057,7 +2058,7 @@ static void process_bin_update(conn *c) { /* Avoid stale data persisting in cache because we failed alloc. * Unacceptable for SET. Anywhere else too? */ if (c->cmd == PROTOCOL_BINARY_CMD_SET) { - it = item_get(key, nkey); + it = item_get(key, nkey, c); if (it) { item_unlink(it); item_remove(it); @@ -2207,7 +2208,7 @@ static void process_bin_delete(conn *c) { stats_prefix_record_delete(key, nkey); } - it = item_get(key, nkey); + it = item_get(key, nkey, c); if (it) { uint64_t cas = ntohll(req->message.header.request.cas); if (cas == 0 || cas == ITEM_get_cas(it)) { @@ -2308,7 +2309,7 @@ static void complete_nread(conn *c) { */ enum store_item_type do_store_item(item *it, int comm, conn *c, const uint32_t hv) { char *key = ITEM_key(it); - item *old_it = do_item_get(key, it->nkey, hv); + item *old_it = do_item_get(key, it->nkey, hv, c); enum store_item_type stored = NOT_STORED; item *new_it = NULL; @@ -2611,6 +2612,7 @@ static void server_stats(ADD_STAT add_stats, conn *c) { APPEND_STAT("cmd_touch", "%llu", (unsigned long long)thread_stats.touch_cmds); APPEND_STAT("get_hits", "%llu", (unsigned long long)slab_stats.get_hits); APPEND_STAT("get_misses", "%llu", (unsigned long long)thread_stats.get_misses); + APPEND_STAT("get_expired", "%llu", (unsigned long long)thread_stats.get_expired); APPEND_STAT("delete_misses", "%llu", (unsigned long long)thread_stats.delete_misses); APPEND_STAT("delete_hits", "%llu", (unsigned long long)slab_stats.delete_hits); APPEND_STAT("incr_misses", "%llu", (unsigned long long)thread_stats.incr_misses); @@ -2907,7 +2909,7 @@ static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens, return; } - it = item_get(key, nkey); + it = item_get(key, nkey, c); if (settings.detail_enabled) { stats_prefix_record_get(key, nkey, NULL != it); } @@ -3129,7 +3131,7 @@ static void process_update_command(conn *c, token_t *tokens, const size_t ntoken /* Avoid stale data persisting in cache because we failed alloc. * Unacceptable for SET. Anywhere else too? */ if (comm == NREAD_SET) { - it = item_get(key, nkey); + it = item_get(key, nkey, c); if (it) { item_unlink(it); item_remove(it); @@ -3170,7 +3172,7 @@ static void process_touch_command(conn *c, token_t *tokens, const size_t ntokens return; } - it = item_touch(key, nkey, realtime(exptime_int)); + it = item_touch(key, nkey, realtime(exptime_int), c); if (it) { item_update(it); pthread_mutex_lock(&c->thread->stats.mutex); @@ -3259,7 +3261,7 @@ enum delta_result_type do_add_delta(conn *c, const char *key, const size_t nkey, int res; item *it; - it = do_item_get(key, nkey, hv); + it = do_item_get(key, nkey, hv, c); if (!it) { return DELTA_ITEM_NOT_FOUND; } @@ -3378,7 +3380,7 @@ static void process_delete_command(conn *c, token_t *tokens, const size_t ntoken stats_prefix_record_delete(key, nkey); } - it = item_get(key, nkey); + it = item_get(key, nkey, c); if (it) { MEMCACHED_COMMAND_DELETE(c->sfd, ITEM_key(it), it->nkey); diff --git a/memcached.h b/memcached.h index df972f5..e53e642 100644 --- a/memcached.h +++ b/memcached.h @@ -238,6 +238,7 @@ struct thread_stats { pthread_mutex_t mutex; uint64_t get_cmds; uint64_t get_misses; + uint64_t get_expired; uint64_t touch_cmds; uint64_t touch_misses; uint64_t delete_misses; @@ -272,6 +273,7 @@ struct stats { uint64_t touch_cmds; uint64_t get_hits; uint64_t get_misses; + uint64_t get_expired; uint64_t touch_hits; uint64_t touch_misses; uint64_t evictions; @@ -583,8 +585,8 @@ conn *conn_from_freelist(void); bool conn_add_to_freelist(conn *c); int is_listen_thread(void); item *item_alloc(char *key, size_t nkey, int flags, rel_time_t exptime, int nbytes); -item *item_get(const char *key, const size_t nkey); -item *item_touch(const char *key, const size_t nkey, uint32_t exptime); +item *item_get(const char *key, const size_t nkey, conn *c); +item *item_touch(const char *key, const size_t nkey, uint32_t exptime, conn *c); int item_link(item *it); void item_remove(item *it); int item_replace(item *it, item *new_it, const uint32_t hv); @@ -1,7 +1,7 @@ #!/usr/bin/perl use strict; -use Test::More tests => 98; +use Test::More tests => 103; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; @@ -30,6 +30,7 @@ my $sock = $server->sock; ## STAT cmd_touch 0 ## STAT get_hits 0 ## STAT get_misses 0 +## STAT get_expired 0 ## STAT delete_misses 0 ## STAT delete_hits 0 ## STAT incr_misses 0 @@ -71,10 +72,10 @@ my $sock = $server->sock; my $stats = mem_stats($sock); # Test number of keys -is(scalar(keys(%$stats)), 53, "53 stats values"); +is(scalar(keys(%$stats)), 54, "54 stats values"); # Test initial state -foreach my $key (qw(curr_items total_items bytes cmd_get cmd_set get_hits evictions get_misses +foreach my $key (qw(curr_items total_items bytes cmd_get cmd_set get_hits evictions get_misses get_expired bytes_written delete_hits delete_misses incr_hits incr_misses decr_hits decr_misses listen_disabled_num lrutail_reflocked time_in_listen_disabled_us)) { is($stats->{$key}, 0, "initial $key is zero"); @@ -190,6 +191,7 @@ is(0, $stats->{'cmd_get'}); is(0, $stats->{'cmd_set'}); is(0, $stats->{'get_hits'}); is(0, $stats->{'get_misses'}); +is(0, $stats->{'get_expired'}); is(0, $stats->{'delete_misses'}); is(0, $stats->{'delete_hits'}); is(0, $stats->{'incr_misses'}); @@ -203,6 +205,15 @@ is(0, $stats->{'evictions'}); is(0, $stats->{'reclaimed'}); is(0, $stats->{'lrutail_reflocked'}); +# item expired +print $sock "set should_expire 0 1 6\r\nfooval\r\n"; +is(scalar <$sock>, "STORED\r\n", "set item to expire"); +sleep(2); +print $sock "get should_expire\r\n"; +is(scalar <$sock>, "END\r\n", "item not returned"); +my $stats = mem_stats($sock); +is(1, $stats->{'get_expired'}, "get_expired counter is 1"); + print $sock "flush_all\r\n"; is(scalar <$sock>, "OK\r\n", "flushed"); @@ -486,22 +486,22 @@ item *item_alloc(char *key, size_t nkey, int flags, rel_time_t exptime, int nbyt * Returns an item if it hasn't been marked as expired, * lazy-expiring as needed. */ -item *item_get(const char *key, const size_t nkey) { +item *item_get(const char *key, const size_t nkey, conn *c) { item *it; uint32_t hv; hv = hash(key, nkey); item_lock(hv); - it = do_item_get(key, nkey, hv); + it = do_item_get(key, nkey, hv, c); item_unlock(hv); return it; } -item *item_touch(const char *key, size_t nkey, uint32_t exptime) { +item *item_touch(const char *key, size_t nkey, uint32_t exptime, conn *c) { item *it; uint32_t hv; hv = hash(key, nkey); item_lock(hv); - it = do_item_touch(key, nkey, exptime, hv); + it = do_item_touch(key, nkey, exptime, hv, c); item_unlock(hv); return it; } @@ -613,6 +613,7 @@ void threadlocal_stats_reset(void) { threads[ii].stats.get_cmds = 0; threads[ii].stats.get_misses = 0; + threads[ii].stats.get_expired = 0; threads[ii].stats.touch_cmds = 0; threads[ii].stats.touch_misses = 0; threads[ii].stats.delete_misses = 0; @@ -653,6 +654,7 @@ void threadlocal_stats_aggregate(struct thread_stats *stats) { stats->get_cmds += threads[ii].stats.get_cmds; stats->get_misses += threads[ii].stats.get_misses; + stats->get_expired += threads[ii].stats.get_expired; stats->touch_cmds += threads[ii].stats.touch_cmds; stats->touch_misses += threads[ii].stats.touch_misses; stats->delete_misses += threads[ii].stats.delete_misses; |