Fix crash in expire when a snapshot is in flight. Caused by a perf optimization getting the expire map out of sync with the val
This commit is contained in:
parent
5dbf1f6bd6
commit
ea4941a3e7
@ -2669,6 +2669,11 @@ void redisDbPersistentData::prepOverwriteForSnapshot(char *key)
|
|||||||
auto itr = m_pdbSnapshot->find_cached_threadsafe(key);
|
auto itr = m_pdbSnapshot->find_cached_threadsafe(key);
|
||||||
if (itr.key() != nullptr)
|
if (itr.key() != nullptr)
|
||||||
{
|
{
|
||||||
|
if (itr.val()->FExpires()) {
|
||||||
|
// Note: I'm sure we could handle this, but its too risky at the moment.
|
||||||
|
// There are known bugs doing this with expires
|
||||||
|
return;
|
||||||
|
}
|
||||||
sds keyNew = sdsdupshared(itr.key());
|
sds keyNew = sdsdupshared(itr.key());
|
||||||
if (dictAdd(m_pdictTombstone, keyNew, (void*)dictHashKey(m_pdict, key)) != DICT_OK)
|
if (dictAdd(m_pdictTombstone, keyNew, (void*)dictHashKey(m_pdict, key)) != DICT_OK)
|
||||||
sdsfree(keyNew);
|
sdsfree(keyNew);
|
||||||
|
@ -2743,9 +2743,10 @@ void readQueryFromClient(connection *conn) {
|
|||||||
parseClientCommandBuffer(c);
|
parseClientCommandBuffer(c);
|
||||||
if (g_pserver->enable_async_commands && !serverTL->disable_async_commands && listLength(g_pserver->monitors) == 0 && (aeLockContention() || serverTL->rgdbSnapshot[c->db->id] || g_fTestMode)) {
|
if (g_pserver->enable_async_commands && !serverTL->disable_async_commands && listLength(g_pserver->monitors) == 0 && (aeLockContention() || serverTL->rgdbSnapshot[c->db->id] || g_fTestMode)) {
|
||||||
// Frequent writers aren't good candidates for this optimization, they cause us to renew the snapshot too often
|
// Frequent writers aren't good candidates for this optimization, they cause us to renew the snapshot too often
|
||||||
// so we exclude them unless the snapshot we need already exists
|
// so we exclude them unless the snapshot we need already exists.
|
||||||
|
// Note: In test mode we want to create snapshots as often as possibl to excercise them - we don't care about perf
|
||||||
bool fSnapshotExists = c->db->mvccLastSnapshot >= c->mvccCheckpoint;
|
bool fSnapshotExists = c->db->mvccLastSnapshot >= c->mvccCheckpoint;
|
||||||
bool fWriteTooRecent = (((getMvccTstamp() - c->mvccCheckpoint) >> MVCC_MS_SHIFT) < static_cast<uint64_t>(g_pserver->snapshot_slip)/2);
|
bool fWriteTooRecent = !g_fTestMode && (((getMvccTstamp() - c->mvccCheckpoint) >> MVCC_MS_SHIFT) < static_cast<uint64_t>(g_pserver->snapshot_slip)/2);
|
||||||
|
|
||||||
// The check below avoids running async commands if this is a frequent writer unless a snapshot is already there to service it
|
// The check below avoids running async commands if this is a frequent writer unless a snapshot is already there to service it
|
||||||
if (!fWriteTooRecent || fSnapshotExists) {
|
if (!fWriteTooRecent || fSnapshotExists) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user