This is an automated email from the ASF dual-hosted git repository.

errose28 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 243978a5bdf HDDS-14498. Zero Downtime Upgrade Design (ZDU) (#9664)
243978a5bdf is described below

commit 243978a5bdf2ff666e3111e45283cf8b1eaa04ef
Author: Stephen O'Donnell <[email protected]>
AuthorDate: Fri Oct 9 00:33:00 2026 +0100

    HDDS-14498. Zero Downtime Upgrade Design (ZDU) (#9664)
    
    Co-authored-by: Ethan Rose <[email protected]>
---
 hadoop-hdds/docs/content/design/zdu-design.md  | 542 +++++++++++++++++++++++++
 hadoop-hdds/docs/content/design/zdu-image1.png | Bin 0 -> 919077 bytes
 2 files changed, 542 insertions(+)

diff --git a/hadoop-hdds/docs/content/design/zdu-design.md 
b/hadoop-hdds/docs/content/design/zdu-design.md
new file mode 100644
index 00000000000..07df5928de1
--- /dev/null
+++ b/hadoop-hdds/docs/content/design/zdu-design.md
@@ -0,0 +1,542 @@
+---
+jira: HDDS-14496
+authors:
+- Stephen O'Donnell
+- Ethan Rose
+- Istvan Fajth
+---
+
+<!--
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License. See accompanying LICENSE file.
+-->
+
+# Zero Downtime Upgrade (ZDU)
+
+## The Goal
+
+The goal of Zero Downtime Upgrade (ZDU) is to allow the software running an 
existing Ozone cluster to be upgraded while the cluster remains operational. 
There should be no gaps in service and the upgrade should be transparent to 
applications using the cluster.
+
+Ozone is already designed to be fault tolerant, so the rolling restart of SCM, 
OM and Datanodes is already possible without impacting users of the cluster. 
The challenge with ZDU is therefore related to wire and disk compatibility, as 
different components within the cluster can be running different software 
versions concurrently. This design will focus on how we solve the wire and disk 
compatibility issues.
+
+## Component Upgrade Order
+
+To simplify reasoning about components of different types running in different 
versions, we should reduce the number of possible version combinations allowed 
as much as possible. Clients are considered external to the Ozone cluster, 
therefore we cannot control their version. However, we already have a framework 
to handle client/server cross compatibility, so rolling upgrade only needs to 
focus on compatibility of internal components. For internal Ozone components, 
we can define and enfor [...]
+
+![Ozone connection diagram](zdu-image1.png)
+
+Here the arrows represent client to server interactions between components, 
with the arrow pointing from the client to the server. The red arrow is 
external clients interacting with Ozone. The shield means that the client needs 
to see a consistent API surface despite leader changes in mixed version 
clusters so that APIs do not seem to disappear and reappear based on the node 
serving the request. The orange lines represent client to server interactions 
for internal Ozone components. For c [...]
+
+1. Upgrade all SCMs to the new version  
+2. Upgrade Recon to the new version  
+3. Upgrade all Datanodes to the new version  
+4. Upgrade all OMs to the new version  
+5. Upgrade all S3 gateways to the new version
+
+Note that in this ordering, Recon will still have a new client/old server 
relationship with OM for a period of time. The OM sync process in Recon is the 
only API that needs to account for this, and it is not on the main data read, 
write, delete, or recovery path. Recon should be upgraded with the SCMs because 
its container report processing from the datanodes shares SCM code, so we do 
not want Recon to handle a different version matrix among datanodes than SCM.
+
+## Software Version Framework
+
+The previous section defines an upgrade order to handle API compatibility 
between internal components of different types without the need for explicit 
versioning. For internal components of the same type, we need to provide 
stronger guarantees when they are in mixed versions:
+
+* Components of the same type must persist the same data  
+* Components of the same type must expose a consistent API surface
+
+To accomplish these goals, we need a versioning framework to track component 
specific versions and ensure components of the same type operate in unison. 
Note that this versioning framework will not extend beyond Ozone into lower 
level libraries like Ratis, Hadoop RPC, gRPC, and protobuf. We are dependent on 
these libraries providing their own cross compatibility guarantees for ZDU to 
function.
+
+### Versioning in the Existing Upgrade Framework
+
+Before discussing versioning in the context of ZDU, we should first review the 
versioning framework currently present which allows for upgrades and downgrades 
within Ozone, and cross compatibility between Ozone and external clients of 
various versions.
+
+Ozone components currently define their version in two classes: 
ComponentVersion and LayoutFeature. Any change to the on-disk format increments 
the Layout Feature/Version, which is internal to the component. You can see 
examples of the Layout Version in classes such as HDDSLayoutFeature, 
OMLayoutFeature and ReconLayoutFeature. Any change to the API layer which may 
affect external clients will increment the ComponentVersion. Component versions 
are defined in classes like OzoneManagerVersi [...]
+
+The existing upgrade framework uses the following terminology:
+
+**Component version**: The logical versioning system used to track 
incompatible changes to components that affect client/server network 
compatibility. Currently it is only used in communication with clients outside 
of Ozone, not within Ozone components themselves. The component version is 
hardcoded in the software and does not change. We currently use the following 
component versions:
+- **OM Version**: Provided to external clients communicating with OM in case a 
newer external client needs to handle compatibility.
+- **Datanode Version**: Provided by Datanodes to external clients in case a 
newer external client needs to handle compatibility.
+- **Client Version**: Provided by external clients to internal Ozone 
components (OM and Datanode) in case a newer Ozone server needs to handle 
compatibility.
+
+**Layout Feature/Version:** The logical versioning system used to track 
incompatible changes to components that affect their internal disk layout. This 
is used to track downgrade compatibility. We currently use the following layout 
features:
+- **OM Layout Feature**: Used to track disk changes within the OM
+- **HDDS Layout Feature**: Used to track disk changes within SCM and 
Datanodes. One shared version is required so that SCM can orchestrate Datanode 
finalization.
+
+**Software Layout Version (SLV):** The highest layout version within the code. 
When the cluster is finalized, it will use this layout version.
+
+**Metadata Layout Version (MLV):** The layout version that is persisted to the 
disk, which indicates what format the component should use when writing 
changes. This may be less than or equal to the software layout version. 
+
+**Pre-finalized:** State a component enters when the MLV is less than the SLV 
after an upgrade. At this time existing features are fully operational. New 
features are blocked, but the cluster can be downgraded to the old software 
version. Pre-finalized status does not affect component version, which always 
reflects the version of the software currently running.
+
+**Finalized:** State a component enters when the MLV is equal to the SLV. A 
component makes this transition from pre-finalized to finalized when it 
receives a finalize command from the admin. At this time all new features are 
fully operational, but downgrade is not allowed. Finalized status does not 
affect component version, which always reflects the version of the software 
currently running.
+
+In the existing upgrade framework, OM and SCM can be finalized in any order. 
SCM will finalize before instructing datanodes to finalize. Recon currently has 
no finalization process, and S3 gateway does not need finalization because it 
is stateless.
+
+### Versioning in the New Upgrade Framework
+
+In practice, tracking network and disk changes separately has proven difficult 
to reason about. Developers are often confused about whether one or both 
versions need to be changed for a feature, and each version’s relationship with 
finalization. Before adding complexity to the upgrade flow with ZDU, it will be 
beneficial to simplify the two versioning schemes into one version that gets 
incremented for any incompatible change. This gives us the following new 
definitions:
+
+**Component version**: The logical versioning system used to track 
incompatible changes to a component, regardless of whether they affect disk or 
network compatibility between the same or different types of components. This 
will extend the existing component version framework. We will use the following 
component versions:
+- **OM Version**: Used within the Ozone Manager ring and provided to external 
clients in case a newer external client needs to handle compatibility.
+- **HDDS Version**: Used within SCM and Datanodes and provided to external 
clients in case a newer external client needs to handle compatibility. One 
shared version is required so that SCM can orchestrate Datanode finalization.
+- **Client Version**: Provided by external clients to internal Ozone 
components in case a newer Ozone server needs to handle compatibility.
+
+**Software version:** The Component Version of the bits that are installed. 
This is always the highest component version contained in the code that is 
running.
+
+**Apparent version:** The Component Version the software is acting as, which 
is persisted to the disk. The apparent version determines the API that is 
exposed by the component and the format it uses to persist data.
+
+**Pre-finalized:** State a component enters when the apparent version on disk 
is less than the software version. At this time all other machines may or may 
not be running the new bits, new features are blocked, and downgrade is allowed.
+
+**Finalized:** State a component enters when the apparent version is equal to 
the software version. A component makes this transition from pre-finalized to 
finalized when it receives a finalize command from the admin. At this time all 
machines are running the new bits, and even though this component is finalized, 
different types of components may not be. Downgrade is not allowed after this 
point.
+
+This simplified version framework lets us enforce **three invariants** to 
reason about the upgrade process among internal components (OM, SCM, Datanode):
+
+* **Internal components of the same type will always operate at the same 
apparent version.**  
+* **At the time of finalization, all internal components must be running the 
new bits.**  
+* **For internal client/server relationships, the server will always finalize 
before the client.**
+
+This table provides a visual example of apparent and software version during a 
rolling upgrade of the Ozone Managers. Each component's version is indicated 
using the notation `<apparent version>/<software version>`, and bold versions 
are running the new software. This notation will be used throughout the 
document to refer to component versions. Note that the apparent versions of the 
OMs always match. See the [appendix](#appendix-step-by-step-zdu-process) for a 
complete cluster-wide example.
+
+| Status                                          | OM1         | OM2         
| OM3         |
+| ----------------------------------------------- | ----------- | ----------- 
| ----------- |
+| All OMs are finalized in the old version        | 100/100     | 100/100     
| 100/100     |
+| OM1 is stopped and started with the new version | **100/105** | 100/100     
| 100/100     |
+| OM2 is stopped and started with the new version | **100/105** | **100/105** 
| 100/100     |
+| All OMs are running the new version             | **100/105** | **100/105** 
| **100/105** |
+| All OMs are finalized atomically via Ratis      | **105/105** | **105/105** 
| **105/105** |
+
+Later sections on upgrade flow and ordering will detail how these invariants 
are enforced. Note that external clients can be in any version and we will 
support full client/server version cross compatibility between internal 
components and external clients.
+
+### Usage of the Versioning Framework During Upgrades
+
+When a cluster is running, its version will be stored on disk as the apparent 
version. An upgrade is triggered when a process is started with a newer version 
than the apparent version written to disk. On startup, the process can read the 
apparent version from disk and notice that its software version is higher. 
Since it has not been finalized, it will then “act as” this earlier apparent 
version until it is later finalized. In this state, the code must be 
implemented such that the API sur [...]
+
+For external clients, the apparent version is what will be communicated from 
the server to provide their view of the server’s version. This differs from the 
current model where clients receive the static component version which is 
always defined by the latest version the software supports. While a client from 
another cluster could in theory attempt to use some of the new features, which 
would result in an error, this is unlikely to happen as the Ozone clients are 
version aware and should [...]
+
+For internal components, the “new client old server” invariant makes version 
passing among internal components of different types mostly unnecessary. For 
example, SCM does not need to worry about whether the OM client it is 
communicating with has the new bits or whether the OM has been finalized. SCM’s 
server will always be newer and finalized before OM. Therefore it can remain 
backwards compatible and will work with the OM in either case.
+
+Recon to OM communication will be the only case where an internal client is 
newer than the server, and therefore the only case where we need to do version 
checks between components using an internal API. The newer Recon client may 
need to learn the older OM's apparent version to handle compatibility during 
the upgrade.
+
+SCM will need to know the software and apparent versions of the Datanodes, but 
not for API compatibility. By using the same HDDS component version instead of 
separate SCM and Datanode versions, SCM can accurately track the expected 
apparent and software versions of Datanodes to either instruct them to finalize 
or fence them out of the cluster. If there was a discrepancy among versions 
being reported by Datanodes and SCM was using its own separate SCM version, it 
would have no source of t [...]
+
+### Migrating to the New Unified Component Version Framework
+
+The existing component version enum will be the basis of the new unified 
versioning framework. This is because it is shared with external clients who 
can be in any version and may contact the cluster at any time. The existing 
layout feature enum is internal to components, and therefore easier to control 
during the migration.
+
+To migrate to one unified component version, we will add a new software 
version “100” to each existing component version enum. Version 100 will 
universally indicate the first version that is ZDU ready, and the point from 
which this unified version will be used to track all changes through the 
existing component version enum.
+
+Note that the version number we use for this migration must be larger than 
both the largest existing component version and largest existing layout version 
to prevent either one from appearing to go back in time before the migrated 
version is finalized. 100 was chosen as an easily identifiable number that can 
be used across all components to indicate the epoch from which they all have 
migrated to the unified framework and support rolling upgrade.
+
+This migration will be transparent in client/server interactions for network 
changes. It will simply appear as a new larger version with all the previous 
versions in the existing component version enum still intact.
+
+This migration will need some handling for disk changes. When the upgraded 
component starts up with software version 100 and sees a version less than that 
persisted to the disk, it must use the old `LayoutFeature` enum to look up that 
version until the cluster is finalized. After finalization, version 100 will be 
written to the disk and all versions from here on can be referenced from the 
`ComponentVersion` enum.
+
+In the current code, Datanodes use their own `DatanodeVersion` and there is no 
`ScmVersion` component version enum. However, Datanodes and SCM share the same 
`HDDSLayoutFeature` for disk versioning. We need to collapse these into a 
single `HDDSVersion` in the new versioning framework. The existing 
`DatanodeVersion` can simply be renamed to `HDDSVersion`, since there is no 
`ScmVersion` to merge it with. From there, migrating from `HDDSLayoutFeature` 
to `HDDSVersion` can be done using the  [...]
+
+##  Strategy To Achieve ZDU
+
+###  Prerequisites
+
+Before an Ozone cluster can use ZDU in an upgrade, the initial version being 
upgraded must also support ZDU. All software versions from 100 onward will be 
ZDU ready, and any Ozone changes after version 100 have to be made in a ZDU 
compatible way. We can say that version 100 is the minimal eligible version for 
ZDU. For example, a cluster would need to be upgraded from version 5 to version 
105 with the existing non-rolling upgrade process. All upgrades starting from 
version 105 could then  [...]
+
+###  Invariants
+
+This is a summary of invariants for internal components outlined in earlier 
sections which will be maintained during the upgrade flow. These provide a 
framework for developers to reason about changes during the upgrade:
+
+* Internal components of different types will always have the server in the 
same or newer version as the client.  
+  * The only exception is Recon to OM communication.  
+* Internal components of the same type will always operate at the same 
apparent version.  
+  * This implies that they expose the same API surface and persist data in the 
same format.  
+* At the time of finalization, all internal components must be running the new 
bits.  
+* Internal components of different types will always have the server side 
finalize before the client side.
+
+###  Order of Operations During the Upgrade
+
+This is a high level summary of all the steps that will happen during a 
rolling upgrade. For a more detailed view, see the 
[appendix](#appendix-step-by-step-zdu-process). Note that rolling upgrade has 
stricter requirements than non-rolling upgrade, so this process can also be 
used for a non-rolling upgrade by performing steps 1-5 at the same time.
+
+1. Deploy the new software version to SCM and rolling restart the SCMs.  
+2. Deploy the new software version to Recon and restart Recon.  
+3. Deploy the new software version to all datanodes and rolling restart the 
DNs.  
+4. Deploy the new software version to all OMs and rolling restart the OMs.  
+5. Deploy the new software and rolling restart all client processes like S3 
Gateway, HTTPFS, Prometheus etc. These processes are all Ozone clients and sit 
somewhat outside of the core Ozone cluster.
+    - At this stage, the cluster is operating with the new software version, 
but is still “acting as” the older apparent version. No data will be written to 
disk in a new format, and new features will be unavailable.
+6. The finalize command is sent to OM by the admin - this is what is used to 
switch the cluster to act as the new version. Upon receipt of the finalize 
command:  
+   7. OM will forward the finalization request to SCM.
+   8. SCM will finalize itself over Ratis, saving the new finalized version.
+   9. After SCM returns success, OM will persist a marker in the DB indicating 
that the leader must poll SCM to learn when HDDS has finished finalizing. The 
command returns to the client and finalization continues throughout the cluster 
asynchronously.
+   10. SCM will notify datanodes over the heartbeat to finalize.
+   11. Only after SCM and all healthy datanodes have been finalized will OM 
get a “ready to finalize” response from the SCM poll. The OM leader will then 
send a finalize command over Ratis to all OMs.
+   12. As OM is the entry point to the cluster for external clients, 
finalizing OM unlocks any new external facing features in the upgraded version.
+
+If the previous upgrade was never finalized, the cluster can still be upgraded 
to the next version. This is because the logical versioning system is not tied 
to any particular Ozone release, it is just a relationship between the number 
written to the disk and the one saved in the code. Any features that have never 
been finalized will remain unfinalized until the finalize command is given.
+
+Before the cluster is finalized, it is possible to downgrade to the previous 
version by stopping the cluster and restarting it with the older software 
version. No data in a new format will have been persisted that the older 
software version will not understand. The restart with the downgraded software 
can either be done non-rolling, or rolling by restarting components in the 
reverse of the order outlined above.
+
+After the cluster is finalized, it cannot be downgraded. This is identical to 
the current upgrade framework. If a component sees that the version number on 
disk is larger than the one in its code, it will fail to start.
+
+During the upgrade, the cluster’s fault tolerance will not change. As nodes 
are being restarted with the new versions, we still require 2 OMs and SCMs 
active at all times to remain available. If any nodes fail to start in the new 
version, our existing fault tolerance accounts for this. The node should be 
brought online either by resolving the issue or downgrading it before others 
are restarted. Note that all nodes must be running the newest software version 
for finalization to begin, but [...]
+
+Initially, this design considered pausing some background operations to remove 
risk during upgrade. Snapshots are an area with complex storage requirements 
that must be mirrored across the OMs. However a ZDU can take several days and 
removing the ability to take or delete snapshots during that time would impact 
backup and disaster recovery schedules which would not be acceptable. Similarly 
block deletion was considered and similar concerns were uncovered around 
freeing space on clusters  [...]
+
+Disk and datanode balancing could be safely suspended if required. For disk 
balancing, the process is all within the same datanode process, so mixed 
component versions are not a concern. Cross node balancing uses the container 
replication mechanism internally, and we would not gain much by pausing it 
during upgrades either.
+
+##  The Finalization Process Per Component
+
+After a cluster has all components started with the new software version, the 
cluster will be operating without any of the features in the new version until 
it is finalized. The finalization process is started when an administrator 
issues a “finalize” command to the cluster. This will be received by OM and 
then forwarded to SCM which will coordinate the process for the whole cluster. 
The existing SCM finalize command will be deprecated and become a no-op for 
compatibility. The cluster wi [...]
+
+### Client Command
+
+To keep the finalization process simple for admins, we will maintain a single 
command that finalizes the whole cluster. The server-side entry point for this 
command must be OM, even though it finalizes after SCM and Datanodes. The 
single command cannot be sent to SCM because there may be releases where we add 
new OM component versions without new HDDS component versions. In this case if 
the command is sent to SCM and OM polls SCM's finalization status to learn to 
finalize after SCM, OM w [...]
+
+###  OM
+
+When OM receives the finalize command from the admin:
+1. OM will call SCM and instruct it to finalize. This is a synchronous call 
made in the pre-execute request processing stage before anything is submitted 
to Ratis.
+2. When SCM responds that it has finalized, OM will persist a marker in the DB 
indicating that cluster finalization is in progress.
+3. The command will return success to the user, indicating that the cluster 
will continue finalizing in the background. A separate status command can be 
used to monitor finalization progress.
+4. When the marker is present, the leader will run a background service to 
poll SCM and check for the combined finalization status of SCM and Datanodes. 
Note that the command to finalize SCM finalizes SCM synchronously but Datanodes 
asynchronously.
+5. When SCM returns that it and all healthy datanodes have finalized, the OM 
leader will send a finalize command to all OMs over Ratis.
+6. The same Ratis transaction that finalizes the OMs will remove the marker 
file from the DB. This will cause the background service polling SCM to 
terminate.
+
+On OM restarts or leader changes when OM is in a pre-finalized state, the 
leader OM will see the DB marker and poll the SCM endpoint periodically to see 
if it should finalize. This will be a small metadata based RPC call that does 
not need to run very frequently, perhaps once a minute. SCM will only reply OK 
after SCM has finalized and all Datanodes have finalized.  This ensures that 
once the finalize command is acked as in-progress back to the user, 
finalization will continue even after [...]
+
+At this stage the HDDS layer of the cluster is ready for any new features or 
on-disk formats. As clients learn the cluster version from OM, OM must be 
finalized before any of the new features are unlocked.
+
+Upon receiving the “ok to finalize” reply from SCM, OM will finalize and send 
the finalize command to all followers over Ratis. This ensures that all OMs 
will replay the finalize request in the correct order with other commands and 
ensure consistency across the cluster. Once all OMs are finalized, OM will stop 
polling the SCM endpoint.
+
+###  SCM
+
+Although OM first receives the command, the first component to finalize is 
SCM. This will unlock any new APIs in SCM, but these will not be called until 
other components who are clients of SCM are also finalized. To coordinate 
between all SCM instances and ensure they switch to any new behaviour 
simultaneously, the finalize command is sent over Ratis, and hence will be 
replayed on the followers alongside other commands in the correct order.
+
+1. SCM receives the finalize RPC command from OM
+2. SCM will make sure that all registered datanodes are heartbeating a 
software version that matches the latest datanode component version shipped 
with the SCM code.  
+    - If SCM’s node set contains any nodes with an older software version, the 
command will be failed.
+    - Datanodes which are dead/offline during finalization and are running an 
old software version will need to be updated to the new software version before 
a finalized SCM allows them to re-register.  
+3. SCM sends the finalize command over Ratis to finalize all SCMs.
+4. SCM returns success for the RPC command
+5. SCM instructs all live Datanodes to finalize, and keeps track of their 
apparent versions for progress, resending the command as necessary.
+6. Until all Datanodes finalize, SCM's upgrade status API will return a flag 
indicating that all of HDDS has not been finalized yet. Once all live Datanodes 
have finalized, this flag is set to true.
+    - This flag combined with the OM DB marker key indicating a finalize 
command was given tells OM that it should finalize.
+
+### OM and SCM Ratis Group Version Validation
+
+When OM and SCM receive a finalize command, they will perform best effort 
verifications to ensure that the other members of their Ratis group are running 
the latest software version before proceeding with the request. This can 
potentially catch cases where an admin has incorrectly updated the software 
before running finalize and some components are still in the old version. This 
is intended as a best effort safety check against user error but is not 
guaranteed to prevent all cases.
+
+1. When the leader OM receives the "finalize upgrade" command from the admin, 
it will call an internal API among the peers to learn their software versions. 
Only if these versions match its own will it forward the finalize command to 
SCM. Otherwise, it will return an error to the admin.
+2. When the leader SCM receives the finalize command from OM, it will also 
call an internal API among its peers to learn their software versions. It will 
also check the last known software versions of all Datanodes.  If any of these 
do not match, it will return an error back to OM which will be forwarded to the 
admin. Since OM does not start finalizing until SCM returns success, the 
operation is aborted.
+3. If SCM decides that all HDDS versions match, it will return success to OM. 
OM will send the "start finalization" command through Ratis to persist the DB 
marker indicating it should poll SCM until HDDS is finalized, and return 
success to the admin.
+
+Note that all software version validation happens before anything is persisted 
with Ratis, which allows the finalization attempt to exit cleanly if software 
versions don't match. If software versions are changed during the finalization 
process it is user error which the system is not designed to handle. Aborting 
finalization partway through is complex and risks divergence among Ratis 
groups. 
+
+###  Datanodes
+
+Unlike SCM, all datanodes are not in a Ratis ring together and therefore it is 
impossible to finalize all datanodes at the same time. SCM will issue the 
finalize command to datanodes after it has been finalized over the Datanode 
heartbeat. SCM will not consider the datanodes as finalized until all 
registered datanodes have reported success. On each heartbeat, a Datanode will 
report its software version and apparent version. Any Datanodes that are 
offline (dead) need not be considered as  [...]
+
+When the datanode software version matches the max Datanode software version 
known to SCM, SCM knows that datanode is running the latest software version 
and it is safe for SCM to finalize.  SCM will not allow the finalize command to 
be passed to any datanode (or finalize itself) until all datanodes are running 
the latest version.
+
+When a datanode is reporting the same software and apparent version, and that 
version matches the max datanode version known to SCM, SCM knows the datanode 
is running the latest version and is finalized. SCM will consider Datanode 
finalization complete when all healthy datanodes are reporting the correct 
software version and report a matching Apparent Version.
+
+If a Datanode attempts to register with a software version greater than the 
max version known to SCM, then it will be rejected. This can only occur if the 
Datanode has been upgraded to a version newer than the SCM version. As the ZDU 
requirement is for SCM to be upgraded first, Datanodes having a higher version 
is invalid.
+
+If a Datanode attempts to register and its software version is less than the 
one known by SCM, it indicates that Datanode is still running the old software 
version. If SCM is pre-finalized, it is expected that datanodes can register 
with the older version, as the DNs will be upgraded after SCM. If SCM is 
finalized, any Datanodes attempting to register at an older software version 
should be rejected permanently until the datanode is upgraded so that the 
versions match.
+
+See the [appendix](#appendix-step-by-step-zdu-process) for a complete table of 
SCM to Datanode version relationships.
+
+####  Mixed Datanode Versions During Write
+
+As Datanodes potentially finalize at different times, there will be a period 
where clients will be writing to a pipeline with a mixture of finalized and 
unfinalized Datanodes. Coupling the version to pipelines and/or subgroups of 
nodes becomes difficult to manage at scale, and the upgrade framework’s current 
method of closing all pipelines and containers on finalization will not work in 
a ZDU scenario.
+
+To ensure that all datanodes in a write pipeline execute a write with the same 
version, they will need to learn the version to use from the client. They 
cannot learn it from peer datanodes because datanode peers do not communicate 
on the erasure coding write path. Clients already learn the component version 
of the datanodes in the pipeline (which will be their apparent version in the 
new framework) in the datanode details for the pipeline they get back from SCM, 
which is propagated through OM.
+
+Due to the finalization requirement, nodes will always have the code to 
execute things at a lower component version than their software version. This 
means that even if a datanode is finalized, it is still able to execute writes 
as a lower version if required. SCM is tracking the finalization status of all 
registered datanodes, so it knows the lowest apparent version among all 
datanodes in a pipeline. SCM can give this out as the component version in the 
datanode details, which clients w [...]
+
+Consider this example where we want to move from datanode component version 
100 to 105:
+
+1. SCM is giving out block allocations tagged with DN version 100 because not 
all datanodes have been finalized to version 105\.  
+2. Clients pass this version to the datanodes they interact with.  
+   * If anything on the write path needs to make a switch based on this 
version, it can. For many features it won't though, so this is just a no-op 
pass through.  
+3. SCM sends the finalize command to all datanodes.  
+   * It still only hands out block allocations in version 100 since this is 
the lowest common version among all DNs.  
+4. SCM learns that all live datanodes have been finalized, meaning the lowest 
common version among all DNs is now 105\.  
+5. SCM begins handing out block allocations tagged with version 105\.
+
+Old clients from versions before the first one with rolling upgrade support 
(v100) will not pass a version to the datanodes. If a datanode does not receive 
a version from the client, it needs to execute the request as version 100 (the 
first component version to support rolling upgrade) to be safe. In practice 
this should not be much of an issue. Version changes that affect the write path 
are going to be rare, like a new container schema. For example, say we are on 
version 105, and versio [...]
+
+It was considered to have SCM give clients the finalized version instead of 
the minimum version to pass to datanodes after SCM sends the finalize command 
to datanodes. In this case, datanodes would finalize as soon as they get the 
write request if they have not already from the heartbeat, and then begin 
processing the request. This approach does not provide much benefit over the 
current proposal:
+
+* Datanode finalization is already designed to be asynchronous within each 
datanode, because the finalize request can come in from the SCM heartbeat at 
any time. Adding a blocking element to the write is therefore not necessary for 
correctness.  
+* Slow clients who allocated blocks before datanodes finalized and took a long 
time to get back to the datanode to actually write them will still write using 
the older version anyways.
+
+Significantly, it has one security drawback: Rogue/custom clients could 
instruct a datanode to finalize with just a block token. Block tokens are the 
only way clients authenticate to the datanode. They are scoped to the current 
block and are not intended to permit node-wide changes like finalization. A 
client with permissions to write a block could use the token to create a 
command with a higher version and get the datanode to finalize ahead of SCM, 
causing the datanode to be fenced out  [...]
+
+####  Mixed Datanode Versions During Replication
+
+Datanodes act in a client server relationship between themselves for 
replication. In general the replication process is quite simple - commands are 
sent to a datanode hosting a container replica (the replication client), and it 
is told to push/upload the data to another node (the replication server). 
Incompatible changes in this area can be handled in a similar way to write 
requests.
+
+SCM knows the apparent version of all Datanodes since their last heartbeat. 
The minimum apparent version of the source and target Datanode can be included 
in the replicate command sent by SCM to the source/client Datanode. If the 
source/client Datanode has a newer apparent version, it must "downgrade" its 
request to the apparent version indicated by the SCM command in order to work 
with the older peer. A newer target/server Datanode will not make incompatible 
changes to existing APIs, so [...]
+
+Note that software version can increase or decrease during upgrade or 
downgrade, but apparent version can only increase. Therefore even if SCM's 
apparent version information for a Datanode is stale when it sends the 
replicate command, the version used will still always be less than the maximum 
supported version and is therefore still valid.
+
+###  S3G
+
+S3 Gateway can be considered a client of the Ozone cluster itself. It is 
stateless and interacts with the wider Ozone cluster via the usual Ozone 
client. Since it does not write anything to disk, it does not have a 
finalization framework and hence is not able to version its APIs using the same 
mechanism as the stateful components and will always act as its latest known 
software version. It also uses the Ozone client to make its calls to the 
cluster, which is version aware. This means S3G [...]
+
+Most changes to S3G will be additive in nature \- adding new APIs or fields / 
options that can be passed over existing APIs. A backwards incompatible change 
to the REST API side of S3 gateway would imply an incompatible change to the S3 
spec itself. To use any of these new features requires some external service to 
send requests to S3G using the new features. Users of S3G should therefore not 
make calls to “new features” until the upgrade is complete, otherwise they will 
get errors. This [...]
+
+If a customer has more complex requirements there are options to keep some S3G 
instances running at the old version and direct all traffic to them at the load 
balancer. This would be similar to blue-green deployments in more traditional 
applications.
+
+###  Recon
+
+Recon acts as both a client and server. It makes requests to both SCM and OM 
and Datanodes heartbeat to it in a similar way as to SCM. In the upgrade flow, 
Recon will be upgraded at the start along with SCM. This keeps things simple 
for the Datanodes, as they will be heartbeating to both SCM and Recon, which 
will both be at the same version. Similar to SCM, Recon will need to be able to 
handle any new and old format heartbeats from datanodes, as the datanodes will 
be at mixed versions as [...]
+
+Recon also makes outgoing calls to OM via a Rest API and to SCM using RPC 
calls. It will need to be able to handle any old or new version responses from 
those APIs. OM will initially be at the older version before being finalized. 
For the Recon to SCM call, SCM and Recon are both upgraded at the same time, 
but SCM would be “acting as” the older version until it is finalized. So again 
Recon must handle both old and new format responses.
+
+Recon's upgrade framework currently only exists to handle migration of disk 
formats on upgrade. Recon finalizes automatically on startup in the newer 
version and runs upgrade actions attached to versions to handle disk 
reformatting as necessary.  If we come across a situation where Recon needs a 
proper finalization framework, it can be added. Recon could then finalize in a 
similar way to OM, by polling the SCM finalization endpoint. Until that time it 
is proposed to avoid complicating it [...]
+
+In the worst case scenario, Recon will write something to disk in a new 
format, and the upgrade is aborted and rolled back. Then the older software 
will be unable to read the new format data. In that case, if the change cannot 
be easily undone manually, Recon can be reconstructed from scratch using a 
fresh OM snapshot.
+
+## Changes From The Existing Non-Rolling Upgrade Framework
+
+The non-rolling upgrade problem is a subset of the rolling upgrade problem. 
Therefore we can continue to support non-rolling upgrades with rolling upgrades 
using the existing strategy outlined in this doc. In addition to the version 
framework migration mentioned earlier, we can also remove or amend various 
aspects of the existing non-rolling upgrade framework which are no longer 
necessary.
+
+### Prepare For Upgrade
+
+The current upgrade process requires a "prepare for upgrade” step before the 
OMs are stopped in the old version and started in the new version. This flushes 
all Ratis transactions from the log to the state machine and puts the OM in a 
read-only mode, which it can leave when all the OMs are restarted in the new 
version. This prevents OMs from applying requests from the Ratis log in 
different versions and potentially diverging their state machines, but the 
read-only requirement will not wo [...]
+
+### Finalization Commands
+
+There is currently no requirement in the code about whether OM or HDDS needs 
to be finalized first. The user is free to send the two commands in any order. 
For rolling upgrades, SCM will be orchestrating the finalization process to 
ensure that servers always finalize first, so we will only expose a single 
`ozone admin upgrade finalize` command which starts this process. OM will 
expose the finalization API to the admin and forward the request to SCM, while 
polling HDDS finalization status [...]
+
+We will also use one `ozone admin upgrade status` command that provides 
upgrade and finalization information for the whole cluster. This command will 
go to OM, OM will gather HDDS upgrade status from SCM, then add its own status 
and return the result to the client.
+
+### Upgrade Actions
+
+The current upgrade framework has support for [upgrade 
actions](https://github.com/apache/ozone/blob/b91292576e6a13c3c0149aca06847397b6ccc5a6/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/upgrade/LayoutFeature.java#L42),
 which allow arbitrary operations to be run at various points in the upgrade. 
These are intended to execute quickly and are not intended to do invasive 
on-disk reformatting, which we avoid doing as part of upgrades in general. In 
practice, only the `ON_FINALIZE [...]
+
+### Finalizing Multiple Versions Over Ratis
+
+When OM or SCM receives a finalize command, it may need to finalize multiple 
versions that are newly introduced with the software. In the common case, 
finalization will just update the version number on disk and move the 
corresponding apparent version number in memory to match. However, there may be 
cases where one of the above upgrade actions also needs to run.
+
+OM and SCM currently take different approaches when one finalize command 
requires finalizing multiple versions over Ratis. Say we are finalizing from 
version 100 to 105. When OM gets the finalize request from the client, the 
leader will send one Ratis request to the Ratis group, and in that one request 
each OM will move from version 100 to 105. When SCM gets the finalize request, 
however, the leader will look at its unfinalized versions and send 5 ratis 
requests: one to finalize to 101,  [...]
+
+OM's method of finalizing is much simpler to work with, because the leader 
does not need a separate handler thread to track multiple Ratis requests before 
acknowledging back to the client. This atomicity also does not need extra 
handling for restarts and leader changes. SCM's method of finalizing does not 
provide any practical advantages. Updating version numbers on disk is already a 
quick operation, and the time it takes to execute an upgrade action is not 
coupled to the number of upgra [...]
+
+### Closing Pipelines on Finalization
+
+SCM currently closes all pipelines, and therefore all containers when HDDS is 
finalized. This can create a momentary pause in write traffic and will be 
removed as part of rolling upgrade. This step will no longer be necessary since 
the client will be instructing the datanodes which version to use for each 
write request.
+
+##  Development Practices to Ensure Compatibility
+
+At any point in the upgrade flow, we can have the pre and post upgrade 
external client version talking to a pre and post upgrade server version. 
Additionally the post upgrade server version can be finalized or not.
+
+If the server is not finalized, then it should be “acting as” the pre upgrade 
version and its exposed API and Apparent Software Version returned to any 
clients will represent the pre-upgrade server version. In that respect, the 
unfinalized upgrade software version can be considered the same as the 
pre-upgrade version from a client’s perspective.
+
+Additionally a server must also be able to handle older client requests, as it 
is possible an older client version from outside the cluster will continue 
using the cluster, even after the upgrade completes. This is already the case 
in Ozone and backward compatibility for clients is already supported.
+
+For both client and server, the onus is only on the newest version to make 
decisions about compatibility. Any old version has no knowledge of the new 
feature, and it cannot enforce decisions about future unknowns.
+
+###  External Client Compatibility
+
+Client changes can be categorized into two areas. Adapting an existing API, or 
making calls to a new API. In either case, the client gets to know the current 
OM version when it is initialized. Using that version it can make decisions 
about which APIs to call, or which fields to pass in an API call.
+
+For an existing API, if a new field is made available at OM, then the client 
should only pass it if OM is reporting an Apparent Version that is greater than 
or equal to the version which introduced the field.
+
+For something like Atomic Rewrite, which added an extra field to an existing 
API, expecting different server behaviour if passed, then the client should 
give an error to the user if an attempt to use the feature occurs before OM can 
support it.
+
+As an older OM version would happily accept unknown fields in the protobuf 
messages, the onus is on the client to ensure it doesn’t expect behaviour which 
the server cannot yet support.
+
+These practices should already be used when making client side changes, and 
therefore there isn’t much change to development on the client side.
+
+###  Internal Client Compatibility
+
+Clients internal to Ozone, like Datanodes heartbeating to SCM, should continue 
to work without modification with rolling upgrades. Because the internal 
servers will always be newer and finalized first, it is their responsibility to 
remain backwards compatible.
+
+###  Server Compatibility
+
+During an upgrade, the server processes must have the ability to “act as” the 
pre-upgrade version. This means that any change to an API behaviour, expected 
fields or resulting data persisted by the server process must be feature gated 
using the version framework, and the old logic retained. Only if the server’s 
Apparent Version is equal or greater than the feature gate version should the 
new behaviour be permitted.
+
+In general, no attempt should be made to use a new feature by an Ozone client, 
as it has its own feature gates. If something slips through due to a bug in the 
client, the server should return an error if it can. The only way the server 
could return an error is by running at the latest version but in an unfinalized 
state, so it knows of the new feature, but it’s not yet available.
+
+As with the clients, this is not a drastic departure from current development 
techniques, as the need to support older clients requires care when changing 
existing APIs. It may mean more frequent additions to the component versions 
than before, because any extension of the API will require a version so the API 
surface remains consistent during the rolling upgrade.
+
+####  Handling Apply Transaction in Mixed OM Versions
+
+Without "prepare for upgrade" in the rolling upgrade framework, we will need a 
way to ensure that OMs in different versions make the same DB modifications 
when applying a write request. The long term mitigation for this is to complete 
the leader execution project, which will ensure that all OMs make the same 
state machine changes as the leader regardless of their version. This project 
is going to take a while to complete and we do not want to block ZDU on its 
completion. Instead, we can  [...]
+
+###  Removing Old Code
+
+If we want to support rolling upgrades from any past version to any current 
version of Ozone, old processing code with disk or network compatibility 
concerns cannot be removed. This code will be required to run before its 
replacement while the last apparent version is being used during the upgrade. 
If we would like to remove old processing code, we will need to create a 
mandatory version that all upgrades must pass through, which would be the last 
one to contain such code. The next relea [...]
+
+###  Testing
+
+Ozone has existing test tools that can be used for compatibility testing at 
both the unit, integration, and acceptance test levels. These would only 
require minimal extension to work with ZDU and the new versioning system.
+
+Unit and integration tests are run by a single Java process in the same 
version as the code being tested, so it is not possible to have truly mixed 
versions in this environment. The current approach used for client cross 
compatibility and disk compatibility testing is allowing tests to inject a 
custom component version or layout version into the client or server using a 
configuration key to see how it responds. This will remain the approach with 
the new versioning framework.
+
+Acceptance tests currently use docker to pull past releases and orchestrate an 
upgrade and downgrade between those past releases and the version under test. 
During this process, the tests will write data, read data, and possibly test 
new features specific to a release. This framework was designed to support 
[pluggable methods for 
upgrading](https://github.com/apache/ozone/blob/de5c0a385ed873425ae94245d8b5b28040ab99ef/hadoop-ozone/dist/src/main/compose/upgrade/upgrades),
 so we will add a  [...]
+
+
+###  Examples From Past Development To Ensure Compatibility
+
+This section talks about some changes made to Ozone over the recent past, and 
how they have been handled for compatibility. This should help the reader 
understand the approach to developing changes compatible with ZDU. In looking 
at these examples, it becomes clear that the current approach to development is 
already performed in a mostly compatible way, so we just need to be more 
rigorous in reviews to ensure that remains the case.
+
+####  Container Reports Adding the isEmpty flag
+
+At some point in the past a new flag was added to the Full Container Reporting 
from datanodes to SCM. This flag, “is Container Empty” was to counter a bug in 
SCM, where it marked containers as empty erroneously. Fixing the bug required a 
change in two places:
+
+1. The Datanode producing the container report  
+2. Container report processing in SCM
+
+Consider whether this change needs a software or layout upgrade.
+
+Protobuf is forward and backwards compatible. This means that if a newer 
client produces a message containing a new field (isEmpty), and the server 
receives this message, the server will not fail. It simply does not know the 
field exists and it gets ignored in the message. In this case, while the 
datanode has been upgraded to a version that fixes the bug, SCM has not and the 
bug is still present until SCM is upgraded.
+
+In a similar way, if the server is newer than a client sending a message, then 
the server needs to check if the new field is present, and have fallback 
handling if it is not. With the currently proposed ZDU framework, this is 
always the case.
+
+In this example, the safe approach would be for SCM to default to setting 
isEmpty to false if it is not passed in the container report, knowing that a 
datanode with a matching software version would always explicitly send the 
field. As the new SCM version knows there is a problem with empty container 
handling it is safe for it to assume the containers are non-empty until told 
otherwise.
+
+Considering this example, I don’t believe that this scenario requires a 
specific “version gate” flag. Many protobuf field additions are like this, 
where the server can simply default to the “old handling” if the expected field 
is not passed. Or in the case of a bug, do the best thing for safety provided 
it doesn’t change persisted data.
+
+Each case must be considered on its own merits and there isn’t a hard rule 
aside from “do not change persisted data”.
+
+####  Atomic Key Rewrite
+
+Atomic Key Rewrite was added to OM to allow Tiering to replace keys in the 
cluster only if they had not been modified since some previous read of the key.
+
+This change involved:
+
+1. A new field, expectedDataGeneration passed from the client to server when 
writing a key  
+2. Persisting that field in the openKey entry in the open key table  
+3. Checking the previously stored field on key commit against the latest 
version of the key to ensure it had not changed.
+
+This problem **does need** a version gate flag from two perspectives.
+
+1. If a new client is talking to a pre-atomic rewrite OM, then the old OM 
would happily accept the expectedDataGeneration in the existing create key 
protobuf message. However, it would not know to check for its existence and 
simply ignore it. The client would therefore believe it is performing “atomic 
rewrites” when it is not. Unlike with the isEmpty flag example, the old OM 
ignoring the flag can do some harm (the client could overwrite a newer version 
of a key than it intended).  
+2. There is a change to the persisted disk data. If a new version client sends 
a message to a new version OM, it will persist the new expectedDataGeneration 
field in the database. If this transaction is replayed on an older OM, it would 
not persist the field as it does not know about it. This can result in database 
mismatches between OM. If a failover occurred to the old version OM before the 
key is committed, then the atomic overwrite cannot be checked as the field is 
not replicated, an [...]
+
+In this case, it is essential that OM “act as” its old version and rejects any 
requests from a client which contain the expectedDataGeneration field. A client 
should ideally also fail to allow the new API to be used at the client side as 
it can ask OM what its current version is. The client check is somewhat 
optional in this case provided integrity is enforced at the server level. 
However in other cases, the client can decide which API to call depending on 
the server version returned.
+
+####  List Keys Light
+
+List Keys Light was added to combat a GC problem which caused OM to struggle 
when returning large file listings.
+
+This is a read only API and there are no concerns about calls to it modifying 
data on OM.
+
+When running an Ozone client with a version that knows about listKeys Light, 
it will attempt to use it rather than the legacy version. However, if the OM is 
older, it will not know about the new API and it would fail to process requests 
from the new client.
+
+Therefore an OM version was added called LIGHTWEIGHT\_LIST\_STATUS. When the 
Ozone client is started, it first sends an RPC to OM to get its version. Then 
it can decide to use List Keys Light if it is available, or fall back to the 
old version if it is not.
+
+With the proposal in this document, we would also tag List Keys Light in OM so 
that it is not available until OM is “acting as” a version which is greater or 
equal to when List Keys Light was introduced. This is not strictly necessary 
from a data integrity standpoint, but it brings consistency to the availability 
of new APIs across OM leader changes and makes it clear to developers that all 
such APIs should be version gated for ZDU. It also should not be possible to 
call the new API from [...]
+
+###  Examples From Future Development To Ensure Compatibility
+
+This section covers a few features that may land in Ozone after rolling 
upgrade support is added, and how the new framework is equipped to handle them
+
+####  Leader Execution
+
+Leader execution makes a switch in the Ozone Manager request processing (and 
potentially SCM after that) to compute the changes to the Ratis state machine 
(RocksDB) on the leader before submitting the request to Ratis, and using Ratis 
to reach consensus on those changes. This differs from the current model where 
the request is submitted to Ratis for consensus, and while applying it to the 
state machine, all OMs compute the required DB changes independently.
+
+Leader execution is being designed with a switch so that requests can be 
migrated one by one, and flows can be switched from the old to the new at the 
beginning of request processing. This is the place where we would put a check 
for the OM’s apparent version. If our apparent version supports leader 
execution, we would use the leader execution flow. Until then, the old flow 
must be used. This supports downgrade so that older OMs can still read the 
entries from the Ratis log. Note that fin [...]
+
+####  Event Notification
+
+Event notification adds support for plugins to read a ledger of events stored 
in the OM and push them to various other services. The ledger is a new RocksDB 
column family. This will need a component version to block plugins from running 
until finalization, otherwise events may seem to appear and disappear as OM 
leader changes while the software is being upgraded. An action bound to the 
finalization event can start the plugins when the version is finalized.  The 
component version must als [...]
+
+This is an example of a feature where rolling upgrade imposes stricter 
versioning requirements than non-rolling upgrade. If only non-rolling upgrade 
is supported, this feature would require no versioning. This is because all the 
OMs would gain or lose the support for writing and pushing events at the same 
time, and the old OM on downgrade would simply ignore the extra ledger column 
family.
+
+####  New Container Schema
+
+Container schemas refer to the layout of individual container replicas stored 
on the datanodes. We are currently on our third container schema since Ozone’s 
inception, and it’s likely that there will be more in the future. Ozone’s 
approach has been to leave existing data in a backwards compatible format and 
do any migration as an optional background process after the upgrade is 
complete. This will not change with rolling upgrades.
+
+Datanodes will choose which container schema to use based on the Datanode 
component version supplied by the client at the time of write to ensure that 
all replicas of the container have the same schema. Once a container is 
created, all writes to that container will use its schema version, regardless 
of the version the client passes. The finalization process outlined in this 
design ensures that all datanodes are in an apparent version that can handle 
this schema version at the time it is  [...]
+
+## Appendix: Step by Step ZDU Process
+
+This section demonstrates every step of a ZDU using an upgrade from software 
version 100 to software version 105 as an example. Assume that the component 
version numbers for OM and HDDS happen to be equivalent during this upgrade. 
Each component's version is indicated using the notation `<apparent 
version>/<software version>`. Versions in bold are running the new software. 
There are only three valid version states a component can be in during this 
upgrade:
+- 100/100: The old version finalized
+- **100/105**: The new version pre-finalized
+- **105/105**: The new version finalized
+
+Any other version is invalid and will be rejected. Note that the apparent 
versions of OM and SCMs always match within their Ratis groups.
+
+### 1. SCM: Deploy New Software
+
+There is no special command required to begin the upgrade process. SCMs can be 
restarted with the new software one by one. This table shows SCM's version 
relationship between other SCMs and their acceptance of Datanodes for 
registration, reads, and writes. It also shows the `DN Pipeline Version`, which 
is the version SCM will attach to block allocations for clients to forward to 
Datanodes to determine the version used to write the data. Note that this 
version is never higher than the low [...]
+
+| Status                                                                       
                   | SCM1        | SCM2        | SCM3        | DN Pipeline 
Version | Datanodes 100/100 | Datanodes 100/105 | Datanodes 105/105 |
+| 
-----------------------------------------------------------------------------------------------
 | ----------- | ----------- | ----------- | ------------------- | 
----------------- | ----------------- | ----------------- |
+| All SCMs are finalized in the old version                                    
                   | 100/100     | 100/100     | 100/100     | 100              
   | Accepted          | Rejected          | Rejected          |
+| SCM1 is stopped and started with the new version                             
                   | **100/105** | 100/100     | 100/100     | 100              
   | Accepted          | Rejected          | Rejected          |
+| SCM2 is stopped and started with the new version                             
                   | **100/105** | **100/105** | 100/100     | 100              
   | Accepted          | Rejected          | Rejected          |
+| New version has been deployed on all SCMs, but they have not yet finalized 
to use new features. | **100/105** | **100/105** | **100/105** | 100            
     | Accepted          | Accepted          | Rejected          |
+
+### 2. Recon: Deploy New Software
+
+Recon currently does not use finalization, so this step is a trivial restart 
in the new version.
+
+### 3. Datanodes: Deploy New Software
+
+Datanodes can be restarted with the new software in any order. Restarting 
Datanodes one by one will ensure that data is always available, but will take 
the longest time. If temporary unavailability is tolerable, or data are already 
grouped using rack placement, then Datanodes can be restarted in larger groups. 
For example, say all data is written with EC-3-2 replication and rack scatter 
placement with six total racks. Then datanodes could be upgraded one rack at a 
time while maintaining  [...]
+
+Since SCM has been upgraded but not finalized, all Datanodes in versions 
100/100 and **100/105** will be accepted by SCM. This means Datanodes can begin 
participating in the cluster again individually as soon as they restart, 
regardless of the upgrade status of their peers.
+
+| Status                                                          | Datanode 1 
 | ...         | Datanode N  |
+| --------------------------------------------------------------- | 
----------- | ----------- | ----------- |
+| All Datanodes are in the old version                            | 100/100    
 | 100/100     | 100/100     |
+| Some Datanodes have been stopped and started in the new version | 
**100/105** | ...         | 100/100     |
+| All Datanodes have been stopped and started in the new version  | 
**100/105** | **100/105** | **100/105** |
+
+### 4. OM: Deploy New Software
+
+Unlike the current non-rolling upgrade framework, there is no need to use 
"prepare for upgrade" to start the OM upgrade process. OMs can be restarted 
with the new software version one by one.
+
+| Status                                                                       
                  | OM1         | OM2         | OM3         |
+| 
----------------------------------------------------------------------------------------------
 | ----------- | ----------- | ----------- |
+| All OMs are finalized in the old version                                     
                  | 100/100     | 100/100     | 100/100     |
+| OM1 is stopped and started with the new version                              
                  | **100/105** | 100/100     | 100/100     |
+| OM2 is stopped and started with the new version                              
                  | **100/105** | **100/105** | 100/100     |
+| New version has been deployed on all OMs, but they have not yet finalized to 
use new features. | **100/105** | **100/105** | **100/105** |
+
+### 5. External Clients (S3 Gateway, HTTPFS): Deploy New Software
+
+External clients are stateless and Ozone supports full external client/server 
cross compatibility, so no finalization is required for this step. After this 
point, all components are running the new software. Regression testing can be 
done on the new version, and a downgrade is possible by reversing the previous 
steps.
+
+### 6. OM: Receives Finalize Command From Admin
+
+The admin will send this command to OM when they have completed regression 
testing in the new version and do not wish to downgrade. OM will verify that 
all its Ratis peers are running matching software versions. Then OM will 
forward the finalize command to SCM. Once SCM succeeds, OM will write a marker 
in the DB indicating that a finalize command was issued and it should poll SCM 
until it receives an indication that it should finalize. The finalize command 
will return success to the admi [...]
+
+
+### 7. SCM: Receives Finalize Command From OM
+
+When OM tells SCM to finalize, SCM will first verify that all live Datanodes 
and its peer SCMs are running the newest software version 105. If any of these 
components are not, the finalize command will be rejected. If this check 
passes, SCM will finalize via Ratis and return success back to the OM. OM will 
return to the admin that finalization has been successfully initiated but is 
not complete. SCM will continue to asynchronously finalize the Datanodes while 
OM waits for this step to co [...]
+
+| Status                                                                       
                   | SCM1        | SCM2        | SCM3        | DN Pipeline 
Version | Datanodes 100/100 | Datanodes 100/105 | Datanodes 105/105 |
+| 
-----------------------------------------------------------------------------------------------
 | ----------- | ----------- | ----------- | ------------------- | 
----------------- | ----------------- | ----------------- |
+| New version has been deployed on all SCMs, but they have not yet finalized 
to use new features  | **100/105** | **100/105** | **100/105** | 100            
     | Rejected          | Accepted          | Rejected          |
+| Finalize command has been sent over Ratis. All SCMs move to the new apparent 
version atomically | **105/105** | **105/105** | **105/105** | 100              
   | Rejected          | Accepted          | Accepted          |
+
+### 8. Datanodes: Receive Finalize Command From SCM
+
+After SCM has finalized, the leader will send finalize commands to all 
Datanodes. It will retry sending this command until all Datanodes heartbeat 
back that they have finalized. Once all Datanodes have finalized, SCM can 
increase the `DN Pipeline Version` so any new features on the Datanode write 
path can be used.
+
+| Status                                                                       
    | SCM1        | SCM2        | SCM3        | DN Pipeline Version | Datanodes 
100/100 | Datanodes 100/105                                           | 
Datanodes 105/105 |
+| 
--------------------------------------------------------------------------------
 | ----------- | ----------- | ----------- | ------------------- | 
----------------- | ----------------------------------------------------------- 
| ----------------- |
+| All SCMs have finalized, and the leader begins instructing Datanodes to 
finalize | **105/105** | **105/105** | **105/105** | 100                 | 
Rejected          | Accepted                                                    
| Accepted          |
+| All live datanodes have finalized                                            
    | **105/105** | **105/105** | **105/105** | **105**             | Rejected  
        | Rejected, but instructed to finalize and retry registration | 
Accepted          |
+
+### 9. OM: Learns to Finalize From Polling SCM 
+
+| Status                                                                       
                                                       | OM1         | OM2      
   | OM3         |
+| 
-----------------------------------------------------------------------------------------------------------------------------------
 | ----------- | ----------- | ----------- |
+| New version has been deployed on all OMs, but they have not yet finalized to 
use new features.                                      | **100/105** | 
**100/105** | **100/105** |
+| SCM + DN finalization is detected and the finalize command is sent over 
Ratis. All OMs move to the new apparent version atomically. | **105/105** | 
**105/105** | **105/105** |
+
+Once these steps have completed, OM will stop polling SCM. The upgrade is 
complete.
diff --git a/hadoop-hdds/docs/content/design/zdu-image1.png 
b/hadoop-hdds/docs/content/design/zdu-image1.png
new file mode 100644
index 00000000000..b956f455cb2
Binary files /dev/null and b/hadoop-hdds/docs/content/design/zdu-image1.png 
differ


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to