Avoid locking as late as possible

Former-commit-id: acc894fe41d4e8869f28928cb0feffa1792c11c4
This commit is contained in:
John Sully 2020-01-11 19:28:13 -05:00
parent ac55fe6dac
commit 4360d1ab3d
2 changed files with 57 additions and 48 deletions

View File

@ -11,9 +11,11 @@ public:
void arm(client *c) // if a client is passed, then the client is already locked void arm(client *c) // if a client is passed, then the client is already locked
{ {
if (m_fArmed)
return;
if (c != nullptr) if (c != nullptr)
{ {
serverAssert(!m_fArmed);
serverAssert(c->lock.fOwnLock()); serverAssert(c->lock.fOwnLock());
if (!aeTryAcquireLock(true /*fWeak*/)) // avoid locking the client if we can if (!aeTryAcquireLock(true /*fWeak*/)) // avoid locking the client if we can

View File

@ -3586,9 +3586,6 @@ int processCommand(client *c, int callFlags) {
incrementMvccTstamp(); incrementMvccTstamp();
if (!locker.isArmed())
locker.arm(c);
/* Handle the maxmemory directive. /* Handle the maxmemory directive.
* *
* Note that we do not want to reclaim memory if we are here re-entering * Note that we do not want to reclaim memory if we are here re-entering
@ -3596,6 +3593,7 @@ int processCommand(client *c, int callFlags) {
* condition, to avoid mixing the propagation of scripts with the * condition, to avoid mixing the propagation of scripts with the
* propagation of DELs due to eviction. */ * propagation of DELs due to eviction. */
if (g_pserver->maxmemory && !g_pserver->lua_timedout) { if (g_pserver->maxmemory && !g_pserver->lua_timedout) {
locker.arm(c);
int out_of_memory = freeMemoryIfNeededAndSafe() == C_ERR; int out_of_memory = freeMemoryIfNeededAndSafe() == C_ERR;
/* freeMemoryIfNeeded may flush replica output buffers. This may result /* freeMemoryIfNeeded may flush replica output buffers. This may result
* into a replica, that may be the active client, to be freed. */ * into a replica, that may be the active client, to be freed. */
@ -3615,44 +3613,48 @@ int processCommand(client *c, int callFlags) {
/* Don't accept write commands if there are problems persisting on disk /* Don't accept write commands if there are problems persisting on disk
* and if this is a master instance. */ * and if this is a master instance. */
int deny_write_type = writeCommandsDeniedByDiskError(); if (c->cmd->flags & CMD_WRITE || c->cmd->proc == pingCommand)
if (deny_write_type != DISK_ERROR_TYPE_NONE &&
listLength(g_pserver->masters) == 0 &&
(c->cmd->flags & CMD_WRITE ||
c->cmd->proc == pingCommand))
{ {
flagTransaction(c); locker.arm(c);
if (deny_write_type == DISK_ERROR_TYPE_RDB) int deny_write_type = writeCommandsDeniedByDiskError();
addReply(c, shared.bgsaveerr); if (deny_write_type != DISK_ERROR_TYPE_NONE &&
else listLength(g_pserver->masters) == 0 &&
addReplySds(c, (c->cmd->flags & CMD_WRITE ||
sdscatprintf(sdsempty(), c->cmd->proc == pingCommand))
"-MISCONF Errors writing to the AOF file: %s\r\n", {
strerror(g_pserver->aof_last_write_errno))); flagTransaction(c);
return C_OK; if (deny_write_type == DISK_ERROR_TYPE_RDB)
} addReply(c, shared.bgsaveerr);
else
addReplySds(c,
sdscatprintf(sdsempty(),
"-MISCONF Errors writing to the AOF file: %s\r\n",
strerror(g_pserver->aof_last_write_errno)));
return C_OK;
}
/* Don't accept write commands if there are not enough good slaves and /* Don't accept write commands if there are not enough good slaves and
* user configured the min-slaves-to-write option. */ * user configured the min-slaves-to-write option. */
if (listLength(g_pserver->masters) == 0 && if (listLength(g_pserver->masters) == 0 &&
g_pserver->repl_min_slaves_to_write && g_pserver->repl_min_slaves_to_write &&
g_pserver->repl_min_slaves_max_lag && g_pserver->repl_min_slaves_max_lag &&
c->cmd->flags & CMD_WRITE && c->cmd->flags & CMD_WRITE &&
g_pserver->repl_good_slaves_count < g_pserver->repl_min_slaves_to_write) g_pserver->repl_good_slaves_count < g_pserver->repl_min_slaves_to_write)
{ {
flagTransaction(c); flagTransaction(c);
addReply(c, shared.noreplicaserr); addReply(c, shared.noreplicaserr);
return C_OK; return C_OK;
} }
/* Don't accept write commands if this is a read only replica. But /* Don't accept write commands if this is a read only replica. But
* accept write commands if this is our master. */ * accept write commands if this is our master. */
if (listLength(g_pserver->masters) && g_pserver->repl_slave_ro && if (listLength(g_pserver->masters) && g_pserver->repl_slave_ro &&
!(c->flags & CLIENT_MASTER) && !(c->flags & CLIENT_MASTER) &&
c->cmd->flags & CMD_WRITE) c->cmd->flags & CMD_WRITE)
{ {
addReply(c, shared.roslaveerr); addReply(c, shared.roslaveerr);
return C_OK; return C_OK;
}
} }
/* Only allow a subset of commands in the context of Pub/Sub if the /* Only allow a subset of commands in the context of Pub/Sub if the
@ -3667,16 +3669,20 @@ int processCommand(client *c, int callFlags) {
return C_OK; return C_OK;
} }
/* Only allow commands with flag "t", such as INFO, SLAVEOF and so on, if (listLength(g_pserver->masters))
* when replica-serve-stale-data is no and we are a replica with a broken
* link with master. */
if (FBrokenLinkToMaster() &&
g_pserver->repl_serve_stale_data == 0 &&
!(c->cmd->flags & CMD_STALE))
{ {
flagTransaction(c); locker.arm(c);
addReply(c, shared.masterdownerr); /* Only allow commands with flag "t", such as INFO, SLAVEOF and so on,
return C_OK; * when replica-serve-stale-data is no and we are a replica with a broken
* link with master. */
if (FBrokenLinkToMaster() &&
g_pserver->repl_serve_stale_data == 0 &&
!(c->cmd->flags & CMD_STALE))
{
flagTransaction(c);
addReply(c, shared.masterdownerr);
return C_OK;
}
} }
/* Loading DB? Return an error if the command has not the /* Loading DB? Return an error if the command has not the
@ -3711,6 +3717,7 @@ int processCommand(client *c, int callFlags) {
queueMultiCommand(c); queueMultiCommand(c);
addReply(c,shared.queued); addReply(c,shared.queued);
} else { } else {
locker.arm(c);
call(c,callFlags); call(c,callFlags);
c->woff = g_pserver->master_repl_offset; c->woff = g_pserver->master_repl_offset;
if (listLength(g_pserver->ready_keys)) if (listLength(g_pserver->ready_keys))