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/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');
|