1. 27 Jun, 2023 1 commit
  2. 26 Jun, 2023 1 commit
    • Chen Tianjie's avatar
      Support TLS service when "tls-cluster" is not enabled and persist both plain... · 22a29935
      Chen Tianjie authored
      Support TLS service when "tls-cluster" is not enabled and persist both plain and TLS port in nodes.conf (#12233)
      
      Originally, when "tls-cluster" is enabled, `port` is set to TLS port. In order to support non-TLS clients, `pport` is used to propagate TCP port across cluster nodes. However when "tls-cluster" is disabled, `port` is set to TCP port, and `pport` is not used, which means the cluster cannot provide TLS service unless "tls-cluster" is on.
      ```
      typedef struct {
          // ...
          uint16_t port;  /* Latest known clients port (TLS or plain). */
          uint16_t pport; /* Latest known clients plaintext port. Only used if the main clients port is for TLS. */
          // ...
      } clusterNode;
      ```
      ```
      typedef struct {
          // ...
          uint16_t port;   /* TCP base port number. */
          uint16_t pport;  /* Sender TCP plaintext port, if base port is TLS */
          // ...
      } clusterMsg;
      ```
      This PR renames `port` and `pport` in `clusterNode` to `tcp_port` and `tls_port`, to record both ports no matter "tls-cluster" is enabled or disabled.
      
      This allows to provide TLS service to clients when "tls-cluster" is disabled: when displaying cluster topology, or giving `MOVED` error, server can provide TLS or TCP port according to client's connection type, no matter what type of connection cluster bus is using.
      
      For backwards compatibility, `port` and `pport` in `clusterMsg` are preserved, when "tls-cluster" is enabled, `port` is set to TLS port and `pport` is set to TCP port, when "tls-cluster" is disabled, `port` is set to TCP port and `pport` is set to TLS port (instead of 0).
      
      Also, in the nodes.conf file, a new aux field displaying an extra port is added to complete the persisted info. We may have `tls_port=xxxxx` or `tcp_port=xxxxx` in the aux field, to complete the cluster topology, while the other port is stored in the normal `<ip>:<port>` field. The format is shown below.
      ```
      <node-id> <ip>:<tcp_port>@<cport>,<hostname>,shard-id=...,tls-port=6379 myself,master - 0 0 0 connected 0-1000
      ```
      Or we can switch the position of two ports, both can be correctly resolved.
      ```
      <node-id> <ip>:<tls_port>@<cport>,<hostname>,shard-id=...,tcp-port=6379 myself,master - 0 0 0 connected 0-1000
      ```
      22a29935
  3. 25 Jun, 2023 2 commits
    • Binbin's avatar
      Move clusterBeforeSleep before blockedBeforeSleep (#12343) · 9600553e
      Binbin authored
      The new blockedBeforeSleep was added in #12337, it breaks the order in 2ecb5edf.
      
      This may be related to #2288, quoted from comment in #2288:
      ```
      Moreover the clusterBeforeSleep() call was misplaced at the end of the chain of the
      beforeSleep() call in redis.c. It should be at the top, before processing un blocking
      clients. This is exactly the reason in the specific instance of the bug as reported,
      why the state was not updated in time before clients served.
      ```
      9600553e
    • Meir Shpilraien (Spielrein)'s avatar
      Fix use after free on blocking RM_Call. (#12342) · 153f8f08
      Meir Shpilraien (Spielrein) authored
      blocking RM_Call was introduced on: #11568, It allows a module to perform
      blocking commands and get the reply asynchronously.If the command gets
      block, a special promise CallReply is returned that allow to set the unblock
      handler. The unblock handler will be called when the command invocation
      finish and it gets, as input, the command real reply.
      
      The issue was that the real CallReply was created using a stack allocated
      RedisModuleCtx which is no longer available after the unblock handler finishes.
      So if the module keeps the CallReply after the unblock handler finished, the
      CallReply holds a pointer to invalid memory and will try to access it when the
      CallReply will be released.
      
      The solution is to create the CallReply with a NULL context to make it totally
      detached and can be freed freely when the module wants.
      
      Test was added to cover this case, running the test with valgrind before the
      fix shows the use after free error. With the fix, there are no valgrind errors.
      
      unrelated: adding a missing `$rd close` in many tests in that file.
      153f8f08
  4. 22 Jun, 2023 2 commits
    • guybe7's avatar
      Modules: Unblock from within a timer coverage (#12337) · 32301999
      guybe7 authored
      Apart from adding the missing coverage, this PR also adds `blockedBeforeSleep`
      that gathers all block-related functions from `beforeSleep`
      
      The order inside `blockedBeforeSleep` is different: now `handleClientsBlockedOnKeys`
      (which may unblock clients) is called before `processUnblockedClients` (which handles
      unblocked clients).
      It makes sense to have this order.
      
      There are no visible effects of the wrong ordering, except some cleanups of the now-unblocked
      client would have  happen in the next `beforeSleep` (will now happen in the current one)
      
      The reason we even got into it is because i triggers an assertion in logresreq.c (breaking
      the assumption that `unblockClient` is called **before** actually flushing the reply to the socket):
      `handleClientsBlockedOnKeys` is called, then it calls `moduleUnblockClientOnKey`, which calls
      `moduleUnblockClient`, which adds the client to `moduleUnblockedClients` back to `beforeSleep`,
      we call `handleClientsWithPendingWritesUsingThreads`, it writes the data of buf to the client, so
      `client->bufpos` became 0
      On the next `beforeSleep`, we call `moduleHandleBlockedClients`, which calls `unblockClient`,
      which calls `reqresAppendResponse`, triggering the assert. (because the `bufpos` is 0) - see https://github.com/redis/redis/pull/12301#discussion_r1226386716
      32301999
    • Gabi Ganam's avatar
      Fix typos in comments (#12338) · 9e5f45f2
      Gabi Ganam authored
      9e5f45f2
  5. 21 Jun, 2023 3 commits
    • Binbin's avatar
      Print strerror when bio initialization fails (#12333) · 47f32bc9
      Binbin authored
      Now we can see something like this:
      ```
      Fatal: Can't initialize Background Jobs. Error message: Cannot allocate memory
      ```
      47f32bc9
    • guybe7's avatar
      Improve moduleBlockClient timeout overflow handling (#12174) · d46ef886
      guybe7 authored
      Continuation of https://github.com/redis/redis/pull/11338
      avoid overflow adding input timeout to "now" in moduleBlockClient.
      d46ef886
    • Madelyn Olson's avatar
      Make nodename test more consistent (#12330) · 73cf0243
      Madelyn Olson authored
      To determine when everything was stable, we couldn't just query the nodename since they aren't API visible by design. Instead, we were using a proxy piece of information which was bumping the epoch and waiting for everyone to observe that. This works for making source Node 0 and Node 1 had pinged, and Node 0 and Node 2 had pinged, but did not guarantee that Node 1 and Node 2 had pinged. Although unlikely, this can cause this failure message. To fix it I hijacked hostnames and used its validation that it has been propagated, since we know that it is stable.
      
      I also noticed while stress testing this sometimes the test took almost 4.5 seconds to finish, which is really close to the current 5 second limit of the log check, so I bumped that up as well just to make it a bit more consistent.
      73cf0243
  6. 20 Jun, 2023 10 commits
    • guybe7's avatar
      Align RM_ReplyWithErrorFormat with RM_ReplyWithError (#12321) · 20fa1560
      guybe7 authored
      Introduced by https://github.com/redis/redis/pull/11923 (Redis 7.2 RC2)
      
      It's very weird and counterintuitive that `RM_ReplyWithError` requires the error-code
      **without** a hyphen while `RM_ReplyWithErrorFormat` requires either the error-code
      **with** a hyphen or no error-code at all
      ```
      RedisModule_ReplyWithError(ctx, "BLA bla bla");
      ```
      vs.
      ```
      RedisModule_ReplyWithErrorFormat(ctx, "-BLA %s", "bla bla");
      ```
      
      This commit aligns RM_ReplyWithErrorFormat to behvae like RM_ReplyWithError.
      it's a breaking changes but it's done before 7.2 goes GA.
      20fa1560
    • Oran Agra's avatar
      Fix broken protocol when PUBLISH emits local push inside MULTI (#12326) · 8ad8f0f9
      Oran Agra authored
      When a connection that's subscribe to a channel emits PUBLISH inside MULTI-EXEC,
      the push notification messes up the EXEC response.
      
      e.g. MULTI, PING, PUSH foo bar, PING, EXEC
      the EXEC's response will contain: PONG, {message foo bar}, 1. and the second PONG
      will be delivered outside the EXEC's response.
      
      Additionally, this PR changes the order of responses in case of a plain PUBLISH (when
      the current client also subscribed to it), by delivering the push after the command's
      response instead of before it.
      This also affects modules calling RM_PublishMessage in a similar way, so that we don't
      run the risk of getting that push mixed together with the module command's response.
      8ad8f0f9
    • judeng's avatar
      use embedded string object and more efficient ll2string for long long value... · 93708c7f
      judeng authored
      
      use embedded string object and more efficient ll2string for long long value convert to string (#12250)
      
      A value of type long long is always less than 21 bytes when convert to a
      string, so always meets the conditions for using embedded string object
      which can always get memory reduction and performance gain (less calls
      to the heap allocator).
      Additionally, for the conversion of longlong type to sds, we also use a faster
      algorithm (the one in util.c instead of the one that used to be in sds.c). 
      
      For the DECR command on 32-bit Redis, we get about a 5.7% performance
      improvement. There will also be some performance gains for some commands
      that heavily use sdscatfmt to convert numbers, such as INFO.
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      93708c7f
    • Binbin's avatar
      zrangeGenericCommand add check for negative offset (#9052) · d9c2ef8a
      Binbin authored
      Now we will check the offset in zrangeGenericCommand.
      With a negative offset, we will throw an error and return.
      
      This also resolve the issue of zeroing the destination key
      in case of the "store" variant when we input a negative offset.
      ```
      127.0.0.1:6379> set key value
      OK
      127.0.0.1:6379> zrangestore key myzset 0 10 byscore limit -1 10
      (integer) 0
      127.0.0.1:6379> exists key
      (integer) 0
      ```
      
      This change affects the following commands:
      - ZRANGE / ZRANGESTORE / ZRANGEBYLEX / ZRANGEBYSCORE
      - ZREVRANGE / ZREVRANGEBYSCORE / ZREVRANGEBYLEX
      d9c2ef8a
    • Wen Hui's avatar
      adding geo command edge cases tests (#12274) · 66ea178c
      Wen Hui authored
      For geosearch and georadius we have already test coverage for wrong type, but we dont have for geodist, geohash, geopos commands. So adding the wrong type test cases for geodist, geohash, geopos commands.
      
      Existing code, we have verify_geo_edge_response_bymember function for wrong type test cases which has member as an option. But the function is being called in other test cases where the output is not inline with these commnds(geodist, geohash, geopos). So I could not include these commands(geodist, geohash, geopos) as part of existing function, hence implemented a new function verify_geo_edge_response_generic and called from the test case.
      66ea178c
    • Binbin's avatar
      Fix ZRANK/ZREVRANK reply_schema description (#12331) · d306d861
      Binbin authored
      The parameter name is WITHSCORE instead of WITHSCORES.
      d306d861
    • mstmdev's avatar
      13e17e94
    • Wen Hui's avatar
      Sanitizer reported memory leak for '--invalid' option or port number is missed... · 813924b4
      Wen Hui authored
      
      Sanitizer reported memory leak for '--invalid' option or port number is missed cases to redis-server. (#12322)
      
      Observed that the sanitizer reported memory leak as clean up is not done
      before the process termination in negative/following cases:
      
      **- when we passed '--invalid' as option to redis-server.**
      
      ```
       -vm:~/mem-leak-issue/redis$ ./src/redis-server --invalid
      
      *** FATAL CONFIG FILE ERROR (Redis 255.255.255) ***
      Reading the configuration file, at line 2
      >>> 'invalid'
      Bad directive or wrong number of arguments
      
      =================================================================
      ==865778==ERROR: LeakSanitizer: detected memory leaks
      
      Direct leak of 8 byte(s) in 1 object(s) allocated from:
          #0 0x7f0985f65867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
          #1 0x558ec86686ec in ztrymalloc_usable_internal /home/ubuntu/mem-leak-issue/redis/src/zmalloc.c:117
          #2 0x558ec86686ec in ztrymalloc_usable /home/ubuntu/mem-leak-issue/redis/src/zmalloc.c:135
          #3 0x558ec86686ec in ztryrealloc_usable_internal /home/ubuntu/mem-leak-issue/redis/src/zmalloc.c:276
          #4 0x558ec86686ec in zrealloc /home/ubuntu/mem-leak-issue/redis/src/zmalloc.c:327
          #5 0x558ec865dd7e in sdssplitargs /home/ubuntu/mem-leak-issue/redis/src/sds.c:1172
          #6 0x558ec87a1be7 in loadServerConfigFromString /home/ubuntu/mem-leak-issue/redis/src/config.c:472
          #7 0x558ec87a13b3 in loadServerConfig /home/ubuntu/mem-leak-issue/redis/src/config.c:718
          #8 0x558ec85e6f15 in main /home/ubuntu/mem-leak-issue/redis/src/server.c:7258
          #9 0x7f09856e5d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
      
      SUMMARY: AddressSanitizer: 8 byte(s) leaked in 1 allocation(s).
      
      ```
      
      **- when we pass '--port' as option and missed to add port number to redis-server.**
      
      ```
      vm:~/mem-leak-issue/redis$ ./src/redis-server --port
      
      *** FATAL CONFIG FILE ERROR (Redis 255.255.255) ***
      Reading the configuration file, at line 2
      >>> 'port'
      wrong number of arguments
      
      =================================================================
      ==865846==ERROR: LeakSanitizer: detected memory leaks
      
      Direct leak of 8 byte(s) in 1 object(s) allocated from:
          #0 0x7fdcdbb1f867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
          #1 0x557e8b04f6ec in ztrymalloc_usable_internal /home/ubuntu/mem-leak-issue/redis/src/zmalloc.c:117
          #2 0x557e8b04f6ec in ztrymalloc_usable /home/ubuntu/mem-leak-issue/redis/src/zmalloc.c:135
          #3 0x557e8b04f6ec in ztryrealloc_usable_internal /home/ubuntu/mem-leak-issue/redis/src/zmalloc.c:276
          #4 0x557e8b04f6ec in zrealloc /home/ubuntu/mem-leak-issue/redis/src/zmalloc.c:327
          #5 0x557e8b044d7e in sdssplitargs /home/ubuntu/mem-leak-issue/redis/src/sds.c:1172
          #6 0x557e8b188be7 in loadServerConfigFromString /home/ubuntu/mem-leak-issue/redis/src/config.c:472
          #7 0x557e8b1883b3 in loadServerConfig /home/ubuntu/mem-leak-issue/redis/src/config.c:718
          #8 0x557e8afcdf15 in main /home/ubuntu/mem-leak-issue/redis/src/server.c:7258
          #9 0x7fdcdb29fd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
      
      Indirect leak of 10 byte(s) in 1 object(s) allocated from:
          #0 0x7fdcdbb1fc18 in __interceptor_realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:164
          #1 0x557e8b04f9aa in ztryrealloc_usable_internal /home/ubuntu/mem-leak-issue/redis/src/zmalloc.c:287
          #2 0x557e8b04f9aa in ztryrealloc_usable /home/ubuntu/mem-leak-issue/redis/src/zmalloc.c:317
          #3 0x557e8b04f9aa in zrealloc_usable /home/ubuntu/mem-leak-issue/redis/src/zmalloc.c:342
          #4 0x557e8b033f90 in _sdsMakeRoomFor /home/ubuntu/mem-leak-issue/redis/src/sds.c:271
          #5 0x557e8b033f90 in sdsMakeRoomFor /home/ubuntu/mem-leak-issue/redis/src/sds.c:295
          #6 0x557e8b033f90 in sdscatlen /home/ubuntu/mem-leak-issue/redis/src/sds.c:486
          #7 0x557e8b044e1f in sdssplitargs /home/ubuntu/mem-leak-issue/redis/src/sds.c:1165
          #8 0x557e8b188be7 in loadServerConfigFromString /home/ubuntu/mem-leak-issue/redis/src/config.c:472
          #9 0x557e8b1883b3 in loadServerConfig /home/ubuntu/mem-leak-issue/redis/src/config.c:718
          #10 0x557e8afcdf15 in main /home/ubuntu/mem-leak-issue/redis/src/server.c:7258
          #11 0x7fdcdb29fd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
      
      SUMMARY: AddressSanitizer: 18 byte(s) leaked in 2 allocation(s).
      
      ```
      
      As part analysis found that the sdsfreesplitres is not called when this condition checks are being hit.
      
      Output after the fix:
      
      
      ```
      vm:~/mem-leak-issue/redis$ ./src/redis-server --invalid
      
      *** FATAL CONFIG FILE ERROR (Redis 255.255.255) ***
      Reading the configuration file, at line 2
      >>> 'invalid'
      Bad directive or wrong number of arguments
      vm:~/mem-leak-issue/redis$
      
      ===========================================
      vm:~/mem-leak-issue/redis$ ./src/redis-server --jdhg
      
      *** FATAL CONFIG FILE ERROR (Redis 255.255.255) ***
      Reading the configuration file, at line 2
      >>> 'jdhg'
      Bad directive or wrong number of arguments
      
      ---------------------------------------------------------------------------
      vm:~/mem-leak-issue/redis$ ./src/redis-server --port
      
      *** FATAL CONFIG FILE ERROR (Redis 255.255.255) ***
      Reading the configuration file, at line 2
      >>> 'port'
      wrong number of arguments
      ```
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      813924b4
    • Shaya Potter's avatar
      Add ability for modules to know which client is being cmd filtered (#12219) · 07316f16
      Shaya Potter authored
      Adds API
      - RedisModule_CommandFilterGetClientId()
      
      Includes addition to commandfilter test module to validate that it works
      by performing the same command from 2 different clients
      07316f16
    • Binbin's avatar
      Fix cluster human_nodename Getter data loss in nodes.conf (#12325) · cd4f3e20
      Binbin authored
      auxHumanNodenameGetter limited to %.40s, since we did not limit the
      length of config cluster-announce-human-nodename, %.40s will cause
      nodename data loss (we will persist it in nodes.conf).
      
      Additional modified auxHumanNodenamePresent to use sdslen.
      cd4f3e20
  7. 19 Jun, 2023 1 commit
    • Binbin's avatar
      Optimize PSUBSCRIBE and PUNSUBSCRIBE from O(N*M) to O(N) (#12298) · b5106249
      Binbin authored
      In the original implementation, the time complexity of the commands
      is actually O(N*M), where N is the number of patterns the client is
      already subscribed and M is the number of patterns to subscribe to.
      The docs are all wrong about this.
      
      Specifically, because the original client->pubsub_patterns is a list,
      so we need to do listSearchKey which is O(N). In this PR, we change it
      to a dict, so the search becomes O(1).
      
      At the same time, both pubsub_channels and pubsubshard_channels are dicts.
      Changing pubsub_patterns to a dictionary improves the readability and
      maintainability of the code.
      b5106249
  8. 18 Jun, 2023 2 commits
    • Oran Agra's avatar
      Set Jemalloc --disable-cache-oblivious to reduce memory overhead (#12315) · 07c14672
      Oran Agra authored
      Apparently for large size classes Jemalloc allocate some extra
      memory (can be up to 25% overhead for allocations of 16kb).
      see https://github.com/jemalloc/jemalloc/issues/1098#issuecomment-1589870476
      
      p.s. from Redis's perspective that looks like external fragmentation,
      (i.e. allocated bytes will be low, and active pages bytes will be large)
      which  can cause active-defrag to eat CPU cycles in vain.
      
      Some details about this mechanism we disable:
      ---------------------------------------------------------------
      Disabling this mechanism only affects large allocations (above 16kb)
      Not only that it isn't expected to cause any performance regressions,
      it's actually recommended, unless you have a specific workload pattern
      and hardware that benefit from this feature -- by default it's enabled and
      adds address randomization to all large buffers, by over allocating 1 page
      per large size class, and offsetting into that page to make the starting
      address of the user buffer randomized. Workloads such as scientific
      computation often handle multiple big matrixes at the same time, and the
      randomization makes sure that the cacheline level accesses don't suffer
      bad conflicts (when they all start from page-aligned addresses).
      
      However the downsize is also quite noticeable, like you observed that extra
      page per large size can cause memory overhead, plus the extra TLB entry.
      The other factor is, hardware in the last few years started doing the
      randomization at the hardware level, i.e. the address to cacheline mapping isn't
      a direct mapping anymore. So there's debate to disable the randomization by default,
      but we are still hesitant because when it matters, it could matter a lot, and having
      it enabled by default limits that worst case behavior, even though it means the
      majority of workloads suffers a regression.
      
      So in short, it's safe and offers better performance in most cases.
      07c14672
    • Wen Hui's avatar
      Cluster human readable nodename feature (#9564) · 070453ee
      Wen Hui authored
      
      
      This PR adds a human readable name to a node in clusters that are visible as part of error logs. This is useful so that admins and operators of Redis cluster have better visibility into failures without having to cross-reference the generated ID with some logical identifier (such as pod-ID or EC2 instance ID). This is mentioned in #8948. Specific nodenames can be set by using the variable cluster-announce-human-nodename. The nodename is gossiped using the clusterbus extension in #9530.
      Co-authored-by: default avatarMadelyn Olson <madelyneolson@gmail.com>
      070453ee
  9. 16 Jun, 2023 4 commits
    • sundb's avatar
      Use Reservoir Sampling for random sampling of dict, and fix hang during fork (#12276) · b00a2351
      sundb authored
      
      
      ## Issue:
      When a dict has a long chain or the length of the chain is longer than
      the number of samples, we will never be able to sample the elements
      at the end of the chain using dictGetSomeKeys().
      This could mean that SRANDMEMBER can be hang in and endless loop.
      The most severe case, is the pathological case of when someone uses SCAN+DEL
      or SSCAN+SREM creating an unevenly distributed dict.
      This was amplified by the recent change in #11692 which prevented a
      down-sizing rehashing while there is a fork.
      
      ## Solution
      1. Before, we will stop sampling when we reach the maximum number
        of samples, even if there is more data after the current chain.
        Now when we reach the maximum we use the Reservoir Sampling
        algorithm to fairly sample the end of the chain that cannot be sampled
      2. Fix the rehashing code, so that the same as it allows rehashing for up-sizing
        during fork when the ratio is extreme, it will allow it for down-sizing as well.
      
      Issue was introduced (or became more severe) by #11692
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      b00a2351
    • Binbin's avatar
      Fix SPOP/RESTORE propagation when doing lazy free (#12320) · 439b0315
      Binbin authored
      In SPOP, when COUNT is greater than or equal to set's size,
      we will remove the set. In dbDelete, we will do DEL or UNLINK
      according to the lazy flag. This is also required for propagate.
      
      In RESTORE, we won't store expired keys into the db, see #7472.
      When used together with REPLACE, it should emit a DEL or UNLINK
      according to the lazy flag.
      
      This PR also adds tests to cover the propagation. The RESTORE
      test will also cover #7472.
      439b0315
    • YaacovHazan's avatar
      Removing duplicated tests (#12318) · 5da9eecd
      YaacovHazan authored
      In 4ba47d2d the following tests added in both tracking.tcl and introspection.tcl
      
      - Coverage: Basic CLIENT CACHING
      - Coverage: Basic CLIENT REPLY
      - Coverage: Basic CLIENT TRACKINGINFO
      - Coverage: Basic CLIENT GETREDIR
      5da9eecd
    • Binbin's avatar
      Add command being unblocked cause another command to get unblocked execution order test (#12324) · 9dc6f93e
      Binbin authored
      * Add command being unblocked cause another command to get unblocked execution order test
      
      In #12301, we observed that if the
      `while(listLength(server.ready_keys) != 0)`
      in handleClientsBlockedOnKeys is changed to
      `if(listLength(server.ready_keys) != 0)`,
      the order of command execution will change.
      
      It is wrong to change that. It means that if a command
      being unblocked causes another command to get unblocked
      (like a BLMOVE would do), then the new unblocked command
      will wait for later to get processed rather than right away.
      
      It'll not have any real implication if we change that since
      we do call handleClientsBlockedOnKeys in beforeSleep again,
      and redis will still behave correctly, but we don't change that.
      
      An example:
      1. $rd1 blmove src{t} dst{t} left right 0
      2. $rd2 blmove dst{t} src{t} right left 0
      3. $rd3 set key1{t}, $rd3 lpush src{t}, $rd3 set key2{t} in a pipeline
      
      The correct order would be:
      1. set key1{t}
      2. lpush src{t}
      3. lmove src{t} dst{t} left right
      4. lmove dst{t} src{t} right left
      5. set key2{t}
      
      The wrong order would be:
      1. set key1{t}
      2. lpush src{t}
      3. lmove src{t} dst{t} left right
      4. set key2{t}
      5. lmove dst{t} src{t} right left
      
      This PR adds corresponding test to cover it.
      
      * Add comment near while(listLength(server.ready_keys) != 0)
      9dc6f93e
  10. 15 Jun, 2023 2 commits
    • Meir Shpilraien (Spielrein)'s avatar
      Prevent PEJ on loading and on readonly replica. (#12304) · cefe4566
      Meir Shpilraien (Spielrein) authored
      While Redis loading data from disk (AOF or RDB), modules will get
      key space notifications. In such stage the module should not register
      any PEJ, the main reason this is forbidden is that PEJ purpose is to
      perform a write operation as a reaction to the key space notification.
      Write operations should not be performed while loading data and so
      there is no reason to register a PEJ. 
      
      Same argument also apply to readonly replica. module should not
      perform any writes as a reaction to key space notifications and so it
      should not register a PEJ.
      
      If a module need to perform some other task which is not involve
      writing, he can do it on the key space notification callback itself.
      cefe4566
    • Binbin's avatar
      Optimize SET PXAT to reduce calls of rewriteClientCommandVector (#12316) · 25447553
      Binbin authored
      In PXAT case, there is no need to do the rewriteClientCommandVector,
      a simply benchmark show we gain a improvement of 10%.
      25447553
  11. 14 Jun, 2023 2 commits
    • judeng's avatar
      improve performance for keys with expiration time (#12177) · 789c33bb
      judeng authored
      This change only affects keys with expiry time.
      For SETEX, the average improvement is 5%, and for GET with
      expiation key, we gain a improvement of 13%.
      
      When keys have expiration time, Redis has an assertion to look
      up the main dict every time when it touches the expires.
      This comes with a performance const, especially during rehash.
      the damage will be double.
      
      It looks like that assert was added some ten years old, maybe out
      of paranoia, and there's probably no reason to keep it at that cost.
      789c33bb
    • Wen Hui's avatar
      Removing the duplicate test case (#12310) · 19460834
      Wen Hui authored
      Looks like the Zadd test case was copied to create Zincrby test case ,but missed to change the command.
      19460834
  12. 13 Jun, 2023 2 commits
    • Harkrishn Patro's avatar
      Allow cluster slots/shards api to respond during loading (#12269) · a9e32767
      Harkrishn Patro authored
      It would be helpful for clients to get cluster slots/shards information during a node failover and is loading data.
      a9e32767
    • Binbin's avatar
      Fix XREADGROUP BLOCK stuck in endless loop (#12301) · e7129e43
      Binbin authored
      
      
      For the XREADGROUP BLOCK > scenario, there is an endless loop.
      Due to #11012, it keep going, reprocess command -> blockForKeys -> reprocess command
      
      The right fix is to avoid an endless loop in handleClientsBlockedOnKey and handleClientsBlockedOnKeys,
      looks like there was some attempt in handleClientsBlockedOnKeys but maybe not sufficiently good,
      and it looks like using a similar trick in handleClientsBlockedOnKey is complicated.
      i.e. stashing the list on the stack and iterating on it after creating a fresh one for future use,
      is problematic since the code keeps accessing the global list.
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      e7129e43
  13. 12 Jun, 2023 1 commit
  14. 11 Jun, 2023 4 commits
    • YaacovHazan's avatar
      Reset command duration for rejected command. (#12247) · 0bfb6d55
      YaacovHazan authored
      In 7.2, After 971b177f
      
       we make sure (assert) that
      the duration has been recorded when resetting the client.
      
      This is not true for rejected commands.
      The use case I found is a blocking command that an ACL rule changed before
      it was unblocked, and while reprocessing it, the command rejected and triggered the assert.
      
      The PR reset the command duration inside rejectCommand / rejectCommandSds.
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      0bfb6d55
    • Chen Tianjie's avatar
      Allow bigger tolerance in eventloop duration test. (#12179) · 2d7d3911
      Chen Tianjie authored
      In #11963, some new tests about eventloop duration were added, which includes time measurement in TCL scripts. This has caused some unexpected CI failures, such as #12169 and #12177, due to slow test servers or some performance jittering.
      2d7d3911
    • Wen Hui's avatar
      Adding missing test cases for Addslot Command (#12288) · d412269f
      Wen Hui authored
      Added missing test case coverage for below scenarios:
      
      1. The command only works if all the specified slots are, from
        the point of view of the node receiving the command, currently
        not assigned. A node will refuse to take ownership for slots that
        already belong to some other node (including itself).
      2. The command fails if the same slot is specified multiple times.
      d412269f
    • Binbin's avatar
      Fix ACLAppendUserForLoading memory leak when merge error (#12296) · 5fd9756d
      Binbin authored
      This leak will only happen in loadServerConfigFromString,
      that is, when we are loading a redis.conf, and the user is wrong.
      
      Because it happens in loadServerConfigFromString, redis will
      exit if there is an error, so this is actually just a cleanup.
      5fd9756d
  15. 08 Jun, 2023 1 commit
  16. 06 Jun, 2023 1 commit
  17. 05 Jun, 2023 1 commit