Stairway icons Database Deployments

Stairway to Reliable Database Deployment Level 3 – Rehearsing Changesets Across Environments

,

Introduction

The previous levels introduced the changeset as the unit of database evolution and defined the rules that govern its behavior. By the end of Level 2, a changeset is expected to follow a clear deployment contract: scripts modify the schema in predictable ways, rollback paths exist, and execution semantics remain deterministic. These guarantees already improve reliability even in very simple setups. In some environments developers work directly on a personal database, or changes may move straight from development to production. Even in these minimal contexts, the changeset model still provides structure: schema evolution is grouped into a controlled unit, and rollback paths remain explicitly defined. As soon as the deployment architecture becomes even slightly more structured, however, an additional step becomes valuable: rehearsing the deployment before it reaches production.

In a basic two-tier architecture, where development happens in a shared DEV or TEST environment and production is the only other layer, rehearsal can still take place within the development environment itself. Once development is complete, the environment is prepared so that the changeset can be executed again as a single operation.

In practice this minimal rehearsal typically involves three steps:

  1. Execute the Rollback scripts in DEV to restore the baseline state corresponding to the previous release.
  2. Verify alignment between DEV and production and confirm that the development environment now reflects the current production baseline.
  3. Execute the Create scripts in DEV to apply the changeset again from that baseline.

At this stage the scripts are no longer being adjusted. The goal is simply to confirm that the changeset behaves correctly when executed from start to finish from the same baseline as production.

Rehearsing in a Three-Tier Architecture

In more structured infrastructures, a three-tier architecture (DEV —> UAT —> PROD) introduces a dedicated UAT environment between development and production. This layer naturally becomes the place where rehearsal occurs. Instead of validating the deployment inside the development environment, the changeset is executed in UAT as a release candidate.

This separation offers an important advantage: development activity remains confined to DEV, while UAT becomes a stable environment where the deployment process itself can be exercised. The changeset can be applied, rolled back, and verified under conditions that more closely resemble the production release. The sections that follow describe how this rehearsal phase typically unfolds in a three-tier architecture and how it helps ensure that a changeset reaches production as a predictable and repeatable deployment.

Rehearsing a changeset means executing it in a controlled environment that closely resembles production, using the exact same scripts that will later be deployed.

The purpose is not only to verify that scripts run successfully, but also to confirm that:

  • rollback behaves as expected,
  • no hidden dependencies exist,
  • environment-specific differences are surfaced early.

Rehearsal answers a simple but critical question: “If I execute this in production, will it behave exactly as I expect?” 

Many teams implicitly treat testing or validation as part of development. In practice, this often means testing functionality on DEV and assuming deployment will work elsewhere. Rehearsal deliberately breaks this assumption. By separating rehearsal from development, you:

  • validate the deployment contract independently,
  • reduce reliance on environment-specific privileges,
  • simulate real deployment conditions.

This separation is especially important because rehearsal is often performed under stricter permissions than development.

Rehearsal Preconditions and Baseline Verification

Rehearsal assumes that UAT reflects production for the objects affected by the changeset. Before any execution takes place, UAT should be verified against PROD and aligned where necessary. In addition, rehearsal relies on a baseline equivalence check between DEV and UAT. This check is not about manually synchronizing environments, but about validating that rollback restores a known and shared starting point.

After executing Rollback in DEV, verify that DEV matches UAT for the objects involved in the changeset. Only when this equivalence is confirmed should the final Create execution in DEV take place. This ensures that the last Create run in DEV starts from the same baseline that will later be used in UAT and PROD, making subsequent comparisons meaningful and trustworthy.

A typical flow looks like this:

  1. Verify UAT–PROD alignment
    • Compare UAT with PROD for the objects affected by the changeset
    • Align UAT to PROD if necessary
  2. Execute Rollback in DEV
    • Restore DEV to the baseline state for the changeset
  3. Verify DEV–UAT equivalence
    • Compare DEV to UAT for the affected objects
    • Confirm that rollback restored a shared starting point
  4. Execute Create in DEV
    • Apply the changeset starting from the verified baseline
    • This execution represents the final authoring run
  5. (Optional but Recommended) Re-execute Rollback and Create in DEV
    • Validate rollback behavior once more
    • Confirm that DEV can return cleanly to the baseline and be restored to the expected post-Create state
  6. Execute Rollback in UAT
    • Confirm rollback scripts execute safely
  7. Execute Create in UAT
    • Apply the changeset exactly as it will be deployed
    • Verify successful execution
  8. Validate schema alignment
    • Compare UAT to DEV after Create
    • Confirm that no differences remain between the objects involved
  9. Execute Rollback in UAT
    • Restore UAT to its original state
    • Confirm alignment with PROD
  10. Final Create execution in UAT
    • Apply the changeset one last time
    • This execution becomes the reference for production deployment

The repetition in this flow is intentional. It demonstrates that the changeset behaves consistently, regardless of environment or execution context.

Script Naming and Execution Ordering

Before rehearsal can be performed reliably, script execution order must be explicit and predictable. In this approach, ordering is primarily enforced through naming conventions, leveraging the natural alphabetical execution order introduced in Level 2.

This applies both in:

  • folder ordering, which defines high-level execution phases,
  • script ordering, which defines execution sequence within each phase.

Forward execution

  1. _schema (create scripts, if present)
  2. Create scripts executed in alphabetical order
  3. Update scripts executed in alphabetical order (if present)

Rollback execution

  1. Rollback scripts executed in reverse order
  2. _schema (rollback scripts, if present)

At this stage, order is no longer conceptual—it is operational. Within a well-structured organization, developers are never allowed to execute scripts in production. Rehearsal is designed to operate within this constraint.

By repeatedly executing Create and Rollback in UAT:

  • the final deployment script becomes a known quantity,
  • confidence no longer depends on interactive debugging,
  • production execution becomes a controlled, low-risk action.

Even in environments where developers do have production access, adopting a rehearsal mindset helps prevent dangerous habits, such as applying ad-hoc fixes directly in PROD.

In Level 2 the deployment contract defined how a changeset is expected to behave. Rehearsal provides the practical counterpart to that definition, ensuring that those guarantees hold when the deployment is executed across environments. The final deployment step will be the topic of Level 4.

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating