Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
d7971f96
Commit
d7971f96
authored
Apr 05, 2022
by
Oran Agra
Browse files
Merge remote-tracking branch 'origin/unstable' into 7.0
parents
d2b5a579
acfb4f7a
Changes
169
Expand all
Hide whitespace changes
Inline
Side-by-side
src/commands/sentinel-info-cache.json
View file @
d7971f96
...
...
@@ -4,13 +4,20 @@
"complexity"
:
"O(N) where N is the number of instances"
,
"group"
:
"sentinel"
,
"since"
:
"3.2.0"
,
"arity"
:
3
,
"arity"
:
-
3
,
"container"
:
"SENTINEL"
,
"function"
:
"sentinelCommand"
,
"command_flags"
:
[
"ADMIN"
,
"SENTINEL"
,
"ONLY_SENTINEL"
],
"arguments"
:
[
{
"name"
:
"nodename"
,
"type"
:
"string"
,
"multiple"
:
true
}
]
}
}
src/commands/sentinel-is-master-down-by-addr.json
View file @
d7971f96
...
...
@@ -11,6 +11,24 @@
"ADMIN"
,
"SENTINEL"
,
"ONLY_SENTINEL"
],
"arguments"
:
[
{
"name"
:
"ip"
,
"type"
:
"string"
},
{
"name"
:
"port"
,
"type"
:
"integer"
},
{
"name"
:
"current-epoch"
,
"type"
:
"integer"
},
{
"name"
:
"runid"
,
"type"
:
"string"
}
]
}
}
src/commands/sentinel-master.json
View file @
d7971f96
...
...
@@ -11,6 +11,12 @@
"ADMIN"
,
"SENTINEL"
,
"ONLY_SENTINEL"
],
"arguments"
:
[
{
"name"
:
"master-name"
,
"type"
:
"string"
}
]
}
}
src/commands/sentinel-monitor.json
View file @
d7971f96
...
...
@@ -11,6 +11,24 @@
"ADMIN"
,
"SENTINEL"
,
"ONLY_SENTINEL"
],
"arguments"
:
[
{
"name"
:
"name"
,
"type"
:
"string"
},
{
"name"
:
"ip"
,
"type"
:
"string"
},
{
"name"
:
"port"
,
"type"
:
"integer"
},
{
"name"
:
"quorum"
,
"type"
:
"integer"
}
]
}
}
src/commands/sentinel-remove.json
View file @
d7971f96
...
...
@@ -11,6 +11,12 @@
"ADMIN"
,
"SENTINEL"
,
"ONLY_SENTINEL"
],
"arguments"
:
[
{
"name"
:
"master-name"
,
"type"
:
"string"
}
]
}
}
src/commands/sentinel-replicas.json
View file @
d7971f96
...
...
@@ -11,6 +11,12 @@
"ADMIN"
,
"SENTINEL"
,
"ONLY_SENTINEL"
],
"arguments"
:
[
{
"name"
:
"master-name"
,
"type"
:
"string"
}
]
}
}
src/commands/sentinel-reset.json
View file @
d7971f96
...
...
@@ -11,6 +11,12 @@
"ADMIN"
,
"SENTINEL"
,
"ONLY_SENTINEL"
],
"arguments"
:
[
{
"name"
:
"pattern"
,
"type"
:
"pattern"
}
]
}
}
src/commands/sentinel-sentinels.json
View file @
d7971f96
...
...
@@ -11,6 +11,12 @@
"ADMIN"
,
"SENTINEL"
,
"ONLY_SENTINEL"
],
"arguments"
:
[
{
"name"
:
"master-name"
,
"type"
:
"string"
}
]
}
}
src/commands/sentinel-set.json
View file @
d7971f96
...
...
@@ -11,6 +11,27 @@
"ADMIN"
,
"SENTINEL"
,
"ONLY_SENTINEL"
],
"arguments"
:
[
{
"name"
:
"master-name"
,
"type"
:
"string"
},
{
"name"
:
"option_value"
,
"type"
:
"block"
,
"multiple"
:
true
,
"arguments"
:
[
{
"name"
:
"option"
,
"type"
:
"string"
},
{
"name"
:
"value"
,
"type"
:
"string"
}
]
}
]
}
}
src/commands/sentinel-simulate-failure.json
View file @
d7971f96
...
...
@@ -10,6 +10,28 @@
"ADMIN"
,
"SENTINEL"
,
"ONLY_SENTINEL"
],
"arguments"
:
[
{
"name"
:
"mode"
,
"type"
:
"oneof"
,
"optional"
:
true
,
"multiple"
:
true
,
"arguments"
:
[
{
"name"
:
"crash-after-election"
,
"type"
:
"pure-token"
},
{
"name"
:
"crash-after-promotion"
,
"type"
:
"pure-token"
},
{
"name"
:
"help"
,
"type"
:
"pure-token"
}
]
}
]
}
}
src/commands/shutdown.json
View file @
d7971f96
...
...
@@ -9,7 +9,7 @@
"history"
:
[
[
"7.0.0"
,
"Added the `NOW`, `FORCE` and `ABORT` modifiers.
Introduced waiting for lagging replicas before exiting.
"
"Added the `NOW`, `FORCE` and `ABORT` modifiers."
]
],
"command_flags"
:
[
...
...
src/commands/slaveof.json
View file @
d7971f96
...
...
@@ -24,7 +24,7 @@
},
{
"name"
:
"port"
,
"type"
:
"
string
"
"type"
:
"
integer
"
}
]
}
...
...
src/commands/sort.json
View file @
d7971f96
...
...
@@ -96,7 +96,7 @@
"token"
:
"GET"
,
"name"
:
"pattern"
,
"key_spec_index"
:
1
,
"type"
:
"
string
"
,
"type"
:
"
pattern
"
,
"optional"
:
true
,
"multiple"
:
true
,
"multiple_token"
:
true
...
...
src/commands/sort_ro.json
View file @
d7971f96
...
...
@@ -82,7 +82,7 @@
"token"
:
"GET"
,
"name"
:
"pattern"
,
"key_spec_index"
:
1
,
"type"
:
"
string
"
,
"type"
:
"
pattern
"
,
"optional"
:
true
,
"multiple"
:
true
,
"multiple_token"
:
true
...
...
src/commands/spublish.json
View file @
d7971f96
{
"SPUBLISH"
:
{
"summary"
:
"Post a message to a shard channel"
,
"complexity"
:
"O(N) where N is the number of clients subscribed to the receiving shard channel."
,
"group"
:
"pubsub"
,
"since"
:
"7.0.0"
,
"arity"
:
3
,
"function"
:
"spublishCommand"
,
"command_flags"
:
[
"PUBSUB"
,
"LOADING"
,
"STALE"
,
"FAST"
,
"MAY_REPLICATE"
],
"arguments"
:
[
{
"name"
:
"channel"
,
"type"
:
"string"
},
{
"name"
:
"message"
,
"type"
:
"string"
}
],
"key_specs"
:
[
{
"flags"
:
[
"NOT_KEY"
"SPUBLISH"
:
{
"summary"
:
"Post a message to a shard channel"
,
"complexity"
:
"O(N) where N is the number of clients subscribed to the receiving shard channel."
,
"group"
:
"pubsub"
,
"since"
:
"7.0.0"
,
"arity"
:
3
,
"function"
:
"spublishCommand"
,
"command_flags"
:
[
"PUBSUB"
,
"LOADING"
,
"STALE"
,
"FAST"
,
"MAY_REPLICATE"
],
"begin_search"
:
{
"index"
:
{
"pos"
:
1
}
},
"find_keys"
:
{
"range"
:
{
"lastkey"
:
0
,
"step"
:
1
,
"limit"
:
0
}
}
}
]
}
"arguments"
:
[
{
"name"
:
"channel"
,
"type"
:
"string"
},
{
"name"
:
"message"
,
"type"
:
"string"
}
],
"key_specs"
:
[
{
"flags"
:
[
"NOT_KEY"
],
"begin_search"
:
{
"index"
:
{
"pos"
:
1
}
},
"find_keys"
:
{
"range"
:
{
"lastkey"
:
0
,
"step"
:
1
,
"limit"
:
0
}
}
}
]
}
}
src/commands/ssubscribe.json
View file @
d7971f96
{
"SSUBSCRIBE"
:
{
"summary"
:
"Listen for messages published to the given shard channels"
,
"complexity"
:
"O(N) where N is the number of shard channels to subscribe to."
,
"group"
:
"pubsub"
,
"since"
:
"7.0.0"
,
"arity"
:
-2
,
"function"
:
"ssubscribeCommand"
,
"command_flags"
:
[
"PUBSUB"
,
"NOSCRIPT"
,
"LOADING"
,
"STALE"
],
"arguments"
:
[
{
"name"
:
"channel"
,
"type"
:
"string"
,
"multiple"
:
true
}
],
"key_specs"
:
[
{
"flags"
:
[
"NOT_KEY"
"SSUBSCRIBE"
:
{
"summary"
:
"Listen for messages published to the given shard channels"
,
"complexity"
:
"O(N) where N is the number of shard channels to subscribe to."
,
"group"
:
"pubsub"
,
"since"
:
"7.0.0"
,
"arity"
:
-2
,
"function"
:
"ssubscribeCommand"
,
"command_flags"
:
[
"PUBSUB"
,
"NOSCRIPT"
,
"LOADING"
,
"STALE"
],
"begin_search"
:
{
"index"
:
{
"pos"
:
1
}
},
"find_keys"
:
{
"range"
:
{
"lastkey"
:
-1
,
"step"
:
1
,
"limit"
:
0
}
}
}
]
}
"arguments"
:
[
{
"name"
:
"channel"
,
"type"
:
"string"
,
"multiple"
:
true
}
],
"key_specs"
:
[
{
"flags"
:
[
"NOT_KEY"
],
"begin_search"
:
{
"index"
:
{
"pos"
:
1
}
},
"find_keys"
:
{
"range"
:
{
"lastkey"
:
-1
,
"step"
:
1
,
"limit"
:
0
}
}
}
]
}
}
src/commands/subscribe.json
View file @
d7971f96
...
...
@@ -6,12 +6,7 @@
"since"
:
"2.0.0"
,
"arity"
:
-2
,
"function"
:
"subscribeCommand"
,
"history"
:
[
[
"6.2.0"
,
"`RESET` can be called to exit subscribed state."
]
],
"history"
:
[],
"command_flags"
:
[
"PUBSUB"
,
"NOSCRIPT"
,
...
...
src/commands/sunsubscribe.json
View file @
d7971f96
{
"SUNSUBSCRIBE"
:
{
"summary"
:
"Stop listening for messages posted to the given shard channels"
,
"complexity"
:
"O(N) where N is the number of clients already subscribed to a channel."
,
"group"
:
"pubsub"
,
"since"
:
"7.0.0"
,
"arity"
:
-1
,
"function"
:
"sunsubscribeCommand"
,
"command_flags"
:
[
"PUBSUB"
,
"NOSCRIPT"
,
"LOADING"
,
"STALE"
],
"arguments"
:
[
{
"name"
:
"channel"
,
"type"
:
"string"
,
"optional"
:
true
,
"multiple"
:
true
}
],
"key_specs"
:
[
{
"flags"
:
[
"NOT_KEY"
"SUNSUBSCRIBE"
:
{
"summary"
:
"Stop listening for messages posted to the given shard channels"
,
"complexity"
:
"O(N) where N is the number of clients already subscribed to a channel."
,
"group"
:
"pubsub"
,
"since"
:
"7.0.0"
,
"arity"
:
-1
,
"function"
:
"sunsubscribeCommand"
,
"command_flags"
:
[
"PUBSUB"
,
"NOSCRIPT"
,
"LOADING"
,
"STALE"
],
"begin_search"
:
{
"index"
:
{
"pos"
:
1
}
},
"find_keys"
:
{
"range"
:
{
"lastkey"
:
-1
,
"step"
:
1
,
"limit"
:
0
}
}
}
]
}
"arguments"
:
[
{
"name"
:
"channel"
,
"type"
:
"string"
,
"optional"
:
true
,
"multiple"
:
true
}
],
"key_specs"
:
[
{
"flags"
:
[
"NOT_KEY"
],
"begin_search"
:
{
"index"
:
{
"pos"
:
1
}
},
"find_keys"
:
{
"range"
:
{
"lastkey"
:
-1
,
"step"
:
1
,
"limit"
:
0
}
}
}
]
}
}
src/config.c
View file @
d7971f96
This diff is collapsed.
Click to expand it.
src/db.c
View file @
d7971f96
...
...
@@ -218,9 +218,12 @@ void dbOverwrite(redisDb *db, robj *key, robj *val) {
val
->
lru
=
old
->
lru
;
}
/* Although the key is not really deleted from the database, we regard
overwrite as two steps of unlink+add, so we still need to call the unlink
callback of the module. */
*
overwrite as two steps of unlink+add, so we still need to call the unlink
*
callback of the module. */
moduleNotifyKeyUnlink
(
key
,
old
,
db
->
id
);
/* We want to try to unblock any client using a blocking XREADGROUP */
if
(
old
->
type
==
OBJ_STREAM
)
signalKeyAsReady
(
db
,
key
,
old
->
type
);
dictSetVal
(
db
->
dict
,
de
,
val
);
if
(
server
.
lazyfree_lazy_server_del
)
{
...
...
@@ -311,6 +314,9 @@ static int dbGenericDelete(redisDb *db, robj *key, int async) {
robj
*
val
=
dictGetVal
(
de
);
/* Tells the module that the key has been unlinked from the database. */
moduleNotifyKeyUnlink
(
key
,
val
,
db
->
id
);
/* We want to try to unblock any client using a blocking XREADGROUP */
if
(
val
->
type
==
OBJ_STREAM
)
signalKeyAsReady
(
db
,
key
,
val
->
type
);
if
(
async
)
{
freeObjAsync
(
key
,
val
,
db
->
id
);
dictSetVal
(
db
->
dict
,
de
,
NULL
);
...
...
@@ -551,6 +557,7 @@ void signalFlushedDb(int dbid, int async) {
}
for
(
int
j
=
startdb
;
j
<=
enddb
;
j
++
)
{
scanDatabaseForDeletedStreams
(
&
server
.
db
[
j
],
NULL
);
touchAllWatchedKeysInDb
(
&
server
.
db
[
j
],
NULL
);
}
...
...
@@ -1311,7 +1318,7 @@ void copyCommand(client *c) {
* one or more blocked clients for B[LR]POP or other blocking commands
* and signal the keys as ready if they are of the right type. See the comment
* where the function is used for more info. */
void
scanDatabaseForReady
List
s
(
redisDb
*
db
)
{
void
scanDatabaseForReady
Key
s
(
redisDb
*
db
)
{
dictEntry
*
de
;
dictIterator
*
di
=
dictGetSafeIterator
(
db
->
blocking_keys
);
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
...
...
@@ -1325,6 +1332,39 @@ void scanDatabaseForReadyLists(redisDb *db) {
dictReleaseIterator
(
di
);
}
/* Since we are unblocking XREADGROUP clients in the event the
* key was deleted/overwritten we must do the same in case the
* database was flushed/swapped. */
void
scanDatabaseForDeletedStreams
(
redisDb
*
emptied
,
redisDb
*
replaced_with
)
{
/* Optimization: If no clients are in type BLOCKED_STREAM,
* we can skip this loop. */
if
(
!
server
.
blocked_clients_by_type
[
BLOCKED_STREAM
])
return
;
dictEntry
*
de
;
dictIterator
*
di
=
dictGetSafeIterator
(
emptied
->
blocking_keys
);
while
((
de
=
dictNext
(
di
))
!=
NULL
)
{
robj
*
key
=
dictGetKey
(
de
);
int
was_stream
=
0
,
is_stream
=
0
;
dictEntry
*
kde
=
dictFind
(
emptied
->
dict
,
key
->
ptr
);
if
(
kde
)
{
robj
*
value
=
dictGetVal
(
kde
);
was_stream
=
value
->
type
==
OBJ_STREAM
;
}
if
(
replaced_with
)
{
dictEntry
*
kde
=
dictFind
(
replaced_with
->
dict
,
key
->
ptr
);
if
(
kde
)
{
robj
*
value
=
dictGetVal
(
kde
);
is_stream
=
value
->
type
==
OBJ_STREAM
;
}
}
/* We want to try to unblock any client using a blocking XREADGROUP */
if
(
was_stream
&&
!
is_stream
)
signalKeyAsReady
(
emptied
,
key
,
OBJ_STREAM
);
}
dictReleaseIterator
(
di
);
}
/* Swap two databases at runtime so that all clients will magically see
* the new database even if already connected. Note that the client
* structure c->db points to a given DB, so we need to be smarter and
...
...
@@ -1345,6 +1385,10 @@ int dbSwapDatabases(int id1, int id2) {
touchAllWatchedKeysInDb
(
db1
,
db2
);
touchAllWatchedKeysInDb
(
db2
,
db1
);
/* Try to unblock any XREADGROUP clients if the key no longer exists. */
scanDatabaseForDeletedStreams
(
db1
,
db2
);
scanDatabaseForDeletedStreams
(
db2
,
db1
);
/* Swap hash tables. Note that we don't swap blocking_keys,
* ready_keys and watched_keys, since we want clients to
* remain in the same DB they were. */
...
...
@@ -1367,8 +1411,8 @@ int dbSwapDatabases(int id1, int id2) {
* in dbAdd() when a list is created. So here we need to rescan
* the list of clients blocked on lists and signal lists as ready
* if needed. */
scanDatabaseForReady
List
s
(
db1
);
scanDatabaseForReady
List
s
(
db2
);
scanDatabaseForReady
Key
s
(
db1
);
scanDatabaseForReady
Key
s
(
db2
);
return
C_OK
;
}
...
...
@@ -1391,6 +1435,9 @@ void swapMainDbWithTempDb(redisDb *tempDb) {
* client watching keys. */
touchAllWatchedKeysInDb
(
activedb
,
newdb
);
/* Try to unblock any XREADGROUP clients if the key no longer exists. */
scanDatabaseForDeletedStreams
(
activedb
,
newdb
);
/* Swap hash tables. Note that we don't swap blocking_keys,
* ready_keys and watched_keys, since clients
* remain in the same DB they were. */
...
...
@@ -1413,7 +1460,7 @@ void swapMainDbWithTempDb(redisDb *tempDb) {
* in dbAdd() when a list is created. So here we need to rescan
* the list of clients blocked on lists and signal lists as ready
* if needed. */
scanDatabaseForReady
List
s
(
activedb
);
scanDatabaseForReady
Key
s
(
activedb
);
}
trackingInvalidateKeysOnFlush
(
1
);
...
...
Prev
1
2
3
4
5
6
7
8
9
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment