summaryrefslogtreecommitdiff
path: root/t/slabs-reassign-chunked.t
blob: 49b9fbfb919573910e251f6f163f59de9caa4659 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env perl

use strict;
use warnings;
use Test::More tests => 8;
use FindBin qw($Bin);
use lib "$Bin/lib";
use MemcachedTest;

my $server = new_memcached('-m 60 -o slab_reassign,slab_automove,lru_crawler,lru_maintainer,slab_chunk_max=4096');
my $sock = $server->sock;

sub dump_stats {
    my $s = shift;
    my $filter = shift || '';
    for my $k (sort keys %$s) {
        if ($filter) {
            next unless $k =~ m/$filter/;
        }
        print STDERR "STAT: $k = ", $s->{$k}, "\n";
    }
}

my $value;
{
    my @chars = ("C".."Z");
    for (1 .. 11000) {
        $value .= $chars[rand @chars];
    }
}
my $keycount = 5100;

my $res;
for (1 .. $keycount) {
#    print STDERR "HI $_\n";
    print $sock "set nfoo$_ 0 0 11000 noreply\r\n$value\r\n";
#    print $sock "set nfoo$_ 0 0 11000\r\n$value\r\n";
#    my $res = scalar <$sock>;
#    print STDERR "RES: $res\n";
}

my $todelete = 0;
{
    my $stats = mem_stats($sock);
    cmp_ok($stats->{curr_items}, '>', 4000, "stored at least 4000 11k items");
    $todelete = $stats->{curr_items} / 2;
#    for ('evictions', 'reclaimed', 'curr_items', 'cmd_set', 'bytes') {
#        print STDERR "$_: ", $stats->{$_}, "\n";
#    }
}

{
    my $s = mem_stats($sock, 'slabs');
    my $sid;
    # Find the highest ID to source from.
    for my $k (keys %$s) {
        next unless $k =~ m/^(\d+):/;
        $sid = $s->{$k} if $s->{$k} > $1;
    }
    for (my $x = 0; $x < 3; $x++) {
        print $sock "slabs reassign 17 0\r\n";
        my $res = scalar <$sock>;
        chomp $res;
    #    print STDERR "SLABS REASSIGN RESULT: $res\n";
        sleep 1;
    }
}

# Make room in old class so rescues can happen when we switch slab classes.
#for (1 .. $todelete) {
#    print $sock "delete nfoo$_ noreply\r\n";
#}

# Give  LRU mover some time to reclaim slab chunks.
#sleep 1;

{
    my $stats = mem_stats($sock);
    cmp_ok($stats->{slab_global_page_pool}, '>', 0, 'global page pool > 0');
    cmp_ok($stats->{slab_reassign_chunk_rescues}, '>', 0, 'some chunk rescues happened');
}

{
    my $hits = 0;
    for (1 .. $keycount) {
        print $sock "get nfoo$_\r\n";
        my $body = scalar(<$sock>);
        my $expected = "VALUE nfoo$_ 0 11000\r\n$value\r\nEND\r\n";
        if ($body =~ /^END/) {
            next;
        } else {
            $body .= scalar(<$sock>) . scalar(<$sock>);
            if ($body ne $expected) {
                die "Something terrible has happened: $expected\nBODY:\n$body\nDONETEST\n";
            }
            $hits++;
        }
    }
    cmp_ok($hits, '>', 0, "fetched back $hits values after reassignment");
}

$value = "A"x3000;
for (1 .. $keycount) {
    print $sock "set ifoo$_ 0 0 3000 noreply\r\n$value\r\n";
}

my $missing = 0;
my $hits = 0;
for (1 .. $keycount) {
    print $sock "get ifoo$_\r\n";
    my $body = scalar(<$sock>);
    my $expected = "VALUE ifoo$_ 0 3000\r\n$value\r\nEND\r\n";
    if ($body =~ /^END/) {
        $missing++;
    } else {
        $body .= scalar(<$sock>) . scalar(<$sock>);
        if ($body ne $expected) {
            print STDERR "Something terrible has happened: $expected\nBODY:\n$body\nDONETEST\n";
        } else {
            $hits++;
        }
    }
}
#print STDERR "HITS: $hits, MISSES: $missing\n";

{
    my $stats = mem_stats($sock);
    cmp_ok($stats->{evictions}, '<', 2000, 'evictions were less than 2000');
#    for ('evictions', 'reclaimed', 'curr_items', 'cmd_set', 'bytes') {
#        print STDERR "$_: ", $stats->{$_}, "\n";
#    }
}

cmp_ok($hits, '>', 4000, 'were able to fetch back 2/3rds of 8k keys');
my $stats_done = mem_stats($sock);
cmp_ok($stats_done->{slab_reassign_chunk_rescues}, '>', 0, 'some reassign chunk rescues happened');
# Reassign rescues won't happen here because the headers are of a different
# size and we aren't moving pages out of that slab class
#cmp_ok($stats_done->{slab_reassign_rescues}, '>', 0, 'some reassign rescues happened');
cmp_ok($stats_done->{slab_reassign_evictions_nomem}, '>', 0, 'some reassign evictions happened');