275 Commits

Author SHA1 Message Date
antirez
b089ba98cc Scripting: expire keys in scripts only at first access.
Keys expiring in the middle of the execution of Lua scripts are to
create inconsistencies in masters and / or AOF files. See the following
example:

    if redis.call("exists",KEYS[1]) == 1
    then
        redis.call("incr","mycounter")
    end

    if redis.call("exists",KEYS[1]) == 1
    then
        return redis.call("incr","mycounter")
    end

The script executes two times the same *if key exists then incrementcounter*
logic. However the two executions will work differently in the master and
the slaves, provided some unlucky timing happens.

In the master the first time the key may still exist, while the second time
the key may no longer exist. This will result in the key incremented just one
time. However as a side effect the master will generate a synthetic
`DEL` command in the replication channel in order to force the slaves to
expire the key (given that key expiration is master-driven).

When the same script will run in the slave, the key will no longer be
there, so the script will not increment the key.

The key idea used to implement the expire-at-first-lookup semantics was
provided by Marc Gravell.
2014-02-03 16:15:53 +01:00
antirez
2eb781b35b dict.c: added optional callback to dictEmpty().
Redis hash table implementation has many non-blocking features like
incremental rehashing, however while deleting a large hash table there
was no way to have a callback called to do some incremental work.

This commit adds this support, as an optiona callback argument to
dictEmpty() that is currently called at a fixed interval (one time every
65k deletions).
2013-12-10 18:46:24 +01:00
antirez
11e81a1e9a Fixed grammar: before H the article is a, not an. 2013-12-05 16:35:32 +01:00
antirez
671c1dfb56 Sentinel: always send CONFIG REWRITE when changing instance role.
This change makes Sentinel less fragile about a number of failure modes.

This commit also fixes a different bug as a side effect, SLAVEOF command
was sent multiple times without incrementing the pending commands count.
2013-11-06 11:13:27 +01:00
antirez
ebcb6251e6 SCAN code refactored to parse cursor first.
The previous implementation of SCAN parsed the cursor in the generic
function implementing SCAN, SSCAN, HSCAN and ZSCAN.

The actual higher-level command implementation only checked for empty
keys and return ASAP in that case. The result was that inverting the
arguments of, for instance, SSCAN for example and write:

    SSCAN 0 key

Instead of

    SSCAN key 0

Resulted into no error, since 0 is a non-existing key name very likely.
Just the iterator returned no elements at all.

In order to fix this issue the code was refactored to extract the
function to parse the cursor and return the error. Every higher level
command implementation now parses the cursor and later checks if the key
exist or not.
2013-11-05 15:47:50 +01:00
antirez
b4048dfec0 SCAN: when iterating ziplists or intsets always return cursor of 0.
The previous implementation assumed that the first call always happens
with cursor set to 0, this may not be the case, and we want to return 0
anyway otherwise the (broken) client code will loop forever.
2013-11-05 15:32:25 +01:00
antirez
101d4bf867 Use strtoul() instead of sscanf() in SCAN implementation. 2013-11-05 15:30:21 +01:00
antirez
f56f78d159 HSCAN/ZSCAN: skip value when matching.
This fixes issue #1360 and #1362.
2013-11-05 12:16:29 +01:00
antirez
eb95d28898 Pass int64_t to intsetGet() instead of long long. 2013-11-05 11:57:30 +01:00
antirez
c4ca5f99bf Inverted variable boolean value and name after scanGenericCommand() refactoring. 2013-10-31 10:35:56 +01:00
antirez
8fc85a1218 scanGenericCommand() refactoring and handling of integer encoded elements.
This commit fixes issue #1354.
2013-10-31 10:32:39 +01:00
antirez
e50090aa06 HSCAN implemented. 2013-10-28 11:35:26 +01:00
antirez
442ae833b2 SCAN: refactored into scanGenericCommand.
The new implementation is capable of iterating the keyspace but also
sets, hashes, and sorted sets, and can be used to implement SSCAN, ZSCAN
and HSCAN.
2013-10-28 11:11:34 +01:00
antirez
48ea8a0a11 SCAN: stay inside 80 cols. 2013-10-25 12:01:49 +02:00
antirez
df13adb037 Revert "Fixed typo in SCAN comment. iff -> if."
Probably here Pieter means "if and only if".

This reverts commit 43fdf3b404413f6e3b2c39ac491238c70ecee81c.
2013-10-25 12:00:13 +02:00
antirez
a25fe0b28d SCAN: simplify keys list cleanup using listSetFreeMethod(). 2013-10-25 11:58:03 +02:00
antirez
fd1b0ad07c SCAN: improve variable names for readability. 2013-10-25 11:54:45 +02:00
antirez
908eba5a8f SCAN: remove additional newlines to conform to Redis code base. 2013-10-25 11:51:08 +02:00
antirez
6e55e543c6 SCAN: remove useless assertion, already enforced by command table. 2013-10-25 11:49:08 +02:00
antirez
64722b0946 SCAN: use define REDIS_LONGSTR_SIZE instead of fixed len. 2013-10-25 11:48:18 +02:00
antirez
43fdf3b404 Fixed typo in SCAN comment. iff -> if. 2013-10-25 11:46:02 +02:00
antirez
9c88ace927 SCAN option name changed: pattern -> match. 2013-10-25 11:45:32 +02:00
Pieter Noordhuis
7a6cfb18f3 SCAN requires at least 1 argument 2013-10-25 10:49:56 +02:00
Pieter Noordhuis
7f490b197f Add SCAN command 2013-10-25 10:49:48 +02:00
antirez
929b6a4480 Cluster: cluster stuff moved from redis.h to cluster.h. 2013-10-09 15:38:05 +02:00
antirez
3130670b97 Allow SHUTDOWN in loading state. 2013-06-27 12:18:29 +02:00
antirez
140260409e EXPIRE should not resurrect keys. Issue #1026. 2013-03-28 12:45:07 +01:00
antirez
873f328fd8 TTL / PTTL commands: two bugs fixed.
This commit fixes two corner cases for the TTL command.

1) When the key was already logically expired (expire time older
than current time) the command returned -1 instead of -2.

2) When the key was existing and the expire was found to be exactly 0
(the key was just about to expire), the command reported -1 (that is, no
expire) instead of a TTL of zero (that is, about to expire).
2013-03-26 11:45:22 +01:00
antirez
a89d435d8e Cluster: move slotToKeyFlush() to emptyDb().
This way we are sure to destroy the slot->key map every time we destroy
the DB, for instance when reloading a DB due to replication.
2013-03-21 17:13:08 +01:00
antirez
996a643752 Cluster: use O(log(N)) algo for countKeysInSlot(). 2013-02-25 12:37:50 +01:00
antirez
d2154254be Cluster: fix case for getKeysInSlot() and countKeysInSlot().
Redis functions start in low case. A few functions about cluster were
capitalized the wrong way.
2013-02-25 11:25:40 +01:00
antirez
1abce14611 Cluster: added new API countKeysInSlot().
This is similar to getKeysInSlot() but just returns the number of keys
found in a given hash slot, without returning the keys.
2013-02-25 11:15:03 +01:00
antirez
392e0fa7eb Cluster: fix case of slotToKey...() functions. 2013-02-22 10:16:21 +01:00
antirez
d04770988d Cluster: empty the internal sorted set mapping keys to slots on FLUSHDB/ALL. 2013-02-22 10:15:32 +01:00
antirez
1649e509c3 Cluster: the cluster state structure is now heap allocated. 2013-02-14 13:20:56 +01:00
antirez
078882025e PSYNC: work in progress, preview #2, rebased to unstable. 2013-02-12 12:52:21 +01:00
antirez
4dfb5752e0 Send 'expired' events when a key expires by lookup. 2013-01-28 13:15:19 +01:00
antirez
fce016d31b Keyspace events: it is now possible to select subclasses of events.
When keyspace events are enabled, the overhead is not sever but
noticeable, so this commit introduces the ability to select subclasses
of events in order to avoid to generate events the user is not
interested in.

The events can be selected using redis.conf or CONFIG SET / GET.
2013-01-28 13:15:12 +01:00
antirez
da04e6ed44 Keyspace events added for more commands. 2013-01-28 13:14:56 +01:00
antirez
5b9357a6b3 Initial test events for the new keyspace notification API. 2013-01-28 13:14:46 +01:00
antirez
2ea9518a53 Fixed over-80-cols comment in db.c 2013-01-28 13:14:42 +01:00
antirez
79a0ef62db Whitelist SIGUSR1 to avoid auto-triggering errors.
This commit fixes issue #875 that was caused by the following events:

1) There is an active child doing BGSAVE.
2) flushall is called (or any other condition that makes Redis killing
the saving child process).
3) An error is sensed by Redis as the child exited with an error (killed
by a singal), that stops accepting write commands until a BGSAVE happens
to be executed with success.

Whitelisting SIGUSR1 and making sure Redis always uses this signal in
order to kill its own children fixes the issue.
2013-01-19 13:30:38 +01:00
guiquanz
9d09ce3981 Fixed many typos. 2013-01-19 10:59:44 +01:00
antirez
aa2bf6ba8b TTL API change: TTL returns -2 for non existing keys.
The previous behavior was to return -1 if:

1) Existing key but without an expire set.
2) Non existing key.

Now the second case is handled in a different, and TTL will return -2
if the key does not exist at all.

PTTL follows the same behavior as well.
2012-11-12 23:04:36 +01:00
antirez
4365e5b2d3 BSD license added to every C source and header file. 2012-11-08 18:31:32 +01:00
antirez
bfc197c3b6 Make sure that SELECT argument is an integer or return an error.
Unfortunately we had still the lame atoi() without any error checking in
place, so "SELECT foo" would work as "SELECT 0". This was not an huge
problem per se but some people expected that DB can be strings and not
just numbers, and without errors you get the feeling that they can be
numbers, but not the behavior.

Now getLongFromObjectOrReply() is used as almost everybody else across
the code, generating an error if the number is not an integer or
overflows the long type.

Thanks to @mipearson for reporting that on Twitter.
2012-09-11 10:32:04 +02:00
Pieter Noordhuis
cc4f65fea4 Use safe dictionary iterator from KEYS
Every matched key in a KEYS call is checked for expiration. When the key
is set to expire, the call to `getExpire` will assert that the key also
exists in the main dictionary. This in turn causes a rehashing step to
be executed. Rehashing a dictionary when there is an iterator active may
result in the iterator emitting duplicate entries, or not emitting some
entries at all. By using a safe iterator, the rehash step is omitted.
2012-05-01 10:52:03 +02:00
antirez
4cb8bb2952 Never used function stringObjectEqualsMs() removed. 2012-04-07 02:10:48 +02:00
antirez
70381bbf82 expireGenericCommand(): better variable names and a top-comment that describes the function's behavior. 2012-04-05 15:52:08 +02:00
Premysl Hruby
c6bf4a0034 for (p)expireat use absolute time, without double recomputation 2012-04-05 15:46:21 +02:00