1. 15 Mar, 2022 2 commits
    • ranshid's avatar
      make sort/ro commands validate external keys access patterns (#10106) (#10340) · 1078e30c
      ranshid authored
      Currently the sort and sort_ro can access external keys via `GET` and `BY`
      in order to make sure the user cannot violate the authorization ACL
      rules, the decision is to reject external keys access patterns unless ACL allows
      SORT full access to all keys.
      I.e. for backwards compatibility, SORT with GET/BY keeps working, but
      if ACL has restrictions to certain keys, these features get permission denied.
      
      ### Implemented solution
      We have discussed several potential solutions and decided to only allow the GET and BY
      arguments when the user has all key permissions with the SORT command. The reasons
      being that SORT with GET or BY is problematic anyway, for instance it is not supported in
      cluster mode since it doesn't declare keys, and we're not sure the combination of that feature
      with ACL key restriction is really required.
      **HOWEVER** If in the fullness of time we will identify a real need for fine grain access
      support ...
      1078e30c
    • yoav-steinberg's avatar
      Optimization: remove `updateClientMemUsage` from i/o threads. (#10401) · cf6dcb7b
      yoav-steinberg authored
      In a benchmark we noticed we spend a relatively long time updating the client
      memory usage leading to performance degradation.
      Before #8687 this was performed in the client's cron and didn't affect performance.
      But since introducing client eviction we need to perform this after filling the input
      buffers and after processing commands. This also lead me to write this code to be
      thread safe and perform it in the i/o threads.
      
      It turns out that the main performance issue here is related to atomic operations
      being performed while updating the total clients memory usage stats used for client
      eviction (`server.stat_clients_type_memory[]`). This update needed to be atomic
      because `updateClientMemUsage()` was called from the IO threads.
      
      In this commit I make sure to call `updateClientMemUsage()` only from the main thread.
      In case of threaded IO I call it for each client during the "fan-in" phase of the read/write
      operation. This also means I could chuck the `updateClientMemUsageBucket()` function
      which was called during this phase and embed it into `updateClientMemUsage()`.
      
      Profiling shows this makes `updateClientMemUsage()` (on my x86_64 linux) roughly x4 faster.
      cf6dcb7b
  2. 14 Mar, 2022 2 commits
  3. 13 Mar, 2022 3 commits
  4. 10 Mar, 2022 4 commits
    • Binbin's avatar
      Initialize help when using redis-cli help or redis-cli ? (#10382) · 1797330e
      Binbin authored
      The following usage will output an empty newline:
      ```
      > redis-cli help set
      empty line
      ```
      
      The reason is that in interactive mode, we have called
      `cliInitHelp`, which initializes help.
      
      When using `redis-cli help xxx` or `redis-cli help ? xxx`,
      we can't match the command due to empty `helpEntries`,
      so we output an empty newline.
      
      In this commit, we will call `cliInitHelp` to init the help.
      Note that in this case, we need to call `cliInitHelp` (COMMAND DOCS)
      every time, which i think is acceptable.
      
      So now the output will look like:
      ```
      [redis]# src/redis-cli help get
      
        GET key
        summary: Get the value of a key
        since: 1.0.0
        group: string
      
      [redis]#
      ```
      
      Fixes #10378
      
      This PR also fix a redis-cli crash when using `--ldb --eval`:
      ```
      [root]# src/redis-cli --ldb --eval test.lua test 1
      Lua debugging session started, please use:
      quit    -- End the session.
      restart -- Restart the script in debug mode again.
      help    -- Show Lua script debugging commands.
      
      * Stopped at 1, stop reason = step over
      -> 1   local num = redis.call('GET', KEYS[1]);
      redis-cli: redis-cli.c:718: cliCountCommands: Assertion
      `commandTable->element[i]->type == 1' failed.
      Aborted
      ```
      Because in ldb mode, `COMMAND DOCS` or `COMMAND` will
      return an array, only with one element, and the type
      is `REDIS_REPLY_STATUS`, the result is `<error> Unknown
      Redis Lua debugger command or wrong number of arguments`.
      
      So if we are in the ldb mode, and init the Redis HELP, we
      will get the wrong response and crash the redis-cli.
      In ldb mode we don't initialize HELP, help is only initialized
      after the lua debugging session ends.
      
      It was broken in #10043
      1797330e
    • ranshid's avatar
      ACL DRYRUN does not validate the verified command args. (#10405) · 11b071a2
      ranshid authored
      As a result we segfault when parsing and matching the command keys.
      11b071a2
    • zhugezy's avatar
      set "disable-thp" config immutable (#10409) · a26cab9d
      zhugezy authored
      It's confusing for this config to be modifiable since it only takes effect on startup
      a26cab9d
    • rangerzhang's avatar
      Fix outdated comments on updateSlavesWaitingBgsave (#10394) · 4e012dae
      rangerzhang authored
      * fix-replication-comments
      
      The described capacity
       `and to schedule a new BGSAVE if there are slaves that attached while a BGSAVE was in progress`
      was moved to `checkChildrenDone()`  named by `replicationStartPendingFork`
      
      But the comment was not changed, may misleading others.
      
      * remove-misleading-comments
      
      The described capacity
       `to schedule a new BGSAVE if there are slaves that attached while a BGSAVE was in progress` 
      and 
      `or when the replication RDB transfer strategy is modified from disk to socket or the other way around` 
      were not correct now.
      4e012dae
  5. 09 Mar, 2022 4 commits
  6. 08 Mar, 2022 6 commits
    • Ronald Petty's avatar
      Update redis.conf (#10396) · b104f3ca
      Ronald Petty authored
      Typo in conf file comment.
      b104f3ca
    • guybe7's avatar
      XREADGROUP: Unblock client if stream is deleted (#10306) · 2a295408
      guybe7 authored
      Deleting a stream while a client is blocked XREADGROUP should unblock the client.
      
      The idea is that if a client is blocked via XREADGROUP is different from
      any other blocking type in the sense that it depends on the existence of both
      the key and the group. Even if the key is deleted and then revived with XADD
      it won't help any clients blocked on XREADGROUP because the group no longer
      exist, so they would fail with -NOGROUP anyway.
      The conclusion is that it's better to unblock these clients (with error) upon
      the deletion of the key, rather than waiting for the first XADD. 
      
      Other changes:
      1. Slightly optimize all `serveClientsBlockedOn*` functions by checking `server.blocked_clients_by_type`
      2. All `serveClientsBlockedOn*` functions now use a list iterator rather than looking at `listFirst`, relying
        on `unblockClient` to delete the head of the list. Before this commit, only `serveClientsBlockedOnStreams`
        used to work like that.
      3. bugfix: CLIENT UNBLOCK ERROR should work even if the command doesn't have a timeout_callback
        (only relevant to module commands)
      2a295408
    • zhaozhao.zz's avatar
      script should not allow may-replicate commands when client pause write (#10364) · 728e6252
      zhaozhao.zz authored
      In some special commands like eval_ro / fcall_ro we allow no-writes commands.
      But may-replicate commands are no-writes too, that leads crash when client pause write:
      728e6252
    • Oran Agra's avatar
      dismiss COW of client output buffer now that it's dynamic (#10371) · b3fe4f31
      Oran Agra authored
      since #9822, the static reply buffer is no longer part of the client structure, so we need to dismiss it.
      b3fe4f31
    • zhugezy's avatar
      remove a piece of redundant comment (#10392) · 4f19b4d0
      zhugezy authored
      introduced in #10147 since we blocked the first-arg mechanism on subcommands
      4f19b4d0
    • Yossi Gottlieb's avatar
      Fix redis-benchmark --cluster with IPv6. (#10393) · 38052fd7
      Yossi Gottlieb authored
      Currently, CLUSTER NODES is parsed and was not done correctly for IPv6
      addresses.
      38052fd7
  7. 07 Mar, 2022 3 commits
  8. 06 Mar, 2022 1 commit
  9. 05 Mar, 2022 1 commit
    • Yuta Hongo's avatar
      redis-cli: Better --json Unicode support and --quoted-json (#10286) · e3ef73dc
      Yuta Hongo authored
      Normally, `redis-cli` escapes non-printable data received from Redis, using a custom scheme (which is also used to handle quoted input). When using `--json` this is not desired as it is not compatible with RFC 7159, which specifies JSON strings are assumed to be Unicode and how they should be escaped.
      
      This commit changes `--json` to follow RFC 7159, which means that properly encoded Unicode strings in Redis will result with a valid Unicode JSON.
      
      However, this introduces a new problem with `--json` and data that is not valid Unicode (e.g., random binary data, text that follows other encoding, etc.). To address this, we add `--quoted-json` which produces JSON strings that follow the original redis-cli quoting scheme.
      
      For example, a value that consists of only null (0x00) bytes will show up as:
      * `"\u0000\u0000\u0000"` when using `--json`
      * `"\\x00\\x00\\x00"` when using `--quoted-json`
      e3ef73dc
  10. 03 Mar, 2022 1 commit
  11. 02 Mar, 2022 1 commit
    • Henry's avatar
      A faster and more robust code of zslRandomLevel using RAND_MAX (#5539) · feb032fd
      Henry authored
      1. since ZSKIPLIST_P is float, using it directly inside the condition used to causes floating point code to be used (gcc/x86)
      2. In some operating system(eg.Windows), the largest value returned from random() is 0x7FFF(15bit), so after bitwise AND with 0xFFFF, the probability of the less operation returning true in the while loop's condition is no more equal to ZSKIPLIST_P.
      3. In case some library has random() returning int in range [0~ZSKIPLIST_P*65535], the while loop will be an infinite loop.
      4. on Linux where RAND_MAX is higher than 0xFFFF, this change actually improves precision (despite not matching the result against a float value)
      feb032fd
  12. 01 Mar, 2022 3 commits
    • ranshid's avatar
      Introduce debug command to disable reply buffer resizing (#10360) · 9b15dd28
      ranshid authored
      In order to resolve some flaky tests which hard rely on examine memory footprint.
      we introduce the following fixes:
      
      # Fix in client-eviction test - by @yoav-steinberg 
      Sometime the libc allocator can use different size client struct allocations.
      this may cause unexpected memory calculations to fail the test.
      
      # Introduce new DEBUG command for disabling reply buffer resizing
      In order to eliminate reply buffer resizing during specific tests.
      we introduced the ability to disable (and enable) the resizing cron job
      
      Co-authored-by: yoav-steinberg yoav@redislabs.com
      9b15dd28
    • Madelyn Olson's avatar
      Move most of the configuration to a hashtable (#10323) · 4a45386e
      Madelyn Olson authored
      * Moved configuration storage from a list to a hash table
      * Configs are returned in a non-deterministic order. It's possible that a client was relying on order (hopefully not).
      * Fixed an esoteric bug where if you did a set with an alias with an error, it would throw an error indicating a bug with the preferred name for that config.
      4a45386e
    • Harkrishn Patro's avatar
  13. 28 Feb, 2022 6 commits
  14. 27 Feb, 2022 3 commits
    • Meir Shpilraien (Spielrein)'s avatar
      Sort out the mess around Lua error messages and error stats (#10329) · aa856b39
      Meir Shpilraien (Spielrein) authored
      
      
      This PR fix 2 issues on Lua scripting:
      * Server error reply statistics (some errors were counted twice).
      * Error code and error strings returning from scripts (error code was missing / misplaced).
      
      ## Statistics
      a Lua script user is considered part of the user application, a sophisticated transaction,
      so we want to count an error even if handled silently by the script, but when it is
      propagated outwards from the script we don't wanna count it twice. on the other hand,
      if the script decides to throw an error on its own (using `redis.error_reply`), we wanna
      count that too.
      Besides, we do count the `calls` in command statistics for the commands the script calls,
      we we should certainly also count `failed_calls`.
      So when a simple `eval "return redis.call('set','x','y')" 0` fails, it should count the failed call
      to both SET and EVAL, but the `errorstats` and `total_error_replies` should be counted only once.
      
      The PR changes the error object that is raised on errors. Instead of raising a simple Lua
      string, Redis will raise a Lua table in the following format:
      
      ```
      {
          err='<error message (including error code)>',
          source='<User source file name>',
          line='<line where the error happned>',
          ignore_error_stats_update=true/false,
      }
      ```
      
      The `luaPushError` function was modified to construct the new error table as describe above.
      The `luaRaiseError` was renamed to `luaError` and is now simply called `lua_error` to raise
      the table on the top of the Lua stack as the error object.
      The reason is that since its functionality is changed, in case some Redis branch / fork uses it,
      it's better to have a compilation error than a bug.
      
      The `source` and `line` fields are enriched by the error handler (if possible) and the
      `ignore_error_stats_update` is optional and if its not present then the default value is `false`.
      If `ignore_error_stats_update` is true, the error will not be counted on the error stats.
      
      When parsing Redis call reply, each error is translated to a Lua table on the format describe
      above and the `ignore_error_stats_update` field is set to `true` so we will not count errors
      twice (we counted this error when we invoke the command).
      
      The changes in this PR might have been considered as a breaking change for users that used
      Lua `pcall` function. Before, the error was a string and now its a table. To keep backward
      comparability the PR override the `pcall` implementation and extract the error message from
      the error table and return it.
      
      Example of the error stats update:
      
      ```
      127.0.0.1:6379> lpush l 1
      (integer) 2
      127.0.0.1:6379> eval "return redis.call('get', 'l')" 0
      (error) WRONGTYPE Operation against a key holding the wrong kind of value. script: e471b73f1ef44774987ab00bdf51f21fd9f7974a, on @user_script:1.
      
      127.0.0.1:6379> info Errorstats
      # Errorstats
      errorstat_WRONGTYPE:count=1
      
      127.0.0.1:6379> info commandstats
      # Commandstats
      cmdstat_eval:calls=1,usec=341,usec_per_call=341.00,rejected_calls=0,failed_calls=1
      cmdstat_info:calls=1,usec=35,usec_per_call=35.00,rejected_calls=0,failed_calls=0
      cmdstat_lpush:calls=1,usec=14,usec_per_call=14.00,rejected_calls=0,failed_calls=0
      cmdstat_get:calls=1,usec=10,usec_per_call=10.00,rejected_calls=0,failed_calls=1
      ```
      
      ## error message
      We can now construct the error message (sent as a reply to the user) from the error table,
      so this solves issues where the error message was malformed and the error code appeared
      in the middle of the error message:
      
      ```diff
      127.0.0.1:6379> eval "return redis.call('set','x','y')" 0
      -(error) ERR Error running script (call to 71e6319f97b0fe8bdfa1c5df3ce4489946dda479): @user_script:1: OOM command not allowed when used memory > 'maxmemory'.
      +(error) OOM command not allowed when used memory > 'maxmemory' @user_script:1. Error running script (call to 71e6319f97b0fe8bdfa1c5df3ce4489946dda479)
      ```
      
      ```diff
      127.0.0.1:6379> eval "redis.call('get', 'l')" 0
      -(error) ERR Error running script (call to f_8a705cfb9fb09515bfe57ca2bd84a5caee2cbbd1): @user_script:1: WRONGTYPE Operation against a key holding the wrong kind of value
      +(error) WRONGTYPE Operation against a key holding the wrong kind of value script: 8a705cfb9fb09515bfe57ca2bd84a5caee2cbbd1, on @user_script:1.
      ```
      
      Notica that `redis.pcall` was not change:
      ```
      127.0.0.1:6379> eval "return redis.pcall('get', 'l')" 0
      (error) WRONGTYPE Operation against a key holding the wrong kind of value
      ```
      
      
      ## other notes
      Notice that Some commands (like GEOADD) changes the cmd variable on the client stats so we
      can not count on it to update the command stats. In order to be able to update those stats correctly
      we needed to promote `realcmd` variable to be located on the client struct.
      
      Tests was added and modified to verify the changes.
      
      Related PR's: #10279, #10218, #10278, #10309
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      aa856b39
    • filipe oliveira's avatar
      Enable redis-benchmark to use RESP3 protocol mode (#10335) · 9f30dd03
      filipe oliveira authored
      Adds `-3` option to cause redis-benchmark to send a `HELLO 3`
      to it can benchmark the effects of RESP3 on the server.
      9f30dd03
    • Madelyn Olson's avatar
      Fixed typo in variable name (#10347) · 35fccd87
      Madelyn Olson authored
      35fccd87