Commit 7b9fc6fc authored by Oran Agra's avatar Oran Agra
Browse files

Merge 'origin/unstable' into 7.0 for 7.0.3

parents 05833959 693acc01
...@@ -1570,6 +1570,52 @@ start_server {tags {"scripting"}} { ...@@ -1570,6 +1570,52 @@ start_server {tags {"scripting"}} {
r config set min-replicas-to-write 0 r config set min-replicas-to-write 0
} }
test "not enough good replicas state change during long script" {
r set x "pre-script value"
r config set min-replicas-to-write 1
r config set lua-time-limit 10
start_server {tags {"external:skip"}} {
# add a replica and wait for the master to recognize it's online
r slaveof [srv -1 host] [srv -1 port]
wait_replica_online [srv -1 client]
# run a slow script that does one write, then waits for INFO to indicate
# that the replica dropped, and then runs another write
set rd [redis_deferring_client -1]
$rd eval {
redis.call('set','x',"script value")
while true do
local info = redis.call('info','replication')
if (string.match(info, "connected_slaves:0")) then
redis.call('set','x',info)
break
end
end
return 1
} 1 x
# wait for the script to time out and yield
wait_for_condition 100 100 {
[catch {r -1 ping} e] == 1
} else {
fail "Can't wait for script to start running"
}
catch {r -1 ping} e
assert_match {BUSY*} $e
# cause the replica to disconnect (triggering the busy script to exit)
r slaveof no one
# make sure the script was able to write after the replica dropped
assert_equal [$rd read] 1
assert_match {*connected_slaves:0*} [r -1 get x]
$rd close
}
r config set min-replicas-to-write 0
r config set lua-time-limit 5000
} {OK} {external:skip needs:repl}
test "allow-stale shebang flag" { test "allow-stale shebang flag" {
r config set replica-serve-stale-data no r config set replica-serve-stale-data no
r replicaof 127.0.0.1 1 r replicaof 127.0.0.1 1
...@@ -1599,19 +1645,19 @@ start_server {tags {"scripting"}} { ...@@ -1599,19 +1645,19 @@ start_server {tags {"scripting"}} {
} 1 x } 1 x
} }
assert_match {*redis_version*} [ assert_match {foobar} [
r eval {#!lua flags=allow-stale,no-writes r eval {#!lua flags=allow-stale,no-writes
return redis.call('info','server') return redis.call('echo','foobar')
} 0 } 0
] ]
# Test again with EVALSHA # Test again with EVALSHA
set sha [ set sha [
r script load {#!lua flags=allow-stale,no-writes r script load {#!lua flags=allow-stale,no-writes
return redis.call('info','server') return redis.call('echo','foobar')
} }
] ]
assert_match {*redis_version*} [r evalsha $sha 0] assert_match {foobar} [r evalsha $sha 0]
r replicaof no one r replicaof no one
r config set replica-serve-stale-data yes r config set replica-serve-stale-data yes
......
...@@ -2208,7 +2208,7 @@ start_server {tags {"zset"}} { ...@@ -2208,7 +2208,7 @@ start_server {tags {"zset"}} {
assert_match "*syntax*" $err assert_match "*syntax*" $err
} }
test {ZRANGESTORE with zset-max-listpack-entries 0 dst key should use skiplist encoding} { test {ZRANGESTORE with zset-max-listpack-entries 0 #10767 case} {
set original_max [lindex [r config get zset-max-listpack-entries] 1] set original_max [lindex [r config get zset-max-listpack-entries] 1]
r config set zset-max-listpack-entries 0 r config set zset-max-listpack-entries 0
r del z1{t} z2{t} r del z1{t} z2{t}
...@@ -2217,6 +2217,18 @@ start_server {tags {"zset"}} { ...@@ -2217,6 +2217,18 @@ start_server {tags {"zset"}} {
r config set zset-max-listpack-entries $original_max r config set zset-max-listpack-entries $original_max
} }
test {ZRANGESTORE with zset-max-listpack-entries 1 dst key should use skiplist encoding} {
set original_max [lindex [r config get zset-max-listpack-entries] 1]
r config set zset-max-listpack-entries 1
r del z1{t} z2{t} z3{t}
r zadd z1{t} 1 a 2 b
assert_equal 1 [r zrangestore z2{t} z1{t} 0 0]
assert_encoding listpack z2{t}
assert_equal 2 [r zrangestore z3{t} z1{t} 0 1]
assert_encoding skiplist z3{t}
r config set zset-max-listpack-entries $original_max
}
test {ZRANGE invalid syntax} { test {ZRANGE invalid syntax} {
catch {r zrange z1{t} 0 -1 limit 1 2} err catch {r zrange z1{t} 0 -1 limit 1 2} err
assert_match "*syntax*" $err assert_match "*syntax*" $err
......
...@@ -11,12 +11,13 @@ def markdown(s) ...@@ -11,12 +11,13 @@ def markdown(s)
s.chop! while s[-1] == "\n" || s[-1] == " " s.chop! while s[-1] == "\n" || s[-1] == " "
lines = s.split("\n") lines = s.split("\n")
newlines = [] newlines = []
# Fix some markdown, except in code blocks indented by 4 spaces. # Fix some markdown
lines.each{|l| lines.each{|l|
# Rewrite RM_Xyz() to RedisModule_Xyz().
l = l.gsub(/(?<![A-Z_])RM_(?=[A-Z])/, 'RedisModule_')
# Fix more markdown, except in code blocks indented by 4 spaces, which we
# don't want to mess with.
if not l.start_with?(' ') if not l.start_with?(' ')
# Rewrite RM_Xyz() to `RedisModule_Xyz()`. The () suffix is
# optional. Even RM_Xyz*() with * as wildcard is handled.
l = l.gsub(/(?<!`)RM_([A-z]+(?:\*?\(\))?)/, '`RedisModule_\1`')
# Add backquotes around RedisModule functions and type where missing. # Add backquotes around RedisModule functions and type where missing.
l = l.gsub(/(?<!`)RedisModule[A-z]+(?:\*?\(\))?/){|x| "`#{x}`"} l = l.gsub(/(?<!`)RedisModule[A-z]+(?:\*?\(\))?/){|x| "`#{x}`"}
# Add backquotes around c functions like malloc() where missing. # Add backquotes around c functions like malloc() where missing.
......
...@@ -19,7 +19,7 @@ struct entry { ...@@ -19,7 +19,7 @@ struct entry {
}; };
#define to_16bit_minutes(x) ((x/60) & 65535) #define to_16bit_minutes(x) ((x/60) & 65535)
#define COUNTER_INIT_VAL 5 #define LFU_INIT_VAL 5
/* Compute the difference in minutes between two 16 bit minutes times /* Compute the difference in minutes between two 16 bit minutes times
* obtained with to_16bit_minutes(). Since they can wrap around if * obtained with to_16bit_minutes(). Since they can wrap around if
...@@ -36,7 +36,7 @@ uint16_t minutes_diff(uint16_t now, uint16_t prev) { ...@@ -36,7 +36,7 @@ uint16_t minutes_diff(uint16_t now, uint16_t prev) {
uint8_t log_incr(uint8_t counter) { uint8_t log_incr(uint8_t counter) {
if (counter == 255) return counter; if (counter == 255) return counter;
double r = (double)rand()/RAND_MAX; double r = (double)rand()/RAND_MAX;
double baseval = counter-COUNTER_INIT_VAL; double baseval = counter-LFU_INIT_VAL;
if (baseval < 0) baseval = 0; if (baseval < 0) baseval = 0;
double limit = 1.0/(baseval*10+1); double limit = 1.0/(baseval*10+1);
if (r < limit) counter++; if (r < limit) counter++;
...@@ -56,7 +56,7 @@ uint8_t scan_entry(struct entry *e) { ...@@ -56,7 +56,7 @@ uint8_t scan_entry(struct entry *e) {
>= decr_every) >= decr_every)
{ {
if (e->counter) { if (e->counter) {
if (e->counter > COUNTER_INIT_VAL*2) { if (e->counter > LFU_INIT_VAL*2) {
e->counter /= 2; e->counter /= 2;
} else { } else {
e->counter--; e->counter--;
...@@ -89,7 +89,7 @@ int main(void) { ...@@ -89,7 +89,7 @@ int main(void) {
/* Initialize. */ /* Initialize. */
for (j = 0; j < keyspace_size; j++) { for (j = 0; j < keyspace_size; j++) {
entries[j].counter = COUNTER_INIT_VAL; entries[j].counter = LFU_INIT_VAL;
entries[j].decrtime = to_16bit_minutes(start); entries[j].decrtime = to_16bit_minutes(start);
entries[j].hits = 0; entries[j].hits = 0;
entries[j].ctime = time(NULL); entries[j].ctime = time(NULL);
...@@ -131,7 +131,7 @@ int main(void) { ...@@ -131,7 +131,7 @@ int main(void) {
* 10 and 19, a random one every 10 seconds. */ * 10 and 19, a random one every 10 seconds. */
if (new_entry_time <= now) { if (new_entry_time <= now) {
idx = 10+(rand()%10); idx = 10+(rand()%10);
entries[idx].counter = COUNTER_INIT_VAL; entries[idx].counter = LFU_INIT_VAL;
entries[idx].decrtime = to_16bit_minutes(time(NULL)); entries[idx].decrtime = to_16bit_minutes(time(NULL));
entries[idx].hits = 0; entries[idx].hits = 0;
entries[idx].ctime = time(NULL); entries[idx].ctime = time(NULL);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment