Skip to content

Give mezod time to shut down cleanly in all variants - #101

Merged
lukasz-zimnoch merged 2 commits into
mainfrom
raise-shutdown-grace-period
Jul 7, 2026
Merged

Give mezod time to shut down cleanly in all variants#101
lukasz-zimnoch merged 2 commits into
mainfrom
raise-shutdown-grace-period

Conversation

@lukasz-zimnoch

@lukasz-zimnoch lukasz-zimnoch commented Jul 7, 2026

Copy link
Copy Markdown
Member

Introduction

A mezod node killed before it finishes shutting down can be left with a corrupted LevelDB MANIFEST (leveldb: manifest corrupted (field 'comparer'): missing on the next start), which makes the node unable to start and requires a restore or resync to recover. This was observed on a testnet node and reported independently by a mainnet validator operator, in both cases after an unclean stop. The supervisor defaults in all deployment variants are too tight for a node that needs to flush state and close five databases on shutdown: Kubernetes gives pods 30 seconds, docker compose 10 seconds, and systemd 90 seconds before escalating to SIGKILL.

Changes

All three deployment variants now give mezod an explicit 120-second shutdown grace period:

  • Helm chart: new terminationGracePeriodSeconds value (default 120) wired into the StatefulSet pod spec. Chart version bumped to 12.1.0; README regenerated with helm-docs.
  • docker compose: stop_grace_period: 2m on the mezod service.
  • native (systemd): TimeoutStopSec=120 in the generated mezo.service unit.

A clean shutdown normally completes in seconds, so the longer grace period has no effect in normal operation; it only delays SIGKILL when a shutdown is genuinely slow or stuck.

Testing

  • helm lint passes and helm template renders terminationGracePeriodSeconds: 120 in the StatefulSet pod spec.
  • docker compose config parses the compose file and renders stop_grace_period: 2m0s on the mezod service.
  • bash -n / sh -n pass on native/v-kit.sh.

mezod must flush state and close its LevelDB databases on shutdown.
When the process is killed before it finishes, the databases can be
left with a corrupted MANIFEST (observed as 'leveldb: manifest
corrupted (field comparer): missing' on the next start), which makes
the node unable to start and requires a resync or restore.

The supervisor defaults are too tight for that: Kubernetes gives pods
30 seconds, docker compose 10 seconds, and systemd 90 seconds before
escalating to SIGKILL. Set an explicit 120-second grace period in all
three deployment variants:

- Helm chart: new terminationGracePeriodSeconds value (default 120)
  wired into the StatefulSet pod spec; chart version bumped to 12.1.0
- docker compose: stop_grace_period on the mezod service
- native systemd unit: TimeoutStopSec

A clean shutdown normally takes seconds, so the longer grace has no
effect in normal operation; it only delays SIGKILL when shutdown is
genuinely slow or stuck.
The pre-commit helm-docs-built hook sorts the values table in file
order (--sort-values-order=file), but the committed README was in
alphanumeric order and out of date, so CI failed. Regenerate it so the
table matches values.yaml order and includes terminationGracePeriodSeconds.
@lukasz-zimnoch
lukasz-zimnoch force-pushed the raise-shutdown-grace-period branch from 9e58a40 to 61ee900 Compare July 7, 2026 11:03
@lukasz-zimnoch lukasz-zimnoch self-assigned this Jul 7, 2026
@lukasz-zimnoch
lukasz-zimnoch marked this pull request as ready for review July 7, 2026 11:57
@lukasz-zimnoch
lukasz-zimnoch merged commit 12076e3 into main Jul 7, 2026
1 check passed
@lukasz-zimnoch
lukasz-zimnoch deleted the raise-shutdown-grace-period branch July 7, 2026 11:57
tomaszslabon added a commit to mezo-org/mezod that referenced this pull request Jul 7, 2026
Depends on: mezo-org/validator-kit#101

### Introduction

A mezod node killed before it finishes shutting down can be left with a
corrupted LevelDB MANIFEST (`leveldb: manifest corrupted (field
'comparer'): missing` on the next start), which makes the node unable to
start without a restore. This happened to `mezo-node-3` on the testnet
after an unclean stop, and a mainnet validator operator reported the
same failure signature independently. The pods currently run with the
implicit Kubernetes default of 30 seconds before SIGKILL, which is too
tight for a node that must flush state and close five databases on
shutdown.

Chart `mezod` 12.1.0 (mezo-org/validator-kit#101) sets
`terminationGracePeriodSeconds: 120` on the node pods by default.

### Changes

Bump the `mezo-org/mezod` chart pin from 12.0.1 to 12.1.0 in both
helmfiles, covering all five testnet validators (`mezo-staging`) and the
mainnet RPC node (`mezo-production`).

### Testing

Both helmfiles parse as valid YAML. `helmfile template` cannot be run
until the 12.1.0 chart tag is published from mezo-org/validator-kit#101;
the chart itself passes `helm lint` and renders
`terminationGracePeriodSeconds: 120` in the StatefulSet pod spec there.
Keep this PR as draft until 12.1.0 is published, then roll out with
`helmfile apply` per cluster.

---

### Author's checklist

- [x] Provided the appropriate description of the pull request
- [x] Updated relevant unit and integration tests
- [x] Updated relevant documentation (`docs/`) or specification
(`x/<module>/spec/`)
- [x] Assigned myself in the `Assignees` field
- [x] Assigned `mezod-developers` in the `Reviewers` field and notified
them on Discord

### Reviewer's checklist

- [ ] Confirmed all author's checklist items have been addressed
- [ ] Considered security implications of the code changes
- [ ] Considered performance implications of the code changes
- [ ] Tested the changes and summarized covered scenarios and results in
a comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants