writes could be acknowledged despite a lack of redundancy. In the event of a zone failure, all data in the
affected PG would be lost.
+.. _entering_stretch_mode:
+
Entering Stretch Mode
---------------------
due to the long time it takes for them to recover after connectivity between
data centers has been restored. This reduces the potential for data loss.
-.. warning:: CRUSH rules that specify a device class are not supported in stretch mode.
- For example, the following rule specifying the ``ssd`` device class will not work::
+.. warning:: Do not specify a device class in the CRUSH rule used for stretch
+ mode. Ceph accepts such a rule and reports healthy stretch mode, but the PGs
+ will fail to peer if a data center is later lost.
+
+ A device class makes CRUSH select OSDs from a shadow tree, in which
+ ``zone1`` is a separate bucket named ``zone1~ssd``::
rule stretch_replicated_rule {
id 1
- type replicated class ssd
- step take default
+ type replicated
+ step take default class ssd
step choose firstn 0 type datacenter
step chooseleaf firstn 2 type host
step emit
}
+ The class is honored and the placement is correct: OSDs of that class are
+ chosen from both data centers, as asked. The problem is in the peering
+ check. Stretch mode resolves each OSD to its ``datacenter`` through the
+ pool's CRUSH rule, so with the rule above it sees ``zone1~ssd`` rather than
+ ``zone1``. You will not notice this while both data centers are up, because
+ peering only counts how many distinct buckets the acting set spans, and two
+ shadow buckets count as two.
+
+ The mismatch matters once a data center is lost. When the cluster enters
+ degraded stretch mode, the Monitors record the surviving data center by its
+ real bucket, ``zone1``, and require every PG to include it. That never
+ matches the ``zone1~ssd`` the rule reports, so every PG of every pool using
+ that rule goes inactive and its data is unavailable.
+
+ Restoring the lost data center does not clear this. The cluster returns to
+ healthy stretch mode only once no PG is left degraded, inactive, or unknown,
+ and these PGs stay inactive for as long as that requirement stands, so
+ recovery never finishes on its own. Breaking the loop takes ``ceph osd
+ force_healthy_stretch_mode --yes-i-really-mean-it``, which drops the
+ requirement and lets the PGs peer.
+
+ Use a rule without a device class from the start, such as the one under
+ :ref:`entering_stretch_mode`. If a cluster is already in stretch mode, check
+ the rule that each of its pools uses and correct it while both data centers
+ are up. Switching a pool to another rule moves most of its data, because the
+ shadow tree and the real tree place data differently even when they hold the
+ same OSDs.
+
In the future, stretch mode could support erasure-coded pools,
enable deployments across more than two data centers,
and accommodate multiple CRUSH device classes.