Page MenuHomePhabricator

Detect MySQL `read_only` and degrade masters to replicas
Open, NormalPublic

Description

mysqld can be set to read-only with --read-only at startup, which is reflected in the read_only global.

When we attempt to perform writes and they fail because this mode is set, we should degrade to read-only mode as though cluster.read-only was set.

In a true master + replica cluster configuration this is probably moot (you'd just take down whichever database you needed to, probably?) but if operations and Phabricator administration aren't the same teams (or the ops team is just more familiar with MySQL than advanced Phabricator options) the intent of putting MySQL into --read-only is unambiguous.

Event Timeline

eadler added a project: Restricted Project.Jul 25 2016, 4:23 PM

Although this is cluster-related, it can be tested with a single database host and is probably not exceptionally difficult to handle better. Briefly:

  • Connect to your MySQL server and put it in read_only mode. Maybe you can do this with set global read_only = 1? That doesn't actually seem to work for me. Otherwise you might have to change config and restart it.
  • Try to perform a write (e.g., edit a task).
  • Observe that Phabricator breaks in a sort-of confusing way.

We could improve this behavior and treat read_only mode more like the setting cluster.read-only.

However, detecting this mode is a little tricky -- I don't want to add a show variables like @@read_only call to every page, since 99.999% of the time this would just slow things down. We probably need to catch whatever exception read_only raises somewhere and flag the database as iffy in cache until we get a good health check.