8034b0f9 |
1 | # redis-sha1.rb - Copyright (C) 2009 Salvatore Sanfilippo |
2 | # BSD license, See the COPYING file for more information. |
3 | # |
4 | # Performs the SHA1 sum of the whole datset. |
5 | # This is useful to spot bugs in persistence related code and to make sure |
6 | # Slaves and Masters are in SYNC. |
7 | # |
8 | # If you hack this code make sure to sort keys and set elements as this are |
9 | # unsorted elements. Otherwise the sum may differ with equal dataset. |
10 | |
11 | require 'rubygems' |
12 | require 'redis' |
13 | require 'digest/sha1' |
14 | |
15 | def redisCopy(opts={}) |
16 | sha1="" |
17 | src = Redis.new(:host => opts[:srchost], :port => opts[:srcport]) |
18 | dst = Redis.new(:host => opts[:dsthost], :port => opts[:dstport]) |
19 | puts "Loading key names..." |
20 | keys = src.keys('*') |
21 | puts "Copying #{keys.length} keys..." |
22 | c = 0 |
23 | keys.each{|k| |
24 | vtype = src.type?(k) |
25 | ttl = src.ttl(k).to_i if vtype != "none" |
26 | |
27 | if vtype == "string" |
28 | dst[k] = src[k] |
29 | elsif vtype == "list" |
30 | list = src.lrange(k,0,-1) |
31 | if list.length == 0 |
32 | # Empty list special case |
33 | dst.lpush(k,"") |
34 | dst.lpop(k) |
35 | else |
36 | list.each{|ele| |
37 | dst.rpush(k,ele) |
38 | } |
39 | end |
40 | elsif vtype == "set" |
41 | set = src.smembers(k) |
42 | if set.length == 0 |
43 | # Empty set special case |
44 | dst.sadd(k,"") |
45 | dst.srem(k,"") |
46 | else |
47 | set.each{|ele| |
48 | dst.sadd(k,ele) |
49 | } |
50 | end |
51 | elsif vtype == "none" |
52 | puts "WARNING: key '#{k}' was removed in the meanwhile." |
53 | end |
54 | |
55 | # Handle keys with an expire time set |
56 | if ttl != -1 and vtype != "none" |
57 | dst.expire(k,ttl) |
58 | end |
59 | |
60 | c = c+1 |
61 | if (c % 1000) == 0 |
62 | puts "#{c}/#{keys.length} completed" |
63 | end |
64 | } |
65 | puts "DONE!" |
66 | end |
67 | |
68 | if ARGV.length != 4 |
69 | puts "Usage: redis-copy.rb <srchost> <srcport> <dsthost> <dstport>" |
70 | exit 1 |
71 | end |
72 | puts "WARNING: it's up to you to FLUSHDB the destination host before to continue, press any key when ready." |
73 | STDIN.gets |
74 | srchost = ARGV[0] |
75 | srcport = ARGV[1] |
76 | dsthost = ARGV[2] |
77 | dstport = ARGV[3] |
78 | puts "Copying #{srchost}:#{srcport} into #{dsthost}:#{dstport}" |
79 | redisCopy(:srchost => srchost, :srcport => srcport.to_i, |
80 | :dsthost => dsthost, :dstport => dstport.to_i) |