From cef052dff8eb12e35f07aa4a738e2fcf0870d7d8 Mon Sep 17 00:00:00 2001 From: Adrian Greeve Date: Tue, 18 Jul 2017 10:24:21 +0800 Subject: [PATCH] MDL-59561 database: Update to creating new indexes in mysql. When updating the mysql system to utf8mb4 not all tables are converted to the row format of compressed or dynamic. If a new index is created there is a possibility that the table could be using compact or redundant and then an error will be shown saying that the index size is too large. This fix handles this exception and converts the table over to compressed. --- lib/ddl/database_manager.php | 15 ++++++++++++++- lib/dml/mysqli_native_moodle_database.php | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/ddl/database_manager.php b/lib/ddl/database_manager.php index aa01e3cba19..41d7cda1af0 100644 --- a/lib/ddl/database_manager.php +++ b/lib/ddl/database_manager.php @@ -823,7 +823,20 @@ class database_manager { throw new ddl_exception('ddlunknownerror', null, 'add_index sql not generated'); } - $this->execute_sql_arr($sqlarr, array($xmldb_table->getName())); + try { + $this->execute_sql_arr($sqlarr, array($xmldb_table->getName())); + } catch (ddl_change_structure_exception $e) { + // There could be a problem with the index length related to the row format of the table. + // If we are using utf8mb4 and the row format is 'compact' or 'redundant' then we need to change it over to + // 'compressed' or 'dynamic'. + if (method_exists($this->mdb, 'convert_table_row_format')) { + $this->mdb->convert_table_row_format($xmldb_table->getName()); + $this->execute_sql_arr($sqlarr, array($xmldb_table->getName())); + } else { + // It's some other problem that we are currently not handling. + throw $e; + } + } } /** diff --git a/lib/dml/mysqli_native_moodle_database.php b/lib/dml/mysqli_native_moodle_database.php index 4227826b9d6..15926ee4b99 100644 --- a/lib/dml/mysqli_native_moodle_database.php +++ b/lib/dml/mysqli_native_moodle_database.php @@ -1917,4 +1917,18 @@ class mysqli_native_moodle_database extends moodle_database { return true; } + + /** + * Converts a table to either 'Compressed' or 'Dynamic' row format. + * + * @param string $tablename Name of the table to convert to the new row format. + */ + public function convert_table_row_format($tablename) { + $currentrowformat = $this->get_row_format($tablename); + if ($currentrowformat == 'Compact' || $currentrowformat == 'Redundant') { + $rowformat = ($this->is_compressed_row_format_supported(false)) ? "ROW_FORMAT=Compressed" : "ROW_FORMAT=Dynamic"; + $prefix = $this->get_prefix(); + $this->change_database_structure("ALTER TABLE {$prefix}$tablename $rowformat"); + } + } }