1. 03 Oct, 2021 1 commit
    • Binbin's avatar
      Cleanup typos, incorrect comments, and fixed small memory leak in redis-cli (#9153) · dd3ac97f
      Binbin authored
      1. Remove forward declarations from header files to functions that do not exist:
      hmsetCommand and rdbSaveTime.
      2. Minor phrasing fixes in #9519
      3. Add missing sdsfree(title) and fix typo in redis-benchmark.
      4. Modify some error comments in some zset commands.
      5. Fix copy-paste bug comment in syncWithMaster about `ip-address`.
      dd3ac97f
  2. 23 Sep, 2021 1 commit
    • yoav-steinberg's avatar
      Client eviction (#8687) · 2753429c
      yoav-steinberg authored
      
      
      ### Description
      A mechanism for disconnecting clients when the sum of all connected clients is above a
      configured limit. This prevents eviction or OOM caused by accumulated used memory
      between all clients. It's a complimentary mechanism to the `client-output-buffer-limit`
      mechanism which takes into account not only a single client and not only output buffers
      but rather all memory used by all clients.
      
      #### Design
      The general design is as following:
      * We track memory usage of each client, taking into account all memory used by the
        client (query buffer, output buffer, parsed arguments, etc...). This is kept up to date
        after reading from the socket, after processing commands and after writing to the socket.
      * Based on the used memory we sort all clients into buckets. Each bucket contains all
        clients using up up to x2 memory of the clients in the bucket below it. For example up
        to 1m clients, up to 2m clients, up to 4m clients, ...
      * Before processing a command and before sleep we check if we're over the configured
        limit. If we are we start disconnecting clients from larger buckets downwards until we're
        under the limit.
      
      #### Config
      `maxmemory-clients` max memory all clients are allowed to consume, above this threshold
      we disconnect clients.
      This config can either be set to 0 (meaning no limit), a size in bytes (possibly with MB/GB
      suffix), or as a percentage of `maxmemory` by using the `%` suffix (e.g. setting it to `10%`
      would mean 10% of `maxmemory`).
      
      #### Important code changes
      * During the development I encountered yet more situations where our io-threads access
        global vars. And needed to fix them. I also had to handle keeps the clients sorted into the
        memory buckets (which are global) while their memory usage changes in the io-thread.
        To achieve this I decided to simplify how we check if we're in an io-thread and make it
        much more explicit. I removed the `CLIENT_PENDING_READ` flag used for checking
        if the client is in an io-thread (it wasn't used for anything else) and just used the global
        `io_threads_op` variable the same way to check during writes.
      * I optimized the cleanup of the client from the `clients_pending_read` list on client freeing.
        We now store a pointer in the `client` struct to this list so we don't need to search in it
        (`pending_read_list_node`).
      * Added `evicted_clients` stat to `INFO` command.
      * Added `CLIENT NO-EVICT ON|OFF` sub command to exclude a specific client from the
        client eviction mechanism. Added corrosponding 'e' flag in the client info string.
      * Added `multi-mem` field in the client info string to show how much memory is used up
        by buffered multi commands.
      * Client `tot-mem` now accounts for buffered multi-commands, pubsub patterns and
        channels (partially), tracking prefixes (partially).
      * CLIENT_CLOSE_ASAP flag is now handled in a new `beforeNextClient()` function so
        clients will be disconnected between processing different clients and not only before sleep.
        This new function can be used in the future for work we want to do outside the command
        processing loop but don't want to wait for all clients to be processed before we get to it.
        Specifically I wanted to handle output-buffer-limit related closing before we process client
        eviction in case the two race with each other.
      * Added a `DEBUG CLIENT-EVICTION` command to print out info about the client eviction
        buckets.
      * Each client now holds a pointer to the client eviction memory usage bucket it belongs to
        and listNode to itself in that bucket for quick removal.
      * Global `io_threads_op` variable now can contain a `IO_THREADS_OP_IDLE` value
        indicating no io-threading is currently being executed.
      * In order to track memory used by each clients in real-time we can't rely on updating
        these stats in `clientsCron()` alone anymore. So now I call `updateClientMemUsage()`
        (used to be `clientsCronTrackClientsMemUsage()`) after command processing, after
        writing data to pubsub clients, after writing the output buffer and after reading from the
        socket (and maybe other places too). The function is written to be fast.
      * Clients are evicted if needed (with appropriate log line) in `beforeSleep()` and before
        processing a command (before performing oom-checks and key-eviction).
      * All clients memory usage buckets are grouped as follows:
        * All clients using less than 64k.
        * 64K..128K
        * 128K..256K
        * ...
        * 2G..4G
        * All clients using 4g and up.
      * Added client-eviction.tcl with a bunch of tests for the new mechanism.
      * Extended maxmemory.tcl to test the interaction between maxmemory and
        maxmemory-clients settings.
      * Added an option to flag a numeric configuration variable as a "percent", this means that
        if we encounter a '%' after the number in the config file (or config set command) we
        consider it as valid. Such a number is store internally as a negative value. This way an
        integer value can be interpreted as either a percent (negative) or absolute value (positive).
        This is useful for example if some numeric configuration can optionally be set to a percentage
        of something else.
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      2753429c
  3. 09 Sep, 2021 1 commit
    • Wang Yuan's avatar
      Delay to discard cached master when full synchronization (#9398) · cee3d67f
      Wang Yuan authored
      * Delay to discard cache master when full synchronization
      * Don't disconnect with replicas before loading transferred RDB when full sync
      
      Previously, once replica need to start full synchronization with master,
      it will discard cached master whatever full synchronization is failed or
      not. 
      Now we discard cached master only when transferring RDB is finished
      and start to change data space, this make replica could start partial
      resynchronization with another new master if new master is failed
      during full synchronization.
      cee3d67f
  4. 05 Aug, 2021 1 commit
    • yoav-steinberg's avatar
      dict struct memory optimizations (#9228) · 5e908a29
      yoav-steinberg authored
      Reduce dict struct memory overhead
      on 64bit dict size goes down from jemalloc's 96 byte bin to its 56 byte bin.
      
      summary of changes:
      - Remove `privdata` from callbacks and dict creation. (this affects many files, see "Interface change" below).
      - Meld `dictht` struct into the `dict` struct to eliminate struct padding. (this affects just dict.c and defrag.c)
      - Eliminate the `sizemask` field, can be calculated from size when needed.
      - Convert the `size` field into `size_exp` (exponent), utilizes one byte instead of 8.
      
      Interface change: pass dict pointer to dict type call back functions.
      This is instead of passing the removed privdata field. In the future if
      we'd like to have private data in the callbacks we can extract it from
      the dict type. We can extend dictType to include a custom dict struct
      allocator and use it to allocate more data at the end of the dict
      struct. This data can then be used to store private data later acccessed
      by the callbacks.
      5e908a29
  5. 02 Aug, 2021 1 commit
    • Binbin's avatar
      Modify some error logs printing level. (#9306) · 4000cb7d
      Binbin authored
      1. In sendBulkToSlave, we used LL_VERBOSE in the past, changed to
      LL_WARNING. (all the other places that do freeClient(slave) use LL_WARNING)
      2. The old style LOG_WARNING, chang it to LL_WARNING. Introduced in an
      old pr (#1690).
      4000cb7d
  6. 30 Jul, 2021 1 commit
  7. 06 Jul, 2021 1 commit
  8. 28 Jun, 2021 1 commit
    • Wang Yuan's avatar
      Remove unnecessary replication backlog memory copy (#9157) · 4fa3e230
      Wang Yuan authored
      in the past, the reply list was a list of sds objects, so this didn't have any overhead,
      but now addReplySds just copies the data from the sds and frees it, so there's no
      need to make a copy of the buffer before copying again.
      this reduces an excessive allocation and free and a memcpy.
      4fa3e230
  9. 24 Jun, 2021 1 commit
    • Yossi Gottlieb's avatar
      Add bind-source-addr configuration argument. (#9142) · f233c4c5
      Yossi Gottlieb authored
      In the past, the first bind address that was explicitly specified was
      also used to bind outgoing connections. This could result with some
      problems. For example: on some systems using `bind 127.0.0.1` would
      result with outgoing connections also binding to `127.0.0.1` and failing
      to connect to remote addresses.
      
      With the recent change to the way `bind` is handled, this presented
      other issues:
      
      * The default first bind address is '*' which is not a valid address.
      * We make no distinction between user-supplied config that is identical
      to the default, and the default config.
      
      This commit addresses both these issues by introducing an explicit
      configuration parameter to control the bind address on outgoing
      connections.
      f233c4c5
  10. 10 Jun, 2021 1 commit
    • Binbin's avatar
      Fixed some typos, add a spell check ci and others minor fix (#8890) · 0bfccc55
      Binbin authored
      This PR adds a spell checker CI action that will fail future PRs if they introduce typos and spelling mistakes.
      This spell checker is based on blacklist of common spelling mistakes, so it will not catch everything,
      but at least it is also unlikely to cause false positives.
      
      Besides that, the PR also fixes many spelling mistakes and types, not all are a result of the spell checker we use.
      
      Here's a summary of other changes:
      1. Scanned the entire source code and fixes all sorts of typos and spelling mistakes (including missing or extra spaces).
      2. Outdated function / variable / argument names in comments
      3. Fix outdated keyspace masks error log when we check `config.notify-keyspace-events` in loadServerConfigFromString.
      4. Trim the white space at the end of line in `module.c`. Check: https://github.com/redis/redis/pull/7751
      5. Some outdated https link URLs.
      6. Fix some outdated comment. Such as:
          - In README: about the rdb, we used to said create a `thread`, change to `process`
          - dbRandomKey function coment (about the dictGetRandomKey, change to dictGetFairRandomKey)
          - notifyKeyspaceEvent fucntion comment (add type arg)
          - Some others minor fix in comment (Most of them are incorrectly quoted by variable names)
      7. Modified the error log so that users can easily distinguish between TCP and TLS in `changeBindAddr`
      0bfccc55
  11. 02 Jun, 2021 1 commit
  12. 20 May, 2021 1 commit
  13. 19 May, 2021 1 commit
  14. 25 Apr, 2021 1 commit
  15. 19 Apr, 2021 1 commit
    • Wen Hui's avatar
      fix invalid master_link_down_since_seconds in info repication (#8785) · 0413fbc7
      Wen Hui authored
      When replica never successfully connect to master, server.repl_down_since
      will be initialized to 0, therefore, the info master_link_down_since_seconds
      was showing the current unix timestamp, which does not make much sense.
      
      This commit fixes the issue by showing master_link_down_since_seconds to -1.
      means the replica never connect to master before.
      
      This commit also resets this variable back to 0 when a replica is turned into
      a master, so that it'll behave the same if the master is later turned into a
      replica again.
      
      The implication of this change is that if some app is checking if the value is > 60
      do something, like conclude the replica is stale, this could case harm (changing
      a big positive number with a small one).
      0413fbc7
  16. 16 Apr, 2021 1 commit
  17. 15 Apr, 2021 1 commit
    • guybe7's avatar
      Add a timeout mechanism for replicas stuck in fullsync (#8762) · d63d0260
      guybe7 authored
      Starting redis 6.0 (part of the TLS feature), diskless master uses pipe from the fork
      child so that the parent is the one sending data to the replicas.
      This mechanism has an issue in which a hung replica will cause the master to wait
      for it to read the data sent to it forever, thus preventing the fork child from terminating
      and preventing the creations of any other forks.
      
      This PR adds a timeout mechanism, much like the ACK-based timeout,
      we disconnect replicas that aren't reading the RDB file fast enough.
      d63d0260
  18. 25 Mar, 2021 1 commit
  19. 14 Mar, 2021 2 commits
    • Huang Zhw's avatar
      Fix typo and outdated comments. (#8640) · 84d056d0
      Huang Zhw authored
      84d056d0
    • Guillem Jover's avatar
      Send the readiness notification when we are ready to accept connections (#8409) · 3a5905fa
      Guillem Jover authored
      On a replica we do accept connections, even though commands accessing
      the database will operate in read-only mode. But the server is still
      already operational and processing commands.
      
      Not sending the readiness notification means that on a HA setup where
      the nodes all start as replicas (with replicaof in the config) with
      a replica that cannot connect to the master server and which might not
      come back in a predictable amount of time or at all, the service
      supervisor will end up timing out the service and terminating it, with
      no option to promote it to be the main instance. This seems counter to
      what the readiness notification is supposed to be signaling.
      
      Instead send the readiness notification when we start accepting
      commands, and then send the various server status changes as that.
      
      Fixes: commit 641c64ad
      Fixes: commit dfb598cf
      3a5905fa
  20. 21 Feb, 2021 1 commit
  21. 09 Feb, 2021 1 commit
  22. 28 Jan, 2021 1 commit
  23. 27 Jan, 2021 1 commit
    • Wang Yuan's avatar
      Implement rdb-only replication (#8303) · ad7d4c6b
      Wang Yuan authored
      In some scenarios, such as remote backup, we only want to get remote
      redis server db snapshot. Currently, redis-cli acts as a replica and
      sends SYNC to redis, but redis still accumulates replication buffer
      in the replica client output buffer, that may result in using vast
      memory, or failing to transfer RDB because of client-output-buffer-limit.
      In this commit, we add 'replconf rdb-only 0|1', redis doesn't send
      incremental replication buffer to them if they send 'replconf rdb-only 1',
      so we can reduce used memory and improve success of getting RDB.
      ad7d4c6b
  24. 08 Jan, 2021 1 commit
  25. 07 Jan, 2021 1 commit
    • YaacovHazan's avatar
      Refactory fork child related infra, Unify child pid · f9dacf8a
      YaacovHazan authored
      This is a refactory commit, isn't suppose to have any actual impact.
      it does the following:
      - keep just one server struct fork child pid variable instead of 3
      - have one server struct variable indicating the purpose of the current fork
        child.
      - redisFork is now responsible of updating the server struct with the pid,
        which means it can be the one that calls updateDictResizePolicy
      - move child info pipe handling into redisFork instead of having them
        repeated outside
      - there are two classes of fork purposes, mutually exclusive group (AOF, RDB,
        Module), and one that can create several forks to coexist in parallel (LDB,
        but maybe Modules some day too, Module API allows for that).
      - minor fix to killRDBChild:
        unlike killAppendOnlyChild and TerminateModuleForkChild, the killRDBChild
        doesn't clear the pid variable or call wait4, so checkChildrenDone does
        the cleanup for it.
        This commit removes the explicit calls to rdbRemoveTempFile, closeChildInfoPipe,
        updateDictResizePolicy, which didn't do any harm, but where unnecessary.
      f9dacf8a
  26. 03 Jan, 2021 1 commit
    • Oran Agra's avatar
      Fix rare assertion as a result of: active defrag while loading (#8281) · 7896debe
      Oran Agra authored
      In #7726 (part of 6.2), we added a mechanism for whileBlockedCron, this
      mechanism has an assertion to make sure the timestamp in
      whileBlockedCron was always set correctly before the blocking operation
      starts.
      
      I now found (thanks to our CI) two bugs in that area:
      1) CONFIG RESETSTAT (if it was allowed during loading) would have
         cleared this var
      2) the call stopLoading (which calls whileBlockedCron) was made too
         early, while the rio is still in use, in which case the update_cksum
         (rdbLoadProgressCallback) may still be called and whileBlockedCron
         can assert.
      7896debe
  27. 24 Dec, 2020 4 commits
    • Oran Agra's avatar
      syncWithMaster: use pipeline for AUTH+REPLCONF*3 · e87c31de
      Oran Agra authored
      The commit deals with the syncWithMaster and the ugly state machine in it.
      It attempts to clean it a bit, but more importantly it uses pipeline for
      part of the work (rather than 7 round trips, we now have 4).
      i.e. the connect and PING are separate, then AUTH + 3 REPLCONF in one pipeline,
      and finally the PSYNC (must be separate since the master has to have an empty
      output buffer).
      e87c31de
    • Oran Agra's avatar
      syncWithMaster: sendSynchronousCommand split to send, and receive · 9bd212cf
      Oran Agra authored
      This is just a refactoring commit.
      
      This function was never actually used as a synchronous (do both send or
      receive), it was always used only ine one of the two modes, which meant it
      has to take extra arguments that are not relevant for the other.
      
      Besides that, a tool that sends a synchronous command, it not something
      we want in our toolbox (synchronous IO in single threaded app is evil).
      
      sendSynchronousCommand was now refactored into separate sending and
      receiving APIs, and the sending part has two variants, one taking vaargs,
      and the other taking argc+argv (and an optional length array which means
      you can use binary sds strings).
      9bd212cf
    • Madelyn Olson's avatar
      Cleanup key tracking documentation and table management (#8039) · 59ff42c4
      Madelyn Olson authored
      Cleanup key tracking documentation, always cleanup the tracking table, and free the tracking table in an async manner when applicable. 
      59ff42c4
    • Madelyn Olson's avatar
      Flow through the error handling path for most errors (#8226) · efaf09ee
      Madelyn Olson authored
      Properly throw errors for invalid replication stream and support https://github.com/redis/redis/pull/8217
      efaf09ee
  28. 17 Dec, 2020 1 commit
  29. 02 Dec, 2020 1 commit
    • Wang Yuan's avatar
      Backup keys to slots map and restore when fail to sync if diskless-load type... · b55a827e
      Wang Yuan authored
      
      Backup keys to slots map and restore when fail to sync if diskless-load type is swapdb in cluster mode (#8108)
      
      When replica diskless-load type is swapdb in cluster mode, we didn't backup
      keys to slots map, so we will lose keys to slots map if fail to sync.
      Now we backup keys to slots map at first, and restore it properly when fail.
      
      This commit includes a refactory/cleanup of the backups mechanism (moving it to db.c and re-structuring it a bit).
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      b55a827e
  30. 22 Nov, 2020 1 commit
    • Wang Yuan's avatar
      Fix diskless replication failure when has non-rdb child process (#8070) · f207e168
      Wang Yuan authored
      If we enable diskless replication, set repl-diskless-sync-delay to 0,
      and master has non-rdb child process such as rewrite aof child, master
      will try to start to a new BGSAVE but fails immediately (before fork)
      when replicas ask for full synchronization, and master always fails
      to start a new BGSAVE and disconnects with replicas until non-rdb
      child process exists.
      
      this bug was introduced in #6271 (not yet released in 6.0.x)
      f207e168
  31. 17 Nov, 2020 1 commit
    • Meir Shpilraien (Spielrein)'s avatar
      Unified MULTI, LUA, and RM_Call with respect to blocking commands (#8025) · d87a0d02
      Meir Shpilraien (Spielrein) authored
      
      
      Blocking command should not be used with MULTI, LUA, and RM_Call. This is because,
      the caller, who executes the command in this context, expects a reply.
      
      Today, LUA and MULTI have a special (and different) treatment to blocking commands:
      
      LUA   - Most commands are marked with no-script flag which are checked when executing
      and command from LUA, commands that are not marked (like XREAD) verify that their
      blocking mode is not used inside LUA (by checking the CLIENT_LUA client flag).
      MULTI - Command that is going to block, first verify that the client is not inside
      multi (by checking the CLIENT_MULTI client flag). If the client is inside multi, they
      return a result which is a match to the empty key with no timeout (for example blpop
      inside MULTI will act as lpop)
      For modules that perform RM_Call with blocking command, the returned results type is
      REDISMODULE_REPLY_UNKNOWN and the caller can not really know what happened.
      
      Disadvantages of the current state are:
      
      No unified approach, LUA, MULTI, and RM_Call, each has a different treatment
      Module can not safely execute blocking command (and get reply or error).
      Though It is true that modules are not like LUA or MULTI and should be smarter not
      to execute blocking commands on RM_Call, sometimes you want to execute a command base
      on client input (for example if you create a module that provides a new scripting
      language like javascript or python).
      While modules (on modules command) can check for REDISMODULE_CTX_FLAGS_LUA or
      REDISMODULE_CTX_FLAGS_MULTI to know not to block the client, there is no way to
      check if the command came from another module using RM_Call. So there is no way
      for a module to know not to block another module RM_Call execution.
      
      This commit adds a way to unify the treatment for blocking clients by introducing
      a new CLIENT_DENY_BLOCKING client flag. On LUA, MULTI, and RM_Call the new flag
      turned on to signify that the client should not be blocked. A blocking command
      verifies that the flag is turned off before blocking. If a blocking command sees
      that the CLIENT_DENY_BLOCKING flag is on, it's not blocking and return results
      which are matches to empty key with no timeout (as MULTI does today).
      
      The new flag is checked on the following commands:
      
      List blocking commands: BLPOP, BRPOP, BRPOPLPUSH, BLMOVE,
      Zset blocking commands: BZPOPMIN, BZPOPMAX
      Stream blocking commands: XREAD, XREADGROUP
      SUBSCRIBE, PSUBSCRIBE, MONITOR
      In addition, the new flag is turned on inside the AOF client, we do not want to
      block the AOF client to prevent deadlocks and commands ordering issues (and there
      is also an existing assert in the code that verifies it).
      
      To keep backward compatibility on LUA, all the no-script flags on existing commands
      were kept untouched. In addition, a LUA special treatment on XREAD and XREADGROUP was kept.
      
      To keep backward compatibility on MULTI (which today allows SUBSCRIBE, and PSUBSCRIBE).
      We added a special treatment on those commands to allow executing them on MULTI.
      
      The only backward compatibility issue that this PR introduces is that now MONITOR
      is not allowed inside MULTI.
      
      Tests were added to verify blocking commands are not blocking the client on LUA, MULTI,
      or RM_Call. Tests were added to verify the module can check for CLIENT_DENY_BLOCKING flag.
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      Co-authored-by: default avatarItamar Haber <itamar@redislabs.com>
      d87a0d02
  32. 28 Oct, 2020 1 commit
    • yoav-steinberg's avatar
      Add local address to CLIENT LIST, and a CLIENT KILL filter. (#7913) · 84b3c18f
      yoav-steinberg authored
      Useful when you want to know through which bind address the client connected to
      the server in case of multiple bind addresses.
      
      - Adding `laddr` field to CLIENT list showing the local (bind) address.
      - Adding `LADDR` option to CLIENT KILL to kill all the clients connected
        to a specific local address.
      - Refactoring to share code.
      84b3c18f
  33. 13 Oct, 2020 1 commit
    • Wang Yuan's avatar
      Remove temporary aof and rdb files in a background thread (#7905) · aaacb8c9
      Wang Yuan authored
      If we fail or stop to rewrite aof, we need to remove temporary aof.
      We also remove temporary rdb when replicas abort to receive rdb.
      But currently we delete them in main thread, to avoid blocking,
      we should use bg_unlink to remove them in a background thread.
      
      Btw, we have already used this way to removed child process temporary rdb.
      aaacb8c9
  34. 25 Sep, 2020 1 commit
    • WuYunlong's avatar
      Add fsync to readSyncBulkPayload(). (#7839) · 0d62caab
      WuYunlong authored
      We should sync temp DB file before renaming as rdb_fsync_range does not use
      flag `SYNC_FILE_RANGE_WAIT_AFTER`.
      
      Refer to `Linux Programmer's Manual`:
      SYNC_FILE_RANGE_WAIT_AFTER
          Wait upon write-out of all pages in the range after performing any write.
      0d62caab
  35. 22 Sep, 2020 1 commit
    • Yossi Gottlieb's avatar
      Fix occasional hangs on replication reconnection. (#7830) · 1980f639
      Yossi Gottlieb authored
      This happens only on diskless replicas when attempting to reconnect after 
      failing to load an RDB file. It is more likely to occur with larger datasets.
      
      After reconnection is initiated, replicationEmptyDbCallback() may get called 
      and try to write to an unconnected socket. This triggered another issue where
      the connection is put into an error state and the connect handler never gets
      called. The problem is a regression introduced by commit c17e597d.
      1980f639
  36. 17 Sep, 2020 1 commit
    • Wang Yuan's avatar
      Implement redisAtomic to replace _Atomic C11 builtin (#7707) · 445a4b66
      Wang Yuan authored
      Redis 6.0 introduces I/O threads, it is so cool and efficient, we use C11
      _Atomic to establish inter-thread synchronization without mutex. But the
      compiler that must supports C11 _Atomic can compile redis code, that brings a
      lot of inconvenience since some common platforms can't support by default such
      as CentOS7, so we want to implement redis atomic type to make it more portable.
      
      We have implemented our atomic variable for redis that only has 'relaxed'
      operations in src/atomicvar.h, so we implement some operations with
      'sequentially-consistent', just like the default behavior of C11 _Atomic that
      can establish inter-thread synchronization. And we replace all uses of C11
      _Atomic with redis atomic variable.
      
      Our implementation of redis atomic variable uses C11 _Atomic, __atomic or
      __sync macros if available, it supports most common platforms, and we will
      detect automatically which feature we use. In Makefile we use a dummy file to
      detect if the compiler supports C11 _Atomic. Now for gcc, we can compile redis
      code theoretically if your gcc version is not less than 4.1.2(starts to support
      __sync_xxx operations). Otherwise, we remove use mutex fallback to implement
      redis atomic variable for performance and test. You will get compiling errors
      if your compiler doesn't support all features of above.
      
      For cover redis atomic variable tests, we add other CI jobs that build redis on
      CentOS6 and CentOS7 and workflow daily jobs that run the tests on them.
      For them, we just install gcc by default in order to cover different compiler
      versions, gcc is 4.4.7 by default installation on CentOS6 and 4.8.5 on CentOS7.
      
      We restore the feature that we can test redis with Helgrind to find data race
      errors. But you need install Valgrind in the default path configuration firstly
      before running your tests, since we use macros in helgrind.h to tell Helgrind
      inter-thread happens-before relationship explicitly for avoiding false positives.
      Please open an issue on github if you find data race errors relate to this commit.
      
      Unrelated:
      - Fix redefinition of typedef 'RedisModuleUserChangedFunc'
        For some old version compilers, they will report errors or warnings, if we
        re-define function type.
      445a4b66