A failed upgrade can leave the database half changed
When bin/magento setup:upgrade stops with an error, it may not return the database to its starting state. Some schema changes may already be applied while later changes are still missing.
That half-applied state creates schema integrity debt. The store may keep running for a while, but a later upgrade can hit the inconsistency. Errors such as "Base table or view not found" may then appear.
This article explains how Magento tracks schema and patch state, how to check whether the database is behind the code, and how to recover from an upgrade that stopped partway through.

How Magento records upgrade state
Magento records applied changes in several places. The setup_module table stores the schema and data version for each module. The patch_list table records which data and schema patches have run.
Declarative schema adds another layer. It describes the expected database structure in db_schema.xml and compares that description with the live database during an upgrade. The db_schema_whitelist.json file lists database elements that Magento may change or remove as schema changes are applied.
These records describe what Magento believes the database contains. If that recorded state disagrees with the actual tables and columns, the upgrade process can choose the wrong next step or fail.
Check whether the database is behind the code
Magento can check whether the database matches the installed code. Run this command:
bin/magento setup:db:status
The command reports whether the database is current or whether a schema or data upgrade is pending. Pending changes mean the code expects database structures that are not present yet.
bin/magento setup:db:status reports that a live, stable store is out of date, an earlier upgrade may not have finished. The code and database are no longer describing the same system.Half-applied patches create false records
Magento records data and schema patches in patch_list after they complete. A failure during a patch can leave database changes in place while the patch record is missing. Manual recovery can also leave the record and the actual database out of sync.
The next upgrade then starts with the wrong assumption. It may run a partly applied patch again and produce duplicate-column or duplicate-key errors. It may also skip a patch whose changes never reached the database.
An upgrade that worked last time can fail now because an earlier incomplete run left behind an inconsistency that nobody noticed.
Declarative schema depends on its whitelist
Declarative schema compares db_schema.xml with the live database and applies the DIFF. The whitelist records which structures are under Magento's control. A missing or stale whitelist can prevent expected schema changes from being applied correctly.
If a custom module was built without generating its whitelist, Magento may not manage the module's schema changes as expected. The bin/magento setup:db-declaration:generate-whitelist command regenerates the whitelist for a module. That can help bring a drifted schema back under control after the module is reviewed.
If a custom module expects declarative schema to manage a table but does not declare it in db_schema.xml, Magento does not have the information it needs to manage that table through declarative schema.
Recover with a database copy first
Start recovery with a verified backup. Schema repair changes the database structure, so you need a reversible path before testing a repair on a live system.
Restore a recent copy and run bin/magento setup:upgrade against that copy. Read the exact error and identify the module or patch that stopped. Then compare the patch_list or setup_module record with the tables and columns that actually exist.
Reconcile the recorded state with the database state only after you understand the difference. Do not delete records or rerun commands by guesswork. Once the copy upgrades from a consistent state, document the repair and apply the same controlled process to production.
Use a dry run before the real upgrade
You can preview an upgrade before changing the database. This gives you a chance to find a schema mismatch without creating another partial run.
Run bin/magento setup:upgrade --dry-run to report what the upgrade would do. On a store with incomplete upgrade history, this preview helps separate a controlled repair from another failed attempt.
Run the dry run against a recent database copy when possible. Reproducing the upgrade there shows where it fails, so the production run follows a path you have already tested.
Check integrity before the next upgrade
A half-applied schema can remain quiet until the next upgrade exposes it. Run bin/magento setup:db:status before a release while the store is stable.
Confirm that the database matches the code and that past upgrades finished. This check helps you enter the next upgrade with a known starting state instead of discovering drift during the first command.