Lookup a key for read operations, or return NULL if the key is not found * in the specified DB. * * As a side effect of calling this function: * 1. A key gets expired if it reached it's TTL. * 2. The key last access time is updated. * 3. The global keys hits/misses stats are updated (reported in INFO). * 4. If keyspace notifications are enabled, a "keymiss" notification is fired. * * This
| 158 | * correctly report a key is expired on slaves even if the master is lagging |
| 159 | * expiring our key via DELs in the replication link. */ |
| 160 | robj_roptr lookupKeyReadWithFlags(redisDb *db, robj *key, int flags) { |
| 161 | robj_roptr val; |
| 162 | |
| 163 | if (expireIfNeeded(db,key) == 1) { |
| 164 | /* If we are in the context of a master, expireIfNeeded() returns 1 |
| 165 | * when the key is no longer valid, so we can return NULL ASAP. */ |
| 166 | if (listLength(g_pserver->masters) == 0) |
| 167 | goto keymiss; |
| 168 | |
| 169 | /* However if we are in the context of a replica, expireIfNeeded() will |
| 170 | * not really try to expire the key, it only returns information |
| 171 | * about the "logical" status of the key: key expiring is up to the |
| 172 | * master in order to have a consistent view of master's data set. |
| 173 | * |
| 174 | * However, if the command caller is not the master, and as additional |
| 175 | * safety measure, the command invoked is a read-only command, we can |
| 176 | * safely return NULL here, and provide a more consistent behavior |
| 177 | * to clients accessing expired values in a read-only fashion, that |
| 178 | * will say the key as non existing. |
| 179 | * |
| 180 | * Notably this covers GETs when slaves are used to scale reads. */ |
| 181 | if (serverTL->current_client && |
| 182 | !FActiveMaster(serverTL->current_client) && |
| 183 | serverTL->current_client->cmd && |
| 184 | serverTL->current_client->cmd->flags & CMD_READONLY) |
| 185 | { |
| 186 | goto keymiss; |
| 187 | } |
| 188 | } |
| 189 | val = lookupKeyConst(db,key,flags); |
| 190 | if (val == nullptr) |
| 191 | goto keymiss; |
| 192 | g_pserver->stat_keyspace_hits++; |
| 193 | return val; |
| 194 | |
| 195 | keymiss: |
| 196 | if (!(flags & LOOKUP_NONOTIFY)) { |
| 197 | notifyKeyspaceEvent(NOTIFY_KEY_MISS, "keymiss", key, db->id); |
| 198 | } |
| 199 | g_pserver->stat_keyspace_misses++; |
| 200 | return NULL; |
| 201 | } |
| 202 | |
| 203 | /* Like lookupKeyReadWithFlags(), but does not use any flag, which is the |
| 204 | * common case. */ |
no test coverage detected