Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
别团等shy哥发育
redis
提交
bff31e12
R
redis
项目概览
别团等shy哥发育
/
redis
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
redis
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bff31e12
编写于
4月 02, 2012
作者:
A
antirez
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
New verions of DUMP, RESTORE, MIGRATE back ported from unstable to 2.6
上级
179ee2db
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
91 addition
and
33 deletion
+91
-33
src/migrate.c
src/migrate.c
+91
-33
未找到文件。
src/migrate.c
浏览文件 @
bff31e12
#include "redis.h"
#include "redis.h"
#include "endianconv.h"
/* -----------------------------------------------------------------------------
/* -----------------------------------------------------------------------------
* RESTORE and MIGRATE commands
*
DUMP,
RESTORE and MIGRATE commands
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/* Generates a DUMP-format representation of the object 'o', adding it to the
* io stream pointed by 'rio'. This function can't fail. */
void
createDumpPayload
(
rio
*
payload
,
robj
*
o
)
{
unsigned
char
buf
[
2
];
uint64_t
crc
;
/* Serialize the object in a RDB-like format. It consist of an object type
* byte followed by the serialized object. This is understood by RESTORE. */
rioInitWithBuffer
(
payload
,
sdsempty
());
redisAssert
(
rdbSaveObjectType
(
payload
,
o
));
redisAssert
(
rdbSaveObject
(
payload
,
o
));
/* Write the footer, this is how it looks like:
* ----------------+---------------------+---------------+
* ... RDB payload | 2 bytes RDB version | 8 bytes CRC64 |
* ----------------+---------------------+---------------+
* RDB version and CRC are both in little endian.
*/
/* RDB version */
buf
[
0
]
=
REDIS_RDB_VERSION
&
0xff
;
buf
[
1
]
=
(
REDIS_RDB_VERSION
>>
8
)
&
0xff
;
payload
->
io
.
buffer
.
ptr
=
sdscatlen
(
payload
->
io
.
buffer
.
ptr
,
buf
,
2
);
/* CRC64 */
crc
=
crc64
((
unsigned
char
*
)
payload
->
io
.
buffer
.
ptr
,
sdslen
(
payload
->
io
.
buffer
.
ptr
));
memrev64ifbe
(
&
crc
);
payload
->
io
.
buffer
.
ptr
=
sdscatlen
(
payload
->
io
.
buffer
.
ptr
,
&
crc
,
8
);
}
/* Verify that the RDB version of the dump payload matches the one of this Redis
* instance and that the checksum is ok.
* If the DUMP payload looks valid REDIS_OK is returned, otherwise REDIS_ERR
* is returned. */
int
verifyDumpPayload
(
unsigned
char
*
p
,
size_t
len
)
{
unsigned
char
*
footer
;
uint16_t
rdbver
;
uint64_t
crc
;
/* At least 2 bytes of RDB version and 8 of CRC64 should be present. */
if
(
len
<
10
)
return
REDIS_ERR
;
footer
=
p
+
(
len
-
10
);
/* Verify RDB version */
rdbver
=
(
footer
[
1
]
<<
8
)
|
footer
[
0
];
if
(
rdbver
!=
REDIS_RDB_VERSION
)
return
REDIS_ERR
;
/* Verify CRC64 */
crc
=
crc64
(
p
,
len
-
8
);
memrev64ifbe
(
&
crc
);
return
(
memcmp
(
&
crc
,
footer
+
2
,
8
)
==
0
)
?
REDIS_OK
:
REDIS_ERR
;
}
/* DUMP keyname
* DUMP is actually not used by Redis Cluster but it is the obvious
* complement of RESTORE and can be useful for different applications. */
void
dumpCommand
(
redisClient
*
c
)
{
robj
*
o
,
*
dumpobj
;
rio
payload
;
/* Check if the key is here. */
if
((
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]))
==
NULL
)
{
addReply
(
c
,
shared
.
nullbulk
);
return
;
}
/* Create the DUMP encoded representation. */
createDumpPayload
(
&
payload
,
o
);
/* Transfer to the client */
dumpobj
=
createObject
(
REDIS_STRING
,
payload
.
io
.
buffer
.
ptr
);
addReplyBulk
(
c
,
dumpobj
);
decrRefCount
(
dumpobj
);
return
;
}
/* RESTORE key ttl serialized-value */
/* RESTORE key ttl serialized-value */
void
restoreCommand
(
redisClient
*
c
)
{
void
restoreCommand
(
redisClient
*
c
)
{
long
ttl
;
long
ttl
;
...
@@ -25,6 +103,12 @@ void restoreCommand(redisClient *c) {
...
@@ -25,6 +103,12 @@ void restoreCommand(redisClient *c) {
return
;
return
;
}
}
/* Verify RDB version and data checksum. */
if
(
verifyDumpPayload
(
c
->
argv
[
3
]
->
ptr
,
sdslen
(
c
->
argv
[
3
]
->
ptr
))
==
REDIS_ERR
)
{
addReplyError
(
c
,
"DUMP payload version or checksum are wrong"
);
return
;
}
rioInitWithBuffer
(
&
payload
,
c
->
argv
[
3
]
->
ptr
);
rioInitWithBuffer
(
&
payload
,
c
->
argv
[
3
]
->
ptr
);
if
(((
type
=
rdbLoadObjectType
(
&
payload
))
==
-
1
)
||
if
(((
type
=
rdbLoadObjectType
(
&
payload
))
==
-
1
)
||
((
obj
=
rdbLoadObject
(
type
,
&
payload
))
==
NULL
))
((
obj
=
rdbLoadObject
(
type
,
&
payload
))
==
NULL
))
...
@@ -35,7 +119,7 @@ void restoreCommand(redisClient *c) {
...
@@ -35,7 +119,7 @@ void restoreCommand(redisClient *c) {
/* Create the key and set the TTL if any */
/* Create the key and set the TTL if any */
dbAdd
(
c
->
db
,
c
->
argv
[
1
],
obj
);
dbAdd
(
c
->
db
,
c
->
argv
[
1
],
obj
);
if
(
ttl
)
setExpire
(
c
->
db
,
c
->
argv
[
1
],
time
(
NULL
)
+
ttl
);
if
(
ttl
)
setExpire
(
c
->
db
,
c
->
argv
[
1
],
mstime
(
)
+
ttl
);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
signalModifiedKey
(
c
->
db
,
c
->
argv
[
1
]);
addReply
(
c
,
shared
.
ok
);
addReply
(
c
,
shared
.
ok
);
server
.
dirty
++
;
server
.
dirty
++
;
...
@@ -78,6 +162,7 @@ void migrateCommand(redisClient *c) {
...
@@ -78,6 +162,7 @@ void migrateCommand(redisClient *c) {
return
;
return
;
}
}
/* Create RESTORE payload and generate the protocol to call the command. */
rioInitWithBuffer
(
&
cmd
,
sdsempty
());
rioInitWithBuffer
(
&
cmd
,
sdsempty
());
redisAssertWithInfo
(
c
,
NULL
,
rioWriteBulkCount
(
&
cmd
,
'*'
,
2
));
redisAssertWithInfo
(
c
,
NULL
,
rioWriteBulkCount
(
&
cmd
,
'*'
,
2
));
redisAssertWithInfo
(
c
,
NULL
,
rioWriteBulkString
(
&
cmd
,
"SELECT"
,
6
));
redisAssertWithInfo
(
c
,
NULL
,
rioWriteBulkString
(
&
cmd
,
"SELECT"
,
6
));
...
@@ -91,11 +176,10 @@ void migrateCommand(redisClient *c) {
...
@@ -91,11 +176,10 @@ void migrateCommand(redisClient *c) {
redisAssertWithInfo
(
c
,
NULL
,
rioWriteBulkLongLong
(
&
cmd
,(
ttl
==
-
1
)
?
0
:
ttl
));
redisAssertWithInfo
(
c
,
NULL
,
rioWriteBulkLongLong
(
&
cmd
,(
ttl
==
-
1
)
?
0
:
ttl
));
/* Finally the last argument that is the serailized object payload
/* Finally the last argument that is the serailized object payload
* in the form: <type><rdb-serialized-object>. */
* in the DUMP format. */
rioInitWithBuffer
(
&
payload
,
sdsempty
());
createDumpPayload
(
&
payload
,
o
);
redisAssertWithInfo
(
c
,
NULL
,
rdbSaveObjectType
(
&
payload
,
o
));
redisAssertWithInfo
(
c
,
NULL
,
rioWriteBulkString
(
&
cmd
,
payload
.
io
.
buffer
.
ptr
,
redisAssertWithInfo
(
c
,
NULL
,
rdbSaveObject
(
&
payload
,
o
)
!=
-
1
);
sdslen
(
payload
.
io
.
buffer
.
ptr
)));
redisAssertWithInfo
(
c
,
NULL
,
rioWriteBulkString
(
&
cmd
,
payload
.
io
.
buffer
.
ptr
,
sdslen
(
payload
.
io
.
buffer
.
ptr
)));
sdsfree
(
payload
.
io
.
buffer
.
ptr
);
sdsfree
(
payload
.
io
.
buffer
.
ptr
);
/* Tranfer the query to the other node in 64K chunks. */
/* Tranfer the query to the other node in 64K chunks. */
...
@@ -162,29 +246,3 @@ socket_rd_err:
...
@@ -162,29 +246,3 @@ socket_rd_err:
close
(
fd
);
close
(
fd
);
return
;
return
;
}
}
/* DUMP keyname
* DUMP is actually not used by Redis Cluster but it is the obvious
* complement of RESTORE and can be useful for different applications. */
void
dumpCommand
(
redisClient
*
c
)
{
robj
*
o
,
*
dumpobj
;
rio
payload
;
/* Check if the key is here. */
if
((
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]))
==
NULL
)
{
addReply
(
c
,
shared
.
nullbulk
);
return
;
}
/* Serialize the object in a RDB-like format. It consist of an object type
* byte followed by the serialized object. This is understood by RESTORE. */
rioInitWithBuffer
(
&
payload
,
sdsempty
());
redisAssertWithInfo
(
c
,
NULL
,
rdbSaveObjectType
(
&
payload
,
o
));
redisAssertWithInfo
(
c
,
NULL
,
rdbSaveObject
(
&
payload
,
o
));
/* Transfer to the client */
dumpobj
=
createObject
(
REDIS_STRING
,
payload
.
io
.
buffer
.
ptr
);
addReplyBulk
(
c
,
dumpobj
);
decrRefCount
(
dumpobj
);
return
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录