dump.tcl 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. start_server {tags {"dump"}} {
  2. test {DUMP / RESTORE are able to serialize / unserialize a simple key} {
  3. r set foo bar
  4. set encoded [r dump foo]
  5. r del foo
  6. list [r exists foo] [r restore foo 0 $encoded] [r ttl foo] [r get foo]
  7. } {0 OK -1 bar}
  8. test {RESTORE can set an arbitrary expire to the materialized key} {
  9. r set foo bar
  10. set encoded [r dump foo]
  11. r del foo
  12. r restore foo 5000 $encoded
  13. set ttl [r pttl foo]
  14. assert {$ttl >= 3000 && $ttl <= 5000}
  15. r get foo
  16. } {bar}
  17. test {RESTORE can set an expire that overflows a 32 bit integer} {
  18. r set foo bar
  19. set encoded [r dump foo]
  20. r del foo
  21. r restore foo 2569591501 $encoded
  22. set ttl [r pttl foo]
  23. assert {$ttl >= (2569591501-3000) && $ttl <= 2569591501}
  24. r get foo
  25. } {bar}
  26. test {RESTORE returns an error of the key already exists} {
  27. r set foo bar
  28. set e {}
  29. catch {r restore foo 0 "..."} e
  30. set e
  31. } {*BUSYKEY*}
  32. test {RESTORE can overwrite an existing key with REPLACE} {
  33. r set foo bar1
  34. set encoded1 [r dump foo]
  35. r set foo bar2
  36. set encoded2 [r dump foo]
  37. r del foo
  38. r restore foo 0 $encoded1
  39. r restore foo 0 $encoded2 replace
  40. r get foo
  41. } {bar2}
  42. test {RESTORE can detect a syntax error for unrecongized options} {
  43. catch {r restore foo 0 "..." invalid-option} e
  44. set e
  45. } {*syntax*}
  46. test {DUMP of non existing key returns nil} {
  47. r dump nonexisting_key
  48. } {}
  49. test {MIGRATE is caching connections} {
  50. # Note, we run this as first test so that the connection cache
  51. # is empty.
  52. set first [srv 0 client]
  53. r set key "Some Value"
  54. start_server {tags {"repl"}} {
  55. set second [srv 0 client]
  56. set second_host [srv 0 host]
  57. set second_port [srv 0 port]
  58. assert_match {*migrate_cached_sockets:0*} [r -1 info]
  59. r -1 migrate $second_host $second_port key 9 1000
  60. assert_match {*migrate_cached_sockets:1*} [r -1 info]
  61. }
  62. }
  63. test {MIGRATE cached connections are released after some time} {
  64. after 15000
  65. assert_match {*migrate_cached_sockets:0*} [r info]
  66. }
  67. test {MIGRATE is able to migrate a key between two instances} {
  68. set first [srv 0 client]
  69. r set key "Some Value"
  70. start_server {tags {"repl"}} {
  71. set second [srv 0 client]
  72. set second_host [srv 0 host]
  73. set second_port [srv 0 port]
  74. assert {[$first exists key] == 1}
  75. assert {[$second exists key] == 0}
  76. set ret [r -1 migrate $second_host $second_port key 9 5000]
  77. assert {$ret eq {OK}}
  78. assert {[$first exists key] == 0}
  79. assert {[$second exists key] == 1}
  80. assert {[$second get key] eq {Some Value}}
  81. assert {[$second ttl key] == -1}
  82. }
  83. }
  84. test {MIGRATE is able to copy a key between two instances} {
  85. set first [srv 0 client]
  86. r del list
  87. r lpush list a b c d
  88. start_server {tags {"repl"}} {
  89. set second [srv 0 client]
  90. set second_host [srv 0 host]
  91. set second_port [srv 0 port]
  92. assert {[$first exists list] == 1}
  93. assert {[$second exists list] == 0}
  94. set ret [r -1 migrate $second_host $second_port list 9 5000 copy]
  95. assert {$ret eq {OK}}
  96. assert {[$first exists list] == 1}
  97. assert {[$second exists list] == 1}
  98. assert {[$first lrange list 0 -1] eq [$second lrange list 0 -1]}
  99. }
  100. }
  101. test {MIGRATE will not overwrite existing keys, unless REPLACE is used} {
  102. set first [srv 0 client]
  103. r del list
  104. r lpush list a b c d
  105. start_server {tags {"repl"}} {
  106. set second [srv 0 client]
  107. set second_host [srv 0 host]
  108. set second_port [srv 0 port]
  109. assert {[$first exists list] == 1}
  110. assert {[$second exists list] == 0}
  111. $second set list somevalue
  112. catch {r -1 migrate $second_host $second_port list 9 5000 copy} e
  113. assert_match {ERR*} $e
  114. set res [r -1 migrate $second_host $second_port list 9 5000 copy replace]
  115. assert {$ret eq {OK}}
  116. assert {[$first exists list] == 1}
  117. assert {[$second exists list] == 1}
  118. assert {[$first lrange list 0 -1] eq [$second lrange list 0 -1]}
  119. }
  120. }
  121. test {MIGRATE propagates TTL correctly} {
  122. set first [srv 0 client]
  123. r set key "Some Value"
  124. start_server {tags {"repl"}} {
  125. set second [srv 0 client]
  126. set second_host [srv 0 host]
  127. set second_port [srv 0 port]
  128. assert {[$first exists key] == 1}
  129. assert {[$second exists key] == 0}
  130. $first expire key 10
  131. set ret [r -1 migrate $second_host $second_port key 9 5000]
  132. assert {$ret eq {OK}}
  133. assert {[$first exists key] == 0}
  134. assert {[$second exists key] == 1}
  135. assert {[$second get key] eq {Some Value}}
  136. assert {[$second ttl key] >= 7 && [$second ttl key] <= 10}
  137. }
  138. }
  139. test {MIGRATE can correctly transfer large values} {
  140. set first [srv 0 client]
  141. r del key
  142. for {set j 0} {$j < 40000} {incr j} {
  143. r rpush key 1 2 3 4 5 6 7 8 9 10
  144. r rpush key "item 1" "item 2" "item 3" "item 4" "item 5" \
  145. "item 6" "item 7" "item 8" "item 9" "item 10"
  146. }
  147. assert {[string length [r dump key]] > (1024*64)}
  148. start_server {tags {"repl"}} {
  149. set second [srv 0 client]
  150. set second_host [srv 0 host]
  151. set second_port [srv 0 port]
  152. assert {[$first exists key] == 1}
  153. assert {[$second exists key] == 0}
  154. set ret [r -1 migrate $second_host $second_port key 9 10000]
  155. assert {$ret eq {OK}}
  156. assert {[$first exists key] == 0}
  157. assert {[$second exists key] == 1}
  158. assert {[$second ttl key] == -1}
  159. assert {[$second llen key] == 40000*20}
  160. }
  161. }
  162. test {MIGRATE can correctly transfer hashes} {
  163. set first [srv 0 client]
  164. r del key
  165. r hmset key field1 "item 1" field2 "item 2" field3 "item 3" \
  166. field4 "item 4" field5 "item 5" field6 "item 6"
  167. start_server {tags {"repl"}} {
  168. set second [srv 0 client]
  169. set second_host [srv 0 host]
  170. set second_port [srv 0 port]
  171. assert {[$first exists key] == 1}
  172. assert {[$second exists key] == 0}
  173. set ret [r -1 migrate $second_host $second_port key 9 10000]
  174. assert {$ret eq {OK}}
  175. assert {[$first exists key] == 0}
  176. assert {[$second exists key] == 1}
  177. assert {[$second ttl key] == -1}
  178. }
  179. }
  180. test {MIGRATE timeout actually works} {
  181. set first [srv 0 client]
  182. r set key "Some Value"
  183. start_server {tags {"repl"}} {
  184. set second [srv 0 client]
  185. set second_host [srv 0 host]
  186. set second_port [srv 0 port]
  187. assert {[$first exists key] == 1}
  188. assert {[$second exists key] == 0}
  189. set rd [redis_deferring_client]
  190. $rd debug sleep 1.0 ; # Make second server unable to reply.
  191. set e {}
  192. catch {r -1 migrate $second_host $second_port key 9 500} e
  193. assert_match {IOERR*} $e
  194. }
  195. }
  196. test {MIGRATE can migrate multiple keys at once} {
  197. set first [srv 0 client]
  198. r set key1 "v1"
  199. r set key2 "v2"
  200. r set key3 "v3"
  201. start_server {tags {"repl"}} {
  202. set second [srv 0 client]
  203. set second_host [srv 0 host]
  204. set second_port [srv 0 port]
  205. assert {[$first exists key1] == 1}
  206. assert {[$second exists key1] == 0}
  207. set ret [r -1 migrate $second_host $second_port "" 9 5000 keys key1 key2 key3]
  208. assert {$ret eq {OK}}
  209. assert {[$first exists key1] == 0}
  210. assert {[$first exists key2] == 0}
  211. assert {[$first exists key3] == 0}
  212. assert {[$second get key1] eq {v1}}
  213. assert {[$second get key2] eq {v2}}
  214. assert {[$second get key3] eq {v3}}
  215. }
  216. }
  217. test {MIGRATE with multiple keys must have empty key arg} {
  218. catch {r MIGRATE 127.0.0.1 6379 NotEmpty 9 5000 keys a b c} e
  219. set e
  220. } {*empty string*}
  221. test {MIGRATE with mutliple keys migrate just existing ones} {
  222. set first [srv 0 client]
  223. r set key1 "v1"
  224. r set key2 "v2"
  225. r set key3 "v3"
  226. start_server {tags {"repl"}} {
  227. set second [srv 0 client]
  228. set second_host [srv 0 host]
  229. set second_port [srv 0 port]
  230. set ret [r -1 migrate $second_host $second_port "" 9 5000 keys nokey-1 nokey-2 nokey-2]
  231. assert {$ret eq {NOKEY}}
  232. assert {[$first exists key1] == 1}
  233. assert {[$second exists key1] == 0}
  234. set ret [r -1 migrate $second_host $second_port "" 9 5000 keys nokey-1 key1 nokey-2 key2 nokey-3 key3]
  235. assert {$ret eq {OK}}
  236. assert {[$first exists key1] == 0}
  237. assert {[$first exists key2] == 0}
  238. assert {[$first exists key3] == 0}
  239. assert {[$second get key1] eq {v1}}
  240. assert {[$second get key2] eq {v2}}
  241. assert {[$second get key3] eq {v3}}
  242. }
  243. }
  244. test {MIGRATE with multiple keys: stress command rewriting} {
  245. set first [srv 0 client]
  246. r flushdb
  247. r mset a 1 b 2 c 3 d 4 c 5 e 6 f 7 g 8 h 9 i 10 l 11 m 12 n 13 o 14 p 15 q 16
  248. start_server {tags {"repl"}} {
  249. set second [srv 0 client]
  250. set second_host [srv 0 host]
  251. set second_port [srv 0 port]
  252. set ret [r -1 migrate $second_host $second_port "" 9 5000 keys a b c d e f g h i l m n o p q]
  253. assert {[$first dbsize] == 0}
  254. assert {[$second dbsize] == 15}
  255. }
  256. }
  257. test {MIGRATE with multiple keys: delete just ack keys} {
  258. set first [srv 0 client]
  259. r flushdb
  260. r mset a 1 b 2 c 3 d 4 c 5 e 6 f 7 g 8 h 9 i 10 l 11 m 12 n 13 o 14 p 15 q 16
  261. start_server {tags {"repl"}} {
  262. set second [srv 0 client]
  263. set second_host [srv 0 host]
  264. set second_port [srv 0 port]
  265. $second mset c _ d _; # Two busy keys and no REPLACE used
  266. catch {r -1 migrate $second_host $second_port "" 9 5000 keys a b c d e f g h i l m n o p q} e
  267. assert {[$first dbsize] == 2}
  268. assert {[$second dbsize] == 15}
  269. assert {[$first exists c] == 1}
  270. assert {[$first exists d] == 1}
  271. }
  272. }
  273. }