[
https://issues.apache.org/jira/browse/HDDS-17019?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Siyao Meng updated HDDS-17019:
------------------------------
Attachment: TestBugMC4DbVolumeFailureNotPropagated.java
> Failure of a datanode DB volume is not propagated to the data volumes whose
> RocksDB it holds, so they stay in service
> ---------------------------------------------------------------------------------------------------------------------
>
> Key: HDDS-17019
> URL: https://issues.apache.org/jira/browse/HDDS-17019
> Project: Apache Ozone
> Issue Type: Bug
> Reporter: Siyao Meng
> Priority: Major
> Attachments: MC-4-fail-data-volumes-of-failed-db-volume.patch,
> TestBugMC4DbVolumeFailureNotPropagated.java
>
>
> h3. Mechanism
> With {{hdds.datanode.container.db.dir}} set, the schema V3 RocksDB of each
> data volume lives on a separate DB volume. {{OzoneContainer}} registers a
> failed volume listener only on the data volume set; the DB volume set has
> none. When the periodic check fails a DB volume, {{DbVolume.failVolume}}
> closes and uncaches the DB stores below it, but the data volumes that use it
> are left NORMAL: they keep their containers, are reported to SCM as healthy
> and are still chosen for new containers. {{DatanodeStoreCache.getDB}} reopens
> a store that is not cached on its next access, so those data volumes go on
> using a RocksDB on the failed DB volume.
> {{HddsVolume.check}} only checks that the data volume's own RocksDB files can
> be read and opened. It does not look at the DB volume's state, so a DB volume
> that fails its own check while those files stay readable (its root directory
> no longer writable, as reproduced here, or a file system remounted read only
> after errors) leaves the data volumes in service. A DB disk that becomes
> unreadable is already caught by each data volume's own check.
> h3. Trigger
> # A datanode with two or more DB volumes. With a single DB volume the
> datanode already shuts down when it fails, because the default
> {{hdds.datanode.failed.db.volumes.tolerated}} of -1 requires one healthy DB
> volume.
> # A DB volume fails its periodic disk check while the RocksDB files on it
> stay readable.
> No client action is involved.
> h3. Impact
> * The data volumes whose DB is on the failed DB volume stay in service until
> the datanode restarts. SCM is not told and their containers are not
> re-replicated.
> * New containers are placed on those data volumes and their block metadata is
> written to the RocksDB that the cache reopened on the failed DB volume. In
> the reproduction the DB files themselves are still writable, so those writes
> succeed. On a file system remounted read only the reopen or the writes would
> fail instead (argued from the code, not run).
> h3. Reproduction
> PASS, deterministic, unmodified source, needs a POSIX file system and a non
> root user. [^TestBugMC4DbVolumeFailureNotPropagated.java]
> ({{hadoop-hdds/container-service}}) starts a real {{OzoneContainer}} with two
> data volumes and two DB volumes; one data volume has its RocksDB on a DB
> volume, the other on itself. The root directory of that DB volume is made
> read only and the real {{StorageVolumeChecker}} fails it through
> {{MutableVolumeSet.checkAllVolumes}}. The data volume set check that follows
> passes, because the RocksDB files stay readable. The data volume stays NORMAL
> with its DB loaded, a new container is placed on it with the round robin
> policy, its block is committed to a DB file under the failed DB volume, and
> the node report shows the data volume as not failed. A passing test means the
> defect is present.
> h3. Patch
> [^MC-4-fail-data-volumes-of-failed-db-volume.patch], against
> cce1ca28944886218132f01c0e271c1fd0700078. It also applies to master at
> 2536fe9cbc3.
> {{OzoneContainer}} registers a failed volume listener on the DB volume set.
> It collects the active data volumes whose DB volume has failed and passes
> them to {{MutableVolumeSet.handleVolumeFailures}} of the data volume set
> (made public for this), which is the existing path for a failed data volume:
> it marks them failed, closes their DBs, applies
> {{hdds.datanode.failed.data.volumes.tolerated}} and runs the data set
> listener that removes their containers and sends a full container report. The
> listener runs after the DB set has released its lock, so no locks are nested.
> Checking the DB volume from {{HddsVolume.check}} instead would only act in
> the next periodic check, because data volumes are checked before DB volumes
> in each cycle.
> This changes behaviour on purpose, on nodes with two or more DB volumes:
> losing a DB disk now fails every data volume whose DB is on it, their
> containers are re-replicated, and if that exceeds the tolerated number of
> failed data volumes the datanode shuts down, as for any other data volume
> loss.
> Not covered: a DB volume that fails {{StorageVolumeUtil.checkVolume}} during
> the SCM version handshake at startup. {{VersionEndpointTask}} fails it
> directly through {{MutableVolumeSet.failVolume}} while holding the DB set
> lock, so the listener does not run there, and the data volumes whose DB was
> already loaded on it stay in service. Covering it would need a separate check
> in that task.
> Covered by {{testDbVolumeFailureFailsDataVolumesWithDbOnIt}} in the existing
> {{TestOzoneContainer}}, with three data volumes whose RocksDB is on the
> failing DB volume, on the other DB volume and on the data volume itself.
> Without the change it fails because no data volume is failed; it also fails
> if every data volume with a DB volume is failed. With it the
> {{TestOzoneContainer}}, volume, DB volume, volume checker and volume health
> check suites (138 tests) and {{TestOzoneContainerWithTLS}}, an integration
> test that starts a real {{OzoneContainer}} with a DB volume configured, pass,
> and checkstyle is clean. With the patch the reproduction fails because the
> data volume is FAILED.
> Found by TLA+ model checking and code review of the datanode volume and
> per-disk RocksDB lifecycle paths under HDDS-15926, on commit
> cce1ca28944886218132f01c0e271c1fd0700078. Checked against HDDS issues and
> apache/ozone pull requests for duplicates before filing. Related but not
> duplicates: HDDS-6616 and HDDS-6541, which added the DB volume check and the
> separate DB location. The attached patch is a proposal for review. Generated
> with Specula (Claude Opus 5.5).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]