- security review H1: anonymous /wp-cron.php requests pass ddl_allowed(),
and dbDelta on an existing table had no lock, so concurrent requests each
ran the ALTER on a large table. The upgrade now runs under the same MySQL
GET_LOCK as the index DDL (skipped when another process holds it) and
re-checks the stored hash once locked; this covers aeav_only too. The table
build moves unchanged to write_table(); lock()/unlock() are shared
- security review M1: after a deferred upgrade the group stays native until
tmdo_drift_resync has rebuilt the rows written meanwhile
(TMDO_Schema_Manager::resynced() from run_scheduled_fix()); with no flat
writes (disabled) it is released at once
- Verify: SchemaUpgradeDeferralTest (lock held elsewhere, resync release),
integration 585, unit 702, phpcs, stan
- PR: PR-111 (2.3 acceptance security review)
- a changed group definition no longer runs dbDelta on an existing table
inside a web request (seconds to minutes on a large table, and every
concurrent request tried it): the group is recorded in tmdo_schema_deferred
and tmdo_ensure_group_indexes is scheduled, whose request upgrades it
- meanwhile the group stays native: Hook Bus field lookups return no field and
the router treats it as drifting; afterwards a drift fix
(tmdo_drift_resync) rebuilds the writes that skipped the flat table
- new tables are still created at once; aeav_only upgrades at once (the flat
table is the only copy); doctor lists deferred groups
- Verify: SchemaUpgradeDeferralTest, Hook Bus and router tests, integration
582, unit 701, phpcs, stan; dev36 live cycle in the 2.3 acceptance
- PR: PR-107