redis-dump 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +8 -2
- data/README.rdoc +5 -0
- data/VERSION.yml +2 -2
- data/bin/redis-load +4 -1
- data/lib/redis/dump.rb +27 -16
- data/redis-dump.gemspec +1 -1
- metadata +10 -10
data/CHANGES.txt
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
REDIS-DUMP, CHANGES
|
2
2
|
|
3
|
+
#### 0.3.4 (2012-12-19) ###############################
|
4
|
+
|
5
|
+
* ADDED: Allow loading of redis dumps with binary data (-n flag) [meekmichael]
|
6
|
+
* FIXED: Rescue exceptions when setting values
|
7
|
+
|
8
|
+
|
3
9
|
#### 0.3.3 (2012-11-22) ###############################
|
4
10
|
|
5
|
-
*
|
11
|
+
* FIXED: issue with return value from zrange in newer versions of redis lib (3.0+).
|
6
12
|
|
7
13
|
#### 0.3.2 (2012-01-05) ###############################
|
8
14
|
|
@@ -47,4 +53,4 @@ REDIS-DUMP, CHANGES
|
|
47
53
|
|
48
54
|
#### 0.1.0 (2010-11-15) ###############################
|
49
55
|
|
50
|
-
Initial public release.
|
56
|
+
Initial public release.
|
data/README.rdoc
CHANGED
@@ -68,6 +68,11 @@ For most sensitive data, you should consider encrypting the data directly withou
|
|
68
68
|
|
69
69
|
# Decrypt the file (automated)
|
70
70
|
$ 3</path/2/passphrase.txt gpg --passphrase-fd 3 path/2/backup-db15.json.gpg
|
71
|
+
|
72
|
+
|
73
|
+
== Loading data with binary strings
|
74
|
+
|
75
|
+
If you have binary or serialized data in your Redis database, the YAJL parser may not load your dump file because it sees some of the binary data as 'invalid bytes in UTF8 string'. If you are certain that your data is binary and not malformed UTF8, you can use the -n flag to redis-load to tell YAJL to not check the input for UTF8 validity. Use with caution!
|
71
76
|
|
72
77
|
== Installation
|
73
78
|
|
data/VERSION.yml
CHANGED
data/bin/redis-load
CHANGED
@@ -28,6 +28,9 @@ class Redis::Dump::CLI
|
|
28
28
|
global :u, :uri, String, "Redis URI (e.g. redis://hostname[:port])"
|
29
29
|
global :d, :database, Integer, "Redis database (e.g. -d 15)"
|
30
30
|
global :s, :sleep, Integer, "Sleep for S seconds after dumping (for debugging)"
|
31
|
+
global :n, :no_check_utf8 do
|
32
|
+
Redis::Dump.check_utf8 = false
|
33
|
+
end
|
31
34
|
global :V, :version, "Display version" do
|
32
35
|
puts "redis-dump v#{Redis::Dump::VERSION.to_s}"
|
33
36
|
exit 0
|
@@ -126,4 +129,4 @@ rescue Interrupt
|
|
126
129
|
rescue => ex
|
127
130
|
STDERR.puts "ERROR (#{ex.class.to_s}): #{ex.message}"
|
128
131
|
STDERR.puts ex.backtrace if Redis::Dump.debug
|
129
|
-
end
|
132
|
+
end
|
data/lib/redis/dump.rb
CHANGED
@@ -16,17 +16,24 @@ class Redis
|
|
16
16
|
@debug = false
|
17
17
|
@encoder = Yajl::Encoder.new
|
18
18
|
@parser = Yajl::Parser.new
|
19
|
-
@safe = true
|
20
19
|
@chunk_size = 10000
|
21
20
|
@with_optimizations = true
|
22
21
|
class << self
|
23
22
|
attr_accessor :debug, :encoder, :parser, :safe, :host, :port, :chunk_size, :with_optimizations
|
23
|
+
def le(msg)
|
24
|
+
STDERR.puts "#%.4f: %s" % [Time.now.utc.to_f, msg]
|
25
|
+
end
|
24
26
|
def ld(msg)
|
25
27
|
STDERR.puts "#%.4f: %s" % [Time.now.utc.to_f, msg] if debug
|
26
28
|
end
|
27
29
|
def memory_usage
|
28
30
|
`ps -o rss= -p #{Process.pid}`.to_i # in kb
|
29
31
|
end
|
32
|
+
def check_utf8=(check)
|
33
|
+
if check == false
|
34
|
+
@parser = Yajl::Parser.new(:check_utf8 => false)
|
35
|
+
end
|
36
|
+
end
|
30
37
|
end
|
31
38
|
attr_accessor :dbs, :uri
|
32
39
|
attr_reader :redis_connections
|
@@ -46,13 +53,13 @@ class Redis
|
|
46
53
|
#self.class.ld 'CONNECT: ' << this_uri
|
47
54
|
Redis.connect :url => this_uri
|
48
55
|
end
|
49
|
-
|
56
|
+
|
50
57
|
def each_database
|
51
58
|
@redis_connections.keys.sort.each do |redis_uri|
|
52
59
|
yield redis_connections[redis_uri]
|
53
60
|
end
|
54
61
|
end
|
55
|
-
|
62
|
+
|
56
63
|
# See each_key
|
57
64
|
def dump filter=nil
|
58
65
|
filter ||= '*'
|
@@ -71,9 +78,9 @@ class Redis
|
|
71
78
|
process_chunk idx, dump_keys_size do |count|
|
72
79
|
Redis::Dump.ld " dumping #{chunk_entries.size} (#{count}) from #{redis.client.id}"
|
73
80
|
output_buffer = []
|
74
|
-
chunk_entries.select! do |key|
|
81
|
+
chunk_entries.select! do |key|
|
75
82
|
type = Redis::Dump.type(redis, key)
|
76
|
-
if self.class.with_optimizations && type == 'string'
|
83
|
+
if self.class.with_optimizations && type == 'string'
|
77
84
|
true
|
78
85
|
else
|
79
86
|
output_buffer.push self.class.encoder.encode(Redis::Dump.dump(redis, key, type))
|
@@ -81,10 +88,10 @@ class Redis
|
|
81
88
|
end
|
82
89
|
end
|
83
90
|
unless output_buffer.empty?
|
84
|
-
yield output_buffer
|
91
|
+
yield output_buffer
|
85
92
|
end
|
86
93
|
unless chunk_entries.empty?
|
87
|
-
yield Redis::Dump.dump_strings(redis, chunk_entries) { |obj| self.class.encoder.encode(obj) }
|
94
|
+
yield Redis::Dump.dump_strings(redis, chunk_entries) { |obj| self.class.encoder.encode(obj) }
|
88
95
|
end
|
89
96
|
output_buffer.clear
|
90
97
|
chunk_entries.clear
|
@@ -96,13 +103,13 @@ class Redis
|
|
96
103
|
end
|
97
104
|
entries
|
98
105
|
end
|
99
|
-
|
106
|
+
|
100
107
|
def process_chunk idx, total_size
|
101
108
|
idxplus = idx+1
|
102
109
|
yield idxplus if (idxplus % self.class.chunk_size).zero? || idxplus >= total_size
|
103
110
|
end
|
104
111
|
private :process_chunk
|
105
|
-
|
112
|
+
|
106
113
|
def report filter='*'
|
107
114
|
values = []
|
108
115
|
total_size, dbs = 0, {}
|
@@ -129,7 +136,7 @@ class Redis
|
|
129
136
|
puts "total: #{total_size.to_bytes}"
|
130
137
|
values
|
131
138
|
end
|
132
|
-
|
139
|
+
|
133
140
|
def load(string_or_stream, &each_record)
|
134
141
|
count = 0
|
135
142
|
Redis::Dump.ld " LOAD SOURCE: #{string_or_stream}"
|
@@ -140,12 +147,16 @@ class Redis
|
|
140
147
|
end
|
141
148
|
this_redis = redis(obj["db"])
|
142
149
|
#Redis::Dump.ld "load[#{this_redis.hash}, #{obj}]"
|
143
|
-
if each_record.nil?
|
150
|
+
if each_record.nil?
|
144
151
|
if Redis::Dump.safe && this_redis.exists(obj['key'])
|
145
152
|
#Redis::Dump.ld " record exists (no change)"
|
146
153
|
next
|
147
154
|
end
|
148
|
-
|
155
|
+
begin
|
156
|
+
Redis::Dump.set_value this_redis, obj['key'], obj['type'], obj['value'], obj['ttl']
|
157
|
+
rescue => ex
|
158
|
+
Redis::Dump.le '(key: %s) %s' % [obj['key'], ex.message]
|
159
|
+
end
|
149
160
|
else
|
150
161
|
each_record.call obj
|
151
162
|
end
|
@@ -182,7 +193,7 @@ class Redis
|
|
182
193
|
idx = -1
|
183
194
|
keys.collect { |key|
|
184
195
|
idx += 1
|
185
|
-
info = {
|
196
|
+
info = {
|
186
197
|
'db' => this_redis.client.db, 'key' => key,
|
187
198
|
'ttl' => this_redis.ttl(key), 'type' => 'string',
|
188
199
|
'value' => vals[idx].to_s, 'size' => vals[idx].to_s.size
|
@@ -201,7 +212,7 @@ class Redis
|
|
201
212
|
def stringify(this_redis, key, t=nil, v=nil)
|
202
213
|
send("stringify_#{t}", this_redis, key, v)
|
203
214
|
end
|
204
|
-
|
215
|
+
|
205
216
|
def set_value_hash(this_redis, key, hash)
|
206
217
|
hash.keys.each { |k| this_redis.hset key, k, hash[k] }
|
207
218
|
end
|
@@ -220,7 +231,7 @@ class Redis
|
|
220
231
|
def set_value_none(this_redis, key, str)
|
221
232
|
# ignore
|
222
233
|
end
|
223
|
-
|
234
|
+
|
224
235
|
def value_string(this_redis, key) this_redis.get key end
|
225
236
|
def value_list (this_redis, key) this_redis.lrange key, 0, -1 end
|
226
237
|
def value_set (this_redis, key) this_redis.smembers key end
|
@@ -235,7 +246,7 @@ class Redis
|
|
235
246
|
def stringify_none (this_redis, key, v=nil) (v || '') end
|
236
247
|
end
|
237
248
|
extend Redis::Dump::ClassMethods
|
238
|
-
|
249
|
+
|
239
250
|
module VERSION
|
240
251
|
def self.stamp
|
241
252
|
@info[:STAMP].to_i
|
data/redis-dump.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-dump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: yajl-ruby
|
16
|
-
requirement: &
|
16
|
+
requirement: &70204696859080 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0.1'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70204696859080
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: redis
|
27
|
-
requirement: &
|
27
|
+
requirement: &70204696858600 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '2.0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70204696858600
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: uri-redis
|
38
|
-
requirement: &
|
38
|
+
requirement: &70204696858120 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.4.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70204696858120
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: drydock
|
49
|
-
requirement: &
|
49
|
+
requirement: &70204696857640 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: 0.6.9
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70204696857640
|
58
58
|
description: Backup and restore your Redis data to and from JSON.
|
59
59
|
email: delano@solutious.com
|
60
60
|
executables:
|