synced with antirez/redis/5.0.6
- disabled 2 tests in unit/maxmemory as they require different approach under Windows (slave process needs to be suspended)
This commit is contained in:
+471
-132
@@ -35,6 +35,14 @@
|
||||
# include /path/to/local.conf
|
||||
# include /path/to/other.conf
|
||||
|
||||
################################## MODULES #####################################
|
||||
|
||||
# Load modules at startup. If the server is not able to load modules
|
||||
# it will abort. It is possible to use multiple loadmodule directives.
|
||||
#
|
||||
# loadmodule /path/to/my_module.so
|
||||
# loadmodule /path/to/other_module.so
|
||||
|
||||
################################## NETWORK #####################################
|
||||
|
||||
# By default, if no "bind" configuration directive is specified, Redis listens
|
||||
@@ -51,7 +59,7 @@
|
||||
# internet, binding to all the interfaces is dangerous and will expose the
|
||||
# instance to everybody on the internet. So by default we uncomment the
|
||||
# following bind directive, that will force Redis to listen only into
|
||||
# the IPv4 lookback interface address (this means Redis will be able to
|
||||
# the IPv4 loopback interface address (this means Redis will be able to
|
||||
# accept connections only from clients running into the same computer it
|
||||
# is running).
|
||||
#
|
||||
@@ -177,6 +185,14 @@ logfile ""
|
||||
# dbid is a number between 0 and 'databases'-1
|
||||
databases 16
|
||||
|
||||
# By default Redis shows an ASCII art logo only when started to log to the
|
||||
# standard output and if the standard output is a TTY. Basically this means
|
||||
# that normally a logo is displayed only in interactive sessions.
|
||||
#
|
||||
# However it is possible to force the pre-4.0 behavior and always show a
|
||||
# ASCII art logo in startup logs by setting the following option to yes.
|
||||
always-show-logo yes
|
||||
|
||||
################################ SNAPSHOTTING ################################
|
||||
#
|
||||
# Save the DB on disk:
|
||||
@@ -248,57 +264,64 @@ dir ./
|
||||
|
||||
################################# REPLICATION #################################
|
||||
|
||||
# Master-Slave replication. Use slaveof to make a Redis instance a copy of
|
||||
# Master-Replica replication. Use replicaof to make a Redis instance a copy of
|
||||
# another Redis server. A few things to understand ASAP about Redis replication.
|
||||
#
|
||||
# +------------------+ +---------------+
|
||||
# | Master | ---> | Replica |
|
||||
# | (receive writes) | | (exact copy) |
|
||||
# +------------------+ +---------------+
|
||||
#
|
||||
# 1) Redis replication is asynchronous, but you can configure a master to
|
||||
# stop accepting writes if it appears to be not connected with at least
|
||||
# a given number of slaves.
|
||||
# 2) Redis slaves are able to perform a partial resynchronization with the
|
||||
# a given number of replicas.
|
||||
# 2) Redis replicas are able to perform a partial resynchronization with the
|
||||
# master if the replication link is lost for a relatively small amount of
|
||||
# time. You may want to configure the replication backlog size (see the next
|
||||
# sections of this file) with a sensible value depending on your needs.
|
||||
# 3) Replication is automatic and does not need user intervention. After a
|
||||
# network partition slaves automatically try to reconnect to masters
|
||||
# network partition replicas automatically try to reconnect to masters
|
||||
# and resynchronize with them.
|
||||
#
|
||||
# slaveof <masterip> <masterport>
|
||||
# replicaof <masterip> <masterport>
|
||||
|
||||
# If the master is password protected (using the "requirepass" configuration
|
||||
# directive below) it is possible to tell the slave to authenticate before
|
||||
# directive below) it is possible to tell the replica to authenticate before
|
||||
# starting the replication synchronization process, otherwise the master will
|
||||
# refuse the slave request.
|
||||
# refuse the replica request.
|
||||
#
|
||||
# masterauth <master-password>
|
||||
|
||||
# When a slave loses its connection with the master, or when the replication
|
||||
# is still in progress, the slave can act in two different ways:
|
||||
# When a replica loses its connection with the master, or when the replication
|
||||
# is still in progress, the replica can act in two different ways:
|
||||
#
|
||||
# 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will
|
||||
# 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will
|
||||
# still reply to client requests, possibly with out of date data, or the
|
||||
# data set may just be empty if this is the first synchronization.
|
||||
#
|
||||
# 2) if slave-serve-stale-data is set to 'no' the slave will reply with
|
||||
# 2) if replica-serve-stale-data is set to 'no' the replica will reply with
|
||||
# an error "SYNC with master in progress" to all the kind of commands
|
||||
# but to INFO and SLAVEOF.
|
||||
# but to INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG,
|
||||
# SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB,
|
||||
# COMMAND, POST, HOST: and LATENCY.
|
||||
#
|
||||
slave-serve-stale-data yes
|
||||
replica-serve-stale-data yes
|
||||
|
||||
# You can configure a slave instance to accept writes or not. Writing against
|
||||
# a slave instance may be useful to store some ephemeral data (because data
|
||||
# written on a slave will be easily deleted after resync with the master) but
|
||||
# You can configure a replica instance to accept writes or not. Writing against
|
||||
# a replica instance may be useful to store some ephemeral data (because data
|
||||
# written on a replica will be easily deleted after resync with the master) but
|
||||
# may also cause problems if clients are writing to it because of a
|
||||
# misconfiguration.
|
||||
#
|
||||
# Since Redis 2.6 by default slaves are read-only.
|
||||
# Since Redis 2.6 by default replicas are read-only.
|
||||
#
|
||||
# Note: read only slaves are not designed to be exposed to untrusted clients
|
||||
# Note: read only replicas are not designed to be exposed to untrusted clients
|
||||
# on the internet. It's just a protection layer against misuse of the instance.
|
||||
# Still a read only slave exports by default all the administrative commands
|
||||
# Still a read only replica exports by default all the administrative commands
|
||||
# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
|
||||
# security of read only slaves using 'rename-command' to shadow all the
|
||||
# security of read only replicas using 'rename-command' to shadow all the
|
||||
# administrative / dangerous commands.
|
||||
slave-read-only yes
|
||||
replica-read-only yes
|
||||
|
||||
# Replication SYNC strategy: disk or socket.
|
||||
#
|
||||
@@ -306,25 +329,25 @@ slave-read-only yes
|
||||
# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY
|
||||
# -------------------------------------------------------
|
||||
#
|
||||
# New slaves and reconnecting slaves that are not able to continue the replication
|
||||
# New replicas and reconnecting replicas that are not able to continue the replication
|
||||
# process just receiving differences, need to do what is called a "full
|
||||
# synchronization". An RDB file is transmitted from the master to the slaves.
|
||||
# synchronization". An RDB file is transmitted from the master to the replicas.
|
||||
# The transmission can happen in two different ways:
|
||||
#
|
||||
# 1) Disk-backed: The Redis master creates a new process that writes the RDB
|
||||
# file on disk. Later the file is transferred by the parent
|
||||
# process to the slaves incrementally.
|
||||
# process to the replicas incrementally.
|
||||
# 2) Diskless: The Redis master creates a new process that directly writes the
|
||||
# RDB file to slave sockets, without touching the disk at all.
|
||||
# RDB file to replica sockets, without touching the disk at all.
|
||||
#
|
||||
# With disk-backed replication, while the RDB file is generated, more slaves
|
||||
# With disk-backed replication, while the RDB file is generated, more replicas
|
||||
# can be queued and served with the RDB file as soon as the current child producing
|
||||
# the RDB file finishes its work. With diskless replication instead once
|
||||
# the transfer starts, new slaves arriving will be queued and a new transfer
|
||||
# the transfer starts, new replicas arriving will be queued and a new transfer
|
||||
# will start when the current one terminates.
|
||||
#
|
||||
# When diskless replication is used, the master waits a configurable amount of
|
||||
# time (in seconds) before starting the transfer in the hope that multiple slaves
|
||||
# time (in seconds) before starting the transfer in the hope that multiple replicas
|
||||
# will arrive and the transfer can be parallelized.
|
||||
#
|
||||
# With slow disks and fast (large bandwidth) networks, diskless replication
|
||||
@@ -333,107 +356,140 @@ repl-diskless-sync no
|
||||
|
||||
# When diskless replication is enabled, it is possible to configure the delay
|
||||
# the server waits in order to spawn the child that transfers the RDB via socket
|
||||
# to the slaves.
|
||||
# to the replicas.
|
||||
#
|
||||
# This is important since once the transfer starts, it is not possible to serve
|
||||
# new slaves arriving, that will be queued for the next RDB transfer, so the server
|
||||
# waits a delay in order to let more slaves arrive.
|
||||
# new replicas arriving, that will be queued for the next RDB transfer, so the server
|
||||
# waits a delay in order to let more replicas arrive.
|
||||
#
|
||||
# The delay is specified in seconds, and by default is 5 seconds. To disable
|
||||
# it entirely just set it to 0 seconds and the transfer will start ASAP.
|
||||
repl-diskless-sync-delay 5
|
||||
|
||||
# Slaves send PINGs to server in a predefined interval. It's possible to change
|
||||
# this interval with the repl_ping_slave_period option. The default value is 10
|
||||
# Replicas send PINGs to server in a predefined interval. It's possible to change
|
||||
# this interval with the repl_ping_replica_period option. The default value is 10
|
||||
# seconds.
|
||||
#
|
||||
# repl-ping-slave-period 10
|
||||
# repl-ping-replica-period 10
|
||||
|
||||
# The following option sets the replication timeout for:
|
||||
#
|
||||
# 1) Bulk transfer I/O during SYNC, from the point of view of slave.
|
||||
# 2) Master timeout from the point of view of slaves (data, pings).
|
||||
# 3) Slave timeout from the point of view of masters (REPLCONF ACK pings).
|
||||
# 1) Bulk transfer I/O during SYNC, from the point of view of replica.
|
||||
# 2) Master timeout from the point of view of replicas (data, pings).
|
||||
# 3) Replica timeout from the point of view of masters (REPLCONF ACK pings).
|
||||
#
|
||||
# It is important to make sure that this value is greater than the value
|
||||
# specified for repl-ping-slave-period otherwise a timeout will be detected
|
||||
# every time there is low traffic between the master and the slave.
|
||||
# specified for repl-ping-replica-period otherwise a timeout will be detected
|
||||
# every time there is low traffic between the master and the replica.
|
||||
#
|
||||
# repl-timeout 60
|
||||
|
||||
# Disable TCP_NODELAY on the slave socket after SYNC?
|
||||
# Disable TCP_NODELAY on the replica socket after SYNC?
|
||||
#
|
||||
# If you select "yes" Redis will use a smaller number of TCP packets and
|
||||
# less bandwidth to send data to slaves. But this can add a delay for
|
||||
# the data to appear on the slave side, up to 40 milliseconds with
|
||||
# less bandwidth to send data to replicas. But this can add a delay for
|
||||
# the data to appear on the replica side, up to 40 milliseconds with
|
||||
# Linux kernels using a default configuration.
|
||||
#
|
||||
# If you select "no" the delay for data to appear on the slave side will
|
||||
# If you select "no" the delay for data to appear on the replica side will
|
||||
# be reduced but more bandwidth will be used for replication.
|
||||
#
|
||||
# By default we optimize for low latency, but in very high traffic conditions
|
||||
# or when the master and slaves are many hops away, turning this to "yes" may
|
||||
# or when the master and replicas are many hops away, turning this to "yes" may
|
||||
# be a good idea.
|
||||
repl-disable-tcp-nodelay no
|
||||
|
||||
# Set the replication backlog size. The backlog is a buffer that accumulates
|
||||
# slave data when slaves are disconnected for some time, so that when a slave
|
||||
# replica data when replicas are disconnected for some time, so that when a replica
|
||||
# wants to reconnect again, often a full resync is not needed, but a partial
|
||||
# resync is enough, just passing the portion of data the slave missed while
|
||||
# resync is enough, just passing the portion of data the replica missed while
|
||||
# disconnected.
|
||||
#
|
||||
# The bigger the replication backlog, the longer the time the slave can be
|
||||
# The bigger the replication backlog, the longer the time the replica can be
|
||||
# disconnected and later be able to perform a partial resynchronization.
|
||||
#
|
||||
# The backlog is only allocated once there is at least a slave connected.
|
||||
# The backlog is only allocated once there is at least a replica connected.
|
||||
#
|
||||
# repl-backlog-size 1mb
|
||||
|
||||
# After a master has no longer connected slaves for some time, the backlog
|
||||
# After a master has no longer connected replicas for some time, the backlog
|
||||
# will be freed. The following option configures the amount of seconds that
|
||||
# need to elapse, starting from the time the last slave disconnected, for
|
||||
# need to elapse, starting from the time the last replica disconnected, for
|
||||
# the backlog buffer to be freed.
|
||||
#
|
||||
# Note that replicas never free the backlog for timeout, since they may be
|
||||
# promoted to masters later, and should be able to correctly "partially
|
||||
# resynchronize" with the replicas: hence they should always accumulate backlog.
|
||||
#
|
||||
# A value of 0 means to never release the backlog.
|
||||
#
|
||||
# repl-backlog-ttl 3600
|
||||
|
||||
# The slave priority is an integer number published by Redis in the INFO output.
|
||||
# It is used by Redis Sentinel in order to select a slave to promote into a
|
||||
# The replica priority is an integer number published by Redis in the INFO output.
|
||||
# It is used by Redis Sentinel in order to select a replica to promote into a
|
||||
# master if the master is no longer working correctly.
|
||||
#
|
||||
# A slave with a low priority number is considered better for promotion, so
|
||||
# for instance if there are three slaves with priority 10, 100, 25 Sentinel will
|
||||
# A replica with a low priority number is considered better for promotion, so
|
||||
# for instance if there are three replicas with priority 10, 100, 25 Sentinel will
|
||||
# pick the one with priority 10, that is the lowest.
|
||||
#
|
||||
# However a special priority of 0 marks the slave as not able to perform the
|
||||
# role of master, so a slave with priority of 0 will never be selected by
|
||||
# However a special priority of 0 marks the replica as not able to perform the
|
||||
# role of master, so a replica with priority of 0 will never be selected by
|
||||
# Redis Sentinel for promotion.
|
||||
#
|
||||
# By default the priority is 100.
|
||||
slave-priority 100
|
||||
replica-priority 100
|
||||
|
||||
# It is possible for a master to stop accepting writes if there are less than
|
||||
# N slaves connected, having a lag less or equal than M seconds.
|
||||
# N replicas connected, having a lag less or equal than M seconds.
|
||||
#
|
||||
# The N slaves need to be in "online" state.
|
||||
# The N replicas need to be in "online" state.
|
||||
#
|
||||
# The lag in seconds, that must be <= the specified value, is calculated from
|
||||
# the last ping received from the slave, that is usually sent every second.
|
||||
# the last ping received from the replica, that is usually sent every second.
|
||||
#
|
||||
# This option does not GUARANTEE that N replicas will accept the write, but
|
||||
# will limit the window of exposure for lost writes in case not enough slaves
|
||||
# will limit the window of exposure for lost writes in case not enough replicas
|
||||
# are available, to the specified number of seconds.
|
||||
#
|
||||
# For example to require at least 3 slaves with a lag <= 10 seconds use:
|
||||
# For example to require at least 3 replicas with a lag <= 10 seconds use:
|
||||
#
|
||||
# min-slaves-to-write 3
|
||||
# min-slaves-max-lag 10
|
||||
# min-replicas-to-write 3
|
||||
# min-replicas-max-lag 10
|
||||
#
|
||||
# Setting one or the other to 0 disables the feature.
|
||||
#
|
||||
# By default min-slaves-to-write is set to 0 (feature disabled) and
|
||||
# min-slaves-max-lag is set to 10.
|
||||
# By default min-replicas-to-write is set to 0 (feature disabled) and
|
||||
# min-replicas-max-lag is set to 10.
|
||||
|
||||
# A Redis master is able to list the address and port of the attached
|
||||
# replicas in different ways. For example the "INFO replication" section
|
||||
# offers this information, which is used, among other tools, by
|
||||
# Redis Sentinel in order to discover replica instances.
|
||||
# Another place where this info is available is in the output of the
|
||||
# "ROLE" command of a master.
|
||||
#
|
||||
# The listed IP and address normally reported by a replica is obtained
|
||||
# in the following way:
|
||||
#
|
||||
# IP: The address is auto detected by checking the peer address
|
||||
# of the socket used by the replica to connect with the master.
|
||||
#
|
||||
# Port: The port is communicated by the replica during the replication
|
||||
# handshake, and is normally the port that the replica is using to
|
||||
# listen for connections.
|
||||
#
|
||||
# However when port forwarding or Network Address Translation (NAT) is
|
||||
# used, the replica may be actually reachable via different IP and port
|
||||
# pairs. The following two options can be used by a replica in order to
|
||||
# report to its master a specific set of IP and port, so that both INFO
|
||||
# and ROLE will report those values.
|
||||
#
|
||||
# There is no need to use both the options if you need to override just
|
||||
# the port or the IP address.
|
||||
#
|
||||
# replica-announce-ip 5.5.5.5
|
||||
# replica-announce-port 1234
|
||||
|
||||
################################## SECURITY ###################################
|
||||
|
||||
@@ -467,9 +523,9 @@ slave-priority 100
|
||||
# rename-command CONFIG ""
|
||||
#
|
||||
# Please note that changing the name of commands that are logged into the
|
||||
# AOF file or transmitted to slaves may cause problems.
|
||||
# AOF file or transmitted to replicas may cause problems.
|
||||
|
||||
################################### LIMITS ####################################
|
||||
################################### CLIENTS ####################################
|
||||
|
||||
# Set the max number of connected clients at the same time. By default
|
||||
# this limit is set to 10000 clients, however if the Redis server is not
|
||||
@@ -482,7 +538,9 @@ slave-priority 100
|
||||
#
|
||||
# maxclients 10000
|
||||
|
||||
# Don't use more memory than the specified amount of bytes.
|
||||
############################## MEMORY MANAGEMENT ################################
|
||||
|
||||
# Set a memory usage limit to the specified amount of bytes.
|
||||
# When the memory limit is reached Redis will try to remove keys
|
||||
# according to the eviction policy selected (see maxmemory-policy).
|
||||
#
|
||||
@@ -491,18 +549,18 @@ slave-priority 100
|
||||
# that would use more memory, like SET, LPUSH, and so on, and will continue
|
||||
# to reply to read-only commands like GET.
|
||||
#
|
||||
# This option is usually useful when using Redis as an LRU cache, or to set
|
||||
# a hard memory limit for an instance (using the 'noeviction' policy).
|
||||
# This option is usually useful when using Redis as an LRU or LFU cache, or to
|
||||
# set a hard memory limit for an instance (using the 'noeviction' policy).
|
||||
#
|
||||
# WARNING: If you have slaves attached to an instance with maxmemory on,
|
||||
# the size of the output buffers needed to feed the slaves are subtracted
|
||||
# WARNING: If you have replicas attached to an instance with maxmemory on,
|
||||
# the size of the output buffers needed to feed the replicas are subtracted
|
||||
# from the used memory count, so that network problems / resyncs will
|
||||
# not trigger a loop where keys are evicted, and in turn the output
|
||||
# buffer of slaves is full with DELs of keys evicted triggering the deletion
|
||||
# buffer of replicas is full with DELs of keys evicted triggering the deletion
|
||||
# of more keys, and so forth until the database is completely emptied.
|
||||
#
|
||||
# In short... if you have slaves attached it is suggested that you set a lower
|
||||
# limit for maxmemory so that there is some free RAM on the system for slave
|
||||
# In short... if you have replicas attached it is suggested that you set a lower
|
||||
# limit for maxmemory so that there is some free RAM on the system for replica
|
||||
# output buffers (but this is not needed if the policy is 'noeviction').
|
||||
#
|
||||
# maxmemory <bytes>
|
||||
@@ -510,12 +568,20 @@ slave-priority 100
|
||||
# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
|
||||
# is reached. You can select among five behaviors:
|
||||
#
|
||||
# volatile-lru -> remove the key with an expire set using an LRU algorithm
|
||||
# allkeys-lru -> remove any key according to the LRU algorithm
|
||||
# volatile-random -> remove a random key with an expire set
|
||||
# allkeys-random -> remove a random key, any key
|
||||
# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
|
||||
# noeviction -> don't expire at all, just return an error on write operations
|
||||
# volatile-lru -> Evict using approximated LRU among the keys with an expire set.
|
||||
# allkeys-lru -> Evict any key using approximated LRU.
|
||||
# volatile-lfu -> Evict using approximated LFU among the keys with an expire set.
|
||||
# allkeys-lfu -> Evict any key using approximated LFU.
|
||||
# volatile-random -> Remove a random key among the ones with an expire set.
|
||||
# allkeys-random -> Remove a random key, any key.
|
||||
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
|
||||
# noeviction -> Don't evict anything, just return an error on write operations.
|
||||
#
|
||||
# LRU means Least Recently Used
|
||||
# LFU means Least Frequently Used
|
||||
#
|
||||
# Both LRU, LFU and volatile-ttl are implemented using approximated
|
||||
# randomized algorithms.
|
||||
#
|
||||
# Note: with any of the above policies, Redis will return an error on write
|
||||
# operations, when there are no suitable keys for eviction.
|
||||
@@ -530,17 +596,86 @@ slave-priority 100
|
||||
#
|
||||
# maxmemory-policy noeviction
|
||||
|
||||
# LRU and minimal TTL algorithms are not precise algorithms but approximated
|
||||
# LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated
|
||||
# algorithms (in order to save memory), so you can tune it for speed or
|
||||
# accuracy. For default Redis will check five keys and pick the one that was
|
||||
# used less recently, you can change the sample size using the following
|
||||
# configuration directive.
|
||||
#
|
||||
# The default of 5 produces good enough results. 10 Approximates very closely
|
||||
# true LRU but costs a bit more CPU. 3 is very fast but not very accurate.
|
||||
# true LRU but costs more CPU. 3 is faster but not very accurate.
|
||||
#
|
||||
# maxmemory-samples 5
|
||||
|
||||
# Starting from Redis 5, by default a replica will ignore its maxmemory setting
|
||||
# (unless it is promoted to master after a failover or manually). It means
|
||||
# that the eviction of keys will be just handled by the master, sending the
|
||||
# DEL commands to the replica as keys evict in the master side.
|
||||
#
|
||||
# This behavior ensures that masters and replicas stay consistent, and is usually
|
||||
# what you want, however if your replica is writable, or you want the replica to have
|
||||
# a different memory setting, and you are sure all the writes performed to the
|
||||
# replica are idempotent, then you may change this default (but be sure to understand
|
||||
# what you are doing).
|
||||
#
|
||||
# Note that since the replica by default does not evict, it may end using more
|
||||
# memory than the one set via maxmemory (there are certain buffers that may
|
||||
# be larger on the replica, or data structures may sometimes take more memory and so
|
||||
# forth). So make sure you monitor your replicas and make sure they have enough
|
||||
# memory to never hit a real out-of-memory condition before the master hits
|
||||
# the configured maxmemory setting.
|
||||
#
|
||||
# replica-ignore-maxmemory yes
|
||||
|
||||
############################# LAZY FREEING ####################################
|
||||
|
||||
# Redis has two primitives to delete keys. One is called DEL and is a blocking
|
||||
# deletion of the object. It means that the server stops processing new commands
|
||||
# in order to reclaim all the memory associated with an object in a synchronous
|
||||
# way. If the key deleted is associated with a small object, the time needed
|
||||
# in order to execute the DEL command is very small and comparable to most other
|
||||
# O(1) or O(log_N) commands in Redis. However if the key is associated with an
|
||||
# aggregated value containing millions of elements, the server can block for
|
||||
# a long time (even seconds) in order to complete the operation.
|
||||
#
|
||||
# For the above reasons Redis also offers non blocking deletion primitives
|
||||
# such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and
|
||||
# FLUSHDB commands, in order to reclaim memory in background. Those commands
|
||||
# are executed in constant time. Another thread will incrementally free the
|
||||
# object in the background as fast as possible.
|
||||
#
|
||||
# DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled.
|
||||
# It's up to the design of the application to understand when it is a good
|
||||
# idea to use one or the other. However the Redis server sometimes has to
|
||||
# delete keys or flush the whole database as a side effect of other operations.
|
||||
# Specifically Redis deletes objects independently of a user call in the
|
||||
# following scenarios:
|
||||
#
|
||||
# 1) On eviction, because of the maxmemory and maxmemory policy configurations,
|
||||
# in order to make room for new data, without going over the specified
|
||||
# memory limit.
|
||||
# 2) Because of expire: when a key with an associated time to live (see the
|
||||
# EXPIRE command) must be deleted from memory.
|
||||
# 3) Because of a side effect of a command that stores data on a key that may
|
||||
# already exist. For example the RENAME command may delete the old key
|
||||
# content when it is replaced with another one. Similarly SUNIONSTORE
|
||||
# or SORT with STORE option may delete existing keys. The SET command
|
||||
# itself removes any old content of the specified key in order to replace
|
||||
# it with the specified string.
|
||||
# 4) During replication, when a replica performs a full resynchronization with
|
||||
# its master, the content of the whole database is removed in order to
|
||||
# load the RDB file just transferred.
|
||||
#
|
||||
# In all the above cases the default is to delete objects in a blocking way,
|
||||
# like if DEL was called. However you can configure each case specifically
|
||||
# in order to instead release memory in a non-blocking way like if UNLINK
|
||||
# was called, using the following configuration directives:
|
||||
|
||||
lazyfree-lazy-eviction no
|
||||
lazyfree-lazy-expire no
|
||||
lazyfree-lazy-server-del no
|
||||
replica-lazy-flush no
|
||||
|
||||
############################## APPEND ONLY MODE ###############################
|
||||
|
||||
# By default Redis asynchronously dumps the dataset on disk. This mode is
|
||||
@@ -659,6 +794,17 @@ auto-aof-rewrite-min-size 64mb
|
||||
# will be found.
|
||||
aof-load-truncated yes
|
||||
|
||||
# When rewriting the AOF file, Redis is able to use an RDB preamble in the
|
||||
# AOF file for faster rewrites and recoveries. When this option is turned
|
||||
# on the rewritten AOF file is composed of two different stanzas:
|
||||
#
|
||||
# [RDB file][AOF tail]
|
||||
#
|
||||
# When loading Redis recognizes that the AOF file starts with the "REDIS"
|
||||
# string and loads the prefixed RDB file, and continues loading the AOF
|
||||
# tail.
|
||||
aof-use-rdb-preamble yes
|
||||
|
||||
################################ LUA SCRIPTING ###############################
|
||||
|
||||
# Max execution time of a Lua script in milliseconds.
|
||||
@@ -678,13 +824,7 @@ aof-load-truncated yes
|
||||
lua-time-limit 5000
|
||||
|
||||
################################ REDIS CLUSTER ###############################
|
||||
#
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
# WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however
|
||||
# in order to mark it as "mature" we need to wait for a non trivial percentage
|
||||
# of users to deploy it in production.
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
#
|
||||
|
||||
# Normal Redis instances can't be part of a Redis Cluster; only nodes that are
|
||||
# started as cluster nodes can. In order to start a Redis instance as a
|
||||
# cluster node enable the cluster support uncommenting the following:
|
||||
@@ -705,42 +845,42 @@ lua-time-limit 5000
|
||||
#
|
||||
# cluster-node-timeout 15000
|
||||
|
||||
# A slave of a failing master will avoid to start a failover if its data
|
||||
# A replica of a failing master will avoid to start a failover if its data
|
||||
# looks too old.
|
||||
#
|
||||
# There is no simple way for a slave to actually have a exact measure of
|
||||
# There is no simple way for a replica to actually have an exact measure of
|
||||
# its "data age", so the following two checks are performed:
|
||||
#
|
||||
# 1) If there are multiple slaves able to failover, they exchange messages
|
||||
# in order to try to give an advantage to the slave with the best
|
||||
# 1) If there are multiple replicas able to failover, they exchange messages
|
||||
# in order to try to give an advantage to the replica with the best
|
||||
# replication offset (more data from the master processed).
|
||||
# Slaves will try to get their rank by offset, and apply to the start
|
||||
# Replicas will try to get their rank by offset, and apply to the start
|
||||
# of the failover a delay proportional to their rank.
|
||||
#
|
||||
# 2) Every single slave computes the time of the last interaction with
|
||||
# 2) Every single replica computes the time of the last interaction with
|
||||
# its master. This can be the last ping or command received (if the master
|
||||
# is still in the "connected" state), or the time that elapsed since the
|
||||
# disconnection with the master (if the replication link is currently down).
|
||||
# If the last interaction is too old, the slave will not try to failover
|
||||
# If the last interaction is too old, the replica will not try to failover
|
||||
# at all.
|
||||
#
|
||||
# The point "2" can be tuned by user. Specifically a slave will not perform
|
||||
# The point "2" can be tuned by user. Specifically a replica will not perform
|
||||
# the failover if, since the last interaction with the master, the time
|
||||
# elapsed is greater than:
|
||||
#
|
||||
# (node-timeout * slave-validity-factor) + repl-ping-slave-period
|
||||
# (node-timeout * replica-validity-factor) + repl-ping-replica-period
|
||||
#
|
||||
# So for example if node-timeout is 30 seconds, and the slave-validity-factor
|
||||
# is 10, and assuming a default repl-ping-slave-period of 10 seconds, the
|
||||
# slave will not try to failover if it was not able to talk with the master
|
||||
# So for example if node-timeout is 30 seconds, and the replica-validity-factor
|
||||
# is 10, and assuming a default repl-ping-replica-period of 10 seconds, the
|
||||
# replica will not try to failover if it was not able to talk with the master
|
||||
# for longer than 310 seconds.
|
||||
#
|
||||
# A large slave-validity-factor may allow slaves with too old data to failover
|
||||
# A large replica-validity-factor may allow replicas with too old data to failover
|
||||
# a master, while a too small value may prevent the cluster from being able to
|
||||
# elect a slave at all.
|
||||
# elect a replica at all.
|
||||
#
|
||||
# For maximum availability, it is possible to set the slave-validity-factor
|
||||
# to a value of 0, which means, that slaves will always try to failover the
|
||||
# For maximum availability, it is possible to set the replica-validity-factor
|
||||
# to a value of 0, which means, that replicas will always try to failover the
|
||||
# master regardless of the last time they interacted with the master.
|
||||
# (However they'll always try to apply a delay proportional to their
|
||||
# offset rank).
|
||||
@@ -748,22 +888,22 @@ lua-time-limit 5000
|
||||
# Zero is the only value able to guarantee that when all the partitions heal
|
||||
# the cluster will always be able to continue.
|
||||
#
|
||||
# cluster-slave-validity-factor 10
|
||||
# cluster-replica-validity-factor 10
|
||||
|
||||
# Cluster slaves are able to migrate to orphaned masters, that are masters
|
||||
# that are left without working slaves. This improves the cluster ability
|
||||
# Cluster replicas are able to migrate to orphaned masters, that are masters
|
||||
# that are left without working replicas. This improves the cluster ability
|
||||
# to resist to failures as otherwise an orphaned master can't be failed over
|
||||
# in case of failure if it has no working slaves.
|
||||
# in case of failure if it has no working replicas.
|
||||
#
|
||||
# Slaves migrate to orphaned masters only if there are still at least a
|
||||
# given number of other working slaves for their old master. This number
|
||||
# is the "migration barrier". A migration barrier of 1 means that a slave
|
||||
# will migrate only if there is at least 1 other working slave for its master
|
||||
# and so forth. It usually reflects the number of slaves you want for every
|
||||
# Replicas migrate to orphaned masters only if there are still at least a
|
||||
# given number of other working replicas for their old master. This number
|
||||
# is the "migration barrier". A migration barrier of 1 means that a replica
|
||||
# will migrate only if there is at least 1 other working replica for its master
|
||||
# and so forth. It usually reflects the number of replicas you want for every
|
||||
# master in your cluster.
|
||||
#
|
||||
# Default is 1 (slaves migrate only if their masters remain with at least
|
||||
# one slave). To disable migration just set it to a very large value.
|
||||
# Default is 1 (replicas migrate only if their masters remain with at least
|
||||
# one replica). To disable migration just set it to a very large value.
|
||||
# A value of 0 can be set but is useful only for debugging and dangerous
|
||||
# in production.
|
||||
#
|
||||
@@ -782,9 +922,52 @@ lua-time-limit 5000
|
||||
#
|
||||
# cluster-require-full-coverage yes
|
||||
|
||||
# This option, when set to yes, prevents replicas from trying to failover its
|
||||
# master during master failures. However the master can still perform a
|
||||
# manual failover, if forced to do so.
|
||||
#
|
||||
# This is useful in different scenarios, especially in the case of multiple
|
||||
# data center operations, where we want one side to never be promoted if not
|
||||
# in the case of a total DC failure.
|
||||
#
|
||||
# cluster-replica-no-failover no
|
||||
|
||||
# In order to setup your cluster make sure to read the documentation
|
||||
# available at http://redis.io web site.
|
||||
|
||||
########################## CLUSTER DOCKER/NAT support ########################
|
||||
|
||||
# In certain deployments, Redis Cluster nodes address discovery fails, because
|
||||
# addresses are NAT-ted or because ports are forwarded (the typical case is
|
||||
# Docker and other containers).
|
||||
#
|
||||
# In order to make Redis Cluster working in such environments, a static
|
||||
# configuration where each node knows its public address is needed. The
|
||||
# following two options are used for this scope, and are:
|
||||
#
|
||||
# * cluster-announce-ip
|
||||
# * cluster-announce-port
|
||||
# * cluster-announce-bus-port
|
||||
#
|
||||
# Each instruct the node about its address, client port, and cluster message
|
||||
# bus port. The information is then published in the header of the bus packets
|
||||
# so that other nodes will be able to correctly map the address of the node
|
||||
# publishing the information.
|
||||
#
|
||||
# If the above options are not used, the normal Redis Cluster auto-detection
|
||||
# will be used instead.
|
||||
#
|
||||
# Note that when remapped, the bus port may not be at the fixed offset of
|
||||
# clients port + 10000, so you can specify any port and bus-port depending
|
||||
# on how they get remapped. If the bus-port is not set, a fixed offset of
|
||||
# 10000 will be used as usually.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# cluster-announce-ip 10.1.1.5
|
||||
# cluster-announce-port 6379
|
||||
# cluster-announce-bus-port 6380
|
||||
|
||||
################################## SLOW LOG ###################################
|
||||
|
||||
# The Redis Slow Log is a system to log queries that exceeded a specified
|
||||
@@ -942,6 +1125,17 @@ zset-max-ziplist-value 64
|
||||
# composed of many HyperLogLogs with cardinality in the 0 - 15000 range.
|
||||
hll-sparse-max-bytes 3000
|
||||
|
||||
# Streams macro node max size / items. The stream data structure is a radix
|
||||
# tree of big nodes that encode multiple items inside. Using this configuration
|
||||
# it is possible to configure how big a single node can be in bytes, and the
|
||||
# maximum number of items it may contain before switching to a new node when
|
||||
# appending new stream entries. If any of the following settings are set to
|
||||
# zero, the limit is ignored, so for instance it is possible to set just a
|
||||
# max entires limit by setting max-bytes to 0 and max-entries to the desired
|
||||
# value.
|
||||
stream-node-max-bytes 4096
|
||||
stream-node-max-entries 100
|
||||
|
||||
# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in
|
||||
# order to help rehashing the main Redis hash table (the one mapping top-level
|
||||
# keys to values). The hash table implementation Redis uses (see dict.c)
|
||||
@@ -970,7 +1164,7 @@ activerehashing yes
|
||||
# The limit can be set differently for the three different classes of clients:
|
||||
#
|
||||
# normal -> normal clients including MONITOR clients
|
||||
# slave -> slave clients
|
||||
# replica -> replica clients
|
||||
# pubsub -> clients subscribed to at least one pubsub channel or pattern
|
||||
#
|
||||
# The syntax of every client-output-buffer-limit directive is the following:
|
||||
@@ -991,19 +1185,33 @@ activerehashing yes
|
||||
# asynchronous clients may create a scenario where data is requested faster
|
||||
# than it can read.
|
||||
#
|
||||
# Instead there is a default limit for pubsub and slave clients, since
|
||||
# subscribers and slaves receive data in a push fashion.
|
||||
# Instead there is a default limit for pubsub and replica clients, since
|
||||
# subscribers and replicas receive data in a push fashion.
|
||||
#
|
||||
# Both the hard or the soft limit can be disabled by setting them to zero.
|
||||
client-output-buffer-limit normal 0 0 0
|
||||
client-output-buffer-limit slave 256mb 64mb 60
|
||||
client-output-buffer-limit replica 256mb 64mb 60
|
||||
client-output-buffer-limit pubsub 32mb 8mb 60
|
||||
|
||||
# Client query buffers accumulate new commands. They are limited to a fixed
|
||||
# amount by default in order to avoid that a protocol desynchronization (for
|
||||
# instance due to a bug in the client) will lead to unbound memory usage in
|
||||
# the query buffer. However you can configure it here if you have very special
|
||||
# needs, such us huge multi/exec requests or alike.
|
||||
#
|
||||
# client-query-buffer-limit 1gb
|
||||
|
||||
# In the Redis protocol, bulk requests, that are, elements representing single
|
||||
# strings, are normally limited ot 512 mb. However you can change this limit
|
||||
# here.
|
||||
#
|
||||
# proto-max-bulk-len 512mb
|
||||
|
||||
# Redis calls an internal function to perform many background tasks, like
|
||||
# closing connections of clients in timeot, purging expired keys that are
|
||||
# closing connections of clients in timeout, purging expired keys that are
|
||||
# never requested, and so forth.
|
||||
#
|
||||
# Not all tasks are perforemd with the same frequency, but Redis checks for
|
||||
# Not all tasks are performed with the same frequency, but Redis checks for
|
||||
# tasks to perform according to the specified "hz" value.
|
||||
#
|
||||
# By default "hz" is set to 10. Raising the value will use more CPU when
|
||||
@@ -1016,18 +1224,149 @@ client-output-buffer-limit pubsub 32mb 8mb 60
|
||||
# 100 only in environments where very low latency is required.
|
||||
hz 10
|
||||
|
||||
# Normally it is useful to have an HZ value which is proportional to the
|
||||
# number of clients connected. This is useful in order, for instance, to
|
||||
# avoid too many clients are processed for each background task invocation
|
||||
# in order to avoid latency spikes.
|
||||
#
|
||||
# Since the default HZ value by default is conservatively set to 10, Redis
|
||||
# offers, and enables by default, the ability to use an adaptive HZ value
|
||||
# which will temporary raise when there are many connected clients.
|
||||
#
|
||||
# When dynamic HZ is enabled, the actual configured HZ will be used as
|
||||
# as a baseline, but multiples of the configured HZ value will be actually
|
||||
# used as needed once more clients are connected. In this way an idle
|
||||
# instance will use very little CPU time while a busy instance will be
|
||||
# more responsive.
|
||||
dynamic-hz yes
|
||||
|
||||
# When a child rewrites the AOF file, if the following option is enabled
|
||||
# the file will be fsync-ed every 32 MB of data generated. This is useful
|
||||
# in order to commit the file to the disk more incrementally and avoid
|
||||
# big latency spikes.
|
||||
aof-rewrite-incremental-fsync yes
|
||||
|
||||
################################## INCLUDES ###################################
|
||||
# When redis saves RDB file, if the following option is enabled
|
||||
# the file will be fsync-ed every 32 MB of data generated. This is useful
|
||||
# in order to commit the file to the disk more incrementally and avoid
|
||||
# big latency spikes.
|
||||
rdb-save-incremental-fsync yes
|
||||
|
||||
# Include one or more other config files here. This is useful if you
|
||||
# have a standard template that goes to all Redis server but also need
|
||||
# to customize a few per-server settings. Include files can include
|
||||
# other files, so use this wisely.
|
||||
# Redis LFU eviction (see maxmemory setting) can be tuned. However it is a good
|
||||
# idea to start with the default settings and only change them after investigating
|
||||
# how to improve the performances and how the keys LFU change over time, which
|
||||
# is possible to inspect via the OBJECT FREQ command.
|
||||
#
|
||||
# include /path/to/local.conf
|
||||
# include /path/to/other.conf
|
||||
# There are two tunable parameters in the Redis LFU implementation: the
|
||||
# counter logarithm factor and the counter decay time. It is important to
|
||||
# understand what the two parameters mean before changing them.
|
||||
#
|
||||
# The LFU counter is just 8 bits per key, it's maximum value is 255, so Redis
|
||||
# uses a probabilistic increment with logarithmic behavior. Given the value
|
||||
# of the old counter, when a key is accessed, the counter is incremented in
|
||||
# this way:
|
||||
#
|
||||
# 1. A random number R between 0 and 1 is extracted.
|
||||
# 2. A probability P is calculated as 1/(old_value*lfu_log_factor+1).
|
||||
# 3. The counter is incremented only if R < P.
|
||||
#
|
||||
# The default lfu-log-factor is 10. This is a table of how the frequency
|
||||
# counter changes with a different number of accesses with different
|
||||
# logarithmic factors:
|
||||
#
|
||||
# +--------+------------+------------+------------+------------+------------+
|
||||
# | factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits |
|
||||
# +--------+------------+------------+------------+------------+------------+
|
||||
# | 0 | 104 | 255 | 255 | 255 | 255 |
|
||||
# +--------+------------+------------+------------+------------+------------+
|
||||
# | 1 | 18 | 49 | 255 | 255 | 255 |
|
||||
# +--------+------------+------------+------------+------------+------------+
|
||||
# | 10 | 10 | 18 | 142 | 255 | 255 |
|
||||
# +--------+------------+------------+------------+------------+------------+
|
||||
# | 100 | 8 | 11 | 49 | 143 | 255 |
|
||||
# +--------+------------+------------+------------+------------+------------+
|
||||
#
|
||||
# NOTE: The above table was obtained by running the following commands:
|
||||
#
|
||||
# redis-benchmark -n 1000000 incr foo
|
||||
# redis-cli object freq foo
|
||||
#
|
||||
# NOTE 2: The counter initial value is 5 in order to give new objects a chance
|
||||
# to accumulate hits.
|
||||
#
|
||||
# The counter decay time is the time, in minutes, that must elapse in order
|
||||
# for the key counter to be divided by two (or decremented if it has a value
|
||||
# less <= 10).
|
||||
#
|
||||
# The default value for the lfu-decay-time is 1. A Special value of 0 means to
|
||||
# decay the counter every time it happens to be scanned.
|
||||
#
|
||||
# lfu-log-factor 10
|
||||
# lfu-decay-time 1
|
||||
|
||||
########################### ACTIVE DEFRAGMENTATION #######################
|
||||
#
|
||||
# WARNING THIS FEATURE IS EXPERIMENTAL. However it was stress tested
|
||||
# even in production and manually tested by multiple engineers for some
|
||||
# time.
|
||||
#
|
||||
# What is active defragmentation?
|
||||
# -------------------------------
|
||||
#
|
||||
# Active (online) defragmentation allows a Redis server to compact the
|
||||
# spaces left between small allocations and deallocations of data in memory,
|
||||
# thus allowing to reclaim back memory.
|
||||
#
|
||||
# Fragmentation is a natural process that happens with every allocator (but
|
||||
# less so with Jemalloc, fortunately) and certain workloads. Normally a server
|
||||
# restart is needed in order to lower the fragmentation, or at least to flush
|
||||
# away all the data and create it again. However thanks to this feature
|
||||
# implemented by Oran Agra for Redis 4.0 this process can happen at runtime
|
||||
# in an "hot" way, while the server is running.
|
||||
#
|
||||
# Basically when the fragmentation is over a certain level (see the
|
||||
# configuration options below) Redis will start to create new copies of the
|
||||
# values in contiguous memory regions by exploiting certain specific Jemalloc
|
||||
# features (in order to understand if an allocation is causing fragmentation
|
||||
# and to allocate it in a better place), and at the same time, will release the
|
||||
# old copies of the data. This process, repeated incrementally for all the keys
|
||||
# will cause the fragmentation to drop back to normal values.
|
||||
#
|
||||
# Important things to understand:
|
||||
#
|
||||
# 1. This feature is disabled by default, and only works if you compiled Redis
|
||||
# to use the copy of Jemalloc we ship with the source code of Redis.
|
||||
# This is the default with Linux builds.
|
||||
#
|
||||
# 2. You never need to enable this feature if you don't have fragmentation
|
||||
# issues.
|
||||
#
|
||||
# 3. Once you experience fragmentation, you can enable this feature when
|
||||
# needed with the command "CONFIG SET activedefrag yes".
|
||||
#
|
||||
# The configuration parameters are able to fine tune the behavior of the
|
||||
# defragmentation process. If you are not sure about what they mean it is
|
||||
# a good idea to leave the defaults untouched.
|
||||
|
||||
# Enabled active defragmentation
|
||||
# activedefrag yes
|
||||
|
||||
# Minimum amount of fragmentation waste to start active defrag
|
||||
# active-defrag-ignore-bytes 100mb
|
||||
|
||||
# Minimum percentage of fragmentation to start active defrag
|
||||
# active-defrag-threshold-lower 10
|
||||
|
||||
# Maximum percentage of fragmentation at which we use maximum effort
|
||||
# active-defrag-threshold-upper 100
|
||||
|
||||
# Minimal effort for defrag in CPU percentage
|
||||
# active-defrag-cycle-min 5
|
||||
|
||||
# Maximal effort for defrag in CPU percentage
|
||||
# active-defrag-cycle-max 75
|
||||
|
||||
# Maximum number of set/hash/zset/list fields that will be processed from
|
||||
# the main dictionary scan
|
||||
# active-defrag-max-scan-fields 1000
|
||||
|
||||
|
||||
@@ -11,4 +11,4 @@ then
|
||||
echo "You need tcl 8.5 or newer in order to run the Redis test"
|
||||
exit 1
|
||||
fi
|
||||
$TCLSH tests/test_helper.tcl $*
|
||||
$TCLSH tests/test_helper.tcl "${@}"
|
||||
|
||||
+74
-19
@@ -1,9 +1,40 @@
|
||||
# Example sentinel.conf
|
||||
|
||||
# *** IMPORTANT ***
|
||||
#
|
||||
# By default Sentinel will not be reachable from interfaces different than
|
||||
# localhost, either use the 'bind' directive to bind to a list of network
|
||||
# interfaces, or disable protected mode with "protected-mode no" by
|
||||
# adding it to this configuration file.
|
||||
#
|
||||
# Before doing that MAKE SURE the instance is protected from the outside
|
||||
# world via firewalling or other means.
|
||||
#
|
||||
# For example you may use one of the following:
|
||||
#
|
||||
# bind 127.0.0.1 192.168.1.1
|
||||
#
|
||||
# protected-mode no
|
||||
|
||||
# port <sentinel-port>
|
||||
# The port that this sentinel instance will run on
|
||||
port 26379
|
||||
|
||||
# By default Redis Sentinel does not run as a daemon. Use 'yes' if you need it.
|
||||
# Note that Redis will write a pid file in /var/run/redis-sentinel.pid when
|
||||
# daemonized.
|
||||
daemonize no
|
||||
|
||||
# When running daemonized, Redis Sentinel writes a pid file in
|
||||
# /var/run/redis-sentinel.pid by default. You can specify a custom pid file
|
||||
# location here.
|
||||
pidfile /var/run/redis-sentinel.pid
|
||||
|
||||
# Specify the log file name. Also the empty string can be used to force
|
||||
# Sentinel to log on the standard output. Note that if you use standard
|
||||
# output for logging but daemonize, logs will be sent to /dev/null
|
||||
logfile ""
|
||||
|
||||
# sentinel announce-ip <ip>
|
||||
# sentinel announce-port <port>
|
||||
#
|
||||
@@ -42,11 +73,11 @@ dir /tmp
|
||||
# be elected by the majority of the known Sentinels in order to
|
||||
# start a failover, so no failover can be performed in minority.
|
||||
#
|
||||
# Slaves are auto-discovered, so you don't need to specify slaves in
|
||||
# Replicas are auto-discovered, so you don't need to specify replicas in
|
||||
# any way. Sentinel itself will rewrite this configuration file adding
|
||||
# the slaves using additional configuration options.
|
||||
# the replicas using additional configuration options.
|
||||
# Also note that the configuration file is rewritten when a
|
||||
# slave is promoted to master.
|
||||
# replica is promoted to master.
|
||||
#
|
||||
# Note: master name should not include special characters or spaces.
|
||||
# The valid charset is A-z 0-9 and the three characters ".-_".
|
||||
@@ -54,11 +85,11 @@ sentinel monitor mymaster 127.0.0.1 6379 2
|
||||
|
||||
# sentinel auth-pass <master-name> <password>
|
||||
#
|
||||
# Set the password to use to authenticate with the master and slaves.
|
||||
# Set the password to use to authenticate with the master and replicas.
|
||||
# Useful if there is a password set in the Redis instances to monitor.
|
||||
#
|
||||
# Note that the master password is also used for slaves, so it is not
|
||||
# possible to set a different password in masters and slaves instances
|
||||
# Note that the master password is also used for replicas, so it is not
|
||||
# possible to set a different password in masters and replicas instances
|
||||
# if you want to be able to monitor these instances with Sentinel.
|
||||
#
|
||||
# However you can have Redis instances without the authentication enabled
|
||||
@@ -73,7 +104,7 @@ sentinel monitor mymaster 127.0.0.1 6379 2
|
||||
|
||||
# sentinel down-after-milliseconds <master-name> <milliseconds>
|
||||
#
|
||||
# Number of milliseconds the master (or any attached slave or sentinel) should
|
||||
# Number of milliseconds the master (or any attached replica or sentinel) should
|
||||
# be unreachable (as in, not acceptable reply to PING, continuously, for the
|
||||
# specified period) in order to consider it in S_DOWN state (Subjectively
|
||||
# Down).
|
||||
@@ -81,11 +112,11 @@ sentinel monitor mymaster 127.0.0.1 6379 2
|
||||
# Default is 30 seconds.
|
||||
sentinel down-after-milliseconds mymaster 30000
|
||||
|
||||
# sentinel parallel-syncs <master-name> <numslaves>
|
||||
# sentinel parallel-syncs <master-name> <numreplicas>
|
||||
#
|
||||
# How many slaves we can reconfigure to point to the new slave simultaneously
|
||||
# during the failover. Use a low number if you use the slaves to serve query
|
||||
# to avoid that all the slaves will be unreachable at about the same
|
||||
# How many replicas we can reconfigure to point to the new replica simultaneously
|
||||
# during the failover. Use a low number if you use the replicas to serve query
|
||||
# to avoid that all the replicas will be unreachable at about the same
|
||||
# time while performing the synchronization with the master.
|
||||
sentinel parallel-syncs mymaster 1
|
||||
|
||||
@@ -97,18 +128,18 @@ sentinel parallel-syncs mymaster 1
|
||||
# already tried against the same master by a given Sentinel, is two
|
||||
# times the failover timeout.
|
||||
#
|
||||
# - The time needed for a slave replicating to a wrong master according
|
||||
# - The time needed for a replica replicating to a wrong master according
|
||||
# to a Sentinel current configuration, to be forced to replicate
|
||||
# with the right master, is exactly the failover timeout (counting since
|
||||
# the moment a Sentinel detected the misconfiguration).
|
||||
#
|
||||
# - The time needed to cancel a failover that is already in progress but
|
||||
# did not produced any configuration change (SLAVEOF NO ONE yet not
|
||||
# acknowledged by the promoted slave).
|
||||
# acknowledged by the promoted replica).
|
||||
#
|
||||
# - The maximum time a failover in progress waits for all the slaves to be
|
||||
# reconfigured as slaves of the new master. However even after this time
|
||||
# the slaves will be reconfigured by the Sentinels anyway, but not with
|
||||
# - The maximum time a failover in progress waits for all the replicas to be
|
||||
# reconfigured as replicas of the new master. However even after this time
|
||||
# the replicas will be reconfigured by the Sentinels anyway, but not with
|
||||
# the exact parallel-syncs progression as specified.
|
||||
#
|
||||
# Default is 3 minutes.
|
||||
@@ -169,7 +200,7 @@ sentinel failover-timeout mymaster 180000
|
||||
# <role> is either "leader" or "observer"
|
||||
#
|
||||
# The arguments from-ip, from-port, to-ip, to-port are used to communicate
|
||||
# the old address of the master and the new address of the elected slave
|
||||
# the old address of the master and the new address of the elected replica
|
||||
# (now a master).
|
||||
#
|
||||
# This script should be resistant to multiple invocations.
|
||||
@@ -177,13 +208,37 @@ sentinel failover-timeout mymaster 180000
|
||||
# Example:
|
||||
#
|
||||
# sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
|
||||
#
|
||||
|
||||
# SECURITY
|
||||
#
|
||||
# By default SENTINEL SET will not be able to change the notification-script
|
||||
# and client-reconfig-script at runtime. This avoids a trivial security issue
|
||||
# where clients can set the script to anything and trigger a failover in order
|
||||
# to get the program executed.
|
||||
sentinel deny-scripts-reconfig yes
|
||||
|
||||
sentinel deny-scripts-reconfig yes
|
||||
|
||||
# REDIS COMMANDS RENAMING
|
||||
#
|
||||
# Sometimes the Redis server has certain commands, that are needed for Sentinel
|
||||
# to work correctly, renamed to unguessable strings. This is often the case
|
||||
# of CONFIG and SLAVEOF in the context of providers that provide Redis as
|
||||
# a service, and don't want the customers to reconfigure the instances outside
|
||||
# of the administration console.
|
||||
#
|
||||
# In such case it is possible to tell Sentinel to use different command names
|
||||
# instead of the normal ones. For example if the master "mymaster", and the
|
||||
# associated replicas, have "CONFIG" all renamed to "GUESSME", I could use:
|
||||
#
|
||||
# SENTINEL rename-command mymaster CONFIG GUESSME
|
||||
#
|
||||
# After such configuration is set, every time Sentinel would use CONFIG it will
|
||||
# use GUESSME instead. Note that there is no actual need to respect the command
|
||||
# case, so writing "config guessme" is the same in the example above.
|
||||
#
|
||||
# SENTINEL SET can also be used in order to perform this configuration at runtime.
|
||||
#
|
||||
# In order to set a command back to its original name (undo the renaming), it
|
||||
# is possible to just rename a command to itsef:
|
||||
#
|
||||
# SENTINEL rename-command mymaster CONFIG CONFIG
|
||||
|
||||
+28
-5
@@ -21,6 +21,11 @@ NODEPS:=clean distclean
|
||||
|
||||
# Default settings
|
||||
STD=-std=c99 -pedantic -DREDIS_STATIC=''
|
||||
ifneq (,$(findstring clang,$(CC)))
|
||||
ifneq (,$(findstring FreeBSD,$(uname_S)))
|
||||
STD+=-Wno-c11-extensions
|
||||
endif
|
||||
endif
|
||||
WARN=-Wall -W -Wno-missing-field-initializers
|
||||
OPT=$(OPTIMIZATION)
|
||||
|
||||
@@ -39,9 +44,13 @@ endif
|
||||
endif
|
||||
|
||||
# To get ARM stack traces if Redis crashes we need a special C flag.
|
||||
ifneq (,$(filter aarch64 armv,$(uname_M)))
|
||||
CFLAGS+=-funwind-tables
|
||||
else
|
||||
ifneq (,$(findstring armv,$(uname_M)))
|
||||
CFLAGS+=-funwind-tables
|
||||
endif
|
||||
endif
|
||||
|
||||
# Backwards compatibility for selecting an allocator
|
||||
ifeq ($(USE_TCMALLOC),yes)
|
||||
@@ -93,14 +102,25 @@ else
|
||||
ifeq ($(uname_S),OpenBSD)
|
||||
# OpenBSD
|
||||
FINAL_LIBS+= -lpthread
|
||||
ifeq ($(USE_BACKTRACE),yes)
|
||||
FINAL_CFLAGS+= -DUSE_BACKTRACE -I/usr/local/include
|
||||
FINAL_LDFLAGS+= -L/usr/local/lib
|
||||
FINAL_LIBS+= -lexecinfo
|
||||
endif
|
||||
|
||||
else
|
||||
ifeq ($(uname_S),FreeBSD)
|
||||
# FreeBSD
|
||||
FINAL_LIBS+= -lpthread
|
||||
FINAL_LIBS+= -lpthread -lexecinfo
|
||||
else
|
||||
ifeq ($(uname_S),DragonFly)
|
||||
# FreeBSD
|
||||
FINAL_LIBS+= -lpthread -lexecinfo
|
||||
else
|
||||
# All the other OSes (notably Linux)
|
||||
FINAL_LDFLAGS+= -rdynamic
|
||||
FINAL_LIBS+=-ldl -pthread
|
||||
FINAL_LIBS+=-ldl -pthread -lrt
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -122,7 +142,7 @@ endif
|
||||
ifeq ($(MALLOC),jemalloc)
|
||||
DEPENDENCY_TARGETS+= jemalloc
|
||||
FINAL_CFLAGS+= -DUSE_JEMALLOC -I../deps/jemalloc/include
|
||||
FINAL_LIBS+= ../deps/jemalloc/lib/libjemalloc.a
|
||||
FINAL_LIBS := ../deps/jemalloc/lib/libjemalloc.a $(FINAL_LIBS)
|
||||
endif
|
||||
|
||||
REDIS_CC=$(QUIET_CC)$(CC) $(FINAL_CFLAGS)
|
||||
@@ -144,9 +164,9 @@ endif
|
||||
|
||||
REDIS_SERVER_NAME=redis-server
|
||||
REDIS_SENTINEL_NAME=redis-sentinel
|
||||
REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o
|
||||
REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o
|
||||
REDIS_CLI_NAME=redis-cli
|
||||
REDIS_CLI_OBJ=anet.o adlist.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o
|
||||
REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o
|
||||
REDIS_BENCHMARK_NAME=redis-benchmark
|
||||
REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o zmalloc.o redis-benchmark.o
|
||||
REDIS_CHECK_RDB_NAME=redis-check-rdb
|
||||
@@ -290,3 +310,6 @@ install: all
|
||||
$(REDIS_INSTALL) $(REDIS_CHECK_RDB_NAME) $(INSTALL_BIN)
|
||||
$(REDIS_INSTALL) $(REDIS_CHECK_AOF_NAME) $(INSTALL_BIN)
|
||||
@ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_SENTINEL_NAME)
|
||||
|
||||
uninstall:
|
||||
rm -f $(INSTALL_BIN)/{$(REDIS_SERVER_NAME),$(REDIS_BENCHMARK_NAME),$(REDIS_CLI_NAME),$(REDIS_CHECK_RDB_NAME),$(REDIS_CHECK_AOF_NAME),$(REDIS_SENTINEL_NAME)}
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
virtual vector<string> Extract(vector<string> tokens, int StartIndex = 0) = 0;
|
||||
} ParamExtractor;
|
||||
|
||||
typedef map<string, ParamExtractor*> RedisParamterMapper;
|
||||
typedef map<string, ParamExtractor*> RedisParameterMapper;
|
||||
|
||||
typedef class FixedParam : public ParamExtractor {
|
||||
private:
|
||||
@@ -282,11 +282,11 @@ static BindParams bp = BindParams();
|
||||
|
||||
typedef class SentinelParams : public ParamExtractor {
|
||||
private:
|
||||
RedisParamterMapper subCommands;
|
||||
RedisParameterMapper subCommands;
|
||||
|
||||
public:
|
||||
SentinelParams() {
|
||||
subCommands = RedisParamterMapper
|
||||
subCommands = RedisParameterMapper
|
||||
{
|
||||
{ "monitor", &fp4 }, // sentinel monitor [master name] [ip] [port] [quorum]
|
||||
{ "auth-pass", &fp2 }, // sentinel auth-pass [master name] [password]
|
||||
@@ -357,7 +357,7 @@ public:
|
||||
static SentinelParams sp = SentinelParams();
|
||||
|
||||
// Map of argument name to argument processing engine.
|
||||
static RedisParamterMapper g_redisArgMap =
|
||||
static RedisParameterMapper g_redisArgMap =
|
||||
{
|
||||
// QFork flags
|
||||
{ cQFork, &fp2 }, // qfork [QForkControlMemoryMap handle] [parent process id]
|
||||
@@ -371,69 +371,85 @@ static RedisParamterMapper g_redisArgMap =
|
||||
{ cServiceStart, &fp0 }, // service-start
|
||||
{ cServiceStop, &fp0 }, // service-stop
|
||||
|
||||
// redis commands
|
||||
{ "daemonize", &fp1 }, // daemonize [yes/no]
|
||||
{ "pidfile", &fp1 }, // pidfile [file]
|
||||
// redis commands (ordered as they appear in config.c/loadServerConfigFromString())
|
||||
{ "timeout", &fp1 }, // timeout [value]
|
||||
{ "tcp-keepalive", &fp1 }, // tcp-keepalive [value]
|
||||
{ "protected-mode", &fp1 }, // protected-mode [yes/no]
|
||||
{ "port", &fp1 }, // port [port number]
|
||||
{ "tcp-backlog", &fp1 }, // tcp-backlog [number]
|
||||
{ "bind", &bp }, // bind [address] [address] ...
|
||||
{ "unixsocket", &fp1 }, // unixsocket [path]
|
||||
{ "timeout", &fp1 }, // timeout [value]
|
||||
{ "tcp-keepalive", &fp1 }, // tcp-keepalive [value]
|
||||
{ "unixsocketperm", &fp1 }, // unixsocketperm [perm]
|
||||
{ "save", &savep }, // save [seconds] [changes] or save ""
|
||||
{ cDir, &fp1 }, // dir [path]
|
||||
{ "loglevel", &fp1 }, // lovlevel [value]
|
||||
{ "logfile", &fp1 }, // logfile [file]
|
||||
{ "always-show-logo", &fp1 }, // always-show-logo [yes/no]
|
||||
{ "syslog-enabled", &fp1 }, // syslog-enabled [yes/no]
|
||||
{ "syslog-ident", &fp1 }, // syslog-ident [string]
|
||||
{ "syslog-facility", &fp1 }, // syslog-facility [string]
|
||||
{ "databases", &fp1 }, // databases [number]
|
||||
{ "save", &savep }, // save [seconds] [changes] or save ""
|
||||
{ "stop-writes-on-bgsave-error", &fp1 }, // stop-writes-on-bgsave-error [yes/no]
|
||||
{ "rdbcompression", &fp1 }, // rdbcompression [yes/no]
|
||||
{ "rdbchecksum", &fp1 }, // rdbchecksum [yes/no]
|
||||
{ "dbfilename", &fp1 }, // dbfilename [filename]
|
||||
{ cDir, &fp1 }, // dir [path]
|
||||
//"include" is handled in ParseConfFile()
|
||||
{ "maxclients", &fp1 }, // maxclients [number]
|
||||
{ "maxmemory", &fp1 }, // maxmemory [bytes]
|
||||
{ "maxmemory-policy", &fp1 }, // maxmemory-policy [policy]
|
||||
{ "maxmemory-samples", &fp1 }, // maxmemory-samples [number]
|
||||
{ "proto-max-bulk-len", &fp1 }, // proto-max-bulk-len [number]
|
||||
{ "client-query-buffer-limit", &fp1 }, // client-query-buffer-limit [number]
|
||||
{ "lfu-log-factor", &fp1 }, // lfu-log-factor [number]
|
||||
{ "lfu-decay-time", &fp1 }, // lfu-decay-time [number]
|
||||
{ "slaveof", &fp2 }, // slaveof [masterip] [master port]
|
||||
{ "replicaof", &fp2 }, // replicaof [masterip] [master port]
|
||||
{ "masterauth", &fp1 }, // masterauth [master-password]
|
||||
{ "slave-serve-stale-data", &fp1 }, // slave-serve-stale-data [yes/no]
|
||||
{ "replica-serve-stale-data", &fp1 }, // replica-serve-stale-data [yes/no]
|
||||
{ "replica-lazy-flush", &fp1},
|
||||
{ "lazyfree-lazy-server-del", &fp1},
|
||||
{ "lazyfree-lazy-expire", &fp1},
|
||||
{ "lazyfree-lazy-eviction", &fp1},
|
||||
{ "slave-read-only", &fp1 }, // slave-read-only [yes/no]
|
||||
{ "replicaof", &fp2 }, // replicaof [masterip] [master port]
|
||||
{ "repl-ping-slave-period", &fp1 }, // repl-ping-slave-period [number]
|
||||
{ "repl-ping-replica-period", &fp1 }, // repl-ping-replica-period [number]
|
||||
{ "repl-timeout", &fp1 }, // repl-timeout [number]
|
||||
{ "repl-disable-tcp-nodelay", &fp1 }, // repl-disable-tcp-nodelay [yes/no]
|
||||
{ "repl-diskless-sync", &fp1 }, // repl-diskless-sync [yes/no]
|
||||
{ "repl-diskless-sync-delay", &fp1 }, // repl-diskless-sync-delay [number]
|
||||
{ "repl-backlog-size", &fp1 }, // repl-backlog-size [number]
|
||||
{ "repl-backlog-ttl", &fp1 }, // repl-backlog-ttl [number]
|
||||
{ "slave-priority", &fp1 }, // slave-priority [number]
|
||||
{ "min-slaves-to-write", &fp1 }, // min-slaves-to-write [number]
|
||||
{ "min-slaves-max-lag", &fp1 }, // min-slaves-max-lag [number]
|
||||
{ "requirepass", &fp1 }, // requirepass [string]
|
||||
{ "rename-command", &fp2 }, // rename-command [command] [string]
|
||||
{ "maxclients", &fp1 }, // maxclients [number]
|
||||
{ "maxmemory", &fp1 }, // maxmemory [bytes]
|
||||
{ "maxmemory-policy", &fp1 }, // maxmemory-policy [policy]
|
||||
{ "maxmemory-samples", &fp1 }, // maxmemory-samples [number]
|
||||
{ "rdb-save-incremental-fsync", &fp1 },
|
||||
{ "appendonly", &fp1 }, // appendonly [yes/no]
|
||||
{ "masterauth", &fp1 }, // masterauth [master-password]
|
||||
{ "slave-serve-stale-data", &fp1 }, // slave-serve-stale-data [yes/no]
|
||||
{ "replica-serve-stale-data", &fp1 }, // replica-serve-stale-data [yes/no]
|
||||
{ "slave-read-only", &fp1 }, // slave-read-only [yes/no]
|
||||
{ "replica-read-only", &fp1 }, // replica-read-only [yes/no]
|
||||
{ "slave-ignore-maxmemory", &fp1 }, // slave-ignore-maxmemory [yes/no]
|
||||
{ "replica-ignore-maxmemory", &fp1 }, // replica-ignore-maxmemory [yes/no]
|
||||
{ "rdbcompression", &fp1 }, // rdbcompression [yes/no]
|
||||
{ "rdbchecksum", &fp1 }, // rdbchecksum [yes/no]
|
||||
{ "activerehashing", &fp1 }, // activerehashing [yes/no]
|
||||
{ "lazyfree-lazy-eviction", &fp1 }, // lazyfree-lazy-eviction [yes/no]
|
||||
{ "lazyfree-lazy-expire", &fp1 }, // lazyfree-lazy-expire [yes/no]
|
||||
{ "lazyfree-lazy-server-del", &fp1 }, // lazyfree-lazy-server-del [yes/no]
|
||||
{ "slave-lazy-flush", &fp1 }, // slave-lazy-flush [yes/no]
|
||||
{ "replica-lazy-flush", &fp1 }, // replica-lazy-flush [yes/no]
|
||||
{ "activedefrag", &fp1 }, // activedefrag [yes/no]
|
||||
{ "daemonize", &fp1 }, // daemonize [yes/no]
|
||||
{ "dynamic-hz", &fp1 }, // dynamic-hz [yes/no]
|
||||
{ "hz", &fp1 }, // hz [number]
|
||||
{ "appendonly", &fp1 }, // appendonly [yes/no]
|
||||
{ "appendfilename", &fp1 }, // appendfilename [filename]
|
||||
{ "no-appendfsync-on-rewrite", &fp1 }, // no-appendfsync-on-rewrite [value]
|
||||
{ "appendfsync", &fp1 }, // appendfsync [value]
|
||||
{ "aof-load-truncated", &fp1 },
|
||||
{ "aof-use-rdb-preamble", &fp1 },
|
||||
{ "rdb-save-incremental-fsync", &fp1 },
|
||||
{ "no-appendfsync-on-rewrite", &fp1 }, // no-appendfsync-on-rewrite [value]
|
||||
{ "auto-aof-rewrite-percentage", &fp1 }, // auto-aof-rewrite-percentage [number]
|
||||
{ "auto-aof-rewrite-min-size", &fp1 }, // auto-aof-rewrite-min-size [number]
|
||||
{ "lua-time-limit", &fp1 }, // lua-time-limit [number]
|
||||
{ "slowlog-log-slower-than", &fp1 }, // slowlog-log-slower-than [number]
|
||||
{ "slowlog-max-len", &fp1 }, // slowlog-max-len [number]
|
||||
{ "notify-keyspace-events", &fp1 }, // notify-keyspace-events [string]
|
||||
{ "aof-rewrite-incremental-fsync", &fp1 }, // aof-rewrite-incremental-fsync [yes/no]
|
||||
{ "rdb-save-incremental-fsync", &fp1 }, // rdb-save-incremental-fsync [yes/no]
|
||||
{ "aof-load-truncated", &fp1 }, // aof-load-truncated [yes/no]
|
||||
{ "aof-use-rdb-preamble", &fp1 }, // aof-use-rdb-preamble [yes/no]
|
||||
{ "requirepass", &fp1 }, // requirepass [string]
|
||||
{ "pidfile", &fp1 }, // pidfile [file]
|
||||
{ "dbfilename", &fp1 }, // dbfilename [filename]
|
||||
{ "active-defrag-threshold-lower", &fp1 }, // active-defrag-threshold-lower [number]
|
||||
{ "active-defrag-threshold-upper", &fp1 }, // active-defrag-threshold-upper [number]
|
||||
{ "active-defrag-ignore-bytes", &fp1 }, // active-defrag-ignore-bytes [number]
|
||||
{ "active-defrag-cycle-min", &fp1 }, // active-defrag-cycle-min [number]
|
||||
{ "active-defrag-cycle-max", &fp1 }, // active-defrag-cycle-max [number]
|
||||
{ "active-defrag-max-scan-fields", &fp1 }, // active-defrag-max-scan-fields [number]
|
||||
{ "hash-max-ziplist-entries", &fp1 }, // hash-max-ziplist-entries [number]
|
||||
{ "hash-max-ziplist-value", &fp1 }, // hash-max-ziplist-value [number]
|
||||
{ "stream-node-max-bytes", &fp1 }, // stream-node-max-bytes [number]
|
||||
{ "stream-node-max-entries", &fp1 }, // stream-node-max-entries [number]
|
||||
{ "list-max-ziplist-entries", &fp1 }, // list-max-ziplist-entries [number] DEAD OPTION
|
||||
{ "list-max-ziplist-value", &fp1 }, // list-max-ziplist-value [number] DEAD OPTION
|
||||
{ "list-max-ziplist-size", &fp1 }, // list-max-ziplist-size [number]
|
||||
@@ -442,36 +458,42 @@ static RedisParamterMapper g_redisArgMap =
|
||||
{ "zset-max-ziplist-entries", &fp1 }, // zset-max-ziplist-entries [number]
|
||||
{ "zset-max-ziplist-value", &fp1 }, // zset-max-ziplist-value [number]
|
||||
{ "hll-sparse-max-bytes", &fp1 }, // hll-sparse-max-bytes [number]
|
||||
{ "activerehashing", &fp1 }, // activerehashing [yes/no]
|
||||
{ "client-output-buffer-limit", &fp4 }, // client-output-buffer-limit [class] [hard limit] [soft limit] [soft seconds]
|
||||
{ "hz", &fp1 }, // hz [number]
|
||||
{ "aof-rewrite-incremental-fsync", &fp1 }, // aof-rewrite-incremental-fsync [yes/no]
|
||||
{ "aof-load-truncated", &fp1 }, // aof-load-truncated [yes/no]
|
||||
{ "rename-command", &fp2 }, // rename-command [command] [string]
|
||||
{ "cluster-enabled", &fp1 }, // cluster-enabled [yes/no]
|
||||
{ "cluster-config-file", &fp1 }, // cluster-config-file [filename]
|
||||
{ "cluster-announce-ip", &fp1 }, // cluster-announce-ip [string]
|
||||
{ "cluster-announce-port", &fp1 }, // cluster-announce-port [number]
|
||||
{ "cluster-announce-bus-port", &fp1 }, // cluster-announce-bus-port [number]
|
||||
{ "cluster-require-full-coverage", &fp1 }, // cluster-require-full-coverage [yes/no]
|
||||
{ "cluster-node-timeout", &fp1 }, // cluster-node-timeout [number]
|
||||
{ "cluster-migration-barrier", &fp1 }, // cluster-migration-barrier [number]
|
||||
{ "cluster-slave-validity-factor", &fp1 }, // cluster-slave-validity-factor [number]
|
||||
{ "cluster-replica-validity-factor",&fp1 }, // cluster-replica-validity-factor [number]
|
||||
{ "cluster-slave-no-failover", &fp1 }, // cluster-slave-no-failover [yes/no]
|
||||
{ "cluster-replica-no-failover", &fp1 }, // cluster-replica-no-failover [yes/no]
|
||||
{ "lua-time-limit", &fp1 }, // lua-time-limit [number]
|
||||
{ "lua-replicate-commands", &fp1 }, // lua-replicate-commands [yes/no]
|
||||
{ "slowlog-log-slower-than", &fp1 }, // slowlog-log-slower-than [number]
|
||||
{ "latency-monitor-threshold", &fp1 }, // latency-monitor-threshold [number]
|
||||
{ "protected-mode", &fp1 }, // protected-mode [yes/no]
|
||||
{ "slowlog-max-len", &fp1 }, // slowlog-max-len [number]
|
||||
{ "client-output-buffer-limit", &fp4 }, // client-output-buffer-limit [class] [hard limit] [soft limit] [soft seconds]
|
||||
{ "stop-writes-on-bgsave-error", &fp1 }, // stop-writes-on-bgsave-error [yes/no]
|
||||
{ "slave-priority", &fp1 }, // slave-priority [number]
|
||||
{ "replica-priority", &fp1 }, // replica-priority [number]
|
||||
{ "slave-announce-ip", &fp1 }, // slave-announce-ip [string]
|
||||
{ "replica-announce-ip", &fp1 }, // replica-announce-ip [string]
|
||||
{ "slave-announce-port", &fp1 }, // slave-announce-port [number]
|
||||
{ "replica-announce-port", &fp1 }, // replica-announce-port [number]
|
||||
{ "min-slaves-to-write", &fp1 }, // min-slaves-to-write [number]
|
||||
{ "min-replicas-to-write", &fp1 }, // min-replicas-to-write [number]
|
||||
{ "min-slaves-max-lag", &fp1 }, // min-slaves-max-lag [number]
|
||||
{ "min-replicas-max-lag", &fp1 }, // min-replicas-max-lag [number]
|
||||
{ "notify-keyspace-events", &fp1 }, // notify-keyspace-events [string]
|
||||
{ "supervised", &fp1 }, // supervised [upstart|systemd|auto|no]
|
||||
{ "loadmodule", &fp1 }, // loadmodule [filename]
|
||||
{ "sentinel", &sp }, // sentinel commands
|
||||
{ "watchdog-period", &fp1 }, // watchdog-period [number]
|
||||
{ "supervised", &fp1}, // supervised [upstart|systemd|auto|no]
|
||||
{ cInclude, &fp1 }, // include [path]
|
||||
{"dynamic-hz", &fp1},
|
||||
|
||||
// sentinel commands
|
||||
{ "sentinel", &sp },
|
||||
|
||||
// cluster commands
|
||||
{"cluster-enabled", &fp1}, // [yes/no]
|
||||
{"cluster-config-file", &fp1}, // [filename]
|
||||
{"cluster-node-timeout", &fp1}, // [number]
|
||||
{"cluster-slave-validity-factor", &fp1}, // [number]
|
||||
{"cluster-migration-barrier", &fp1}, // [1/0]
|
||||
{"cluster-require-full-coverage", &fp1}, // [yes/no]
|
||||
|
||||
//streams commands
|
||||
{"stream-node-max-bytes", &fp1},
|
||||
{"stream-node-max-entries", &fp1},
|
||||
{"stream-node-max-entries", &fp1},
|
||||
|
||||
//modules
|
||||
{"loadmodule", &fp1} // [filename]
|
||||
{ cInclude, &fp1 } // include [path]
|
||||
};
|
||||
|
||||
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
|
||||
|
||||
@@ -462,7 +462,7 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags)
|
||||
* before replying to a client. */
|
||||
int invert = fe->mask & AE_BARRIER;
|
||||
|
||||
/* Note the "fe->mask & mask & ..." code: maybe an already
|
||||
/* Note the "fe->mask & mask & ..." code: maybe an already
|
||||
* processed event removed an element that fired and we still
|
||||
* didn't processed, so we check if the event is still valid.
|
||||
*
|
||||
|
||||
+1
-1
@@ -273,7 +273,7 @@ int anetResolveIP(char *err, char *host, char *ipbuf, size_t ipbuf_len) {
|
||||
|
||||
static int anetSetReuseAddr(char *err, int fd) {
|
||||
int yes = 1;
|
||||
/* Make sure connection-intensive things like the redis benckmark
|
||||
/* Make sure connection-intensive things like the redis benchmark
|
||||
* will be able to close/open sockets a zillion of times */
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) {
|
||||
anetSetError(err, "setsockopt SO_REUSEADDR: %s", IF_WIN32(wsa_strerror(errno), strerror(errno)));
|
||||
|
||||
@@ -900,7 +900,7 @@ uxeof: /* Unexpected AOF end of file. */
|
||||
if (valid_up_to == -1) {
|
||||
serverLog(LL_WARNING,"Last valid command offset is invalid");
|
||||
} else {
|
||||
serverLog(LL_WARNING, "Error truncating the AOF file: %s",
|
||||
serverLog(LL_WARNING,"Error truncating the AOF file: %s",
|
||||
IF_WIN32(wsa_strerror(errno), strerror(errno)));
|
||||
}
|
||||
} else {
|
||||
@@ -936,7 +936,7 @@ int rioWriteBulkObject(rio *r, robj *obj) {
|
||||
/* Avoid using getDecodedObject to help copy-on-write (we are often
|
||||
* in a child process when this function is called). */
|
||||
if (obj->encoding == OBJ_ENCODING_INT) {
|
||||
return (int)rioWriteBulkLongLong(r,(PORT_LONGLONG)((int)obj->ptr)); WIN_PORT_FIX /* cast (int) */
|
||||
return (int)rioWriteBulkLongLong(r,(PORT_LONG)obj->ptr); WIN_PORT_FIX /* cast (int) */
|
||||
} else if (sdsEncodedObject(obj)) {
|
||||
return (int)rioWriteBulkString(r,obj->ptr,sdslen(obj->ptr)); WIN_PORT_FIX /* cast (int) */
|
||||
} else {
|
||||
|
||||
@@ -222,7 +222,7 @@ void *bioProcessBackgroundJobs(void *arg) {
|
||||
}
|
||||
zfree(job);
|
||||
|
||||
/* Lock again before reiterating the loop, if there are no longer
|
||||
/* Lock again before reiterating the loop, if there are no longer
|
||||
* jobs to process we'll block again in pthread_cond_wait(). */
|
||||
pthread_mutex_lock(&bio_mutex[type]);
|
||||
listDelNode(bio_jobs[type],ln);
|
||||
|
||||
+2
-2
@@ -112,10 +112,10 @@ PORT_LONG redisBitpos(void *s, PORT_ULONG count, int bit) {
|
||||
* blocks of 1 or 0 bits compared to the vanilla bit per bit processing.
|
||||
*
|
||||
* Note that if we start from an address that is not aligned
|
||||
* to sizeof(PORT_ULONG) we consume it byte by byte until it is
|
||||
* to sizeof(unsigned long) we consume it byte by byte until it is
|
||||
* aligned. */
|
||||
|
||||
/* Skip initial bits not aligned to sizeof(PORT_ULONG) byte by byte. */
|
||||
/* Skip initial bits not aligned to sizeof(unsigned long) byte by byte. */
|
||||
skipval = bit ? 0 : UCHAR_MAX;
|
||||
c = (unsigned char*) s;
|
||||
found = 0;
|
||||
|
||||
+3
-3
@@ -2197,7 +2197,7 @@ void clusterWriteHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
nwritten = write(fd, link->sndbuf, sdslen(link->sndbuf));
|
||||
if (nwritten <= 0) {
|
||||
serverLog(LL_DEBUG,"I/O error writing to node link: %s",
|
||||
strerror(errno));
|
||||
(nwritten == -1) ? strerror(errno) : "short write");
|
||||
handleLinkIOError(link);
|
||||
return;
|
||||
}
|
||||
@@ -3645,7 +3645,7 @@ void clusterCron(void) {
|
||||
if (nodeIsSlave(myself)) {
|
||||
clusterHandleManualFailover();
|
||||
if (!(server.cluster_module_flags & CLUSTER_MODULE_FLAG_NO_FAILOVER))
|
||||
clusterHandleSlaveFailover();
|
||||
clusterHandleSlaveFailover();
|
||||
/* If there are orphaned slaves, and we are a slave among the masters
|
||||
* with the max number of non-failing slaves, consider migrating to
|
||||
* the orphaned masters. Note that it does not make sense to try
|
||||
@@ -4572,7 +4572,7 @@ NULL
|
||||
|
||||
/* Produce the reply protocol. */
|
||||
addReplySds(c,sdscatprintf(sdsempty(),"$%Iu\r\n", WIN_PORT_FIX /* %lu -> %Iu */
|
||||
(PORT_ULONG)sdslen(info)));
|
||||
(PORT_ULONG)sdslen(info)));
|
||||
addReplySds(c,info);
|
||||
addReply(c,shared.crlf);
|
||||
} else if (!strcasecmp(c->argv[1]->ptr,"saveconfig") && c->argc == 2) {
|
||||
|
||||
+2
-2
@@ -129,7 +129,7 @@ const char *configEnumGetName(configEnum *ce, int val) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Wrapper for configEnumGetName() returning "unknown" insetad of NULL if
|
||||
/* Wrapper for configEnumGetName() returning "unknown" instead of NULL if
|
||||
* there is no match. */
|
||||
const char *configEnumGetNameOrUnknown(configEnum *ce, int val) {
|
||||
const char *name = configEnumGetName(ce,val);
|
||||
@@ -2376,6 +2376,6 @@ NULL
|
||||
}
|
||||
} else {
|
||||
addReplySubcommandSyntaxError(c);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ void dbAdd(redisDb *db, robj *key, robj *val) {
|
||||
val->type == OBJ_ZSET)
|
||||
signalKeyAsReady(db, key);
|
||||
if (server.cluster_enabled) slotToKeyAdd(key);
|
||||
}
|
||||
}
|
||||
|
||||
/* Overwrite an existing key with a new value. Incrementing the reference
|
||||
* count of the new value is up to the caller.
|
||||
@@ -194,7 +194,7 @@ void dbOverwrite(redisDb *db, robj *key, robj *val) {
|
||||
|
||||
serverAssertWithInfo(NULL,key,de != NULL);
|
||||
dictEntry auxentry = *de;
|
||||
robj *old = dictGetVal(de);
|
||||
robj *old = dictGetVal(de);
|
||||
if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
|
||||
val->lru = old->lru;
|
||||
}
|
||||
@@ -343,7 +343,7 @@ robj *dbUnshareStringValue(redisDb *db, robj *key, robj *o) {
|
||||
* database(s). Otherwise -1 is returned in the specific case the
|
||||
* DB number is out of range, and errno is set to EINVAL. */
|
||||
PORT_LONGLONG emptyDb(int dbnum, int flags, void(callback)(void*)) {
|
||||
int j, async = (flags & EMPTYDB_ASYNC);
|
||||
int async = (flags & EMPTYDB_ASYNC);
|
||||
PORT_LONGLONG removed = 0;
|
||||
|
||||
if (dbnum < -1 || dbnum >= server.dbnum) {
|
||||
@@ -1397,7 +1397,7 @@ int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numk
|
||||
for (i = 5; i < argc; i++) {
|
||||
char *arg = argv[i]->ptr;
|
||||
/* For the case when user specifies both "store" and "storedist" options, the
|
||||
* second key specified would override the first key. This behavior is kept
|
||||
* second key specified would override the first key. This behavior is kept
|
||||
* the same as in georadiusCommand method.
|
||||
*/
|
||||
if ((!strcasecmp(arg, "store") || !strcasecmp(arg, "storedist")) && ((i+1) < argc)) {
|
||||
@@ -1418,7 +1418,7 @@ int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numk
|
||||
if(num > 1) {
|
||||
keys[1] = stored_key;
|
||||
}
|
||||
*numkeys = num;
|
||||
*numkeys = num;
|
||||
return keys;
|
||||
}
|
||||
|
||||
|
||||
+102
-98
@@ -42,7 +42,11 @@
|
||||
|
||||
#ifdef HAVE_BACKTRACE
|
||||
#include <execinfo.h>
|
||||
#ifndef __OpenBSD__
|
||||
#include <ucontext.h>
|
||||
#else
|
||||
typedef ucontext_t sigcontext_t;
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include "bio.h"
|
||||
#include <unistd.h>
|
||||
@@ -121,98 +125,98 @@ void mixStringObjectDigest(unsigned char *digest, robj *o) {
|
||||
* present. */
|
||||
void xorObjectDigest(redisDb *db, robj *keyobj, unsigned char *digest, robj *o) {
|
||||
uint32_t aux = htonl(o->type);
|
||||
mixDigest(digest,&aux,sizeof(aux));
|
||||
PORT_LONGLONG expiretime = getExpire(db,keyobj);
|
||||
char buf[128];
|
||||
mixDigest(digest,&aux,sizeof(aux));
|
||||
PORT_LONGLONG expiretime = getExpire(db,keyobj);
|
||||
char buf[128];
|
||||
|
||||
/* Save the key and associated value */
|
||||
if (o->type == OBJ_STRING) {
|
||||
/* Save the key and associated value */
|
||||
if (o->type == OBJ_STRING) {
|
||||
mixStringObjectDigest(digest,o);
|
||||
} else if (o->type == OBJ_LIST) {
|
||||
listTypeIterator *li = listTypeInitIterator(o,0,LIST_TAIL);
|
||||
listTypeEntry entry;
|
||||
while(listTypeNext(li,&entry)) {
|
||||
robj *eleobj = listTypeGet(&entry);
|
||||
} else if (o->type == OBJ_LIST) {
|
||||
listTypeIterator *li = listTypeInitIterator(o,0,LIST_TAIL);
|
||||
listTypeEntry entry;
|
||||
while(listTypeNext(li,&entry)) {
|
||||
robj *eleobj = listTypeGet(&entry);
|
||||
mixStringObjectDigest(digest,eleobj);
|
||||
decrRefCount(eleobj);
|
||||
}
|
||||
listTypeReleaseIterator(li);
|
||||
} else if (o->type == OBJ_SET) {
|
||||
setTypeIterator *si = setTypeInitIterator(o);
|
||||
sds sdsele;
|
||||
while((sdsele = setTypeNextObject(si)) != NULL) {
|
||||
xorDigest(digest,sdsele,sdslen(sdsele));
|
||||
sdsfree(sdsele);
|
||||
}
|
||||
setTypeReleaseIterator(si);
|
||||
} else if (o->type == OBJ_ZSET) {
|
||||
unsigned char eledigest[20];
|
||||
decrRefCount(eleobj);
|
||||
}
|
||||
listTypeReleaseIterator(li);
|
||||
} else if (o->type == OBJ_SET) {
|
||||
setTypeIterator *si = setTypeInitIterator(o);
|
||||
sds sdsele;
|
||||
while((sdsele = setTypeNextObject(si)) != NULL) {
|
||||
xorDigest(digest,sdsele,sdslen(sdsele));
|
||||
sdsfree(sdsele);
|
||||
}
|
||||
setTypeReleaseIterator(si);
|
||||
} else if (o->type == OBJ_ZSET) {
|
||||
unsigned char eledigest[20];
|
||||
|
||||
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||
unsigned char *zl = o->ptr;
|
||||
unsigned char *eptr, *sptr;
|
||||
unsigned char *vstr;
|
||||
unsigned int vlen;
|
||||
PORT_LONGLONG vll;
|
||||
double score;
|
||||
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||
unsigned char *zl = o->ptr;
|
||||
unsigned char *eptr, *sptr;
|
||||
unsigned char *vstr;
|
||||
unsigned int vlen;
|
||||
PORT_LONGLONG vll;
|
||||
double score;
|
||||
|
||||
eptr = ziplistIndex(zl,0);
|
||||
serverAssert(eptr != NULL);
|
||||
sptr = ziplistNext(zl,eptr);
|
||||
serverAssert(sptr != NULL);
|
||||
eptr = ziplistIndex(zl,0);
|
||||
serverAssert(eptr != NULL);
|
||||
sptr = ziplistNext(zl,eptr);
|
||||
serverAssert(sptr != NULL);
|
||||
|
||||
while (eptr != NULL) {
|
||||
serverAssert(ziplistGet(eptr,&vstr,&vlen,&vll));
|
||||
score = zzlGetScore(sptr);
|
||||
while (eptr != NULL) {
|
||||
serverAssert(ziplistGet(eptr,&vstr,&vlen,&vll));
|
||||
score = zzlGetScore(sptr);
|
||||
|
||||
memset(eledigest,0,20);
|
||||
if (vstr != NULL) {
|
||||
mixDigest(eledigest,vstr,vlen);
|
||||
} else {
|
||||
ll2string(buf,sizeof(buf),vll);
|
||||
mixDigest(eledigest,buf,strlen(buf));
|
||||
}
|
||||
|
||||
snprintf(buf,sizeof(buf),"%.17g",score);
|
||||
mixDigest(eledigest,buf,strlen(buf));
|
||||
xorDigest(digest,eledigest,20);
|
||||
zzlNext(zl,&eptr,&sptr);
|
||||
}
|
||||
} else if (o->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||
zset *zs = o->ptr;
|
||||
dictIterator *di = dictGetIterator(zs->dict);
|
||||
dictEntry *de;
|
||||
|
||||
while((de = dictNext(di)) != NULL) {
|
||||
sds sdsele = dictGetKey(de);
|
||||
double *score = dictGetVal(de);
|
||||
|
||||
snprintf(buf,sizeof(buf),"%.17g",*score);
|
||||
memset(eledigest,0,20);
|
||||
mixDigest(eledigest,sdsele,sdslen(sdsele));
|
||||
mixDigest(eledigest,buf,strlen(buf));
|
||||
xorDigest(digest,eledigest,20);
|
||||
}
|
||||
dictReleaseIterator(di);
|
||||
memset(eledigest,0,20);
|
||||
if (vstr != NULL) {
|
||||
mixDigest(eledigest,vstr,vlen);
|
||||
} else {
|
||||
serverPanic("Unknown sorted set encoding");
|
||||
ll2string(buf,sizeof(buf),vll);
|
||||
mixDigest(eledigest,buf,strlen(buf));
|
||||
}
|
||||
} else if (o->type == OBJ_HASH) {
|
||||
hashTypeIterator *hi = hashTypeInitIterator(o);
|
||||
while (hashTypeNext(hi) != C_ERR) {
|
||||
unsigned char eledigest[20];
|
||||
sds sdsele;
|
||||
|
||||
memset(eledigest,0,20);
|
||||
sdsele = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_KEY);
|
||||
mixDigest(eledigest,sdsele,sdslen(sdsele));
|
||||
sdsfree(sdsele);
|
||||
sdsele = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_VALUE);
|
||||
mixDigest(eledigest,sdsele,sdslen(sdsele));
|
||||
sdsfree(sdsele);
|
||||
xorDigest(digest,eledigest,20);
|
||||
}
|
||||
hashTypeReleaseIterator(hi);
|
||||
snprintf(buf,sizeof(buf),"%.17g",score);
|
||||
mixDigest(eledigest,buf,strlen(buf));
|
||||
xorDigest(digest,eledigest,20);
|
||||
zzlNext(zl,&eptr,&sptr);
|
||||
}
|
||||
} else if (o->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||
zset *zs = o->ptr;
|
||||
dictIterator *di = dictGetIterator(zs->dict);
|
||||
dictEntry *de;
|
||||
|
||||
while((de = dictNext(di)) != NULL) {
|
||||
sds sdsele = dictGetKey(de);
|
||||
double *score = dictGetVal(de);
|
||||
|
||||
snprintf(buf,sizeof(buf),"%.17g",*score);
|
||||
memset(eledigest,0,20);
|
||||
mixDigest(eledigest,sdsele,sdslen(sdsele));
|
||||
mixDigest(eledigest,buf,strlen(buf));
|
||||
xorDigest(digest,eledigest,20);
|
||||
}
|
||||
dictReleaseIterator(di);
|
||||
} else {
|
||||
serverPanic("Unknown sorted set encoding");
|
||||
}
|
||||
} else if (o->type == OBJ_HASH) {
|
||||
hashTypeIterator *hi = hashTypeInitIterator(o);
|
||||
while (hashTypeNext(hi) != C_ERR) {
|
||||
unsigned char eledigest[20];
|
||||
sds sdsele;
|
||||
|
||||
memset(eledigest,0,20);
|
||||
sdsele = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_KEY);
|
||||
mixDigest(eledigest,sdsele,sdslen(sdsele));
|
||||
sdsfree(sdsele);
|
||||
sdsele = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_VALUE);
|
||||
mixDigest(eledigest,sdsele,sdslen(sdsele));
|
||||
sdsfree(sdsele);
|
||||
xorDigest(digest,eledigest,20);
|
||||
}
|
||||
hashTypeReleaseIterator(hi);
|
||||
} else if (o->type == OBJ_STREAM) {
|
||||
streamIterator si;
|
||||
streamIteratorStart(&si,o->ptr,NULL,NULL,0);
|
||||
@@ -234,20 +238,20 @@ void xorObjectDigest(redisDb *db, robj *keyobj, unsigned char *digest, robj *o)
|
||||
}
|
||||
}
|
||||
streamIteratorStop(&si);
|
||||
} else if (o->type == OBJ_MODULE) {
|
||||
RedisModuleDigest md;
|
||||
moduleValue *mv = o->ptr;
|
||||
moduleType *mt = mv->type;
|
||||
moduleInitDigestContext(md);
|
||||
if (mt->digest) {
|
||||
mt->digest(&md,mv->value);
|
||||
xorDigest(digest,md.x,sizeof(md.x));
|
||||
}
|
||||
} else {
|
||||
serverPanic("Unknown object type");
|
||||
}
|
||||
/* If the key has an expire, add it to the mix */
|
||||
if (expiretime != -1) xorDigest(digest,"!!expire!!",10);
|
||||
} else if (o->type == OBJ_MODULE) {
|
||||
RedisModuleDigest md;
|
||||
moduleValue *mv = o->ptr;
|
||||
moduleType *mt = mv->type;
|
||||
moduleInitDigestContext(md);
|
||||
if (mt->digest) {
|
||||
mt->digest(&md,mv->value);
|
||||
xorDigest(digest,md.x,sizeof(md.x));
|
||||
}
|
||||
} else {
|
||||
serverPanic("Unknown object type");
|
||||
}
|
||||
/* If the key has an expire, add it to the mix */
|
||||
if (expiretime != -1) xorDigest(digest,"!!expire!!",10);
|
||||
}
|
||||
|
||||
/* Compute the dataset digest. Since keys, sets elements, hashes elements
|
||||
@@ -527,8 +531,8 @@ NULL
|
||||
|
||||
sds d = sdsempty();
|
||||
for (int i = 0; i < 20; i++) d = sdscatprintf(d, "%02x",digest[i]);
|
||||
addReplyStatus(c,d);
|
||||
sdsfree(d);
|
||||
addReplyStatus(c,d);
|
||||
sdsfree(d);
|
||||
}
|
||||
} else if (!strcasecmp(c->argv[1]->ptr,"sleep") && c->argc == 3) {
|
||||
double dtime = strtod(c->argv[2]->ptr,NULL);
|
||||
|
||||
+30
-29
@@ -838,7 +838,7 @@ PORT_LONG defragKey(redisDb *db, dictEntry *de) {
|
||||
|
||||
/* Defrag scan callback for the main db dictionary. */
|
||||
void defragScanCallback(void *privdata, const dictEntry *de) {
|
||||
int defragged = defragKey((redisDb*)privdata, (dictEntry*)de);
|
||||
PORT_LONG defragged = defragKey((redisDb*)privdata, (dictEntry*)de);
|
||||
server.stat_active_defrag_hits += defragged;
|
||||
if(defragged)
|
||||
server.stat_active_defrag_key_hits++;
|
||||
@@ -876,7 +876,7 @@ float getAllocatorFragmentation(size_t *out_frag_bytes) {
|
||||
if(out_frag_bytes)
|
||||
*out_frag_bytes = frag_bytes;
|
||||
serverLog(LL_DEBUG,
|
||||
"allocated=%zu, active=%zu, resident=%zu, frag=%.0f%% (%.0f%% rss), frag_bytes=%zu (%zu%% rss)",
|
||||
"allocated=%zu, active=%zu, resident=%zu, frag=%.0f%% (%.0f%% rss), frag_bytes=%zu (%zu rss)",
|
||||
allocated, active, resident, frag_pct, rss_pct, frag_bytes, rss_bytes);
|
||||
return frag_pct;
|
||||
}
|
||||
@@ -995,35 +995,35 @@ int defragLaterStep(redisDb *db, PORT_LONGLONG endtime) {
|
||||
|
||||
/* decide if defrag is needed, and at what CPU effort to invest in it */
|
||||
void computeDefragCycles() {
|
||||
size_t frag_bytes;
|
||||
float frag_pct = getAllocatorFragmentation(&frag_bytes);
|
||||
/* If we're not already running, and below the threshold, exit. */
|
||||
if (!server.active_defrag_running) {
|
||||
if(frag_pct < server.active_defrag_threshold_lower || frag_bytes < server.active_defrag_ignore_bytes)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate the adaptive aggressiveness of the defrag */
|
||||
int cpu_pct = INTERPOLATE(frag_pct,
|
||||
server.active_defrag_threshold_lower,
|
||||
server.active_defrag_threshold_upper,
|
||||
server.active_defrag_cycle_min,
|
||||
server.active_defrag_cycle_max);
|
||||
cpu_pct = LIMIT(cpu_pct,
|
||||
server.active_defrag_cycle_min,
|
||||
server.active_defrag_cycle_max);
|
||||
/* We allow increasing the aggressiveness during a scan, but don't
|
||||
* reduce it. */
|
||||
if (!server.active_defrag_running ||
|
||||
cpu_pct > server.active_defrag_running)
|
||||
{
|
||||
server.active_defrag_running = cpu_pct;
|
||||
serverLog(LL_VERBOSE,
|
||||
"Starting active defrag, frag=%.0f%%, frag_bytes=%zu, cpu=%d%%",
|
||||
frag_pct, frag_bytes, cpu_pct);
|
||||
}
|
||||
size_t frag_bytes;
|
||||
float frag_pct = getAllocatorFragmentation(&frag_bytes);
|
||||
/* If we're not already running, and below the threshold, exit. */
|
||||
if (!server.active_defrag_running) {
|
||||
if(frag_pct < server.active_defrag_threshold_lower || frag_bytes < server.active_defrag_ignore_bytes)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate the adaptive aggressiveness of the defrag */
|
||||
int cpu_pct = INTERPOLATE(frag_pct,
|
||||
server.active_defrag_threshold_lower,
|
||||
server.active_defrag_threshold_upper,
|
||||
server.active_defrag_cycle_min,
|
||||
server.active_defrag_cycle_max);
|
||||
cpu_pct = LIMIT(cpu_pct,
|
||||
server.active_defrag_cycle_min,
|
||||
server.active_defrag_cycle_max);
|
||||
/* We allow increasing the aggressiveness during a scan, but don't
|
||||
* reduce it. */
|
||||
if (!server.active_defrag_running ||
|
||||
cpu_pct > server.active_defrag_running)
|
||||
{
|
||||
server.active_defrag_running = cpu_pct;
|
||||
serverLog(LL_VERBOSE,
|
||||
"Starting active defrag, frag=%.0f%%, frag_bytes=%zu, cpu=%d%%",
|
||||
frag_pct, frag_bytes, cpu_pct);
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform incremental defragmentation work from the serverCron.
|
||||
* This works in a similar way to activeExpireCycle, in the sense that
|
||||
* we do incremental work across calls. */
|
||||
@@ -1058,6 +1058,7 @@ void activeDefragCycle(void) {
|
||||
latencyStartMonitor(latency);
|
||||
|
||||
do {
|
||||
/* if we're not continuing a scan from the last call or loop, start a new one */
|
||||
if (!cursor) {
|
||||
/* finish any leftovers from previous db before moving to the next one */
|
||||
if (db && defragLaterStep(db, endtime)) {
|
||||
|
||||
+4
-4
@@ -250,7 +250,7 @@ PORT_LONGLONG timeInMilliseconds(void) {
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv,NULL);
|
||||
return (((PORT_LONGLONG)tv.tv_sec)*1000)+(tv.tv_usec/1000);
|
||||
return (((long long)tv.tv_sec)*1000)+(tv.tv_usec/1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -723,9 +723,9 @@ unsigned int dictGetSomeKeys(dict *d, dictEntry **des, unsigned int count) {
|
||||
* the current rehashing index, so we jump if possible.
|
||||
* (this happens when going from big to small table). */
|
||||
if (i >= d->ht[1].size)
|
||||
i = (PORT_ULONG) d->rehashidx; WIN_PORT_FIX /* cast (unsigned long) */
|
||||
else
|
||||
continue;
|
||||
i = (PORT_ULONG) d->rehashidx; WIN_PORT_FIX /* cast (unsigned long) */
|
||||
else
|
||||
continue;
|
||||
}
|
||||
if (i >= d->ht[j].size) continue; /* Out of range for this table. */
|
||||
dictEntry *he = d->ht[j].table[i];
|
||||
|
||||
+4
-4
@@ -127,8 +127,8 @@ int geohashEncode(const GeoHashRange *long_range, const GeoHashRange *lat_range,
|
||||
|
||||
/* Return an error when trying to index outside the supported
|
||||
* constraints. */
|
||||
if (longitude > 180 || longitude < -180 ||
|
||||
latitude > 85.05112878 || latitude < -85.05112878) return 0;
|
||||
if (longitude > GEO_LONG_MAX || longitude < GEO_LONG_MIN ||
|
||||
latitude > GEO_LAT_MAX || latitude < GEO_LAT_MIN) return 0;
|
||||
|
||||
hash->bits = 0;
|
||||
hash->step = step;
|
||||
@@ -144,8 +144,8 @@ int geohashEncode(const GeoHashRange *long_range, const GeoHashRange *lat_range,
|
||||
(longitude - long_range->min) / (long_range->max - long_range->min);
|
||||
|
||||
/* convert to fixed point based on the step size */
|
||||
lat_offset *= (1 << step);
|
||||
long_offset *= (1 << step);
|
||||
lat_offset *= (1ULL << step);
|
||||
long_offset *= (1ULL << step);
|
||||
hash->bits = interleave64(lat_offset, long_offset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+5
-5
@@ -404,11 +404,11 @@ uint64_t MurmurHash64A (const void * key, int len, unsigned int seed) {
|
||||
uint64_t k;
|
||||
|
||||
#if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
#ifdef USE_ALIGNED_ACCESS
|
||||
memcpy(&k,data,sizeof(uint64_t));
|
||||
#else
|
||||
#ifdef USE_ALIGNED_ACCESS
|
||||
memcpy(&k,data,sizeof(uint64_t));
|
||||
#else
|
||||
k = *((uint64_t*)data);
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
k = (uint64_t) data[0];
|
||||
k |= (uint64_t) data[1] << 8;
|
||||
@@ -565,7 +565,7 @@ void hllDenseRegHisto(uint8_t *registers, int* reghisto) {
|
||||
r += 12;
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < HLL_REGISTERS; j++) {
|
||||
for(j = 0; j < HLL_REGISTERS; j++) {
|
||||
PORT_ULONG reg;
|
||||
HLL_DENSE_GET_REGISTER(reg,registers,j);
|
||||
reghisto[reg]++;
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
GIT_SHA1=`(git show-ref --head --hash=8 2> /dev/null || echo 00000000) | head -n1`
|
||||
GIT_DIRTY=`git diff --no-ext-diff 2> /dev/null | wc -l`
|
||||
BUILD_ID=`uname -n`"-"`date +%s`
|
||||
if [ -n "$SOURCE_DATE_EPOCH" ]; then
|
||||
BUILD_ID=$(date -u -d "@$SOURCE_DATE_EPOCH" +%s 2>/dev/null || date -u -r "$SOURCE_DATE_EPOCH" +%s 2>/dev/null || date -u %s)
|
||||
fi
|
||||
test -f release.h || touch release.h
|
||||
(cat release.h | grep SHA1 | grep $GIT_SHA1) && \
|
||||
(cat release.h | grep DIRTY | grep $GIT_DIRTY) && exit 0 # Already up-to-date
|
||||
|
||||
+23
-25
@@ -889,7 +889,6 @@ RedisModuleString *RM_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new module string object from a printf format and arguments.
|
||||
* The returned string must be freed with RedisModule_FreeString(), unless
|
||||
* automatic memory is enabled.
|
||||
@@ -1112,10 +1111,10 @@ int RM_WrongArity(RedisModuleCtx *ctx) {
|
||||
* initialized to run the timers callbacks. */
|
||||
client *moduleGetReplyClient(RedisModuleCtx *ctx) {
|
||||
if (ctx->flags & REDISMODULE_CTX_THREAD_SAFE) {
|
||||
if (ctx->blocked_client)
|
||||
return ctx->blocked_client->reply_client;
|
||||
if (ctx->blocked_client)
|
||||
return ctx->blocked_client->reply_client;
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
} else {
|
||||
/* If this is a non thread safe context, just return the client
|
||||
* that is running the command if any. This may be NULL as well
|
||||
@@ -1428,33 +1427,33 @@ int RM_GetSelectedDb(RedisModuleCtx *ctx) {
|
||||
}
|
||||
|
||||
|
||||
/* Return the current context's flags. The flags provide information on the
|
||||
/* Return the current context's flags. The flags provide information on the
|
||||
* current request context (whether the client is a Lua script or in a MULTI),
|
||||
* and about the Redis instance in general, i.e replication and persistence.
|
||||
*
|
||||
* and about the Redis instance in general, i.e replication and persistence.
|
||||
*
|
||||
* The available flags are:
|
||||
*
|
||||
*
|
||||
* * REDISMODULE_CTX_FLAGS_LUA: The command is running in a Lua script
|
||||
*
|
||||
*
|
||||
* * REDISMODULE_CTX_FLAGS_MULTI: The command is running inside a transaction
|
||||
*
|
||||
*
|
||||
* * REDISMODULE_CTX_FLAGS_REPLICATED: The command was sent over the replication
|
||||
* link by the MASTER
|
||||
*
|
||||
* * REDISMODULE_CTX_FLAGS_MASTER: The Redis instance is a master
|
||||
*
|
||||
*
|
||||
* * REDISMODULE_CTX_FLAGS_SLAVE: The Redis instance is a slave
|
||||
*
|
||||
*
|
||||
* * REDISMODULE_CTX_FLAGS_READONLY: The Redis instance is read-only
|
||||
*
|
||||
*
|
||||
* * REDISMODULE_CTX_FLAGS_CLUSTER: The Redis instance is in cluster mode
|
||||
*
|
||||
*
|
||||
* * REDISMODULE_CTX_FLAGS_AOF: The Redis instance has AOF enabled
|
||||
*
|
||||
*
|
||||
* * REDISMODULE_CTX_FLAGS_RDB: The instance has RDB enabled
|
||||
*
|
||||
*
|
||||
* * REDISMODULE_CTX_FLAGS_MAXMEMORY: The instance has Maxmemory set
|
||||
*
|
||||
*
|
||||
* * REDISMODULE_CTX_FLAGS_EVICT: Maxmemory is set and has an eviction
|
||||
* policy that may delete keys
|
||||
*
|
||||
@@ -1465,13 +1464,13 @@ int RM_GetSelectedDb(RedisModuleCtx *ctx) {
|
||||
* reaching the maxmemory level.
|
||||
*/
|
||||
int RM_GetContextFlags(RedisModuleCtx *ctx) {
|
||||
|
||||
|
||||
int flags = 0;
|
||||
/* Client specific flags */
|
||||
if (ctx->client) {
|
||||
if (ctx->client->flags & CLIENT_LUA)
|
||||
if (ctx->client->flags & CLIENT_LUA)
|
||||
flags |= REDISMODULE_CTX_FLAGS_LUA;
|
||||
if (ctx->client->flags & CLIENT_MULTI)
|
||||
if (ctx->client->flags & CLIENT_MULTI)
|
||||
flags |= REDISMODULE_CTX_FLAGS_MULTI;
|
||||
/* Module command recieved from MASTER, is replicated. */
|
||||
if (ctx->client->flags & CLIENT_MASTER)
|
||||
@@ -1480,14 +1479,14 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) {
|
||||
|
||||
if (server.cluster_enabled)
|
||||
flags |= REDISMODULE_CTX_FLAGS_CLUSTER;
|
||||
|
||||
|
||||
if (server.loading)
|
||||
flags |= REDISMODULE_CTX_FLAGS_LOADING;
|
||||
|
||||
/* Maxmemory and eviction policy */
|
||||
if (server.maxmemory > 0) {
|
||||
flags |= REDISMODULE_CTX_FLAGS_MAXMEMORY;
|
||||
|
||||
|
||||
if (server.maxmemory_policy != MAXMEMORY_NO_EVICTION)
|
||||
flags |= REDISMODULE_CTX_FLAGS_EVICT;
|
||||
}
|
||||
@@ -1506,7 +1505,7 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) {
|
||||
if (server.repl_slave_ro)
|
||||
flags |= REDISMODULE_CTX_FLAGS_READONLY;
|
||||
}
|
||||
|
||||
|
||||
/* OOM flag. */
|
||||
float level;
|
||||
int retval = getMaxmemoryState(NULL,NULL,NULL,&level);
|
||||
@@ -2726,7 +2725,7 @@ robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int
|
||||
size_t len = va_arg(ap,size_t);
|
||||
argv[argc++] = createStringObject(buf,len);
|
||||
} else if (*p == 'l') {
|
||||
PORT_LONG ll = va_arg(ap, PORT_LONGLONG);
|
||||
PORT_LONG ll = va_arg(ap,PORT_LONGLONG);
|
||||
argv[argc++] = createObject(OBJ_STRING,sdsfromlonglong(ll));
|
||||
} else if (*p == 'v') {
|
||||
/* A vector of strings */
|
||||
@@ -3382,7 +3381,6 @@ loaderr:
|
||||
/* Iterate over modules, and trigger rdb aux saving for the ones modules types
|
||||
* who asked for it. */
|
||||
ssize_t rdbSaveModulesAux(rio *rdb, int when) {
|
||||
|
||||
size_t total_written = 0;
|
||||
dictIterator *di = dictGetIterator(modules);
|
||||
dictEntry *de;
|
||||
|
||||
+14
-19
@@ -261,14 +261,14 @@ int _addReplyToBuffer(client *c, const char *s, size_t len) {
|
||||
if (len > available) return C_ERR;
|
||||
|
||||
memcpy(c->buf+c->bufpos,s,len);
|
||||
c->bufpos+= (int)len; WIN_PORT_FIX /* cast (int) */
|
||||
c->bufpos+=(int)len; WIN_PORT_FIX /* cast (int) */
|
||||
return C_OK;
|
||||
}
|
||||
|
||||
void _addReplyStringToList(client *c, const char *s, size_t len) {
|
||||
if (c->flags & CLIENT_CLOSE_AFTER_REPLY) return;
|
||||
|
||||
listNode *ln = listLast(c->reply);
|
||||
listNode *ln = listLast(c->reply);
|
||||
clientReplyBlock *tail = ln? listNodeValue(ln): NULL;
|
||||
|
||||
/* Note that 'tail' may be NULL even if we have a tail node, becuase when
|
||||
@@ -317,7 +317,7 @@ void addReply(client *c, robj *obj) {
|
||||
/* For integer encoded strings we just convert it into a string
|
||||
* using our optimized function, and attach the resulting string
|
||||
* to the output buffer. */
|
||||
char buf[32];
|
||||
char buf[32];
|
||||
size_t len = ll2string(buf,sizeof(buf),(PORT_LONG)obj->ptr);
|
||||
if (_addReplyToBuffer(c,buf,len) != C_OK)
|
||||
_addReplyStringToList(c,buf,len);
|
||||
@@ -336,7 +336,7 @@ void addReplySds(client *c, sds s) {
|
||||
}
|
||||
if (_addReplyToBuffer(c,s,sdslen(s)) != C_OK)
|
||||
_addReplyStringToList(c,s,sdslen(s));
|
||||
sdsfree(s);
|
||||
sdsfree(s);
|
||||
}
|
||||
|
||||
/* This low level function just adds whatever protocol you send it to the
|
||||
@@ -902,7 +902,7 @@ void freeClient(client *c) {
|
||||
|
||||
/* Log link disconnection with slave */
|
||||
if ((c->flags & CLIENT_SLAVE) && !(c->flags & CLIENT_MONITOR)) {
|
||||
serverLog(LL_WARNING,"Connection with slave %s lost.",
|
||||
serverLog(LL_WARNING,"Connection with replica %s lost.",
|
||||
replicationGetSlaveName(c));
|
||||
}
|
||||
|
||||
@@ -1088,10 +1088,9 @@ int writeToClient(int fd, client *c, int handler_installed) {
|
||||
|
||||
/* If we fully sent the object on head go to the next one */
|
||||
if (c->sentlen == objlen) {
|
||||
c->reply_bytes -= (PORT_ULONG)o->size;
|
||||
c->reply_bytes -= (PORT_ULONG)o->size;
|
||||
listDelNode(c->reply,listFirst(c->reply));
|
||||
c->sentlen = 0;
|
||||
|
||||
/* If there are no longer objects in the list, we expect
|
||||
* the count of reply bytes to be exactly zero. */
|
||||
if (listLength(c->reply) == 0)
|
||||
@@ -1120,13 +1119,8 @@ int writeToClient(int fd, client *c, int handler_installed) {
|
||||
if (errno == EAGAIN) {
|
||||
nwritten = 0;
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
serverLog(LL_VERBOSE,
|
||||
"Error writing to client: %s", wsa_strerror(errno));
|
||||
#else
|
||||
serverLog(LL_VERBOSE,
|
||||
"Error writing to client: %s", strerror(errno));
|
||||
#endif
|
||||
"Error writing to client: %s", IF_WIN32(wsa_strerror,strerror)(errno));
|
||||
freeClient(c);
|
||||
return C_ERR;
|
||||
}
|
||||
@@ -1392,7 +1386,7 @@ static void setProtocolError(const char *errstr, client *c) {
|
||||
* to be '*'. Otherwise for inline commands processInlineBuffer() is called. */
|
||||
int processMultibulkBuffer(client *c) {
|
||||
char *newline = NULL;
|
||||
int ok;
|
||||
int ok;
|
||||
PORT_LONGLONG ll;
|
||||
|
||||
if (c->multibulklen == 0) {
|
||||
@@ -1482,11 +1476,11 @@ int processMultibulkBuffer(client *c) {
|
||||
if (sdslen(c->querybuf)-c->qb_pos <= (size_t)ll+2) {
|
||||
sdsrange(c->querybuf,c->qb_pos,-1);
|
||||
c->qb_pos = 0;
|
||||
/* Hint the sds library about the amount of bytes this string is
|
||||
* going to contain. */
|
||||
/* Hint the sds library about the amount of bytes this string is
|
||||
* going to contain. */
|
||||
c->querybuf = sdsMakeRoomFor(c->querybuf,ll+2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
c->bulklen = (PORT_LONG)ll; WIN_PORT_FIX /* cast (PORT_LONG) */
|
||||
}
|
||||
|
||||
@@ -1531,6 +1525,7 @@ int processMultibulkBuffer(client *c) {
|
||||
* pending query buffer, already representing a full command, to process. */
|
||||
void processInputBuffer(client *c) {
|
||||
server.current_client = c;
|
||||
|
||||
/* Keep processing while there is something in the input buffer */
|
||||
while(c->qb_pos < sdslen(c->querybuf)) {
|
||||
/* Return if clients are paused. */
|
||||
@@ -1992,7 +1987,7 @@ NULL
|
||||
} else {
|
||||
addReply(c,shared.czero);
|
||||
}
|
||||
}else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) {
|
||||
} else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) {
|
||||
int j, len = (int)sdslen(c->argv[2]->ptr); WIN_PORT_FIX /* cast (int) */
|
||||
char *p = c->argv[2]->ptr;
|
||||
|
||||
|
||||
+3
-3
@@ -473,9 +473,9 @@ robj *tryObjectEncoding(robj *o) {
|
||||
} else {
|
||||
if (o->encoding == OBJ_ENCODING_RAW) {
|
||||
sdsfree(o->ptr);
|
||||
o->encoding = OBJ_ENCODING_INT;
|
||||
o->ptr = (void*) value;
|
||||
return o;
|
||||
o->encoding = OBJ_ENCODING_INT;
|
||||
o->ptr = (void*) value;
|
||||
return o;
|
||||
} else if (o->encoding == OBJ_ENCODING_EMBSTR) {
|
||||
decrRefCount(o);
|
||||
return createStringObjectFromLongLongForValue(value);
|
||||
|
||||
+1
-1
@@ -334,7 +334,7 @@ NULL
|
||||
};
|
||||
addReplyHelp(c, help);
|
||||
} else if (!strcasecmp(c->argv[1]->ptr,"channels") &&
|
||||
(c->argc == 2 || c->argc ==3))
|
||||
(c->argc == 2 || c->argc == 3))
|
||||
{
|
||||
/* PUBSUB CHANNELS [<pattern>] */
|
||||
sds pat = (c->argc == 2) ? NULL : c->argv[2]->ptr;
|
||||
|
||||
+1
-1
@@ -149,7 +149,7 @@ REDIS_STATIC quicklistNode *quicklistCreateNode(void) {
|
||||
}
|
||||
|
||||
/* Return cached quicklist count */
|
||||
PORT_ULONG quicklistCount(const quicklist *ql) { return (unsigned int)(ql->count); } WIN_PORT_FIX /* cast (unsigned int) */
|
||||
PORT_ULONG quicklistCount(const quicklist *ql) { return (PORT_ULONG)(ql->count); } WIN_PORT_FIX /* cast (unsigned int) */
|
||||
|
||||
/* Free entire quicklist. */
|
||||
void quicklistRelease(quicklist *quicklist) {
|
||||
|
||||
@@ -1674,8 +1674,8 @@ int raxSeek(raxIterator *it, const char *op, unsigned char *ele, size_t len) {
|
||||
*
|
||||
* So in that case, we don't seek backward. */
|
||||
} else {
|
||||
if (gt && !raxIteratorNextStep(it,0)) return 0;
|
||||
if (lt && !raxIteratorPrevStep(it,0)) return 0;
|
||||
if (gt && !raxIteratorNextStep(it,0)) return 0;
|
||||
if (lt && !raxIteratorPrevStep(it,0)) return 0;
|
||||
}
|
||||
it->flags |= RAX_ITER_JUST_SEEKED; /* Ignore next call. */
|
||||
}
|
||||
|
||||
@@ -1009,7 +1009,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) {
|
||||
if (retval == -1)
|
||||
io.error = 1;
|
||||
else
|
||||
io.bytes += retval;
|
||||
io.bytes += retval;
|
||||
|
||||
if (io.ctx) {
|
||||
moduleFreeContext(io.ctx);
|
||||
@@ -1226,7 +1226,7 @@ int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi) {
|
||||
}
|
||||
}
|
||||
dictReleaseIterator(di);
|
||||
di = NULL; /* So that we don't release it again on error. */
|
||||
di = NULL; /* So that we don't release it again on error. */
|
||||
}
|
||||
|
||||
/* If we are storing the replication information on disk, persist
|
||||
@@ -2119,19 +2119,19 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi, int loading_aof) {
|
||||
decrRefCount(key);
|
||||
decrRefCount(val);
|
||||
} else {
|
||||
/* Add the new object in the hash table */
|
||||
dbAdd(db,key,val);
|
||||
|
||||
/* Set the expire time if needed */
|
||||
if (expiretime != -1) setExpire(NULL,db,key,expiretime);
|
||||
/* Add the new object in the hash table */
|
||||
dbAdd(db,key,val);
|
||||
|
||||
/* Set the expire time if needed */
|
||||
if (expiretime != -1) setExpire(NULL,db,key,expiretime);
|
||||
|
||||
/* Set usage information (for eviction). */
|
||||
objectSetLRUOrLFU(val,lfu_freq,lru_idle,lru_clock);
|
||||
|
||||
/* Decrement the key refcount since dbAdd() will take its
|
||||
* own reference. */
|
||||
decrRefCount(key);
|
||||
}
|
||||
decrRefCount(key);
|
||||
}
|
||||
|
||||
/* Reset the state that is key-specified and is populated by
|
||||
* opcodes before the key, so that we start from scratch again. */
|
||||
|
||||
@@ -124,10 +124,10 @@ static PORT_LONGLONG ustime(void) {
|
||||
return GetHighResRelativeTime(1000000);
|
||||
#else
|
||||
struct timeval tv;
|
||||
PORT_LONGLONG ust;
|
||||
long long ust;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
ust = ((PORT_LONG)tv.tv_sec)*1000000;
|
||||
ust = ((long)tv.tv_sec)*1000000;
|
||||
ust += tv.tv_usec;
|
||||
return ust;
|
||||
#endif
|
||||
@@ -138,10 +138,10 @@ static PORT_LONGLONG mstime(void) {
|
||||
return GetHighResRelativeTime(1000);
|
||||
#else
|
||||
struct timeval tv;
|
||||
PORT_LONGLONG mst;
|
||||
long long mst;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
mst = ((PORT_LONGLONG)tv.tv_sec)*1000;
|
||||
mst = ((long long)tv.tv_sec)*1000;
|
||||
mst += tv.tv_usec/1000;
|
||||
return mst;
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
snprintf(error, sizeof(error), "0x%16llx: %s", (PORT_LONGLONG)epos, __buf); \
|
||||
}
|
||||
|
||||
static char error[1024];
|
||||
static char error[1044];
|
||||
static off_t epos;
|
||||
|
||||
int consumeNewline(char *buf) {
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
|
||||
void createSharedObjects(void);
|
||||
void rdbLoadProgressCallback(rio *r, const void *buf, size_t len);
|
||||
PORT_LONGLONG rdbLoadMillisecondTime(rio *rdb);
|
||||
int rdbCheckMode = 0;
|
||||
|
||||
struct {
|
||||
|
||||
+4
-4
@@ -811,11 +811,11 @@ static int cliConnect(int flags) {
|
||||
|
||||
if (context->err) {
|
||||
if (!(flags & CC_QUIET)) {
|
||||
fprintf(stderr,"Could not connect to Redis at ");
|
||||
if (config.hostsocket == NULL)
|
||||
fprintf(stderr,"Could not connect to Redis at ");
|
||||
if (config.hostsocket == NULL)
|
||||
fprintf(stderr,"%s:%d: %s\n",
|
||||
config.hostip,config.hostport,context->errstr);
|
||||
else
|
||||
else
|
||||
fprintf(stderr,"%s: %s\n",
|
||||
config.hostsocket,context->errstr);
|
||||
}
|
||||
@@ -6478,7 +6478,7 @@ static void findBigKeys(int memkeys, unsigned memkeys_samples) {
|
||||
|
||||
/* Reallocate our type and size array if we need to */
|
||||
if(keys->elements > arrsize) {
|
||||
types = zrealloc(types, sizeof(int)*keys->elements);
|
||||
types = zrealloc(types, sizeof(typeinfo*)*keys->elements);
|
||||
sizes = zrealloc(sizes, sizeof(PORT_ULONGLONG)*keys->elements);
|
||||
|
||||
if(!types || !sizes) {
|
||||
|
||||
+26
-26
@@ -16,7 +16,7 @@ def colorized(str, color)
|
||||
}[color]
|
||||
return str if !color_code
|
||||
"\033[#{color_code}m#{str}\033[0m"
|
||||
end
|
||||
end
|
||||
|
||||
class String
|
||||
|
||||
@@ -24,10 +24,10 @@ class String
|
||||
color = :"#{color}"
|
||||
define_method(color){
|
||||
colorized(self, color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
COMMANDS = %w(create check info fix reshard rebalance add-node
|
||||
del-node set-timeout call import help)
|
||||
@@ -39,49 +39,49 @@ ALLOWED_OPTIONS={
|
||||
"reshard" => {"from" => true, "to" => true, "slots" => true, "yes" => false, "timeout" => true, "pipeline" => true},
|
||||
"rebalance" => {"weight" => [], "auto-weights" => false, "use-empty-masters" => false, "timeout" => true, "simulate" => false, "pipeline" => true, "threshold" => true},
|
||||
"fix" => {"timeout" => 0},
|
||||
}
|
||||
}
|
||||
|
||||
def parse_options(cmd)
|
||||
def parse_options(cmd)
|
||||
cmd = cmd.downcase
|
||||
idx = 0
|
||||
options={}
|
||||
options = {}
|
||||
args = []
|
||||
while (arg = ARGV.shift)
|
||||
if arg[0..1] == "--"
|
||||
option = arg[2..-1]
|
||||
|
||||
# --verbose is a global option
|
||||
# --verbose is a global option
|
||||
if option == "--verbose"
|
||||
options['verbose'] = true
|
||||
next
|
||||
end
|
||||
next
|
||||
end
|
||||
if ALLOWED_OPTIONS[cmd] == nil ||
|
||||
ALLOWED_OPTIONS[cmd][option] == nil
|
||||
next
|
||||
end
|
||||
if ALLOWED_OPTIONS[cmd][option] != false
|
||||
end
|
||||
if ALLOWED_OPTIONS[cmd][option] != false
|
||||
value = ARGV.shift
|
||||
next if !value
|
||||
else
|
||||
value = true
|
||||
end
|
||||
|
||||
# If the option is set to [], it's a multiple arguments
|
||||
# option. We just queue every new value into an array.
|
||||
if ALLOWED_OPTIONS[cmd][option] == []
|
||||
options[option] = [] if !options[option]
|
||||
options[option] << value
|
||||
else
|
||||
options[option] = value
|
||||
end
|
||||
else
|
||||
value = true
|
||||
end
|
||||
|
||||
# If the option is set to [], it's a multiple arguments
|
||||
# option. We just queue every new value into an array.
|
||||
if ALLOWED_OPTIONS[cmd][option] == []
|
||||
options[option] = [] if !options[option]
|
||||
options[option] << value
|
||||
else
|
||||
options[option] = value
|
||||
end
|
||||
else
|
||||
next if arg[0,1] == '-'
|
||||
args << arg
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return options,args
|
||||
end
|
||||
end
|
||||
|
||||
def command_example(cmd, args, opts)
|
||||
cmd = "redis-cli --cluster #{cmd}"
|
||||
@@ -126,4 +126,4 @@ puts ''
|
||||
puts "To get help about all subcommands, type:"
|
||||
puts "redis-cli --cluster help".bold
|
||||
puts ''
|
||||
exit 1
|
||||
exit 1
|
||||
|
||||
+2
-2
@@ -38,12 +38,12 @@
|
||||
#ifndef __REDIS_ASSERT_H__
|
||||
#define __REDIS_ASSERT_H__
|
||||
|
||||
POSIX_ONLY(#include <unistd.h>) /* for _exit() */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Win32_Interop/Win32_Portability.h"
|
||||
#endif
|
||||
|
||||
POSIX_ONLY(#include <unistd.h>) /* for _exit() */
|
||||
|
||||
#define assert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),_exit(1)))
|
||||
#define panic(...) _serverPanic(__FILE__,__LINE__,__VA_ARGS__),_exit(1)
|
||||
|
||||
|
||||
+2
-2
@@ -164,9 +164,9 @@ typedef struct RedisModuleDictIter RedisModuleDictIter;
|
||||
typedef struct RedisModuleCommandFilterCtx RedisModuleCommandFilterCtx;
|
||||
typedef struct RedisModuleCommandFilter RedisModuleCommandFilter;
|
||||
|
||||
typedef int (*RedisModuleCmdFunc) (RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
|
||||
typedef int (*RedisModuleCmdFunc)(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
|
||||
typedef void (*RedisModuleDisconnectFunc)(RedisModuleCtx *ctx, RedisModuleBlockedClient *bc);
|
||||
typedef int (*RedisModuleNotificationFunc) (RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key);
|
||||
typedef int (*RedisModuleNotificationFunc)(RedisModuleCtx *ctx, int type, const char *event, RedisModuleString *key);
|
||||
typedef void *(*RedisModuleTypeLoadFunc)(RedisModuleIO *rdb, int encver);
|
||||
typedef void (*RedisModuleTypeSaveFunc)(RedisModuleIO *rdb, void *value);
|
||||
typedef int (*RedisModuleTypeAuxLoadFunc)(RedisModuleIO *rdb, int encver, int when);
|
||||
|
||||
+12
-11
@@ -1355,8 +1355,8 @@ void readSyncBulkPayload(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
|
||||
server.repl_transfer_lastio = server.unixtime;
|
||||
if ((nwritten = write(server.repl_transfer_fd,buf,nread)) != nread) {
|
||||
serverLog(LL_WARNING, "Write error or short write writing to the DB dump file needed for MASTER <-> REPLICA synchronization: %s",
|
||||
(nwritten == -1) ? IF_WIN32(wsa_strerror(errno), strerror(errno)) : "short write");
|
||||
serverLog(LL_WARNING,"Write error or short write writing to the DB dump file needed for MASTER <-> REPLICA synchronization: %s",
|
||||
(nwritten == -1) ? IF_WIN32(wsa_strerror(errno), strerror(errno)) : "short write");
|
||||
goto error;
|
||||
}
|
||||
server.repl_transfer_read += nread;
|
||||
@@ -1399,7 +1399,7 @@ void readSyncBulkPayload(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
server.repl_transfer_fd = -1;
|
||||
#endif
|
||||
|
||||
/* Ensure background save doesn't overwrite synced data */
|
||||
/* Ensure background save doesn't overwrite synced data */
|
||||
if (server.rdb_child_pid != -1) {
|
||||
serverLog(LL_NOTICE,
|
||||
"Replica is about to load the RDB file received from the "
|
||||
@@ -1411,8 +1411,9 @@ void readSyncBulkPayload(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
IF_WIN32(AbortForkOperation(), kill(server.rdb_child_pid,SIGUSR1));
|
||||
rdbRemoveTempFile(server.rdb_child_pid);
|
||||
}
|
||||
|
||||
if (rename(server.repl_transfer_tmpfile,server.rdb_filename) == -1) {
|
||||
serverLog(LL_WARNING,"Failed trying to rename the temp DB into dump.rdb in MASTER <-> SLAVE synchronization: %s", IF_WIN32(wsa_strerror(errno),strerror(errno)));
|
||||
serverLog(LL_WARNING,"Failed trying to rename the temp DB into dump.rdb in MASTER <-> REPLICA synchronization: %s", IF_WIN32(wsa_strerror(errno),strerror(errno)));
|
||||
cancelReplicationHandshake();
|
||||
return;
|
||||
}
|
||||
@@ -1507,7 +1508,7 @@ char *sendSynchronousCommand(int flags, int fd, ...) {
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
|
||||
cmd = sdscatprintf(cmd,"*%Iu\r\n",argslen); WIN_PORT_FIX /* zu->Iu */
|
||||
cmd = sdscatsds(cmd,cmdargs);
|
||||
sdsfree(cmdargs);
|
||||
@@ -1527,7 +1528,7 @@ char *sendSynchronousCommand(int flags, int fd, ...) {
|
||||
if (flags & SYNC_CMD_READ) {
|
||||
char buf[256];
|
||||
|
||||
if (syncReadLine(fd,buf,sizeof(buf), (PORT_LONGLONG)server.repl_syncio_timeout*1000) WIN_PORT_FIX /* cast (PORT_LONGLONG) */
|
||||
if (syncReadLine(fd,buf,sizeof(buf),(PORT_LONGLONG)server.repl_syncio_timeout*1000) WIN_PORT_FIX /* cast (PORT_LONGLONG) */
|
||||
== -1)
|
||||
{
|
||||
return sdscatprintf(sdsempty(),"-Reading from master: %s",
|
||||
@@ -2763,11 +2764,11 @@ void replicationCron(void) {
|
||||
clientsArePaused();
|
||||
|
||||
if (!manual_failover_in_progress) {
|
||||
ping_argv[0] = createStringObject("PING",4);
|
||||
replicationFeedSlaves(server.slaves, server.slaveseldb,
|
||||
ping_argv, 1);
|
||||
decrRefCount(ping_argv[0]);
|
||||
}
|
||||
ping_argv[0] = createStringObject("PING",4);
|
||||
replicationFeedSlaves(server.slaves, server.slaveseldb,
|
||||
ping_argv, 1);
|
||||
decrRefCount(ping_argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Second, send a newline to all the slaves in pre-synchronization
|
||||
|
||||
@@ -121,7 +121,7 @@ static size_t rioFileWrite(rio *r, const void *buf, size_t len) {
|
||||
r->io.file.buffered >= r->io.file.autosync)
|
||||
{
|
||||
fflush(r->io.file.fp);
|
||||
redis_fsync(fileno(r->io.file.fp));
|
||||
redis_fsync(fileno(r->io.file.fp));
|
||||
r->io.file.buffered = 0;
|
||||
}
|
||||
return retval;
|
||||
|
||||
+4
-4
@@ -504,7 +504,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
|
||||
goto cleanup;
|
||||
} else if (deny_write_type != DISK_ERROR_TYPE_NONE) {
|
||||
if (deny_write_type == DISK_ERROR_TYPE_RDB) {
|
||||
luaPushError(lua, shared.bgsaveerr->ptr);
|
||||
luaPushError(lua, shared.bgsaveerr->ptr);
|
||||
} else {
|
||||
sds aof_write_err = sdscatfmt(sdsempty(),
|
||||
"-MISCONF Errors writing to the AOF file: %s\r\n",
|
||||
@@ -1457,9 +1457,9 @@ void evalGenericCommand(client *c, int evalsha) {
|
||||
resetRefCount(createStringObject("LOAD",4)),
|
||||
script);
|
||||
} else {
|
||||
rewriteClientCommandArgument(c,0,
|
||||
resetRefCount(createStringObject("EVAL",4)));
|
||||
rewriteClientCommandArgument(c,1,script);
|
||||
rewriteClientCommandArgument(c,0,
|
||||
resetRefCount(createStringObject("EVAL",4)));
|
||||
rewriteClientCommandArgument(c,1,script);
|
||||
}
|
||||
forceCommandPropagation(c,PROPAGATE_REPL|PROPAGATE_AOF);
|
||||
}
|
||||
|
||||
@@ -720,7 +720,7 @@ sds sdscatfmt(sds s, char const *fmt, ...) {
|
||||
* s = sdstrim(s,"Aa. :");
|
||||
* printf("%s\n", s);
|
||||
*
|
||||
* Output will be just "Hello World".
|
||||
* Output will be just "HelloWorld".
|
||||
*/
|
||||
sds sdstrim(sds s, const char *cset) {
|
||||
char *start, *end, *sp, *ep;
|
||||
|
||||
+4
-4
@@ -2198,7 +2198,7 @@ void sentinelReconnectInstance(sentinelRedisInstance *ri) {
|
||||
retval = redisAsyncCommand(link->pc,
|
||||
sentinelReceiveHelloMessages, ri, "%s %s",
|
||||
sentinelInstanceMapCommand(ri,"SUBSCRIBE"),
|
||||
SENTINEL_HELLO_CHANNEL);
|
||||
SENTINEL_HELLO_CHANNEL);
|
||||
if (retval != C_OK) {
|
||||
/* If we can't subscribe, the Pub/Sub connection is useless
|
||||
* and we can simply disconnect it and try again. */
|
||||
@@ -2744,7 +2744,7 @@ int sentinelSendHello(sentinelRedisInstance *ri) {
|
||||
retval = redisAsyncCommand(ri->link->cc,
|
||||
sentinelPublishReplyCallback, ri, "%s %s %s",
|
||||
sentinelInstanceMapCommand(ri,"PUBLISH"),
|
||||
SENTINEL_HELLO_CHANNEL,payload);
|
||||
SENTINEL_HELLO_CHANNEL,payload);
|
||||
if (retval != C_OK) return C_ERR;
|
||||
ri->link->pending_commands++;
|
||||
return C_OK;
|
||||
@@ -3195,7 +3195,7 @@ void sentinelCommand(client *c) {
|
||||
!= C_OK)
|
||||
return;
|
||||
ri = getSentinelRedisInstanceByAddrAndRunID(sentinel.masters,
|
||||
c->argv[2]->ptr, (int) port, NULL); WIN_PORT_FIX /* cast (int) */
|
||||
c->argv[2]->ptr,(int)port,NULL); WIN_PORT_FIX /* cast (int) */
|
||||
|
||||
/* It exists? Is actually a master? Is subjectively down? It's down.
|
||||
* Note: if we are in tilt mode we always reply with "0". */
|
||||
@@ -4000,7 +4000,7 @@ char *sentinelGetLeader(sentinelRedisInstance *master, uint64_t epoch) {
|
||||
serverAssert(master->flags & (SRI_O_DOWN|SRI_FAILOVER_IN_PROGRESS));
|
||||
counters = dictCreate(&leaderVotesDictType,NULL);
|
||||
|
||||
voters = (unsigned int)dictSize(master->sentinels)+1; /* All the other sentinels and me. */ WIN_PORT_FIX /* cast (unsigned int) */
|
||||
voters = (unsigned int)dictSize(master->sentinels)+1; /* All the other sentinels and me.*/ WIN_PORT_FIX /* cast (unsigned int) */
|
||||
|
||||
/* Count other sentinels votes */
|
||||
di = dictGetIterator(master->sentinels);
|
||||
|
||||
+55
-55
@@ -485,8 +485,8 @@ int dictSdsKeyCompare(void *privdata, const void *key1,
|
||||
int l1,l2;
|
||||
DICT_NOTUSED(privdata);
|
||||
|
||||
l1 = (int) sdslen((sds)key1); WIN_PORT_FIX /* cast (int) */
|
||||
l2 = (int) sdslen((sds)key2); WIN_PORT_FIX /* cast (int) */
|
||||
l1 = (int)sdslen((sds)key1); WIN_PORT_FIX /* cast (int) */
|
||||
l2 = (int)sdslen((sds)key2); WIN_PORT_FIX /* cast (int) */
|
||||
if (l1 != l2) return 0;
|
||||
return memcmp(key1, key2, l1) == 0;
|
||||
}
|
||||
@@ -584,7 +584,7 @@ dictType objectKeyPointerValueDictType = {
|
||||
NULL, /* key dup */
|
||||
NULL, /* val dup */
|
||||
dictEncObjKeyCompare, /* key compare */
|
||||
dictObjectDestructor, /* key destructor */
|
||||
dictObjectDestructor, /* key destructor */
|
||||
NULL /* val destructor */
|
||||
};
|
||||
|
||||
@@ -796,7 +796,7 @@ void updateDictResizePolicy(void) {
|
||||
void trackInstantaneousMetric(int metric, PORT_LONGLONG current_reading) {
|
||||
PORT_LONGLONG t = mstime() - server.inst_metric[metric].last_sample_time;
|
||||
PORT_LONGLONG ops = current_reading -
|
||||
server.inst_metric[metric].last_sample_count;
|
||||
server.inst_metric[metric].last_sample_count;
|
||||
PORT_LONGLONG ops_sec;
|
||||
|
||||
ops_sec = t > 0 ? (ops*1000/t) : 0;
|
||||
@@ -1013,10 +1013,10 @@ void databasesCron(void) {
|
||||
* as master will synthesize DELs for us. */
|
||||
if (server.active_expire_enabled) {
|
||||
if (server.masterhost == NULL) {
|
||||
activeExpireCycle(ACTIVE_EXPIRE_CYCLE_SLOW);
|
||||
activeExpireCycle(ACTIVE_EXPIRE_CYCLE_SLOW);
|
||||
} else {
|
||||
expireSlaveKeys();
|
||||
}
|
||||
expireSlaveKeys();
|
||||
}
|
||||
}
|
||||
|
||||
/* Defrag keys gradually. */
|
||||
@@ -1075,16 +1075,13 @@ void updateCachedTime(void) {
|
||||
* and cache the result. However calling localtime_r in this context is safe
|
||||
* since we will never fork() while here, in the main thread. The logging
|
||||
* function will call a thread safe version of localtime that has no locks. */
|
||||
#if _WIN32
|
||||
server.daylight_active = 0; //TODO port call to windows
|
||||
#else
|
||||
struct tm tm;
|
||||
localtime_r(&server.unixtime, &tm);
|
||||
server.daylight_active = tm.tm_isdst;
|
||||
struct tm tm;
|
||||
#ifdef _WIN32
|
||||
localtime_s(&tm,&server.unixtime);
|
||||
#else
|
||||
localtime_r(&server.unixtime,&tm);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
server.daylight_active = tm.tm_isdst;
|
||||
}
|
||||
|
||||
/* This is our timer interrupt, called server.hz times per second.
|
||||
@@ -1297,7 +1294,7 @@ int serverCron(struct aeEventLoop *eventLoop, PORT_LONGLONG id, void *clientData
|
||||
} else {
|
||||
/* If there is not a background saving/rewrite in progress check if
|
||||
* we have to save/rewrite now. */
|
||||
for (j = 0; j < server.saveparamslen; j++) {
|
||||
for (j = 0; j < server.saveparamslen; j++) {
|
||||
struct saveparam *sp = server.saveparams+j;
|
||||
|
||||
/* Save if we reached the given amount of changes,
|
||||
@@ -1317,23 +1314,23 @@ int serverCron(struct aeEventLoop *eventLoop, PORT_LONGLONG id, void *clientData
|
||||
rdbSaveBackground(server.rdb_filename,rsiptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Trigger an AOF rewrite if needed. */
|
||||
if (server.aof_state == AOF_ON &&
|
||||
server.rdb_child_pid == -1 &&
|
||||
server.aof_child_pid == -1 &&
|
||||
server.aof_rewrite_perc &&
|
||||
server.aof_current_size > server.aof_rewrite_min_size)
|
||||
{
|
||||
/* Trigger an AOF rewrite if needed. */
|
||||
if (server.aof_state == AOF_ON &&
|
||||
server.rdb_child_pid == -1 &&
|
||||
server.aof_child_pid == -1 &&
|
||||
server.aof_rewrite_perc &&
|
||||
server.aof_current_size > server.aof_rewrite_min_size)
|
||||
{
|
||||
PORT_LONGLONG base = server.aof_rewrite_base_size ?
|
||||
server.aof_rewrite_base_size : 1;
|
||||
server.aof_rewrite_base_size : 1;
|
||||
PORT_LONGLONG growth = (server.aof_current_size*100/base) - 100;
|
||||
if (growth >= server.aof_rewrite_perc) {
|
||||
serverLog(LL_NOTICE,"Starting automatic rewriting of AOF on %lld%% growth",growth);
|
||||
rewriteAppendOnlyFileBackground();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1366,7 +1363,7 @@ int serverCron(struct aeEventLoop *eventLoop, PORT_LONGLONG id, void *clientData
|
||||
}
|
||||
|
||||
/* Run the Sentinel timer if we are in sentinel mode. */
|
||||
if (server.sentinel_mode) sentinelTimer();
|
||||
if (server.sentinel_mode) sentinelTimer();
|
||||
|
||||
/* Cleanup expired MIGRATE cached sockets. */
|
||||
run_with_period(1000) {
|
||||
@@ -1588,7 +1585,7 @@ void initServerConfig(void) {
|
||||
server.configfile = NULL;
|
||||
server.executable = NULL;
|
||||
server.hz = server.config_hz = CONFIG_DEFAULT_HZ;
|
||||
server.dynamic_hz = CONFIG_DEFAULT_DYNAMIC_HZ;
|
||||
server.dynamic_hz = CONFIG_DEFAULT_DYNAMIC_HZ;
|
||||
server.arch_bits = (sizeof(PORT_LONG) == 8) ? 64 : 32;
|
||||
server.port = CONFIG_DEFAULT_SERVER_PORT;
|
||||
server.tcp_backlog = CONFIG_DEFAULT_TCP_BACKLOG;
|
||||
@@ -1787,7 +1784,6 @@ void initServerConfig(void) {
|
||||
|
||||
extern char **environ;
|
||||
|
||||
|
||||
/* Restart the server, executing the same executable that started this
|
||||
* instance, with the same arguments and configuration file.
|
||||
*
|
||||
@@ -1825,7 +1821,7 @@ int restartServer(int flags, mstime_t delay) {
|
||||
}
|
||||
|
||||
/* Perform a proper shutdown. */
|
||||
if (flags & RESTART_SERVER_GRACEFULLY &&
|
||||
if (flags & RESTART_SERVER_GRACEFULLY &&
|
||||
prepareForShutdown(SHUTDOWN_NOFLAGS) != C_OK)
|
||||
{
|
||||
serverLog(LL_WARNING,"Can't restart: error preparing for shutdown");
|
||||
@@ -1837,16 +1833,19 @@ int restartServer(int flags, mstime_t delay) {
|
||||
for (j = 3; j < server.maxclients + 1024; j++) {
|
||||
/* Test the descriptor validity before closing it, otherwise
|
||||
* Valgrind issues a warning on close(). */
|
||||
if (fcntl(j, IF_WIN32(F_GETFL, 1), 0) != -1) close(j);
|
||||
#if _WIN32
|
||||
if (fcntl(j, F_GETFL, 0) != -1) close(j);
|
||||
#else
|
||||
if (fcntl(j,F_GETFD) != -1) close(j);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Execute the server with the original command line. */
|
||||
if (delay) usleep(delay*1000);
|
||||
zfree(server.exec_argv[0]);
|
||||
server.exec_argv[0] = zstrdup(server.executable);
|
||||
execve(server.executable, server.exec_argv, environ);
|
||||
|
||||
execve(server.executable,server.exec_argv,environ);
|
||||
|
||||
/* If an error occurred here, there is nothing we can do, but exit. */
|
||||
_exit(1);
|
||||
|
||||
@@ -3131,9 +3130,9 @@ NULL
|
||||
if (!keys) {
|
||||
addReplyError(c,"Invalid arguments specified for command");
|
||||
} else {
|
||||
addReplyMultiBulkLen(c,numkeys);
|
||||
for (j = 0; j < numkeys; j++) addReplyBulk(c,c->argv[keys[j]+2]);
|
||||
getKeysFreeResult(keys);
|
||||
addReplyMultiBulkLen(c,numkeys);
|
||||
for (j = 0; j < numkeys; j++) addReplyBulk(c,c->argv[keys[j]+2]);
|
||||
getKeysFreeResult(keys);
|
||||
}
|
||||
} else {
|
||||
addReplySubcommandSyntaxError(c);
|
||||
@@ -3176,7 +3175,7 @@ sds genRedisInfoString(char *section) {
|
||||
sds info = sdsempty();
|
||||
time_t uptime = server.unixtime-server.stat_starttime;
|
||||
int j;
|
||||
struct rusage self_ru, c_ru;
|
||||
struct rusage self_ru, c_ru;
|
||||
int allsections = 0, defsections = 0;
|
||||
int sections = 0;
|
||||
|
||||
@@ -3186,7 +3185,7 @@ sds genRedisInfoString(char *section) {
|
||||
|
||||
getrusage(RUSAGE_SELF, &self_ru);
|
||||
getrusage(RUSAGE_CHILDREN, &c_ru);
|
||||
|
||||
|
||||
/* Server */
|
||||
if (allsections || defsections || !strcasecmp(section,"server")) {
|
||||
POSIX_ONLY(static int call_uname = 1;)
|
||||
@@ -3227,8 +3226,8 @@ sds genRedisInfoString(char *section) {
|
||||
"uptime_in_seconds:%lld\r\n" WIN_PORT_FIX /* %jd -> %lld */
|
||||
"uptime_in_days:%lld\r\n" WIN_PORT_FIX /* %jd -> %lld */
|
||||
"hz:%d\r\n"
|
||||
"configured_hz:%d\r\n"
|
||||
"lru_clock:%Id\r\n" WIN_PORT_FIX /* %ld -> %Id */
|
||||
"configured_hz:%d\r\n"
|
||||
"lru_clock:%Id\r\n" WIN_PORT_FIX /* %ld -> %Id */
|
||||
"executable:%s\r\n"
|
||||
"config_file:%s\r\n",
|
||||
REDIS_VERSION,
|
||||
@@ -3291,7 +3290,7 @@ sds genRedisInfoString(char *section) {
|
||||
size_t zmalloc_used = zmalloc_used_memory();
|
||||
size_t total_system_mem = server.system_memory_size;
|
||||
const char *evict_policy = evictPolicyToString();
|
||||
PORT_LONGLONG memory_lua = (PORT_LONGLONG) lua_gc(server.lua,LUA_GCCOUNT,0)*1024;
|
||||
PORT_LONGLONG memory_lua = (PORT_LONGLONG)lua_gc(server.lua,LUA_GCCOUNT,0)*1024;
|
||||
struct redisMemOverhead *mh = getMemoryOverheadData();
|
||||
|
||||
/* Peak memory is updated from time to time by serverCron() so it
|
||||
@@ -3363,7 +3362,7 @@ sds genRedisInfoString(char *section) {
|
||||
mh->startup_allocated,
|
||||
mh->dataset,
|
||||
mh->dataset_perc,
|
||||
server.cron_malloc_stats.allocator_allocated,
|
||||
server.cron_malloc_stats.allocator_allocated,
|
||||
server.cron_malloc_stats.allocator_active,
|
||||
server.cron_malloc_stats.allocator_resident,
|
||||
(PORT_ULONG)total_system_mem,
|
||||
@@ -3582,7 +3581,7 @@ sds genRedisInfoString(char *section) {
|
||||
"master_sync_left_bytes:%lld\r\n"
|
||||
"master_sync_last_io_seconds_ago:%d\r\n"
|
||||
, (PORT_LONGLONG)
|
||||
(server.repl_transfer_size - server.repl_transfer_read),
|
||||
(server.repl_transfer_size - server.repl_transfer_read),
|
||||
(int)(server.unixtime-server.repl_transfer_lastio)
|
||||
);
|
||||
}
|
||||
@@ -3678,14 +3677,14 @@ sds genRedisInfoString(char *section) {
|
||||
if (sections++) info = sdscat(info,"\r\n");
|
||||
info = sdscatprintf(info,
|
||||
"# CPU\r\n"
|
||||
"used_cpu_sys:%.2f\r\n"
|
||||
"used_cpu_user:%.2f\r\n"
|
||||
"used_cpu_sys_children:%.2f\r\n"
|
||||
"used_cpu_user_children:%.2f\r\n",
|
||||
(IF_WIN32(double,float))self_ru.ru_stime.tv_sec+(float)self_ru.ru_stime.tv_usec/1000000, WIN_PORT_FIX /* warning 26451 */
|
||||
(IF_WIN32(double,float))self_ru.ru_utime.tv_sec+(float)self_ru.ru_utime.tv_usec/1000000, WIN_PORT_FIX /* warning 26451 */
|
||||
(IF_WIN32(double,float))c_ru.ru_stime.tv_sec+(float)c_ru.ru_stime.tv_usec/1000000, WIN_PORT_FIX /* warning 26451 */
|
||||
(IF_WIN32(double,float))c_ru.ru_utime.tv_sec+(float)c_ru.ru_utime.tv_usec/1000000); WIN_PORT_FIX /* warning 26451 */
|
||||
"used_cpu_sys:%ld.%06ld\r\n"
|
||||
"used_cpu_user:%ld.%06ld\r\n"
|
||||
"used_cpu_sys_children:%ld.%06ld\r\n"
|
||||
"used_cpu_user_children:%ld.%06ld\r\n",
|
||||
(PORT_LONG)self_ru.ru_stime.tv_sec, (PORT_LONG)self_ru.ru_stime.tv_usec,
|
||||
(PORT_LONG)self_ru.ru_utime.tv_sec, (PORT_LONG)self_ru.ru_utime.tv_usec,
|
||||
(PORT_LONG)c_ru.ru_stime.tv_sec, (PORT_LONG)c_ru.ru_stime.tv_usec,
|
||||
(PORT_LONG)c_ru.ru_utime.tv_sec, (PORT_LONG)c_ru.ru_utime.tv_usec);
|
||||
}
|
||||
|
||||
/* Command statistics */
|
||||
@@ -4157,8 +4156,9 @@ int main(int argc, char **argv) {
|
||||
pthread_mutex_init(&moduleGIL, NULL);
|
||||
#endif
|
||||
|
||||
srand((unsigned int)time(NULL)^getpid()); WIN_PORT_FIX /* cast (unsigned int) */
|
||||
srand((unsigned int)time(NULL)^getpid()); WIN_PORT_FIX /* cast (unsigned int) */
|
||||
gettimeofday(&tv,NULL);
|
||||
|
||||
char hashseed[16];
|
||||
getRandomHexChars(hashseed,sizeof(hashseed));
|
||||
dictSetHashFunctionSeed((uint8_t*)hashseed);
|
||||
@@ -4169,7 +4169,7 @@ int main(int argc, char **argv) {
|
||||
/* Store the executable path and arguments in a safe place in order
|
||||
* to be able to restart the server later. */
|
||||
server.executable = getAbsolutePath(argv[0]);
|
||||
server.exec_argv = zmalloc(sizeof(char*)*((size_t)argc+1));
|
||||
server.exec_argv = zmalloc(sizeof(char*)*((size_t)argc+1));
|
||||
server.exec_argv[argc] = NULL;
|
||||
for (j = 0; j < argc; j++) server.exec_argv[j] = zstrdup(argv[j]);
|
||||
|
||||
|
||||
+5
-5
@@ -93,7 +93,7 @@ typedef PORT_LONGLONG mstime_t; /* millisecond time type. */
|
||||
|
||||
/* Static server configuration */
|
||||
#define CONFIG_DEFAULT_DYNAMIC_HZ 1 /* Adapt hz to # of clients.*/
|
||||
#define CONFIG_DEFAULT_HZ 10 /* Time interrupt calls/sec. */
|
||||
#define CONFIG_DEFAULT_HZ 10 /* Time interrupt calls/sec. */
|
||||
#define CONFIG_MIN_HZ 1
|
||||
#define CONFIG_MAX_HZ 500
|
||||
#define MAX_CLIENTS_PER_CLOCK_TICK 200 /* HZ is adapted based on that. */
|
||||
@@ -666,7 +666,7 @@ typedef struct redisDb {
|
||||
dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */
|
||||
int id; /* Database ID */
|
||||
PORT_LONGLONG avg_ttl; /* Average TTL, just for stats */
|
||||
list *defrag_later; /* List of key names to attempt to defrag one by one, gradually. */
|
||||
list *defrag_later; /* List of key names to attempt to defrag one by one, gradually. */
|
||||
} redisDb;
|
||||
|
||||
/* Client MULTI/EXEC state */
|
||||
@@ -1049,7 +1049,7 @@ struct redisServer {
|
||||
PORT_LONGLONG slowlog_entry_id; /* SLOWLOG current entry ID */
|
||||
PORT_LONGLONG slowlog_log_slower_than; /* SLOWLOG time limit (to get logged) */
|
||||
PORT_ULONG slowlog_max_len; /* SLOWLOG max number of items logged */
|
||||
struct malloc_stats cron_malloc_stats; /* sampled in serverCron(). */
|
||||
struct malloc_stats cron_malloc_stats; /* sampled in serverCron(). */
|
||||
PORT_LONGLONG stat_net_input_bytes; /* Bytes read from network. */
|
||||
PORT_LONGLONG stat_net_output_bytes; /* Bytes written to network. */
|
||||
size_t stat_rdb_cow_bytes; /* Copy on write bytes during RDB saving. */
|
||||
@@ -1103,7 +1103,7 @@ struct redisServer {
|
||||
int aof_lastbgrewrite_status; /* C_OK or C_ERR */
|
||||
PORT_ULONG aof_delayed_fsync; /* delayed AOF fsync() counter */
|
||||
int aof_rewrite_incremental_fsync;/* fsync incrementally while aof rewriting? */
|
||||
int rdb_save_incremental_fsync; /* fsync incrementally while rdb saving? */
|
||||
int rdb_save_incremental_fsync; /* fsync incrementally while rdb saving? */
|
||||
int aof_last_write_status; /* C_OK or C_ERR */
|
||||
int aof_last_write_errno; /* Valid if aof_last_write_status is ERR */
|
||||
int aof_load_truncated; /* Don't stop on unexpected AOF EOF. */
|
||||
@@ -1212,7 +1212,7 @@ struct redisServer {
|
||||
list *clients_waiting_acks; /* Clients waiting in WAIT command. */
|
||||
int get_ack_from_slaves; /* If true we send REPLCONF GETACK. */
|
||||
/* Limits */
|
||||
PORT_ULONGLONG maxclients; /* Max number of simultaneous clients */
|
||||
unsigned int maxclients; /* Max number of simultaneous clients */
|
||||
PORT_ULONGLONG maxmemory; /* Max number of memory bytes to use */
|
||||
int maxmemory_policy; /* Policy for key eviction */
|
||||
int maxmemory_samples; /* Pricision of random sampling */
|
||||
|
||||
@@ -0,0 +1,632 @@
|
||||
/* Execute config directives */
|
||||
if (!strcasecmp(argv[0],"timeout") && argc == 2) {
|
||||
server.maxidletime = atoi(argv[1]);
|
||||
if (server.maxidletime < 0) {
|
||||
err = "Invalid timeout value"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"tcp-keepalive") && argc == 2) {
|
||||
server.tcpkeepalive = atoi(argv[1]);
|
||||
if (server.tcpkeepalive < 0) {
|
||||
err = "Invalid tcp-keepalive value"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"protected-mode") && argc == 2) {
|
||||
if ((server.protected_mode = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"port") && argc == 2) {
|
||||
server.port = atoi(argv[1]);
|
||||
if (server.port < 0 || server.port > 65535) {
|
||||
err = "Invalid port"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"tcp-backlog") && argc == 2) {
|
||||
server.tcp_backlog = atoi(argv[1]);
|
||||
if (server.tcp_backlog < 0) {
|
||||
err = "Invalid backlog value"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"bind") && argc >= 2) {
|
||||
int j, addresses = argc-1;
|
||||
|
||||
if (addresses > CONFIG_BINDADDR_MAX) {
|
||||
err = "Too many bind addresses specified"; goto loaderr;
|
||||
}
|
||||
for (j = 0; j < addresses; j++)
|
||||
server.bindaddr[j] = zstrdup(argv[j+1]);
|
||||
server.bindaddr_count = addresses;
|
||||
} else if (!strcasecmp(argv[0],"unixsocket") && argc == 2) {
|
||||
server.unixsocket = zstrdup(argv[1]);
|
||||
} else if (!strcasecmp(argv[0],"unixsocketperm") && argc == 2) {
|
||||
errno = 0;
|
||||
server.unixsocketperm = (mode_t)strtol(argv[1], NULL, 8);
|
||||
if (errno || server.unixsocketperm > 0777) {
|
||||
err = "Invalid socket file permissions"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"save")) {
|
||||
if (argc == 3) {
|
||||
int seconds = atoi(argv[1]);
|
||||
int changes = atoi(argv[2]);
|
||||
if (seconds < 1 || changes < 0) {
|
||||
err = "Invalid save parameters"; goto loaderr;
|
||||
}
|
||||
appendServerSaveParams(seconds,changes);
|
||||
} else if (argc == 2 && !strcasecmp(argv[1],"")) {
|
||||
resetServerSaveParams();
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"dir") && argc == 2) {
|
||||
if (chdir(argv[1]) == -1) {
|
||||
serverLog(LL_WARNING,"Can't chdir to '%s': %s",
|
||||
argv[1], IF_WIN32(wsa_strerror(errno), strerror(errno)));
|
||||
exit(1);
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"loglevel") && argc == 2) {
|
||||
server.verbosity = configEnumGetValue(loglevel_enum,argv[1]);
|
||||
if (server.verbosity == INT_MIN) {
|
||||
err = "Invalid log level. "
|
||||
"Must be one of debug, verbose, notice, warning";
|
||||
goto loaderr;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
setLogVerbosityLevel(server.verbosity);
|
||||
#endif
|
||||
} else if (!strcasecmp(argv[0],"logfile") && argc == 2) {
|
||||
FILE *logfp;
|
||||
|
||||
zfree(server.logfile);
|
||||
#ifdef _WIN32
|
||||
int length = (int)sdslen(argv[1]);
|
||||
if ((argv[1][0] == '\'' && argv[1][length-1] == '\'') ||
|
||||
(argv[1][0] == '\"' && argv[1][length-1] == '\"')) {
|
||||
if (length == 2) {
|
||||
server.logfile = zstrdup("\0");
|
||||
} else {
|
||||
size_t l = (size_t) length - 2 + 1;
|
||||
char *p = zmalloc(l);
|
||||
memcpy(p, argv[1]+1, l);
|
||||
server.logfile = p;
|
||||
}
|
||||
} else {
|
||||
server.logfile = zstrdup(argv[1]);
|
||||
}
|
||||
#else
|
||||
server.logfile = zstrdup(argv[1]);
|
||||
#endif
|
||||
if (server.logfile[0] != '\0') {
|
||||
/* Test if we are able to open the file. The server will not
|
||||
* be able to abort just for this problem later... */
|
||||
logfp = fopen(server.logfile,"a");
|
||||
if (logfp == NULL) {
|
||||
err = sdscatprintf(sdsempty(),
|
||||
"Can't open the log file: %s", IF_WIN32(wsa_strerror(errno), strerror(errno)));
|
||||
goto loaderr;
|
||||
#ifdef _WIN32
|
||||
} else {
|
||||
setLogFile(server.logfile);
|
||||
#endif
|
||||
}
|
||||
fclose(logfp);
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"always-show-logo") && argc == 2) {
|
||||
if ((server.always_show_logo = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"syslog-enabled") && argc == 2) {
|
||||
if ((server.syslog_enabled = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
setSyslogEnabled(server.syslog_enabled);
|
||||
#endif
|
||||
} else if (!strcasecmp(argv[0],"syslog-ident") && argc == 2) {
|
||||
if (server.syslog_ident) zfree(server.syslog_ident);
|
||||
server.syslog_ident = zstrdup(argv[1]);
|
||||
#ifdef _WIN32
|
||||
setSyslogIdent(server.syslog_ident);
|
||||
#endif
|
||||
} else if (!strcasecmp(argv[0],"syslog-facility") && argc == 2) {
|
||||
#ifdef _WIN32
|
||||
// Skip error - just ignore syslog-facility
|
||||
#else
|
||||
server.syslog_facility =
|
||||
configEnumGetValue(syslog_facility_enum,argv[1]);
|
||||
if (server.syslog_facility == INT_MIN) {
|
||||
err = "Invalid log facility. Must be one of USER or between LOCAL0-LOCAL7";
|
||||
goto loaderr;
|
||||
}
|
||||
#endif
|
||||
} else if (!strcasecmp(argv[0],"databases") && argc == 2) {
|
||||
server.dbnum = atoi(argv[1]);
|
||||
if (server.dbnum < 1) {
|
||||
err = "Invalid number of databases"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"include") && argc == 2) {
|
||||
loadServerConfig(argv[1],NULL);
|
||||
} else if (!strcasecmp(argv[0],"maxclients") && argc == 2) {
|
||||
server.maxclients = atoi(argv[1]);
|
||||
if (server.maxclients < 1) {
|
||||
err = "Invalid max clients limit"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"maxmemory") && argc == 2) {
|
||||
server.maxmemory = memtoll(argv[1],NULL);
|
||||
} else if (!strcasecmp(argv[0],"maxmemory-policy") && argc == 2) {
|
||||
server.maxmemory_policy =
|
||||
configEnumGetValue(maxmemory_policy_enum,argv[1]);
|
||||
if (server.maxmemory_policy == INT_MIN) {
|
||||
err = "Invalid maxmemory policy";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"maxmemory-samples") && argc == 2) {
|
||||
server.maxmemory_samples = atoi(argv[1]);
|
||||
if (server.maxmemory_samples <= 0) {
|
||||
err = "maxmemory-samples must be 1 or greater";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if ((!strcasecmp(argv[0],"proto-max-bulk-len")) && argc == 2) {
|
||||
server.proto_max_bulk_len = memtoll(argv[1],NULL);
|
||||
} else if ((!strcasecmp(argv[0],"client-query-buffer-limit")) && argc == 2) {
|
||||
server.client_max_querybuf_len = memtoll(argv[1],NULL);
|
||||
} else if (!strcasecmp(argv[0],"lfu-log-factor") && argc == 2) {
|
||||
server.lfu_log_factor = atoi(argv[1]);
|
||||
if (server.lfu_log_factor < 0) {
|
||||
err = "lfu-log-factor must be 0 or greater";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"lfu-decay-time") && argc == 2) {
|
||||
server.lfu_decay_time = atoi(argv[1]);
|
||||
if (server.lfu_decay_time < 0) {
|
||||
err = "lfu-decay-time must be 0 or greater";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if ((!strcasecmp(argv[0],"slaveof") ||
|
||||
!strcasecmp(argv[0],"replicaof")) && argc == 3) {
|
||||
slaveof_linenum = linenum;
|
||||
server.masterhost = sdsnew(argv[1]);
|
||||
server.masterport = atoi(argv[2]);
|
||||
server.repl_state = REPL_STATE_CONNECT;
|
||||
} else if ((!strcasecmp(argv[0],"repl-ping-slave-period") ||
|
||||
!strcasecmp(argv[0],"repl-ping-replica-period")) &&
|
||||
argc == 2)
|
||||
{
|
||||
server.repl_ping_slave_period = atoi(argv[1]);
|
||||
if (server.repl_ping_slave_period <= 0) {
|
||||
err = "repl-ping-replica-period must be 1 or greater";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"repl-timeout") && argc == 2) {
|
||||
server.repl_timeout = atoi(argv[1]);
|
||||
if (server.repl_timeout <= 0) {
|
||||
err = "repl-timeout must be 1 or greater";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"repl-disable-tcp-nodelay") && argc==2) {
|
||||
if ((server.repl_disable_tcp_nodelay = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"repl-diskless-sync") && argc==2) {
|
||||
if ((server.repl_diskless_sync = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"repl-diskless-sync-delay") && argc==2) {
|
||||
server.repl_diskless_sync_delay = atoi(argv[1]);
|
||||
if (server.repl_diskless_sync_delay < 0) {
|
||||
err = "repl-diskless-sync-delay can't be negative";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"repl-backlog-size") && argc == 2) {
|
||||
PORT_LONGLONG size = memtoll(argv[1],NULL);
|
||||
if (size <= 0) {
|
||||
err = "repl-backlog-size must be 1 or greater.";
|
||||
goto loaderr;
|
||||
}
|
||||
resizeReplicationBacklog(size);
|
||||
} else if (!strcasecmp(argv[0],"repl-backlog-ttl") && argc == 2) {
|
||||
server.repl_backlog_time_limit = atoi(argv[1]);
|
||||
if (server.repl_backlog_time_limit < 0) {
|
||||
err = "repl-backlog-ttl can't be negative ";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"masterauth") && argc == 2) {
|
||||
zfree(server.masterauth);
|
||||
server.masterauth = argv[1][0] ? zstrdup(argv[1]) : NULL;
|
||||
} else if ((!strcasecmp(argv[0],"slave-serve-stale-data") ||
|
||||
!strcasecmp(argv[0],"replica-serve-stale-data"))
|
||||
&& argc == 2)
|
||||
{
|
||||
if ((server.repl_serve_stale_data = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if ((!strcasecmp(argv[0],"slave-read-only") ||
|
||||
!strcasecmp(argv[0],"replica-read-only"))
|
||||
&& argc == 2)
|
||||
{
|
||||
if ((server.repl_slave_ro = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if ((!strcasecmp(argv[0],"slave-ignore-maxmemory") ||
|
||||
!strcasecmp(argv[0],"replica-ignore-maxmemory"))
|
||||
&& argc == 2)
|
||||
{
|
||||
if ((server.repl_slave_ignore_maxmemory = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"rdbcompression") && argc == 2) {
|
||||
if ((server.rdb_compression = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"rdbchecksum") && argc == 2) {
|
||||
if ((server.rdb_checksum = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"activerehashing") && argc == 2) {
|
||||
if ((server.activerehashing = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"lazyfree-lazy-eviction") && argc == 2) {
|
||||
if ((server.lazyfree_lazy_eviction = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"lazyfree-lazy-expire") && argc == 2) {
|
||||
if ((server.lazyfree_lazy_expire = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"lazyfree-lazy-server-del") && argc == 2){
|
||||
if ((server.lazyfree_lazy_server_del = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if ((!strcasecmp(argv[0],"slave-lazy-flush") ||
|
||||
!strcasecmp(argv[0],"replica-lazy-flush")) && argc == 2)
|
||||
{
|
||||
if ((server.repl_slave_lazy_flush = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"activedefrag") && argc == 2) {
|
||||
if ((server.active_defrag_enabled = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
if (server.active_defrag_enabled) {
|
||||
#ifndef HAVE_DEFRAG
|
||||
err = "active defrag can't be enabled without proper jemalloc support"; goto loaderr;
|
||||
#endif
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"daemonize") && argc == 2) {
|
||||
if ((server.daemonize = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"dynamic-hz") && argc == 2) {
|
||||
if ((server.dynamic_hz = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"hz") && argc == 2) {
|
||||
server.config_hz = atoi(argv[1]);
|
||||
if (server.config_hz < CONFIG_MIN_HZ) server.config_hz = CONFIG_MIN_HZ;
|
||||
if (server.config_hz > CONFIG_MAX_HZ) server.config_hz = CONFIG_MAX_HZ;
|
||||
} else if (!strcasecmp(argv[0],"appendonly") && argc == 2) {
|
||||
int yes;
|
||||
|
||||
if ((yes = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
server.aof_state = yes ? AOF_ON : AOF_OFF;
|
||||
} else if (!strcasecmp(argv[0],"appendfilename") && argc == 2) {
|
||||
if (!pathIsBaseName(argv[1])) {
|
||||
err = "appendfilename can't be a path, just a filename";
|
||||
goto loaderr;
|
||||
}
|
||||
zfree(server.aof_filename);
|
||||
server.aof_filename = zstrdup(argv[1]);
|
||||
} else if (!strcasecmp(argv[0],"no-appendfsync-on-rewrite")
|
||||
&& argc == 2) {
|
||||
if ((server.aof_no_fsync_on_rewrite= yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"appendfsync") && argc == 2) {
|
||||
server.aof_fsync = configEnumGetValue(aof_fsync_enum,argv[1]);
|
||||
if (server.aof_fsync == INT_MIN) {
|
||||
err = "argument must be 'no', 'always' or 'everysec'";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"auto-aof-rewrite-percentage") &&
|
||||
argc == 2)
|
||||
{
|
||||
server.aof_rewrite_perc = atoi(argv[1]);
|
||||
if (server.aof_rewrite_perc < 0) {
|
||||
err = "Invalid negative percentage for AOF auto rewrite";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"auto-aof-rewrite-min-size") &&
|
||||
argc == 2)
|
||||
{
|
||||
server.aof_rewrite_min_size = memtoll(argv[1],NULL);
|
||||
} else if (!strcasecmp(argv[0],"aof-rewrite-incremental-fsync") &&
|
||||
argc == 2)
|
||||
{
|
||||
if ((server.aof_rewrite_incremental_fsync =
|
||||
yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"rdb-save-incremental-fsync") &&
|
||||
argc == 2)
|
||||
{
|
||||
if ((server.rdb_save_incremental_fsync =
|
||||
yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"aof-load-truncated") && argc == 2) {
|
||||
if ((server.aof_load_truncated = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"aof-use-rdb-preamble") && argc == 2) {
|
||||
if ((server.aof_use_rdb_preamble = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"requirepass") && argc == 2) {
|
||||
if (strlen(argv[1]) > CONFIG_AUTHPASS_MAX_LEN) {
|
||||
err = "Password is longer than CONFIG_AUTHPASS_MAX_LEN";
|
||||
goto loaderr;
|
||||
}
|
||||
server.requirepass = argv[1][0] ? zstrdup(argv[1]) : NULL;
|
||||
} else if (!strcasecmp(argv[0],"pidfile") && argc == 2) {
|
||||
zfree(server.pidfile);
|
||||
server.pidfile = zstrdup(argv[1]);
|
||||
} else if (!strcasecmp(argv[0],"dbfilename") && argc == 2) {
|
||||
if (!pathIsBaseName(argv[1])) {
|
||||
err = "dbfilename can't be a path, just a filename";
|
||||
goto loaderr;
|
||||
}
|
||||
zfree(server.rdb_filename);
|
||||
server.rdb_filename = zstrdup(argv[1]);
|
||||
} else if (!strcasecmp(argv[0],"active-defrag-threshold-lower") && argc == 2) {
|
||||
server.active_defrag_threshold_lower = atoi(argv[1]);
|
||||
if (server.active_defrag_threshold_lower < 0 ||
|
||||
server.active_defrag_threshold_lower > 1000) {
|
||||
err = "active-defrag-threshold-lower must be between 0 and 1000";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"active-defrag-threshold-upper") && argc == 2) {
|
||||
server.active_defrag_threshold_upper = atoi(argv[1]);
|
||||
if (server.active_defrag_threshold_upper < 0 ||
|
||||
server.active_defrag_threshold_upper > 1000) {
|
||||
err = "active-defrag-threshold-upper must be between 0 and 1000";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"active-defrag-ignore-bytes") && argc == 2) {
|
||||
server.active_defrag_ignore_bytes = memtoll(argv[1], NULL);
|
||||
if (server.active_defrag_ignore_bytes <= 0) {
|
||||
err = "active-defrag-ignore-bytes must above 0";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"active-defrag-cycle-min") && argc == 2) {
|
||||
server.active_defrag_cycle_min = atoi(argv[1]);
|
||||
if (server.active_defrag_cycle_min < 1 || server.active_defrag_cycle_min > 99) {
|
||||
err = "active-defrag-cycle-min must be between 1 and 99";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"active-defrag-cycle-max") && argc == 2) {
|
||||
server.active_defrag_cycle_max = atoi(argv[1]);
|
||||
if (server.active_defrag_cycle_max < 1 || server.active_defrag_cycle_max > 99) {
|
||||
err = "active-defrag-cycle-max must be between 1 and 99";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"active-defrag-max-scan-fields") && argc == 2) {
|
||||
server.active_defrag_max_scan_fields = strtoll(argv[1],NULL,10);
|
||||
if (server.active_defrag_max_scan_fields < 1) {
|
||||
err = "active-defrag-max-scan-fields must be positive";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"hash-max-ziplist-entries") && argc == 2) {
|
||||
server.hash_max_ziplist_entries = memtoll(argv[1], NULL);
|
||||
} else if (!strcasecmp(argv[0],"hash-max-ziplist-value") && argc == 2) {
|
||||
server.hash_max_ziplist_value = memtoll(argv[1], NULL);
|
||||
} else if (!strcasecmp(argv[0],"stream-node-max-bytes") && argc == 2) {
|
||||
server.stream_node_max_bytes = memtoll(argv[1], NULL);
|
||||
} else if (!strcasecmp(argv[0],"stream-node-max-entries") && argc == 2) {
|
||||
server.stream_node_max_entries = atoi(argv[1]);
|
||||
} else if (!strcasecmp(argv[0],"list-max-ziplist-entries") && argc == 2){
|
||||
/* DEAD OPTION */
|
||||
} else if (!strcasecmp(argv[0],"list-max-ziplist-value") && argc == 2) {
|
||||
/* DEAD OPTION */
|
||||
} else if (!strcasecmp(argv[0],"list-max-ziplist-size") && argc == 2) {
|
||||
server.list_max_ziplist_size = atoi(argv[1]);
|
||||
} else if (!strcasecmp(argv[0],"list-compress-depth") && argc == 2) {
|
||||
server.list_compress_depth = atoi(argv[1]);
|
||||
} else if (!strcasecmp(argv[0],"set-max-intset-entries") && argc == 2) {
|
||||
server.set_max_intset_entries = memtoll(argv[1], NULL);
|
||||
} else if (!strcasecmp(argv[0],"zset-max-ziplist-entries") && argc == 2) {
|
||||
server.zset_max_ziplist_entries = memtoll(argv[1], NULL);
|
||||
} else if (!strcasecmp(argv[0],"zset-max-ziplist-value") && argc == 2) {
|
||||
server.zset_max_ziplist_value = memtoll(argv[1], NULL);
|
||||
} else if (!strcasecmp(argv[0],"hll-sparse-max-bytes") && argc == 2) {
|
||||
server.hll_sparse_max_bytes = memtoll(argv[1], NULL);
|
||||
} else if (!strcasecmp(argv[0],"rename-command") && argc == 3) {
|
||||
struct redisCommand *cmd = lookupCommand(argv[1]);
|
||||
int retval;
|
||||
|
||||
if (!cmd) {
|
||||
err = "No such command in rename-command";
|
||||
goto loaderr;
|
||||
}
|
||||
|
||||
/* If the target command name is the empty string we just
|
||||
* remove it from the command table. */
|
||||
retval = dictDelete(server.commands, argv[1]);
|
||||
serverAssert(retval == DICT_OK);
|
||||
|
||||
/* Otherwise we re-add the command under a different name. */
|
||||
if (sdslen(argv[2]) != 0) {
|
||||
sds copy = sdsdup(argv[2]);
|
||||
|
||||
retval = dictAdd(server.commands, copy, cmd);
|
||||
if (retval != DICT_OK) {
|
||||
sdsfree(copy);
|
||||
err = "Target command name already exists"; goto loaderr;
|
||||
}
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"cluster-enabled") && argc == 2) {
|
||||
if ((server.cluster_enabled = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"cluster-config-file") && argc == 2) {
|
||||
zfree(server.cluster_configfile);
|
||||
server.cluster_configfile = zstrdup(argv[1]);
|
||||
} else if (!strcasecmp(argv[0],"cluster-announce-ip") && argc == 2) {
|
||||
zfree(server.cluster_announce_ip);
|
||||
server.cluster_announce_ip = zstrdup(argv[1]);
|
||||
} else if (!strcasecmp(argv[0],"cluster-announce-port") && argc == 2) {
|
||||
server.cluster_announce_port = atoi(argv[1]);
|
||||
if (server.cluster_announce_port < 0 ||
|
||||
server.cluster_announce_port > 65535)
|
||||
{
|
||||
err = "Invalid port"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"cluster-announce-bus-port") &&
|
||||
argc == 2)
|
||||
{
|
||||
server.cluster_announce_bus_port = atoi(argv[1]);
|
||||
if (server.cluster_announce_bus_port < 0 ||
|
||||
server.cluster_announce_bus_port > 65535)
|
||||
{
|
||||
err = "Invalid port"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"cluster-require-full-coverage") &&
|
||||
argc == 2)
|
||||
{
|
||||
if ((server.cluster_require_full_coverage = yesnotoi(argv[1])) == -1)
|
||||
{
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"cluster-node-timeout") && argc == 2) {
|
||||
server.cluster_node_timeout = strtoll(argv[1],NULL,10);
|
||||
if (server.cluster_node_timeout <= 0) {
|
||||
err = "cluster node timeout must be 1 or greater"; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"cluster-migration-barrier")
|
||||
&& argc == 2)
|
||||
{
|
||||
server.cluster_migration_barrier = atoi(argv[1]);
|
||||
if (server.cluster_migration_barrier < 0) {
|
||||
err = "cluster migration barrier must zero or positive";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if ((!strcasecmp(argv[0],"cluster-slave-validity-factor") ||
|
||||
!strcasecmp(argv[0],"cluster-replica-validity-factor"))
|
||||
&& argc == 2)
|
||||
{
|
||||
server.cluster_slave_validity_factor = atoi(argv[1]);
|
||||
if (server.cluster_slave_validity_factor < 0) {
|
||||
err = "cluster replica validity factor must be zero or positive";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if ((!strcasecmp(argv[0],"cluster-slave-no-failover") ||
|
||||
!strcasecmp(argv[0],"cluster-replica-no-failover")) &&
|
||||
argc == 2)
|
||||
{
|
||||
server.cluster_slave_no_failover = yesnotoi(argv[1]);
|
||||
if (server.cluster_slave_no_failover == -1) {
|
||||
err = "argument must be 'yes' or 'no'";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"lua-time-limit") && argc == 2) {
|
||||
server.lua_time_limit = strtoll(argv[1],NULL,10);
|
||||
} else if (!strcasecmp(argv[0],"lua-replicate-commands") && argc == 2) {
|
||||
server.lua_always_replicate_commands = yesnotoi(argv[1]);
|
||||
} else if (!strcasecmp(argv[0],"slowlog-log-slower-than") &&
|
||||
argc == 2)
|
||||
{
|
||||
server.slowlog_log_slower_than = strtoll(argv[1],NULL,10);
|
||||
} else if (!strcasecmp(argv[0],"latency-monitor-threshold") &&
|
||||
argc == 2)
|
||||
{
|
||||
server.latency_monitor_threshold = strtoll(argv[1],NULL,10);
|
||||
if (server.latency_monitor_threshold < 0) {
|
||||
err = "The latency threshold can't be negative";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"slowlog-max-len") && argc == 2) {
|
||||
server.slowlog_max_len = (PORT_ULONG)(strtoll(argv[1],NULL,10)); WIN_PORT_FIX /* cast (PORT_ULONG) */
|
||||
} else if (!strcasecmp(argv[0],"client-output-buffer-limit") &&
|
||||
argc == 5)
|
||||
{
|
||||
int class = getClientTypeByName(argv[1]);
|
||||
PORT_ULONGLONG hard, soft;
|
||||
int soft_seconds;
|
||||
|
||||
if (class == -1 || class == CLIENT_TYPE_MASTER) {
|
||||
err = "Unrecognized client limit class: the user specified "
|
||||
"an invalid one, or 'master' which has no buffer limits.";
|
||||
goto loaderr;
|
||||
}
|
||||
hard = memtoll(argv[2],NULL);
|
||||
soft = memtoll(argv[3],NULL);
|
||||
soft_seconds = atoi(argv[4]);
|
||||
if (soft_seconds < 0) {
|
||||
err = "Negative number of seconds in soft limit is invalid";
|
||||
goto loaderr;
|
||||
}
|
||||
server.client_obuf_limits[class].hard_limit_bytes = hard;
|
||||
server.client_obuf_limits[class].soft_limit_bytes = soft;
|
||||
server.client_obuf_limits[class].soft_limit_seconds = soft_seconds;
|
||||
} else if (!strcasecmp(argv[0],"stop-writes-on-bgsave-error") &&
|
||||
argc == 2) {
|
||||
if ((server.stop_writes_on_bgsave_err = yesnotoi(argv[1])) == -1) {
|
||||
err = "argument must be 'yes' or 'no'"; goto loaderr;
|
||||
}
|
||||
} else if ((!strcasecmp(argv[0],"slave-priority") ||
|
||||
!strcasecmp(argv[0],"replica-priority")) && argc == 2)
|
||||
{
|
||||
server.slave_priority = atoi(argv[1]);
|
||||
} else if ((!strcasecmp(argv[0],"slave-announce-ip") ||
|
||||
!strcasecmp(argv[0],"replica-announce-ip")) && argc == 2)
|
||||
{
|
||||
zfree(server.slave_announce_ip);
|
||||
server.slave_announce_ip = zstrdup(argv[1]);
|
||||
} else if ((!strcasecmp(argv[0],"slave-announce-port") ||
|
||||
!strcasecmp(argv[0],"replica-announce-port")) && argc == 2)
|
||||
{
|
||||
server.slave_announce_port = atoi(argv[1]);
|
||||
if (server.slave_announce_port < 0 ||
|
||||
server.slave_announce_port > 65535)
|
||||
{
|
||||
err = "Invalid port"; goto loaderr;
|
||||
}
|
||||
} else if ((!strcasecmp(argv[0],"min-slaves-to-write") ||
|
||||
!strcasecmp(argv[0],"min-replicas-to-write")) && argc == 2)
|
||||
{
|
||||
server.repl_min_slaves_to_write = atoi(argv[1]);
|
||||
if (server.repl_min_slaves_to_write < 0) {
|
||||
err = "Invalid value for min-replicas-to-write."; goto loaderr;
|
||||
}
|
||||
} else if ((!strcasecmp(argv[0],"min-slaves-max-lag") ||
|
||||
!strcasecmp(argv[0],"min-replicas-max-lag")) && argc == 2)
|
||||
{
|
||||
server.repl_min_slaves_max_lag = atoi(argv[1]);
|
||||
if (server.repl_min_slaves_max_lag < 0) {
|
||||
err = "Invalid value for min-replicas-max-lag."; goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"notify-keyspace-events") && argc == 2) {
|
||||
int flags = keyspaceEventsStringToFlags(argv[1]);
|
||||
|
||||
if (flags == -1) {
|
||||
err = "Invalid event class character. Use 'g$lshzxeA'.";
|
||||
goto loaderr;
|
||||
}
|
||||
server.notify_keyspace_events = flags;
|
||||
} else if (!strcasecmp(argv[0],"supervised") && argc == 2) {
|
||||
server.supervised_mode =
|
||||
configEnumGetValue(supervised_mode_enum,argv[1]);
|
||||
|
||||
if (server.supervised_mode == INT_MIN) {
|
||||
err = "Invalid option for 'supervised'. "
|
||||
"Allowed values: 'upstart', 'systemd', 'auto', or 'no'";
|
||||
goto loaderr;
|
||||
}
|
||||
} else if (!strcasecmp(argv[0],"loadmodule") && argc >= 2) {
|
||||
queueLoadModule(argv[1],&argv[2],argc-2);
|
||||
} else if (!strcasecmp(argv[0],"sentinel")) {
|
||||
/* argc == 1 is handled by main() as we need to enter the sentinel
|
||||
* mode ASAP. */
|
||||
if (argc != 1) {
|
||||
if (!server.sentinel_mode) {
|
||||
err = "sentinel directive while not in sentinel mode";
|
||||
goto loaderr;
|
||||
}
|
||||
err = sentinelHandleConfiguration(argv+1,argc-1);
|
||||
if (err) goto loaderr;
|
||||
}
|
||||
+12
-12
@@ -142,12 +142,12 @@ uint64_t siphash(const uint8_t *in, const size_t inlen, const uint8_t *k) {
|
||||
}
|
||||
|
||||
switch (left) {
|
||||
case 7: b |= ((uint64_t)in[6]) << 48;
|
||||
case 6: b |= ((uint64_t)in[5]) << 40;
|
||||
case 5: b |= ((uint64_t)in[4]) << 32;
|
||||
case 4: b |= ((uint64_t)in[3]) << 24;
|
||||
case 3: b |= ((uint64_t)in[2]) << 16;
|
||||
case 2: b |= ((uint64_t)in[1]) << 8;
|
||||
case 7: b |= ((uint64_t)in[6]) << 48; /* fall-thru */
|
||||
case 6: b |= ((uint64_t)in[5]) << 40; /* fall-thru */
|
||||
case 5: b |= ((uint64_t)in[4]) << 32; /* fall-thru */
|
||||
case 4: b |= ((uint64_t)in[3]) << 24; /* fall-thru */
|
||||
case 3: b |= ((uint64_t)in[2]) << 16; /* fall-thru */
|
||||
case 2: b |= ((uint64_t)in[1]) << 8; /* fall-thru */
|
||||
case 1: b |= ((uint64_t)in[0]); break;
|
||||
case 0: break;
|
||||
}
|
||||
@@ -202,12 +202,12 @@ uint64_t siphash_nocase(const uint8_t *in, const size_t inlen, const uint8_t *k)
|
||||
}
|
||||
|
||||
switch (left) {
|
||||
case 7: b |= ((uint64_t)siptlw(in[6])) << 48;
|
||||
case 6: b |= ((uint64_t)siptlw(in[5])) << 40;
|
||||
case 5: b |= ((uint64_t)siptlw(in[4])) << 32;
|
||||
case 4: b |= ((uint64_t)siptlw(in[3])) << 24;
|
||||
case 3: b |= ((uint64_t)siptlw(in[2])) << 16;
|
||||
case 2: b |= ((uint64_t)siptlw(in[1])) << 8;
|
||||
case 7: b |= ((uint64_t)siptlw(in[6])) << 48; /* fall-thru */
|
||||
case 6: b |= ((uint64_t)siptlw(in[5])) << 40; /* fall-thru */
|
||||
case 5: b |= ((uint64_t)siptlw(in[4])) << 32; /* fall-thru */
|
||||
case 4: b |= ((uint64_t)siptlw(in[3])) << 24; /* fall-thru */
|
||||
case 3: b |= ((uint64_t)siptlw(in[2])) << 16; /* fall-thru */
|
||||
case 2: b |= ((uint64_t)siptlw(in[1])) << 8; /* fall-thru */
|
||||
case 1: b |= ((uint64_t)siptlw(in[0])); break;
|
||||
case 0: break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1123,7 +1123,7 @@ int streamGenericParseIDOrReply(client *c, robj *o, streamID *id, uint64_t missi
|
||||
/* Parse <ms>-<seq> form. */
|
||||
char *dot = strchr(buf,'-');
|
||||
if (dot) *dot = '\0';
|
||||
PORT_LONGLONG ms, seq;
|
||||
PORT_ULONGLONG ms, seq;
|
||||
if (string2ull(buf,&ms) == 0) goto invalid;
|
||||
if (dot && string2ull(dot+1,&seq) == 0) goto invalid;
|
||||
if (!dot) seq = missing_seq;
|
||||
|
||||
+4
-3
@@ -307,16 +307,17 @@ void msetGenericCommand(client *c, int nx) {
|
||||
addReplyError(c,"wrong number of arguments for MSET");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Handle the NX flag. The MSETNX semantic is to return zero and don't
|
||||
* set anything if at least one key alerady exists. */
|
||||
if (nx) {
|
||||
for (j = 1; j < c->argc; j += 2) {
|
||||
if (lookupKeyWrite(c->db,c->argv[j]) != NULL) {
|
||||
addReply(c, shared.czero);
|
||||
return;
|
||||
addReply(c, shared.czero);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 1; j < c->argc; j += 2) {
|
||||
c->argv[j+1] = tryObjectEncoding(c->argv[j+1]);
|
||||
|
||||
+33
-36
@@ -162,7 +162,7 @@ zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
|
||||
for (i = zsl->level; i < level; i++) {
|
||||
rank[i] = 0;
|
||||
update[i] = zsl->header;
|
||||
update[i]->level[i].span = zsl->length;
|
||||
update[i]->level[i].span = zsl->length;
|
||||
}
|
||||
zsl->level = level;
|
||||
}
|
||||
@@ -787,45 +787,42 @@ unsigned int zzlLength(unsigned char *zl) {
|
||||
|
||||
/* Move to next entry based on the values in eptr and sptr. Both are set to
|
||||
* NULL when there is no next entry. */
|
||||
void zzlNext(unsigned char* zl, unsigned char** eptr, unsigned char** sptr) {
|
||||
unsigned char* l_eptr, * l_sptr; WIN_PORT_FIX /* compiler error: _sptr -> l_sptr */
|
||||
serverAssert(*eptr != NULL && *sptr != NULL);
|
||||
void zzlNext(unsigned char *zl, unsigned char **eptr, unsigned char **sptr) {
|
||||
unsigned char *l_eptr, *l_sptr; WIN_PORT_FIX /* compiler error: _sptr -> l_sptr */
|
||||
serverAssert(*eptr != NULL && *sptr != NULL);
|
||||
|
||||
l_eptr = ziplistNext(zl, *sptr);
|
||||
if (l_eptr != NULL) {
|
||||
l_sptr = ziplistNext(zl, l_eptr);
|
||||
serverAssert(l_sptr != NULL);
|
||||
}
|
||||
else {
|
||||
/* No next entry. */
|
||||
l_sptr = NULL;
|
||||
}
|
||||
l_eptr = ziplistNext(zl, *sptr);
|
||||
if (l_eptr != NULL) {
|
||||
l_sptr = ziplistNext(zl, l_eptr);
|
||||
serverAssert(l_sptr != NULL);
|
||||
} else {
|
||||
/* No next entry. */
|
||||
l_sptr = NULL;
|
||||
}
|
||||
|
||||
*eptr = l_eptr;
|
||||
*sptr = l_sptr;
|
||||
*eptr = l_eptr;
|
||||
*sptr = l_sptr;
|
||||
}
|
||||
|
||||
/* Move to the previous entry based on the values in eptr and sptr. Both are
|
||||
* set to NULL when there is no next entry. */
|
||||
void zzlPrev(unsigned char* zl, unsigned char** eptr, unsigned char** sptr) {
|
||||
unsigned char* l_eptr, * l_sptr; WIN_PORT_FIX /* compiler error: _sptr -> l_sptr */
|
||||
serverAssert(*eptr != NULL && *sptr != NULL);
|
||||
void zzlPrev(unsigned char *zl, unsigned char **eptr, unsigned char **sptr) {
|
||||
unsigned char *l_eptr, *l_sptr; WIN_PORT_FIX /* compiler error: _sptr -> l_sptr */
|
||||
serverAssert(*eptr != NULL && *sptr != NULL);
|
||||
|
||||
l_sptr = ziplistPrev(zl, *eptr);
|
||||
if (l_sptr != NULL) {
|
||||
l_eptr = ziplistPrev(zl, l_sptr);
|
||||
serverAssert(l_eptr != NULL);
|
||||
}
|
||||
else {
|
||||
/* No previous entry. */
|
||||
l_eptr = NULL;
|
||||
}
|
||||
l_sptr = ziplistPrev(zl, *eptr);
|
||||
if (l_sptr != NULL) {
|
||||
l_eptr = ziplistPrev(zl, l_sptr);
|
||||
serverAssert(l_eptr != NULL);
|
||||
} else {
|
||||
/* No previous entry. */
|
||||
l_eptr = NULL;
|
||||
}
|
||||
|
||||
*eptr = l_eptr;
|
||||
*sptr = l_sptr;
|
||||
*eptr = l_eptr;
|
||||
*sptr = l_sptr;
|
||||
}
|
||||
|
||||
|
||||
/* Returns if there is a part of the zset is in range. Should only be used
|
||||
* internally by zzlFirstInRange and zzlLastInRange. */
|
||||
int zzlIsInRange(unsigned char *zl, zrangespec *range) {
|
||||
@@ -1931,7 +1928,7 @@ void zuiClearIterator(zsetopsrc *op) {
|
||||
}
|
||||
}
|
||||
|
||||
int zuiLength(zsetopsrc *op) {
|
||||
PORT_ULONG zuiLength(zsetopsrc *op) {
|
||||
if (op->subject == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -1940,7 +1937,7 @@ int zuiLength(zsetopsrc *op) {
|
||||
return intsetLen(op->subject->ptr);
|
||||
} else if (op->encoding == OBJ_ENCODING_HT) {
|
||||
dict *ht = op->subject->ptr;
|
||||
return (int)dictSize(ht); WIN_PORT_FIX /* cast (int) */
|
||||
return dictSize(ht);
|
||||
} else {
|
||||
serverPanic("Unknown set encoding");
|
||||
}
|
||||
@@ -1949,7 +1946,7 @@ int zuiLength(zsetopsrc *op) {
|
||||
return zzlLength(op->subject->ptr);
|
||||
} else if (op->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||
zset *zs = op->subject->ptr;
|
||||
return (int)zs->zsl->length; WIN_PORT_FIX /* cast (int) */
|
||||
return zs->zsl->length;
|
||||
} else {
|
||||
serverPanic("Unknown sorted set encoding");
|
||||
}
|
||||
@@ -2186,7 +2183,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
||||
zsetopsrc *src;
|
||||
zsetopval zval;
|
||||
sds tmp;
|
||||
unsigned int maxelelen = 0;
|
||||
size_t maxelelen = 0;
|
||||
robj *dstobj;
|
||||
zset *dstzset;
|
||||
zskiplistNode *znode;
|
||||
@@ -2310,7 +2307,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
||||
tmp = zuiNewSdsFromValue(&zval);
|
||||
znode = zslInsert(dstzset->zsl,score,tmp);
|
||||
dictAdd(dstzset->dict,tmp,&znode->score);
|
||||
if (sdslen(tmp) > maxelelen) maxelelen = (unsigned int)sdslen(tmp); WIN_PORT_FIX /* cast (unsigned int) */
|
||||
if (sdslen(tmp) > maxelelen) maxelelen = sdslen(tmp);
|
||||
}
|
||||
}
|
||||
zuiClearIterator(&src[0]);
|
||||
@@ -2346,7 +2343,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
||||
/* Remember the longest single element encountered,
|
||||
* to understand if it's possible to convert to ziplist
|
||||
* at the end. */
|
||||
if (sdslen(tmp) > maxelelen) maxelelen = (unsigned int)sdslen(tmp); WIN_PORT_FIX /* cast (unsigned int) */
|
||||
if (sdslen(tmp) > maxelelen) maxelelen = sdslen(tmp);
|
||||
/* Update the element with its initial score. */
|
||||
dictSetKey(accumulator, de, tmp);
|
||||
dictSetDoubleVal(de,score);
|
||||
|
||||
+36
-37
@@ -455,7 +455,7 @@ int string2l(const char *s, size_t slen, PORT_LONG *lval) {
|
||||
* a double: no spaces or other characters before or after the string
|
||||
* representing the number are accepted. */
|
||||
int string2ld(const char *s, size_t slen, PORT_LONGDOUBLE *dp) {
|
||||
char buf[256];
|
||||
char buf[MAX_LONG_DOUBLE_CHARS];
|
||||
PORT_LONGDOUBLE value;
|
||||
char *eptr;
|
||||
|
||||
@@ -575,45 +575,44 @@ void getRandomBytes(unsigned char *p, size_t len) {
|
||||
static unsigned char seed[20]; /* The SHA1 seed, from /dev/urandom. */
|
||||
static uint64_t counter = 0; /* The counter we hash with the seed. */
|
||||
|
||||
|
||||
if (!seed_initialized) {
|
||||
/* Initialize a seed and use SHA1 in counter mode, where we hash
|
||||
* the same seed with a progressive counter. For the goals of this
|
||||
* function we just need non-colliding strings, there are no
|
||||
* cryptographic security needs. */
|
||||
FILE *fp = fopen("/dev/urandom","r");
|
||||
if (fp == NULL || fread(seed,sizeof(seed),1,fp) != 1) {
|
||||
/* Revert to a weaker seed, and in this case reseed again
|
||||
* at every call.*/
|
||||
for (unsigned int j = 0; j < sizeof(seed); j++) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv,NULL);
|
||||
pid_t pid = getpid();
|
||||
seed[j] = tv.tv_sec ^ tv.tv_usec ^ pid ^ (PORT_LONG)fp;
|
||||
}
|
||||
} else {
|
||||
seed_initialized = 1;
|
||||
}
|
||||
if (fp) fclose(fp);
|
||||
}
|
||||
|
||||
while(len) {
|
||||
unsigned char digest[20];
|
||||
SHA1_CTX ctx;
|
||||
unsigned int copylen = len > 20 ? 20 : len;
|
||||
|
||||
SHA1Init(&ctx);
|
||||
SHA1Update(&ctx, seed, sizeof(seed));
|
||||
SHA1Update(&ctx, (unsigned char*)&counter,sizeof(counter));
|
||||
SHA1Final(digest, &ctx);
|
||||
counter++;
|
||||
|
||||
memcpy(p,digest,copylen);
|
||||
len -= copylen;
|
||||
p += copylen;
|
||||
if (!seed_initialized) {
|
||||
/* Initialize a seed and use SHA1 in counter mode, where we hash
|
||||
* the same seed with a progressive counter. For the goals of this
|
||||
* function we just need non-colliding strings, there are no
|
||||
* cryptographic security needs. */
|
||||
FILE *fp = fopen("/dev/urandom","r");
|
||||
if (fp == NULL || fread(seed,sizeof(seed),1,fp) != 1) {
|
||||
/* Revert to a weaker seed, and in this case reseed again
|
||||
* at every call.*/
|
||||
for (unsigned int j = 0; j < sizeof(seed); j++) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv,NULL);
|
||||
pid_t pid = getpid();
|
||||
seed[j] = tv.tv_sec ^ tv.tv_usec ^ pid ^ (PORT_LONG)fp;
|
||||
}
|
||||
} else {
|
||||
seed_initialized = 1;
|
||||
}
|
||||
if (fp) fclose(fp);
|
||||
}
|
||||
|
||||
while(len) {
|
||||
unsigned char digest[20];
|
||||
SHA1_CTX ctx;
|
||||
unsigned int copylen = len > 20 ? 20 : len;
|
||||
|
||||
SHA1Init(&ctx);
|
||||
SHA1Update(&ctx, seed, sizeof(seed));
|
||||
SHA1Update(&ctx, (unsigned char*)&counter,sizeof(counter));
|
||||
SHA1Final(digest, &ctx);
|
||||
counter++;
|
||||
|
||||
memcpy(p,digest,copylen);
|
||||
len -= copylen;
|
||||
p += copylen;
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate the Redis "Run ID", a SHA1-sized random number that identifies a
|
||||
* given execution of Redis, so that if you are talking with an instance
|
||||
* having run_id == A, and you reconnect and it has run_id == B, you can be
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* This function provide us access to the original libc free(). This is useful
|
||||
* for instance to free results obtained by backtrace_symbols(). We need
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Redis configuration for testing.
|
||||
|
||||
#always-show-logo yes
|
||||
always-show-logo yes
|
||||
notify-keyspace-events KEA
|
||||
daemonize no
|
||||
pidfile /var/run/redis.pid
|
||||
|
||||
@@ -72,14 +72,13 @@ test "Cluster consistency during live resharding" {
|
||||
puts -nonewline "...Starting resharding..."
|
||||
flush stdout
|
||||
set target [dict get [get_myself [randomInt 5]] id]
|
||||
# WIN_PORT_FIX: 'exec' -> 'exec ruby'
|
||||
set tribpid [lindex [exec ruby \
|
||||
../../../src/redis-trib.rb reshard \
|
||||
--from all \
|
||||
--to $target \
|
||||
--slots 100 \
|
||||
--yes \
|
||||
set tribpid [lindex [exec \
|
||||
../../../src/redis-cli --cluster reshard \
|
||||
127.0.0.1:[get_instance_attrib redis 0 port] \
|
||||
--cluster-from all \
|
||||
--cluster-to $target \
|
||||
--cluster-slots 100 \
|
||||
--cluster-yes \
|
||||
| [info nameofexecutable] \
|
||||
../tests/helpers/onlydots.tcl \
|
||||
&] 0]
|
||||
|
||||
@@ -30,11 +30,10 @@ test "Each master should have at least two replicas attached" {
|
||||
|
||||
set master0_id [dict get [get_myself 0] id]
|
||||
test "Resharding all the master #0 slots away from it" {
|
||||
# WIN_PORT_FIX: 'exec' -> 'exec ruby'
|
||||
set output [exec ruby \
|
||||
../../../src/redis-trib.rb rebalance \
|
||||
--weight ${master0_id}=0 \
|
||||
127.0.0.1:[get_instance_attrib redis 0 port] >@ stdout]
|
||||
set output [exec \
|
||||
../../../src/redis-cli --cluster rebalance \
|
||||
127.0.0.1:[get_instance_attrib redis 0 port] \
|
||||
--cluster-weight ${master0_id}=0 >@ stdout ]
|
||||
}
|
||||
|
||||
test "Master #0 should lose its replicas" {
|
||||
@@ -49,12 +48,11 @@ test "Resharding back some slot to master #0" {
|
||||
# Wait for the cluster config to propagate before attempting a
|
||||
# new resharding.
|
||||
after 10000
|
||||
# WIN_PORT_FIX: 'exec' -> 'exec ruby'
|
||||
set output [exec ruby \
|
||||
../../../src/redis-trib.rb rebalance \
|
||||
--weight ${master0_id}=.01 \
|
||||
--use-empty-masters \
|
||||
127.0.0.1:[get_instance_attrib redis 0 port] >@ stdout]
|
||||
set output [exec \
|
||||
../../../src/redis-cli --cluster rebalance \
|
||||
127.0.0.1:[get_instance_attrib redis 0 port] \
|
||||
--cluster-weight ${master0_id}=.01 \
|
||||
--cluster-use-empty-masters >@ stdout]
|
||||
}
|
||||
|
||||
test "Master #0 should re-acquire one or more replicas" {
|
||||
|
||||
+1
-1
@@ -334,7 +334,7 @@ proc end_tests {} {
|
||||
puts "GOOD! No errors."
|
||||
exit 0
|
||||
} else {
|
||||
puts "WARNING $::failed tests faield."
|
||||
puts "WARNING $::failed test(s) failed."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ start_server {} {
|
||||
set cycle 1
|
||||
while {([clock seconds]-$start_time) < $duration} {
|
||||
test "PSYNC2: --- CYCLE $cycle ---" {}
|
||||
incr cycle
|
||||
incr cycle
|
||||
|
||||
# Create a random replication layout.
|
||||
# Start with switching master (this simulates a failover).
|
||||
|
||||
@@ -17,7 +17,7 @@ test "Basic failover works if the master is down" {
|
||||
wait_for_condition 1000 50 {
|
||||
[lindex [S $id SENTINEL GET-MASTER-ADDR-BY-NAME mymaster] 1] != $old_port
|
||||
} else {
|
||||
fail "At least one Sentinel did not received failover info"
|
||||
fail "At least one Sentinel did not receive failover info"
|
||||
}
|
||||
}
|
||||
restart_instance redis $master_id
|
||||
@@ -108,7 +108,7 @@ test "Failover works if we configure for absolute agreement" {
|
||||
wait_for_condition 1000 50 {
|
||||
[lindex [S $id SENTINEL GET-MASTER-ADDR-BY-NAME mymaster] 1] != $old_port
|
||||
} else {
|
||||
fail "At least one Sentinel did not received failover info"
|
||||
fail "At least one Sentinel did not receive failover info"
|
||||
}
|
||||
}
|
||||
restart_instance redis $master_id
|
||||
|
||||
@@ -16,7 +16,7 @@ test "We can failover with Sentinel 1 crashed" {
|
||||
wait_for_condition 1000 50 {
|
||||
[lindex [S $id SENTINEL GET-MASTER-ADDR-BY-NAME mymaster] 1] != $old_port
|
||||
} else {
|
||||
fail "Sentinel $id did not received failover info"
|
||||
fail "Sentinel $id did not receive failover info"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ test "After Sentinel 1 is restarted, its config gets updated" {
|
||||
wait_for_condition 1000 50 {
|
||||
[lindex [S 1 SENTINEL GET-MASTER-ADDR-BY-NAME mymaster] 1] != $old_port
|
||||
} else {
|
||||
fail "Restarted Sentinel did not received failover info"
|
||||
fail "Restarted Sentinel did not receive failover info"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ proc 02_crash_and_failover {} {
|
||||
wait_for_condition 1000 50 {
|
||||
[lindex [S $id SENTINEL GET-MASTER-ADDR-BY-NAME mymaster] 1] != $old_port
|
||||
} else {
|
||||
fail "At least one Sentinel did not received failover info"
|
||||
fail "At least one Sentinel did not receive failover info"
|
||||
}
|
||||
}
|
||||
restart_instance redis $master_id
|
||||
|
||||
@@ -12,7 +12,7 @@ test "Manual failover works" {
|
||||
wait_for_condition 1000 50 {
|
||||
[lindex [S $id SENTINEL GET-MASTER-ADDR-BY-NAME mymaster] 1] != $old_port
|
||||
} else {
|
||||
fail "At least one Sentinel did not received failover info"
|
||||
fail "At least one Sentinel did not receive failover info"
|
||||
}
|
||||
}
|
||||
set addr [S 0 SENTINEL GET-MASTER-ADDR-BY-NAME mymaster]
|
||||
|
||||
+34
-1
@@ -25,6 +25,39 @@ start_server {tags {"dump"}} {
|
||||
assert {$ttl >= (2569591501-3000) && $ttl <= 2569591501}
|
||||
r get foo
|
||||
} {bar}
|
||||
|
||||
test {RESTORE can set an absolute expire} {
|
||||
r set foo bar
|
||||
set encoded [r dump foo]
|
||||
r del foo
|
||||
set now [clock milliseconds]
|
||||
r restore foo [expr $now+3000] $encoded absttl
|
||||
set ttl [r pttl foo]
|
||||
assert {$ttl >= 2900 && $ttl <= 3100}
|
||||
r get foo
|
||||
} {bar}
|
||||
|
||||
test {RESTORE can set LRU} {
|
||||
r set foo bar
|
||||
set encoded [r dump foo]
|
||||
r del foo
|
||||
r config set maxmemory-policy allkeys-lru
|
||||
r restore foo 0 $encoded idletime 1000
|
||||
set idle [r object idletime foo]
|
||||
assert {$idle >= 1000 && $idle <= 1010}
|
||||
r get foo
|
||||
} {bar}
|
||||
|
||||
test {RESTORE can set LFU} {
|
||||
r set foo bar
|
||||
set encoded [r dump foo]
|
||||
r del foo
|
||||
r config set maxmemory-policy allkeys-lfu
|
||||
r restore foo 0 $encoded freq 100
|
||||
set freq [r object freq foo]
|
||||
assert {$freq == 100}
|
||||
r get foo
|
||||
} {bar}
|
||||
|
||||
test {RESTORE returns an error of the key already exists} {
|
||||
r set foo bar
|
||||
@@ -246,7 +279,7 @@ start_server {tags {"dump"}} {
|
||||
set e
|
||||
} {*empty string*}
|
||||
|
||||
test {MIGRATE with mutliple keys migrate just existing ones} {
|
||||
test {MIGRATE with multiple keys migrate just existing ones} {
|
||||
set first [srv 0 client]
|
||||
r set key1 "v1"
|
||||
r set key2 "v2"
|
||||
|
||||
@@ -121,7 +121,7 @@ start_server {tags {"expire"}} {
|
||||
list $a $b
|
||||
} {somevalue {}}
|
||||
|
||||
test {TTL returns tiem to live in seconds} {
|
||||
test {TTL returns time to live in seconds} {
|
||||
r del x
|
||||
r setex x 10 somevalue
|
||||
set ttl [r ttl x]
|
||||
|
||||
@@ -186,7 +186,7 @@ proc test_slave_buffers {test_name cmd_count payload_len limit_memory pipeline}
|
||||
|
||||
# put the slave to sleep
|
||||
set rd_slave [redis_deferring_client]
|
||||
catch {exec taskkill.exe -F -T -PID $slave_pid}
|
||||
exec kill -SIGSTOP $slave_pid
|
||||
|
||||
# send some 10mb worth of commands that don't increase the memory usage
|
||||
if {$pipeline == 1} {
|
||||
@@ -226,7 +226,7 @@ proc test_slave_buffers {test_name cmd_count payload_len limit_memory pipeline}
|
||||
|
||||
}
|
||||
# unfreeze slave process (after the 'test' succeeded or failed, but before we attempt to terminate the server
|
||||
catch {exec taskkill.exe -F -T -PID $slave_pid}
|
||||
exec kill -SIGCONT $slave_pid
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,9 +235,12 @@ proc test_slave_buffers {test_name cmd_count payload_len limit_memory pipeline}
|
||||
# we wanna use many small commands, and we don't wanna wait long
|
||||
# so we need to use a pipeline (redis_deferring_client)
|
||||
# that may cause query buffer to fill and induce eviction, so we disable it
|
||||
test_slave_buffers {slave buffer are counted correctly} 1000000 10 0 1
|
||||
# Redis for Windows: disabled as it requires stopping the slave process (SIGSTOP) and then
|
||||
# letting it continue (SIGCONT)
|
||||
#test_slave_buffers {slave buffer are counted correctly} 1000000 10 0 1
|
||||
|
||||
# test that slave buffer don't induce eviction
|
||||
# test again with fewer (and bigger) commands without pipeline, but with eviction
|
||||
test_slave_buffers "replica buffer don't induce eviction" 100000 100 1 0
|
||||
|
||||
# Redis for Windows: disabled as it requires stopping the slave process (SIGSTOP) and then
|
||||
# letting it continue (SIGCONT)
|
||||
#test_slave_buffers "replica buffer don't induce eviction" 100000 100 1 0
|
||||
|
||||
@@ -36,18 +36,18 @@ start_server {tags {"memefficiency"}} {
|
||||
}
|
||||
}
|
||||
|
||||
start_server {tags {"defrag"}} {
|
||||
if {[string match {*jemalloc*} [s mem_allocator]]} {
|
||||
test "Active defrag" {
|
||||
r config set activedefrag no
|
||||
r config set active-defrag-threshold-lower 5
|
||||
start_server {tags {"defrag"}} {
|
||||
if {[string match {*jemalloc*} [s mem_allocator]]} {
|
||||
test "Active defrag" {
|
||||
r config set activedefrag no
|
||||
r config set active-defrag-threshold-lower 5
|
||||
r config set active-defrag-cycle-min 65
|
||||
r config set active-defrag-cycle-max 75
|
||||
r config set active-defrag-ignore-bytes 2mb
|
||||
r config set maxmemory 100mb
|
||||
r config set maxmemory-policy allkeys-lru
|
||||
r debug populate 700000 asdf 150
|
||||
r debug populate 170000 asdf 300
|
||||
r config set active-defrag-ignore-bytes 2mb
|
||||
r config set maxmemory 100mb
|
||||
r config set maxmemory-policy allkeys-lru
|
||||
r debug populate 700000 asdf 150
|
||||
r debug populate 170000 asdf 300
|
||||
r ping ;# trigger eviction following the previous population
|
||||
after 120 ;# serverCron only updates the info once in 100ms
|
||||
set frag [s allocator_frag_ratio]
|
||||
@@ -191,8 +191,8 @@ start_server {tags {"memefficiency"}} {
|
||||
lassign $event eventname time latency max
|
||||
if {$eventname == "active-defrag-cycle"} {
|
||||
set max_latency $max
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if {$::verbose} {
|
||||
puts "frag $frag"
|
||||
puts "max latency $max_latency"
|
||||
|
||||
@@ -525,12 +525,12 @@ start_server {tags {"hash"}} {
|
||||
# 1.23 cannot be represented correctly with 64 bit doubles, so we skip
|
||||
# the test, since we are only testing pretty printing here and is not
|
||||
# a bug if the program outputs things like 1.299999...
|
||||
if {!$::valgrind && [string match *x86_64* [exec uname -a]]} {
|
||||
test {Test HINCRBYFLOAT for correct float representation (issue #2846)} {
|
||||
r del myhash
|
||||
assert {[r hincrbyfloat myhash float 1.23] eq {1.23}}
|
||||
assert {[r hincrbyfloat myhash float 0.77] eq {2}}
|
||||
assert {[r hincrbyfloat myhash float -0.1] eq {1.9}}
|
||||
}
|
||||
}
|
||||
# if {!$::valgrind && [string match *x86_64* [exec uname -a]]} {
|
||||
# test {Test HINCRBYFLOAT for correct float representation (issue #2846)} {
|
||||
# r del myhash
|
||||
# assert {[r hincrbyfloat myhash float 1.23] eq {1.23}}
|
||||
# assert {[r hincrbyfloat myhash float 0.77] eq {2}}
|
||||
# assert {[r hincrbyfloat myhash float -0.1] eq {1.9}}
|
||||
# }
|
||||
# }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user