antirez/redis — pull request #499 by eric (2012-05-04 23:06:49+00:00)
Title: Add "readonly" setting to server config to block write commands

## Background

There are two scenarios when dealing with failover that would be greatly improved by the introduction of a `readonly` flag for redis.

### 1. During a graceful failover

To perform an upgrade of your redis cluster, it is possible to quickly quiesce all writes and quickly do the failover with a very small interruption.

During the period where we invoke the slave statements, it is possible that writes could be made to the old master and would cause them to be lost when the slave of statement is invoked.

Being able to set both the old and new masters to readonly during that window would allow us to guarantee no clients thought they successfully wrote to the server when they didn't.

### 2. When a client isn't properly notified of the new master

If a client (for any number of reasons, including a network partition, a service not running properly, a code bug, etc.) does not properly update it's configuration data to reflect the new master IP and continues to write to the old one, those writes will never be seen by the master and by the rest of the systems.

## Solution

This pull request introduces a configuration setting called `readonly` that can be set in the configuration file or runtime and blocks all commands that modify data.

It does this by introducing a flag called `REDIS_CMD_MODIFIES_DATA` that is applied to redis commands that modify data and rejects all writes that do not come from a client that is marked as `REDIS_MASTER`.

## Using it

The setting can be set to "yes" or "no" in the configuration file:

# Change setting to 'yes' to prevent writes to this server
readonly no

or via the config command:

$ redis-cli config set readonly yes

If a blocked command is sent from a client, the server responds with:

-ERR command not allowed when readonly is set to yes