Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
7e69548d
Commit
7e69548d
authored
Jan 05, 2010
by
antirez
Browse files
SAVE now works with VM
parent
e3cadb8a
Changes
1
Hide whitespace changes
Inline
Side-by-side
redis.c
View file @
7e69548d
...
...
@@ -492,7 +492,9 @@ static int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele);
static
void
vmInit
(
void
);
static
void
vmMarkPagesFree
(
off_t
page
,
off_t
count
);
static
robj
*
vmLoadObject
(
robj
*
key
);
static
robj
*
vmPreviewObject
(
robj
*
key
);
static
int
vmSwapOneObject
(
void
);
static
int
vmCanSwapOut
(
void
);
static
void
authCommand
(
redisClient
*
c
);
static
void
pingCommand
(
redisClient
*
c
);
...
...
@@ -1177,10 +1179,16 @@ static int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientD
/* Swap a few keys on disk if we are over the memory limit and VM
* is enbled. */
while
(
server
.
vm_enabled
&&
zmalloc_used_memory
()
>
server
.
vm_max_memory
)
{
if
(
vmSwapOneObject
()
==
REDIS_ERR
)
{
redisLog
(
REDIS_WARNING
,
"WARNING: vm-max-memory limit reached but unable to swap more objects out!"
);
break
;
if
(
vmCanSwapOut
())
{
while
(
server
.
vm_enabled
&&
zmalloc_used_memory
()
>
server
.
vm_max_memory
)
{
if
(
vmSwapOneObject
()
==
REDIS_ERR
)
{
if
(
zmalloc_used_memory
()
>
(
server
.
vm_max_memory
+
server
.
vm_max_memory
/
10
))
{
redisLog
(
REDIS_WARNING
,
"WARNING: vm-max-memory limit exceeded by more than 10%% but unable to swap more objects out!"
);
}
break
;
}
}
}
...
...
@@ -2877,11 +2885,28 @@ static int rdbSave(char *filename) {
if
(
rdbSaveType
(
fp
,
REDIS_EXPIRETIME
)
==
-
1
)
goto
werr
;
if
(
rdbSaveTime
(
fp
,
expiretime
)
==
-
1
)
goto
werr
;
}
/* Save the key and associated value */
if
(
rdbSaveType
(
fp
,
o
->
type
)
==
-
1
)
goto
werr
;
if
(
rdbSaveStringObject
(
fp
,
key
)
==
-
1
)
goto
werr
;
/* Save the actual value */
if
(
rdbSaveObject
(
fp
,
o
)
==
-
1
)
goto
werr
;
/* Save the key and associated value. This requires special
* handling if the value is swapped out. */
if
(
key
->
storage
==
REDIS_VM_MEMORY
)
{
/* Save type, key, value */
if
(
rdbSaveType
(
fp
,
o
->
type
)
==
-
1
)
goto
werr
;
if
(
rdbSaveStringObject
(
fp
,
key
)
==
-
1
)
goto
werr
;
if
(
rdbSaveObject
(
fp
,
o
)
==
-
1
)
goto
werr
;
}
else
{
robj
*
po
,
*
newkey
;
/* Get a preview of the object in memory */
po
=
vmPreviewObject
(
key
);
/* Also duplicate the key object, to pass around a standard
* string object. */
newkey
=
dupStringObject
(
key
);
/* Save type, key, value */
if
(
rdbSaveType
(
fp
,
key
->
vtype
)
==
-
1
)
goto
werr
;
if
(
rdbSaveStringObject
(
fp
,
newkey
)
==
-
1
)
goto
werr
;
if
(
rdbSaveObject
(
fp
,
po
)
==
-
1
)
goto
werr
;
/* Remove the loaded object from memory */
decrRefCount
(
po
);
decrRefCount
(
newkey
);
}
}
dictReleaseIterator
(
di
);
}
...
...
@@ -6833,8 +6858,11 @@ static int vmSwapObject(robj *key, robj *val) {
}
/* Load the value object relative to the 'key' object from swap to memory.
* The newly allocated object is returned. */
static
robj
*
vmLoadObject
(
robj
*
key
)
{
* The newly allocated object is returned.
*
* If preview is true the unserialized object is returned to the caller but
* no changes are made to the key object, nor the pages are marked as freed */
static
robj
*
vmGenericLoadObject
(
robj
*
key
,
int
preview
)
{
robj
*
val
;
assert
(
key
->
storage
==
REDIS_VM_SWAPPED
);
...
...
@@ -6849,14 +6877,29 @@ static robj *vmLoadObject(robj *key) {
redisLog
(
REDIS_WARNING
,
"Unrecoverable VM problem in vmLoadObject(): can't load object from swap file: %s"
,
strerror
(
errno
));
exit
(
1
);
}
key
->
storage
=
REDIS_VM_MEMORY
;
key
->
vm
.
atime
=
server
.
unixtime
;
vmMarkPagesFree
(
key
->
vm
.
page
,
key
->
vm
.
usedpages
);
redisLog
(
REDIS_DEBUG
,
"VM: object %s loaded from disk"
,
(
unsigned
char
*
)
key
->
ptr
);
if
(
!
preview
)
{
key
->
storage
=
REDIS_VM_MEMORY
;
key
->
vm
.
atime
=
server
.
unixtime
;
vmMarkPagesFree
(
key
->
vm
.
page
,
key
->
vm
.
usedpages
);
redisLog
(
REDIS_DEBUG
,
"VM: object %s loaded from disk"
,
(
unsigned
char
*
)
key
->
ptr
);
}
return
val
;
}
/* Plain object loading, from swap to memory */
static
robj
*
vmLoadObject
(
robj
*
key
)
{
return
vmGenericLoadObject
(
key
,
0
);
}
/* Just load the value on disk, without to modify the key.
* This is useful when we want to perform some operation on the value
* without to really bring it from swap to memory, like while saving the
* dataset or rewriting the append only log. */
static
robj
*
vmPreviewObject
(
robj
*
key
)
{
return
vmGenericLoadObject
(
key
,
1
);
}
/* How a good candidate is this object for swapping?
* The better candidate it is, the greater the returned value.
*
...
...
@@ -6982,6 +7025,13 @@ static int vmSwapOneObject(void) {
}
}
/* Return true if it's safe to swap out objects in a given moment.
* Basically we don't want to swap objects out while there is a BGSAVE
* or a BGAEOREWRITE running in backgroud. */
static
int
vmCanSwapOut
(
void
)
{
return
(
server
.
bgsavechildpid
==
-
1
&&
server
.
bgrewritechildpid
==
-
1
);
}
/* ================================= Debugging ============================== */
static
void
debugCommand
(
redisClient
*
c
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment