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
Show whitespace changes
Inline
Side-by-side
redis.c
View file @
7e69548d
...
@@ -492,7 +492,9 @@ static int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele);
...
@@ -492,7 +492,9 @@ static int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele);
static void vmInit(void);
static void vmInit(void);
static void vmMarkPagesFree(off_t page, off_t count);
static void vmMarkPagesFree(off_t page, off_t count);
static robj *vmLoadObject(robj *key);
static robj *vmLoadObject(robj *key);
static robj *vmPreviewObject(robj *key);
static int vmSwapOneObject(void);
static int vmSwapOneObject(void);
static int vmCanSwapOut(void);
static void authCommand(redisClient *c);
static void authCommand(redisClient *c);
static void pingCommand(redisClient *c);
static void pingCommand(redisClient *c);
...
@@ -1177,12 +1179,18 @@ static int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientD
...
@@ -1177,12 +1179,18 @@ 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
/* Swap a few keys on disk if we are over the memory limit and VM
* is enbled. */
* is enbled. */
while
(
server
.
vm_enabled
&&
zmalloc_used_memory
()
>
server
.
vm_max_memory
)
{
if (vmCanSwapOut()) {
while (server.vm_enabled && zmalloc_used_memory() >
server.vm_max_memory) {
if (vmSwapOneObject() == REDIS_ERR) {
if (vmSwapOneObject() == REDIS_ERR) {
redisLog
(
REDIS_WARNING
,
"WARNING: vm-max-memory limit reached but unable to swap more objects out!"
);
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;
break;
}
}
}
}
}
/* Check if we should connect to a MASTER */
/* Check if we should connect to a MASTER */
if (server.replstate == REDIS_REPL_CONNECT) {
if (server.replstate == REDIS_REPL_CONNECT) {
...
@@ -2877,11 +2885,28 @@ static int rdbSave(char *filename) {
...
@@ -2877,11 +2885,28 @@ static int rdbSave(char *filename) {
if (rdbSaveType(fp,REDIS_EXPIRETIME) == -1) goto werr;
if (rdbSaveType(fp,REDIS_EXPIRETIME) == -1) goto werr;
if (rdbSaveTime(fp,expiretime) == -1) goto werr;
if (rdbSaveTime(fp,expiretime) == -1) goto werr;
}
}
/* Save the key and associated value */
/* 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 (rdbSaveType(fp,o->type) == -1) goto werr;
if (rdbSaveStringObject(fp,key) == -1) goto werr;
if (rdbSaveStringObject(fp,key) == -1) goto werr;
/* Save the actual value */
if (rdbSaveObject(fp,o) == -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);
dictReleaseIterator(di);
}
}
...
@@ -6833,8 +6858,11 @@ static int vmSwapObject(robj *key, robj *val) {
...
@@ -6833,8 +6858,11 @@ static int vmSwapObject(robj *key, robj *val) {
}
}
/* Load the value object relative to the 'key' object from swap to memory.
/* Load the value object relative to the 'key' object from swap to memory.
* The newly allocated object is returned. */
* The newly allocated object is returned.
static
robj
*
vmLoadObject
(
robj
*
key
)
{
*
* 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;
robj *val;
assert(key->storage == REDIS_VM_SWAPPED);
assert(key->storage == REDIS_VM_SWAPPED);
...
@@ -6849,14 +6877,29 @@ static robj *vmLoadObject(robj *key) {
...
@@ -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));
redisLog(REDIS_WARNING, "Unrecoverable VM problem in vmLoadObject(): can't load object from swap file: %s", strerror(errno));
exit(1);
exit(1);
}
}
if (!preview) {
key->storage = REDIS_VM_MEMORY;
key->storage = REDIS_VM_MEMORY;
key->vm.atime = server.unixtime;
key->vm.atime = server.unixtime;
vmMarkPagesFree(key->vm.page,key->vm.usedpages);
vmMarkPagesFree(key->vm.page,key->vm.usedpages);
redisLog(REDIS_DEBUG, "VM: object %s loaded from disk",
redisLog(REDIS_DEBUG, "VM: object %s loaded from disk",
(unsigned char*) key->ptr);
(unsigned char*) key->ptr);
}
return val;
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?
/* How a good candidate is this object for swapping?
* The better candidate it is, the greater the returned value.
* The better candidate it is, the greater the returned value.
*
*
...
@@ -6982,6 +7025,13 @@ static int vmSwapOneObject(void) {
...
@@ -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 ============================== */
/* ================================= Debugging ============================== */
static void debugCommand(redisClient *c) {
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