Subject: | Parser error for big get_multi replies |
Example:
perl -MCache::Memcached -le 'my $c = Cache::Memcached->new({servers => ["vs-memcache-01:11211", "vs-memcache-02:11211"]}); for my $i (1..100) { my $r = $c->get_multi(map { "Config:Queue:".$_ } 0..800); for my $k (keys %$r) { print "$i\t$k" unless $k =~ /^Config:Queue:\d+$/; } }'
Fetching 800 keys at once in one get_multi call (done by Data::ObjectDriver's memcached module) results in corrupted keys if they have bigger values (roughly 200 bytes in this case). Instead of "Config:Queue:400", the key gets called "Config:Queue:40<some unprintable ASCII char>". Happens for one key per run on every 9th to 10th run.
The data returned by Memcached is correct as strace shows:
read(5, "[...]type_test\10\201\0\0\0\10type_b\0\0\0\7columns\r\nVALUE Config:Queue:748 1 187\r\n", 131072) = 47630
read(4, [other server data read without problems]) = 101
select(8, [4 5], NULL, NULL, {tv_sec=1, tv_usec=0}) = 2 (in [4 5], left {tv_sec=0, tv_usec=999998})
read(5, "\5\n\3\0\0\0\1\4\3\0\0\0\n\10\201\0\0\0\10type_d[...]\r\n", 189) = 189
The first read has the key at the end of the packet. The next line reads a packet from another memcached server and the last line reads the payload for the key at the end of the first packet.
This is repeatable: If a key name is passed at the end of one read and the value starts at the beginning of the next read, then the key name is broken afterwards and it's always broken at the last char of the key name.
Might also be a problem in Cache::Memcached::GetParserXS instead of Cache::Memcached.
Data::ObjectDriver assumes that everything is fine if the number of keys returned from get_multi is the same as requested which results in data corruption at the end.