From 7a835fcd8fe7888ba9a5003ee7a07e5cb0dff2d1 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sun, 23 Mar 2025 02:09:21 +0300 Subject: [PATCH] Add allow_net_split parameter --- docs/config/osd.en.md | 15 +++++++++++++++ docs/config/osd.ru.md | 16 ++++++++++++++++ docs/config/pool.en.md | 3 +++ docs/config/pool.ru.md | 3 +++ docs/config/src/osd.yml | 22 ++++++++++++++++++++++ docs/usage/admin.en.md | 17 +++++++++++++---- docs/usage/admin.ru.md | 18 ++++++++++++++---- src/osd/osd.cpp | 1 + src/osd/osd.h | 1 + src/osd/osd_peering.cpp | 2 +- 10 files changed, 89 insertions(+), 9 deletions(-) diff --git a/docs/config/osd.en.md b/docs/config/osd.en.md index 1b0262cb..a3035958 100644 --- a/docs/config/osd.en.md +++ b/docs/config/osd.en.md @@ -63,6 +63,7 @@ with an OSD restart or, for some of them, even without restarting by updating co - [recovery_tune_sleep_cutoff_us](#recovery_tune_sleep_cutoff_us) - [discard_on_start](#discard_on_start) - [min_discard_size](#min_discard_size) +- [allow_net_split](#allow_net_split) ## osd_iothread_count @@ -644,3 +645,17 @@ Discard (SSD TRIM) unused data device blocks on every OSD startup. - Default: 1048576 Minimum consecutive block size to TRIM it. + +## allow_net_split + +- Type: boolean +- Default: false + +Allow "safe" cases of network splits/partitions - allow to start PGs without +connections to some OSDs currently registered as alive in etcd, if the number +of actually connected PG OSDs is at least pg_minsize. That is, allow some OSDs to lose +connectivity with some other OSDs as long as it doesn't break pg_minsize guarantees. +The downside is that it increases the probability of writing data into just pg_minsize +OSDs during failover which can lead to PGs becoming incomplete after additional outages. + +The old behaviour in versions up to 2.0.0 was equal to enabled allow_net_split. diff --git a/docs/config/osd.ru.md b/docs/config/osd.ru.md index eed8691a..504f0486 100644 --- a/docs/config/osd.ru.md +++ b/docs/config/osd.ru.md @@ -64,6 +64,7 @@ - [recovery_tune_sleep_cutoff_us](#recovery_tune_sleep_cutoff_us) - [discard_on_start](#discard_on_start) - [min_discard_size](#min_discard_size) +- [allow_net_split](#allow_net_split) ## osd_iothread_count @@ -675,3 +676,18 @@ EC (кодов коррекции ошибок) с более, чем 1 диск - Значение по умолчанию: 1048576 Минимальный размер последовательного блока данных, чтобы освобождать его через TRIM. + +## allow_net_split + +- Тип: булево (да/нет) +- Значение по умолчанию: false + +Разрешить "безопасные" случаи разделений сети - разрешить активировать PG без +соединений к некоторым OSD, помеченным активными в etcd, если общее число активных +OSD в PG составляет как минимум pg_minsize. То есть, разрешать некоторым OSD терять +соединения с некоторыми другими OSD, если это не нарушает гарантий pg_minsize. +Минус такого разрешения в том, что оно повышает вероятность записи данных ровно в +pg_minsize OSD во время переключений, что может потом привести к тому, что PG станут +неполными (incomplete), если упадут ещё какие-то OSD. + +Старое поведение в версиях до 2.0.0 было идентично включённому allow_net_split. diff --git a/docs/config/pool.en.md b/docs/config/pool.en.md index fa34665a..76ace346 100644 --- a/docs/config/pool.en.md +++ b/docs/config/pool.en.md @@ -189,6 +189,9 @@ So, pg_minsize regulates the number of failures that a pool can tolerate without temporary downtime for [osd_out_time](monitor.en.md#osd_out_time), but at a cost of slightly reduced storage reliability. +See also [allow_net_split](osd.en.md#allow_net_split) and +[PG state descriptions](../usage/admin.en.md#pg-states). + FIXME: pg_minsize behaviour may be changed in the future to only make PGs read-only instead of deactivating them. diff --git a/docs/config/pool.ru.md b/docs/config/pool.ru.md index d7557ceb..34b9b8b6 100644 --- a/docs/config/pool.ru.md +++ b/docs/config/pool.ru.md @@ -413,6 +413,9 @@ OSD с "all". (например, `s3:standard`) - конкретное содержимое `` пока никак не проверяется компонентами Vitastor S3. +Смотрите также [allow_net_split](osd.ru.md#allow_net_split) и +[документацию по состояниям PG](../usage/admin.ru.md#состояния-pg). + Все остальные значения used_for_app, кроме начинающихся на `fs:` или `s3:`, не означают ничего особенного для основных компонентов Vitastor. Поэтому сейчас вы можете использовать их свободно любым желаемым способом. diff --git a/docs/config/src/osd.yml b/docs/config/src/osd.yml index fae18dce..f707be44 100644 --- a/docs/config/src/osd.yml +++ b/docs/config/src/osd.yml @@ -774,3 +774,25 @@ default: 1048576 info: Minimum consecutive block size to TRIM it. info_ru: Минимальный размер последовательного блока данных, чтобы освобождать его через TRIM. +- name: allow_net_split + type: bool + default: false + info: | + Allow "safe" cases of network splits/partitions - allow to start PGs without + connections to some OSDs currently registered as alive in etcd, if the number + of actually connected PG OSDs is at least pg_minsize. That is, allow some OSDs to lose + connectivity with some other OSDs as long as it doesn't break pg_minsize guarantees. + The downside is that it increases the probability of writing data into just pg_minsize + OSDs during failover which can lead to PGs becoming incomplete after additional outages. + + The old behaviour in versions up to 2.0.0 was equal to enabled allow_net_split. + info_ru: | + Разрешить "безопасные" случаи разделений сети - разрешить активировать PG без + соединений к некоторым OSD, помеченным активными в etcd, если общее число активных + OSD в PG составляет как минимум pg_minsize. То есть, разрешать некоторым OSD терять + соединения с некоторыми другими OSD, если это не нарушает гарантий pg_minsize. + Минус такого разрешения в том, что оно повышает вероятность записи данных ровно в + pg_minsize OSD во время переключений, что может потом привести к тому, что PG станут + неполными (incomplete), если упадут ещё какие-то OSD. + + Старое поведение в версиях до 2.0.0 было идентично включённому allow_net_split. diff --git a/docs/usage/admin.en.md b/docs/usage/admin.en.md index 98f44f84..c8f77432 100644 --- a/docs/usage/admin.en.md +++ b/docs/usage/admin.en.md @@ -35,10 +35,19 @@ PG state consists of exactly 1 base state and an arbitrary number of additional PG state always includes exactly 1 of the following base states: - **active** — PG is active and handles user I/O. -- **incomplete** — Not enough OSDs are available to activate this PG. That is, more disks - are lost than it's allowed by the pool's redundancy scheme. For example, if the pool has - pg_size=3 and pg_minsize=1, part of the data may be written only to 1 OSD. If that exact - OSD is lost, PG will become **incomplete**. +- **incomplete** — Not enough OSDs are available to activate this PG. More exactly, that + means one of the following: + - Less than pg_minsize current target OSDs are available for the PG. I.e. more disks + are lost than allowed by the pool's redundancy scheme. + - All OSDs of some of PG's history records are unavailable, or, for EC pools, less + than (pg_size-parity_chunks) OSDs are available in one of the history records. + In other words it means that some data in this PG was written to a such OSD set that + it's currently impossible to read it back because these OSDs are down. For example, + if the pool has pg_size=3 and pg_minsize=1, part of the data may be written only to + 1 OSD. If that exact OSD is lost, PG will become **incomplete**. + - [allow_net_split](../config/osd.en.md#allow_net_split) is disabled (default) and + primary OSD of the PG can't connect to some secondary OSDs marked as alive in etcd. + I.e. a network partition happened: OSDs can talk to etcd, but not to some other OSDs. - **offline** — PG isn't activated by any OSD at all. Either primary OSD isn't set for this PG at all (if the pool is just created), or an unavailable OSD is set as primary, or the primary OSD refuses to start this PG (for example, because of wrong block_size), diff --git a/docs/usage/admin.ru.md b/docs/usage/admin.ru.md index e1bb9171..cce54d6b 100644 --- a/docs/usage/admin.ru.md +++ b/docs/usage/admin.ru.md @@ -35,10 +35,20 @@ Состояние PG включает в себя ровно 1 флаг из следующих: - **active** — PG активна и обрабатывает запросы ввода-вывода от пользователей. -- **incomplete** — Недостаточно живых OSD, чтобы включить эту PG. - То есть, дисков потеряно больше, чем разрешено схемой отказоустойчивости пула и pg_minsize. - Например, если у пула pg_size=3 и pg_minsize=1, то часть данных может записаться всего на 1 OSD. - Если потом конкретно этот OSD упадёт, PG окажется **incomplete**. +- **incomplete** — Недостаточно живых OSD, чтобы включить эту PG. Если точнее, то это + означает один из следующих вариантов: + - Доступно менее, чем pg_minsize текущих целевых OSD данной PG. Иными словами, потеряно + больше дисков, чем это разрешает схема отказоустойчивости пула. + - Все OSD одной из исторических записей PG недоступны, или, для EC-пулов, в одной + из исторических записей PG доступно менее, чем (pg_size-parity_chunks) OSD. Другими + словами это означает, что часть данных этой PG была записана в такой набор OSD, из + которого их сейчас невозможно прочитать обратно, так как OSD не включены. Например, + если у пула pg_size=3 и pg_minsize=1, то часть данных может записаться всего на 1 OSD. + Если потом конкретно этот OSD упадёт, PG окажется **incomplete**. + - [allow_net_split](../config/osd.ru.md#allow_net_split) отключено (по умолчанию) и + первичный OSD данной PG не может соединиться с частью вторичных OSD этой PG, помеченных + как живых в etcd. Это означает, что произошло разделение сети: OSD могут общаться с etcd, + но не могут общаться с частью других OSD. - **offline** — PG вообще не активирована ни одним OSD. Либо первичный OSD не назначен вообще (если пул только создан), либо в качестве первичного назначен недоступный OSD, либо назначенный OSD отказывается запускать эту PG (например, из-за несовпадения block_size), diff --git a/src/osd/osd.cpp b/src/osd/osd.cpp index 7ff32e26..255d1bb9 100644 --- a/src/osd/osd.cpp +++ b/src/osd/osd.cpp @@ -186,6 +186,7 @@ void osd_t::parse_config(bool init) no_recovery = json_is_true(config["no_recovery"]); auto old_no_scrub = no_scrub; no_scrub = json_is_true(config["no_scrub"]); + allow_net_split = json_is_true(config["allow_net_split"]); auto old_autosync_interval = autosync_interval; if (!config["autosync_interval"].is_null()) { diff --git a/src/osd/osd.h b/src/osd/osd.h index 1347df0b..274fea0f 100644 --- a/src/osd/osd.h +++ b/src/osd/osd.h @@ -106,6 +106,7 @@ class osd_t bool no_rebalance = false; bool no_recovery = false; bool no_scrub = false; + bool allow_net_split = false; std::string bind_address; int bind_port, listen_backlog = 128; // FIXME: Implement client queue depth limit diff --git a/src/osd/osd_peering.cpp b/src/osd/osd_peering.cpp index 0d30fc36..67db9196 100644 --- a/src/osd/osd_peering.cpp +++ b/src/osd/osd_peering.cpp @@ -211,7 +211,7 @@ void osd_t::start_pg_peering(pg_t & pg) all_connected = false; } } - if (!all_connected) + if (!all_connected && !allow_net_split) { // Wait until all OSDs are either connected or their /osd/state disappears from etcd pg.state = PG_INCOMPLETE;