Unverified Commit 62419c01 authored by Binbin's avatar Binbin Committed by GitHub
Browse files

Handle missing fields in dbSwapDatabases and swapMainDbWithTempDb (#12763)

The change in dbSwapDatabases seems harmless. Because in non-clustered
mode, dbBuckets calculations are strictly accurate and in cluster mode,
we only have one DB. Modify it for uniformity (just like resize_cursor).

The change in swapMainDbWithTempDb is needed in case we swap with the
temp db, otherwise the overhead memory usage of db can be miscalculated.

In addition we will swap all fields (including rehashing list), just for
completeness (and reduce the chance of surprises in the future).

Introduced in #12697.
parent e6423b7a
...@@ -757,6 +757,7 @@ redisDb *initTempDb(void) { ...@@ -757,6 +757,7 @@ redisDb *initTempDb(void) {
tempDb[i].dict = dictCreateMultiple(&dbDictType, tempDb[i].dict_count); tempDb[i].dict = dictCreateMultiple(&dbDictType, tempDb[i].dict_count);
tempDb[i].expires = dictCreateMultiple(&dbExpiresDictType, tempDb[i].dict_count); tempDb[i].expires = dictCreateMultiple(&dbExpiresDictType, tempDb[i].dict_count);
for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) { for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) {
tempDb[i].sub_dict[subdict].rehashing = listCreate();
tempDb[i].sub_dict[subdict].slot_size_index = server.cluster_enabled ? zcalloc(sizeof(unsigned long long) * (CLUSTER_SLOTS + 1)) : NULL; tempDb[i].sub_dict[subdict].slot_size_index = server.cluster_enabled ? zcalloc(sizeof(unsigned long long) * (CLUSTER_SLOTS + 1)) : NULL;
} }
} }
...@@ -777,8 +778,9 @@ void discardTempDb(redisDb *tempDb, void(callback)(dict*)) { ...@@ -777,8 +778,9 @@ void discardTempDb(redisDb *tempDb, void(callback)(dict*)) {
} }
zfree(tempDb[i].dict); zfree(tempDb[i].dict);
zfree(tempDb[i].expires); zfree(tempDb[i].expires);
if (server.cluster_enabled) { for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) {
for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) { listRelease(tempDb[i].sub_dict[subdict].rehashing);
if (server.cluster_enabled) {
zfree(tempDb[i].sub_dict[subdict].slot_size_index); zfree(tempDb[i].sub_dict[subdict].slot_size_index);
} }
} }
...@@ -1888,7 +1890,9 @@ int dbSwapDatabases(int id1, int id2) { ...@@ -1888,7 +1890,9 @@ int dbSwapDatabases(int id1, int id2) {
db1->expires_cursor = db2->expires_cursor; db1->expires_cursor = db2->expires_cursor;
db1->dict_count = db2->dict_count; db1->dict_count = db2->dict_count;
for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) { for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) {
db1->sub_dict[subdict].rehashing = db2->sub_dict[subdict].rehashing;
db1->sub_dict[subdict].key_count = db2->sub_dict[subdict].key_count; db1->sub_dict[subdict].key_count = db2->sub_dict[subdict].key_count;
db1->sub_dict[subdict].bucket_count = db2->sub_dict[subdict].bucket_count;
db1->sub_dict[subdict].non_empty_slots = db2->sub_dict[subdict].non_empty_slots; db1->sub_dict[subdict].non_empty_slots = db2->sub_dict[subdict].non_empty_slots;
db1->sub_dict[subdict].resize_cursor = db2->sub_dict[subdict].resize_cursor; db1->sub_dict[subdict].resize_cursor = db2->sub_dict[subdict].resize_cursor;
db1->sub_dict[subdict].slot_size_index = db2->sub_dict[subdict].slot_size_index; db1->sub_dict[subdict].slot_size_index = db2->sub_dict[subdict].slot_size_index;
...@@ -1900,7 +1904,9 @@ int dbSwapDatabases(int id1, int id2) { ...@@ -1900,7 +1904,9 @@ int dbSwapDatabases(int id1, int id2) {
db2->expires_cursor = aux.expires_cursor; db2->expires_cursor = aux.expires_cursor;
db2->dict_count = aux.dict_count; db2->dict_count = aux.dict_count;
for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) { for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) {
db2->sub_dict[subdict].rehashing = aux.sub_dict[subdict].rehashing;
db2->sub_dict[subdict].key_count = aux.sub_dict[subdict].key_count; db2->sub_dict[subdict].key_count = aux.sub_dict[subdict].key_count;
db2->sub_dict[subdict].bucket_count = aux.sub_dict[subdict].bucket_count;
db2->sub_dict[subdict].non_empty_slots = aux.sub_dict[subdict].non_empty_slots; db2->sub_dict[subdict].non_empty_slots = aux.sub_dict[subdict].non_empty_slots;
db2->sub_dict[subdict].resize_cursor = aux.sub_dict[subdict].resize_cursor; db2->sub_dict[subdict].resize_cursor = aux.sub_dict[subdict].resize_cursor;
db2->sub_dict[subdict].slot_size_index = aux.sub_dict[subdict].slot_size_index; db2->sub_dict[subdict].slot_size_index = aux.sub_dict[subdict].slot_size_index;
...@@ -1944,7 +1950,9 @@ void swapMainDbWithTempDb(redisDb *tempDb) { ...@@ -1944,7 +1950,9 @@ void swapMainDbWithTempDb(redisDb *tempDb) {
activedb->expires_cursor = newdb->expires_cursor; activedb->expires_cursor = newdb->expires_cursor;
activedb->dict_count = newdb->dict_count; activedb->dict_count = newdb->dict_count;
for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) { for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) {
activedb->sub_dict[subdict].rehashing = newdb->sub_dict[subdict].rehashing;
activedb->sub_dict[subdict].key_count = newdb->sub_dict[subdict].key_count; activedb->sub_dict[subdict].key_count = newdb->sub_dict[subdict].key_count;
activedb->sub_dict[subdict].bucket_count = newdb->sub_dict[subdict].bucket_count;
activedb->sub_dict[subdict].non_empty_slots = newdb->sub_dict[subdict].non_empty_slots; activedb->sub_dict[subdict].non_empty_slots = newdb->sub_dict[subdict].non_empty_slots;
activedb->sub_dict[subdict].resize_cursor = newdb->sub_dict[subdict].resize_cursor; activedb->sub_dict[subdict].resize_cursor = newdb->sub_dict[subdict].resize_cursor;
activedb->sub_dict[subdict].slot_size_index = newdb->sub_dict[subdict].slot_size_index; activedb->sub_dict[subdict].slot_size_index = newdb->sub_dict[subdict].slot_size_index;
...@@ -1956,7 +1964,9 @@ void swapMainDbWithTempDb(redisDb *tempDb) { ...@@ -1956,7 +1964,9 @@ void swapMainDbWithTempDb(redisDb *tempDb) {
newdb->expires_cursor = aux.expires_cursor; newdb->expires_cursor = aux.expires_cursor;
newdb->dict_count = aux.dict_count; newdb->dict_count = aux.dict_count;
for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) { for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) {
newdb->sub_dict[subdict].rehashing = aux.sub_dict[subdict].rehashing;
newdb->sub_dict[subdict].key_count = aux.sub_dict[subdict].key_count; newdb->sub_dict[subdict].key_count = aux.sub_dict[subdict].key_count;
newdb->sub_dict[subdict].bucket_count = aux.sub_dict[subdict].bucket_count;
newdb->sub_dict[subdict].non_empty_slots = aux.sub_dict[subdict].non_empty_slots; newdb->sub_dict[subdict].non_empty_slots = aux.sub_dict[subdict].non_empty_slots;
newdb->sub_dict[subdict].resize_cursor = aux.sub_dict[subdict].resize_cursor; newdb->sub_dict[subdict].resize_cursor = aux.sub_dict[subdict].resize_cursor;
newdb->sub_dict[subdict].slot_size_index = aux.sub_dict[subdict].slot_size_index; newdb->sub_dict[subdict].slot_size_index = aux.sub_dict[subdict].slot_size_index;
......
...@@ -2651,6 +2651,7 @@ void makeThreadKillable(void) { ...@@ -2651,6 +2651,7 @@ void makeThreadKillable(void) {
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
} }
/* When adding fields, please check the initTempDb related logic. */
void initDbState(redisDb *db){ void initDbState(redisDb *db){
for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) { for (dbKeyType subdict = DB_MAIN; subdict <= DB_EXPIRES; subdict++) {
db->sub_dict[subdict].rehashing = listCreate(); db->sub_dict[subdict].rehashing = listCreate();
......
...@@ -969,6 +969,7 @@ typedef struct replBufBlock { ...@@ -969,6 +969,7 @@ typedef struct replBufBlock {
char buf[]; char buf[];
} replBufBlock; } replBufBlock;
/* When adding fields, please check the swap db related logic. */
typedef struct dbDictState { typedef struct dbDictState {
list *rehashing; /* List of dictionaries in this DB that are currently rehashing. */ list *rehashing; /* List of dictionaries in this DB that are currently rehashing. */
int resize_cursor; /* Cron job uses this cursor to gradually resize dictionaries (only used for cluster-enabled). */ int resize_cursor; /* Cron job uses this cursor to gradually resize dictionaries (only used for cluster-enabled). */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment