Fix a bug where swapdb result was not recovered after keydb restarts in FLASH mode. (#668)

Co-authored-by: k00809413 <karthick.ariyaratnam1@huawei.com>
This commit is contained in:
Karthick Ariyaratnam 2023-06-21 16:26:14 -04:00 committed by GitHub
parent 45b41fbde6
commit 46660b9f18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 9 deletions

View File

@ -1769,7 +1769,7 @@ int dbSwapDatabases(int id1, int id2) {
/* SWAPDB db1 db2 */
void swapdbCommand(client *c) {
int id1, id2, oriId;
int id1, id2, oriIdx;
/* Not allowed in cluster mode: we have just DB 0 there. */
if (g_pserver->cluster_enabled) {
@ -1786,8 +1786,13 @@ void swapdbCommand(client *c) {
"invalid second DB index") != C_OK)
return;
//get client's original db's id
oriId=c->db->id;
// get client's original db's index
for (int idb=0; idb < cserver.dbnum; ++idb) {
if (g_pserver->db[idb]->id == c->db->id) {
oriIdx = idb;
break;
}
}
/* Swap... */
if (dbSwapDatabases(id1,id2) == C_ERR) {
@ -1798,9 +1803,17 @@ void swapdbCommand(client *c) {
moduleFireServerEvent(REDISMODULE_EVENT_SWAPDB,0,&si);
g_pserver->dirty++;
//set client's db to original db
c->db=g_pserver->db[oriId];
// set client's db to original db
c->db=g_pserver->db[oriIdx];
// Persist the databse index to dbid mapping into FLASH for later recovery.
if (g_pserver->m_pstorageFactory != nullptr && g_pserver->metadataDb != nullptr) {
std::string dbid_key = "db-" + std::to_string(id1);
g_pserver->metadataDb->insert(dbid_key.c_str(), dbid_key.length(), &g_pserver->db[id1]->id, sizeof(g_pserver->db[id1]->id), true);
dbid_key = "db-" + std::to_string(id2);
g_pserver->metadataDb->insert(dbid_key.c_str(), dbid_key.length(), &g_pserver->db[id2]->id, sizeof(g_pserver->db[id2]->id), true);
}
addReply(c,shared.ok);
}
}

View File

@ -3881,9 +3881,25 @@ void initServer(void) {
g_pserver->db = (redisDb**)zmalloc(sizeof(redisDb*)*cserver.dbnum, MALLOC_LOCAL);
/* Create the Redis databases, and initialize other internal state. */
for (int j = 0; j < cserver.dbnum; j++) {
g_pserver->db[j] = new (MALLOC_LOCAL) redisDb();
g_pserver->db[j]->initialize(j);
if (g_pserver->m_pstorageFactory == nullptr) {
for (int j = 0; j < cserver.dbnum; j++) {
g_pserver->db[j] = new (MALLOC_LOCAL) redisDb();
g_pserver->db[j]->initialize(j);
}
} else {
// Read FLASH metadata and load the appropriate dbid into each databse index, as each DB index can have different dbid mapped due to the swapdb command.
g_pserver->metadataDb = g_pserver->m_pstorageFactory->createMetadataDb();
for (int idb = 0; idb < cserver.dbnum; ++idb)
{
int dbid = idb;
std::string dbid_key = "db-" + std::to_string(idb);
g_pserver->metadataDb->retrieve(dbid_key.c_str(), dbid_key.length(), [&](const char *, size_t, const void *data, size_t){
dbid = *(int*)data;
});
g_pserver->db[idb] = new (MALLOC_LOCAL) redisDb();
g_pserver->db[idb]->initialize(dbid);
}
}
for (int i = 0; i < MAX_EVENT_LOOPS; ++i)
@ -4033,7 +4049,6 @@ void initServer(void) {
latencyMonitorInit();
if (g_pserver->m_pstorageFactory) {
g_pserver->metadataDb = g_pserver->m_pstorageFactory->createMetadataDb();
if (g_pserver->metadataDb) {
g_pserver->metadataDb->retrieve("repl-id", 7, [&](const char *, size_t, const void *data, size_t cb){
if (cb == sizeof(g_pserver->replid)) {