]> git.saurik.com Git - redis.git/commitdiff
Warns if /proc/sys/vm/overcommit_memory is set to 0 on Linux. Also make sure to don...
authorantirez <antirez@gmail.com>
Mon, 4 May 2009 14:26:06 +0000 (16:26 +0200)
committerantirez <antirez@gmail.com>
Mon, 4 May 2009 14:26:06 +0000 (16:26 +0200)
TODO
redis.c

diff --git a/TODO b/TODO
index 4c932d34f385a91967f56ae3d2ed22f9b4f4fbde..57ec0a5d1f8c758ad6e9784ba8db6bdcffe6de54 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,5 +1,7 @@
 BEFORE REDIS 1.0.0-rc1
 
+- Resize the expires hash tables if needed as well
+- Elapsed time in logs for SAVE when saving is going to take more than 2 seconds
 - TTL command that returns -1 if a key is not volatile otherwise the time to live of a volatile key.
 - Remove max number of args limit
 - What happens if the saving child gets killed or segfaults instead of ending normally? Handle this.
diff --git a/redis.c b/redis.c
index 75c7eac4390761703cd0af8874a98ca89e9a9c85..89812107edfc33529251b170065aedbc1aa2a6eb 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -652,6 +652,25 @@ void closeTimedoutClients(void) {
     }
 }
 
+/* If the percentage of used slots in the HT reaches REDIS_HT_MINFILL
+ * we resize the hash table to save memory */
+void tryResizeHashTables(void) {
+    int j;
+
+    for (j = 0; j < server.dbnum; j++) {
+        long long size, used;
+
+        size = dictSlots(server.db[j].dict);
+        used = dictSize(server.db[j].dict);
+        if (size && used && size > REDIS_HT_MINSLOTS &&
+            (used*100/size < REDIS_HT_MINFILL)) {
+            redisLog(REDIS_NOTICE,"The hash table %d is too sparse, resize it...",j);
+            dictResize(server.db[j].dict);
+            redisLog(REDIS_NOTICE,"Hash table %d resized.",j);
+        }
+    }
+}
+
 int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
     int j, loops = server.cronloops++;
     REDIS_NOTUSED(eventLoop);
@@ -661,8 +680,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
     /* Update the global state with the amount of used memory */
     server.usedmemory = zmalloc_used_memory();
 
-    /* If the percentage of used slots in the HT reaches REDIS_HT_MINFILL
-     * we resize the hash table to save memory */
+    /* Show some info about non-empty databases */
     for (j = 0; j < server.dbnum; j++) {
         long long size, used, vkeys;
 
@@ -673,14 +691,16 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
             redisLog(REDIS_DEBUG,"DB %d: %d keys (%d volatile) in %d slots HT.",j,used,vkeys,size);
             /* dictPrintStats(server.dict); */
         }
-        if (size && used && size > REDIS_HT_MINSLOTS &&
-            (used*100/size < REDIS_HT_MINFILL)) {
-            redisLog(REDIS_NOTICE,"The hash table %d is too sparse, resize it...",j);
-            dictResize(server.db[j].dict);
-            redisLog(REDIS_NOTICE,"Hash table %d resized.",j);
-        }
     }
 
+    /* We don't want to resize the hash tables while a bacground saving
+     * is in progress: the saving child is created using fork() that is
+     * implemented with a copy-on-write semantic in most modern systems, so
+     * if we resize the HT while there is the saving child at work actually
+     * a lot of memory movements in the parent will cause a lot of pages
+     * copied. */
+    if (!server.bgsaveinprogress) tryResizeHashTables();
+
     /* Show information about connected clients */
     if (!(loops % 5)) {
         redisLog(REDIS_DEBUG,"%d clients connected (%d slaves), %zu bytes in use",
@@ -3815,6 +3835,28 @@ static int syncWithMaster(void) {
 
 /* =================================== Main! ================================ */
 
+#ifdef __linux__
+int linuxOvercommitMemoryValue(void) {
+    FILE *fp = fopen("/proc/sys/vm/overcommit_memory","r");
+    char buf[64];
+
+    if (!fp) return -1;
+    if (fgets(buf,64,fp) == NULL) {
+        fclose(fp);
+        return -1;
+    }
+    fclose(fp);
+
+    return atoi(buf);
+}
+
+void linuxOvercommitMemoryWarning(void) {
+    if (linuxOvercommitMemoryValue() == 0) {
+        redisLog(REDIS_WARNING,"WARNING overcommit_memory is set to 0! Background save may fail under low condition memory. To fix this issue add 'echo 1 > /proc/sys/vm/overcommit_memory' in your init scripts.");
+    }
+}
+#endif /* __linux__ */
+
 static void daemonize(void) {
     int fd;
     FILE *fp;
@@ -3840,6 +3882,10 @@ static void daemonize(void) {
 }
 
 int main(int argc, char **argv) {
+#ifdef __linux__
+    linuxOvercommitMemoryWarning();
+#endif
+
     initServerConfig();
     if (argc == 2) {
         ResetServerSaveParams();