fix(2meet-data-optimizer): alter an existing flat table in one process at a time; keep a deferred group native until its drift fix

- 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)
This commit is contained in:
2026-09-27 17:22:57 +08:00
parent 0aec4b9bb6
commit 29adb05567
4 changed files with 149 additions and 20 deletions
+1 -1
View File
@@ -144,7 +144,7 @@ class TMDO_CLI {
}
$deferred = array_keys( (array) get_option( TMDO_Schema_Manager::DEFERRED_OPTION, array() ) );
if ( $deferred ) {
WP_CLI::warning( ' [SCHEMA] table upgrades not done yet (these groups use native meta meanwhile): ' . implode( ', ', $deferred ) . ' — see the error log if this run did not finish them.' );
WP_CLI::warning( ' [SCHEMA] groups using native meta until their table upgrade and the drift resync after it (tmdo_drift_resync) are done: ' . implode( ', ', $deferred ) . '.' );
}
$pending = TMDO_Schema_Manager::pending_indexes();
if ( $pending ) {