Changeset 745

Show
Ignore:
Timestamp:
03/03/08 07:51:02 (7 months ago)
Author:
dsallings
Message:

Merged commit 'trunk' into lbinary as of r744

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/binary/server/ChangeLog

    r722 r745  
     12008-03-02 [Version 1.2.5-rc1 released] 
     2 
     3       * Add per-item-class tracking of evictions and OOM errors (dormando) 
     4 
     5       * Optimize item_alloc() a little (dormando) 
     6 
     7       * Give 'SERVER_ERROR out of memory' errors more context (dormando) 
     8 
     9       * Enable usage of large memory pages under solaris 
     10         (Trond.Norbye@Sun.COM) 
     11 
     12       * Enable UDP by default, clean up server socket code 
     13         (brian@tangent.org) 
     14 
    115       * 'noreply' support (Tomash Brechko) 
    216 
  • branches/binary/server/configure.ac

    r725 r745  
    11AC_PREREQ(2.52) 
    2 AC_INIT(memcached, 1.2.4, brad@danga.com) 
     2AC_INIT(memcached, 1.2.5, brad@danga.com) 
    33AC_CANONICAL_SYSTEM 
    44AC_CONFIG_SRCDIR(memcached.c) 
  • branches/binary/server/doc/memcached.1

    r629 r745  
    106106specified, stats collection is turned on automatically; if not, then it may 
    107107be turned on by sending the "stats detail on" command to the server. 
     108.TP 
     109.B \-L 
     110Try to use large memory pages (if available). Increasing the memory page size 
     111could reduce the number of TLB misses and improve the performance. In order to 
     112get large pages from the OS, memcached will allocate the total item-cache in 
     113one large chunk. Only available if supported on your OS. 
    108114.br 
    109115.SH LICENSE 
  • branches/binary/server/items.c

    r642 r745  
    2828 
    2929#define LARGEST_ID 255 
     30typedef struct { 
     31    unsigned int evicted; 
     32    unsigned int outofmemory; 
     33} itemstats_t; 
     34 
    3035static item *heads[LARGEST_ID]; 
    3136static item *tails[LARGEST_ID]; 
     37static itemstats_t itemstats[LARGEST_ID]; 
    3238static unsigned int sizes[LARGEST_ID]; 
    3339 
    3440void item_init(void) { 
    3541    int i; 
     42    memset(itemstats, 0, sizeof(itemstats_t) * LARGEST_ID); 
    3643    for(i = 0; i < LARGEST_ID; i++) { 
    3744        heads[i] = NULL; 
     
    8996        return 0; 
    9097 
    91     it = slabs_alloc(ntotal); 
     98    it = slabs_alloc(ntotal, id); 
    9299    if (it == 0) { 
    93100        int tries = 50; 
     
    98105         */ 
    99106 
    100         if (settings.evict_to_free == 0) return NULL; 
     107        if (settings.evict_to_free == 0) { 
     108            itemstats[id].outofmemory++; 
     109            return NULL; 
     110        } 
    101111 
    102112        /* 
     
    107117         */ 
    108118 
    109         if (id > LARGEST_ID) return NULL; 
    110         if (tails[id] == 0) return NULL; 
     119        if (tails[id] == 0) { 
     120            itemstats[id].outofmemory++; 
     121            return NULL; 
     122        } 
    111123 
    112124        for (search = tails[id]; tries > 0 && search != NULL; tries--, search=search->prev) { 
    113125            if (search->refcount == 0) { 
    114                if (search->exptime == 0 || search->exptime > current_time) { 
    115                        STATS_LOCK(); 
    116                        stats.evictions++; 
    117                        STATS_UNLOCK(); 
     126                if (search->exptime == 0 || search->exptime > current_time) { 
     127                    itemstats[id].evicted++; 
     128                    STATS_LOCK(); 
     129                    stats.evictions++; 
     130                    STATS_UNLOCK(); 
    118131                } 
    119132                do_item_unlink(search); 
     
    121134            } 
    122135        } 
    123         it = slabs_alloc(ntotal); 
    124         if (it == 0) return NULL; 
     136        it = slabs_alloc(ntotal, id); 
     137        if (it == 0) { 
     138            itemstats[id].outofmemory++; 
     139            return NULL; 
     140        } 
    125141    } 
    126142 
     
    146162void item_free(item *it) { 
    147163    size_t ntotal = ITEM_ntotal(it); 
     164    unsigned int clsid; 
    148165    assert((it->it_flags & ITEM_LINKED) == 0); 
    149166    assert(it != heads[it->slabs_clsid]); 
     
    152169 
    153170    /* so slab size changer can tell later if item is already free or not */ 
     171    clsid = it->slabs_clsid; 
    154172    it->slabs_clsid = 0; 
    155173    it->it_flags |= ITEM_SLABBED; 
    156174    DEBUG_REFCNT(it, 'F'); 
    157     slabs_free(it, ntotal); 
     175    slabs_free(it, ntotal, clsid); 
    158176} 
    159177 
     
    311329 
    312330char *do_item_stats(int *bytes) { 
    313     size_t bufleft = (size_t) LARGEST_ID * 80; 
     331    size_t bufleft = (size_t) LARGEST_ID * 160; 
    314332    char *buffer = malloc(bufleft); 
    315333    char *bufcurr = buffer; 
     
    324342    for (i = 0; i < LARGEST_ID; i++) { 
    325343        if (tails[i] != NULL) { 
    326             linelen = snprintf(bufcurr, bufleft, "STAT items:%d:number %u\r\nSTAT items:%d:age %u\r\n", 
    327                                i, sizes[i], i, now - tails[i]->time); 
     344            linelen = snprintf(bufcurr, bufleft, 
     345                "STAT items:%d:number %u\r\n" 
     346                "STAT items:%d:age %u\r\n" 
     347                "STAT items:%d:evicted %u\r\n" 
     348                "STAT items:%d:outofmemory %u\r\n", 
     349                    i, sizes[i], i, now - tails[i]->time, i, 
     350                    itemstats[i].evicted, i, itemstats[i].outofmemory); 
    328351            if (linelen + sizeof("END\r\n") < bufleft) { 
    329352                bufcurr += linelen; 
  • branches/binary/server/memcached.c

    r735 r745  
    16131613        c->write_and_go = get_init_state(c); 
    16141614    } else { 
    1615         out_string(c, "SERVER_ERROR out of memory"); 
     1615        out_string(c, "SERVER_ERROR out of memory writing stats"); 
    16161616    } 
    16171617} 
     
    17501750 
    17511751        if ((wbuf = (char *)malloc(wsize)) == NULL) { 
    1752             out_string(c, "SERVER_ERROR out of memory"); 
     1752            out_string(c, "SERVER_ERROR out of memory writing stats maps"); 
    17531753            return; 
    17541754        } 
     
    19171917                    stats.get_misses += stats_get_misses; 
    19181918                    STATS_UNLOCK(); 
    1919                     out_string(c, "SERVER_ERROR out of memory"); 
     1919                    out_string(c, "SERVER_ERROR out of memory making CAS suffix"); 
    19201920                    return; 
    19211921                  } 
     
    19861986    if (key_token->value != NULL || add_iov(c, "END\r\n", 5) != 0 
    19871987        || (IS_UDP(c->protocol) && build_udp_headers(c) != 0)) { 
    1988         out_string(c, "SERVER_ERROR out of memory"); 
     1988        out_string(c, "SERVER_ERROR out of memory writing get response"); 
    19891989    } 
    19901990    else { 
     
    20612061            out_string(c, "SERVER_ERROR object too large for cache"); 
    20622062        else 
    2063             out_string(c, "SERVER_ERROR out of memory"); 
     2063            out_string(c, "SERVER_ERROR out of memory storing object"); 
    20642064        /* swallow the data line */ 
    20652065        c->write_and_go = conn_swallow; 
     
    21642164        new_it = do_item_alloc(ITEM_key(it), it->nkey, atoi(ITEM_suffix(it) + 1), it->exptime, res + 2 ); 
    21652165        if (new_it == 0) { 
    2166             return "SERVER_ERROR out of memory"; 
     2166            return "SERVER_ERROR out of memory in incr/decr"; 
    21672167        } 
    21682168        memcpy(ITEM_data(new_it), buf, res); 
     
    22552255             */ 
    22562256            item_remove(it);    /* release reference */ 
    2257             return "SERVER_ERROR out of memory"; 
     2257            return "SERVER_ERROR out of memory expanding delete queue"; 
    22582258        } 
    22592259    } 
     
    23002300    c->iovused = 0; 
    23012301    if (add_msghdr(c) != 0) { 
    2302         out_string(c, "SERVER_ERROR out of memory"); 
     2302        out_string(c, "SERVER_ERROR out of memory preparing response"); 
    23032303        return; 
    23042304    } 
     
    25802580                    fprintf(stderr, "Couldn't realloc input buffer\n"); 
    25812581                c->rbytes = 0; /* ignore what we read */ 
    2582                 out_string(c, "SERVER_ERROR out of memory"); 
     2582                out_string(c, "SERVER_ERROR out of memory reading request"); 
    25832583                c->write_and_go = conn_closing; 
    25842584                return 1; 
  • branches/binary/server/memcached.h

    r733 r745  
    364364void  mt_item_update(item *it); 
    365365void  mt_run_deferred_deletes(void); 
    366 void *mt_slabs_alloc(size_t size); 
    367 void  mt_slabs_free(void *ptr, size_t size); 
     366void *mt_slabs_alloc(size_t size, unsigned int id); 
     367void  mt_slabs_free(void *ptr, size_t size, unsigned int id); 
    368368int   mt_slabs_reassign(unsigned char srcid, unsigned char dstid); 
    369369char *mt_slabs_stats(int *buflen); 
     
    393393# define item_unlink(x)              mt_item_unlink(x) 
    394394# define run_deferred_deletes()      mt_run_deferred_deletes() 
    395 # define slabs_alloc(x)              mt_slabs_alloc(x
    396 # define slabs_free(x,y)             mt_slabs_free(x,y
     395# define slabs_alloc(x,y)            mt_slabs_alloc(x,y
     396# define slabs_free(x,y,z)           mt_slabs_free(x,y,z
    397397# define slabs_reassign(x,y)         mt_slabs_reassign(x,y) 
    398398# define slabs_stats(x)              mt_slabs_stats(x) 
     
    426426# define item_update(x)              do_item_update(x) 
    427427# define run_deferred_deletes()      do_run_deferred_deletes() 
    428 # define slabs_alloc(x)              do_slabs_alloc(x
    429 # define slabs_free(x,y)             do_slabs_free(x,y
     428# define slabs_alloc(x,y)            do_slabs_alloc(x,y
     429# define slabs_free(x,y,z)           do_slabs_free(x,y,z
    430430# define slabs_reassign(x,y)         do_slabs_reassign(x,y) 
    431431# define slabs_stats(x)              do_slabs_stats(x) 
  • branches/binary/server/memcached.spec

    r648 r745  
    11Name:           memcached 
    2 Version:        1.2.4 
     2Version:        1.2.5 
    33Release:        1%{?dist} 
    44Summary:        High Performance, Distributed Memory Object Cache 
  • branches/binary/server/slabs.c

    r725 r745  
    219219 
    220220/*@null@*/ 
    221 void *do_slabs_alloc(const size_t size) { 
     221void *do_slabs_alloc(const size_t size, unsigned int id) { 
    222222    slabclass_t *p; 
    223223 
    224     unsigned int id = slabs_clsid(size); 
    225224    if (id < POWER_SMALLEST || id > power_largest) 
    226225        return NULL; 
     
    259258} 
    260259 
    261 void do_slabs_free(void *ptr, const size_t size) { 
    262     unsigned char id = slabs_clsid(size); 
     260void do_slabs_free(void *ptr, const size_t size, unsigned int id) { 
    263261    slabclass_t *p; 
    264262 
  • branches/binary/server/slabs.h

    r725 r745  
    1818 
    1919/** Allocate object of given length. 0 on error */ /*@null@*/ 
    20 void *do_slabs_alloc(const size_t size); 
     20void *do_slabs_alloc(const size_t size, unsigned int id); 
    2121 
    2222/** Free previously allocated object */ 
    23 void do_slabs_free(void *ptr, size_t size); 
     23void do_slabs_free(void *ptr, size_t size, unsigned int id); 
    2424 
    2525/** Fill buffer with stats */ /*@null@*/ 
  • branches/binary/server/thread.c

    r672 r745  
    572572/******************************* SLAB ALLOCATOR ******************************/ 
    573573 
    574 void *mt_slabs_alloc(size_t size) { 
     574void *mt_slabs_alloc(size_t size, unsigned int id) { 
    575575    void *ret; 
    576576 
    577577    pthread_mutex_lock(&slabs_lock); 
    578     ret = do_slabs_alloc(size); 
     578    ret = do_slabs_alloc(size, id); 
    579579    pthread_mutex_unlock(&slabs_lock); 
    580580    return ret; 
    581581} 
    582582 
    583 void mt_slabs_free(void *ptr, size_t size) { 
     583void mt_slabs_free(void *ptr, size_t size, unsigned int id) { 
    584584    pthread_mutex_lock(&slabs_lock); 
    585     do_slabs_free(ptr, size); 
     585    do_slabs_free(ptr, size, id); 
    586586    pthread_mutex_unlock(&slabs_lock); 
    587587}