PluginProbe
404 Solution / 4.3.0
404 Solution v4.3.0
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / database / upgrades / DatabaseUpgradeEngineNormalization.php

DatabaseUpgradeEngineNormalization.php in 404 Solution 4.3.0, at includes/database/upgrades/DatabaseUpgradeEngineNormalization.php

69 lines 3.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 /**
8 * Plugin-table storage-engine drift correction.
9 *
10 * Walks every plugin table and ALTERs anything that is not InnoDB back to InnoDB.
11 * Plugin tables are uniformly InnoDB by design: crash-safe, no MyISAM "table is full"
12 * (.MYI 4 GiB) failure mode, no table-level locking on high-traffic logsv2 writes.
13 * Hosting migrations and manual SQL restores periodically revert tables to MyISAM;
14 * this component is the centralised place that reverts them back.
15 *
16 * Reachable from {@see ABJ_404_Solution_DatabaseUpgradeSelfHeal::verifyAndRepairCurrentSite()}
17 * and from {@see ABJ_404_Solution_DatabaseUpgradeDailyMaintenance::runDatabaseMaintenanceTasks()}
18 * via the coordinator delegate map.
19 */
20 class ABJ_404_Solution_DatabaseUpgradeEngineNormalization extends ABJ_404_Solution_DatabaseUpgradeComponent {
21
22 /** @return void */
23 function updateTableEngineToInnoDB() {
24 $result = $this->viewRead->getTableEngines();
25 $resultRows = isset($result['rows']) && is_array($result['rows']) ? $result['rows'] : [];
26 if (empty($resultRows)) {
27 return;
28 }
29
30 foreach ($resultRows as $row) {
31 if (!is_array($row)) {
32 continue;
33 }
34 $tableName = array_key_exists('table_name', $row) ? (string)$row['table_name'] :
35 (array_key_exists('TABLE_NAME', $row) ? (string)$row['TABLE_NAME'] : '');
36 $engine = array_key_exists('engine', $row) ? (string)$row['engine'] :
37 (array_key_exists('ENGINE', $row) ? (string)$row['ENGINE'] : '');
38
39 // All plugin tables use InnoDB: crash-safe, no row-count ceiling, no table-level
40 // locking. The former MyISAM special-case for logsv2 ("OPTIMIZE TABLE is slow
41 // otherwise") no longer applies -- OPTIMIZE TABLE on InnoDB has been equivalent to
42 // ALTER TABLE ... ENGINE=InnoDB since MySQL 5.6 (rebuilds tablespace in-place).
43 // InnoDB also eliminates the MyISAM-specific "table is full" failure mode on sites
44 // with disk pressure (MyISAM .MYI files cannot grow past 4 GiB by default).
45 if (strtolower($engine) === 'innodb') {
46 continue;
47 }
48
49 $this->logger->infoMessage("Updating " . $tableName . " to InnoDB.");
50 $query = 'alter table `' . $tableName . '` engine = InnoDB;';
51
52 $result = $this->dbCore->queryAndGetResults($query, array("log_errors" => false));
53 $this->logger->infoMessage("I changed an engine: " . $query);
54 $lastError = isset($result['last_error']) && is_string($result['last_error']) ? $result['last_error'] : '';
55
56 if ($lastError !== '' &&
57 strpos($lastError, 'Index column size too large') !== false) {
58
59 // delete the indexes, try again, and create the indexes later.
60 $this->upgrades()->schemaDiffUpgrade()->deleteIndexes($tableName);
61
62 $this->dbCore->queryAndGetResults($query,
63 array("ignore_errors" => array("Unknown storage engine")));
64 $this->logger->infoMessage("I tried to change an engine again: " . $query);
65 }
66 }
67 }
68 }
69