summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Reschke <lukas@statuscode.ch>2017-05-08 12:18:40 +0200
committerGitHub <noreply@github.com>2017-05-08 12:18:40 +0200
commit4d101ca2bec2f8b799535b35188755dbb01e9641 (patch)
tree93463513a8a0b9ae976cc3561627052cded91819
parent7cc750fe376a0b676818d06ec00837f655f4a51e (diff)
parent3afad7fe407ad6c5ef772d0e89f3f3cc06111a36 (diff)
downloadnextcloud-server-4d101ca2bec2f8b799535b35188755dbb01e9641.tar.gz
nextcloud-server-4d101ca2bec2f8b799535b35188755dbb01e9641.zip
Merge pull request #4514 from nextcloud/automatic-mysql-4byte-detection
Automatic mysql 4byte detection
-rw-r--r--config/config.sample.php21
-rw-r--r--core/Command/Db/ConvertMysqlToMB4.php12
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/DB/MySqlTools.php49
-rw-r--r--lib/private/Setup/MySQL.php8
6 files changed, 78 insertions, 14 deletions
diff --git a/config/config.sample.php b/config/config.sample.php
index d106d03f602..9f2ede88169 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -1235,16 +1235,23 @@ $CONFIG = array(
'sqlite.journal_mode' => 'DELETE',
/**
- * If this setting is set to true MySQL can handle 4 byte characters instead of
- * 3 byte characters
- *
+ * During setup, if requirements are met (see below), this setting is set to true
+ * and MySQL can handle 4 byte characters instead of 3 byte characters.
+ *
+ * If you want to convert an existing 3-byte setup into a 4-byte setup please
+ * set the parameters in MySQL as mentioned below and run the migration command:
+ * ./occ db:convert-mysql-charset
+ * The config setting will be set automatically after a successful run.
+ *
+ * Consult the documentation for more details.
+ *
* MySQL requires a special setup for longer indexes (> 767 bytes) which are
* needed:
*
* [mysqld]
- * innodb_large_prefix=true
- * innodb_file_format=barracuda
- * innodb_file_per_table=true
+ * innodb_large_prefix=ON
+ * innodb_file_format=Barracuda
+ * innodb_file_per_table=ON
*
* Tables will be created with
* * character set: utf8mb4
@@ -1257,8 +1264,6 @@ $CONFIG = array(
* https://mariadb.com/kb/en/mariadb/xtradbinnodb-server-system-variables/#innodb_large_prefix
* http://www.tocker.ca/2013/10/31/benchmarking-innodb-page-compression-performance.html
* http://mechanics.flite.com/blog/2014/07/29/using-innodb-large-prefix-to-avoid-error-1071/
- *
- * WARNING: EXPERIMENTAL
*/
'mysql.utf8mb4' => false,
diff --git a/core/Command/Db/ConvertMysqlToMB4.php b/core/Command/Db/ConvertMysqlToMB4.php
index 286274753ee..38aff8b09d8 100644
--- a/core/Command/Db/ConvertMysqlToMB4.php
+++ b/core/Command/Db/ConvertMysqlToMB4.php
@@ -22,6 +22,7 @@
namespace OC\Core\Command\Db;
use Doctrine\DBAL\Platforms\MySqlPlatform;
+use OC\DB\MySqlTools;
use OC\Migration\ConsoleOutput;
use OC\Repair\Collation;
use OCP\IConfig;
@@ -71,18 +72,17 @@ class ConvertMysqlToMB4 extends Command {
return 1;
}
- $oldValue = $this->config->getSystemValue('mysql.utf8mb4', false);
- // enable charset
- $this->config->setSystemValue('mysql.utf8mb4', true);
-
- if (!$this->connection->supports4ByteText()) {
+ $tools = new MySqlTools();
+ if (!$tools->supports4ByteCharset($this->connection)) {
$url = $this->urlGenerator->linkToDocs('admin-mysql-utf8mb4');
$output->writeln("The database is not properly setup to use the charset utf8mb4.");
$output->writeln("For more information please read the documentation at $url");
- $this->config->setSystemValue('mysql.utf8mb4', $oldValue);
return 1;
}
+ // enable charset
+ $this->config->setSystemValue('mysql.utf8mb4', true);
+
// run conversion
$coll = new Collation($this->config, $this->logger, $this->connection, false);
$coll->run(new ConsoleOutput($output));
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 2151aeff33b..703d624397c 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -488,6 +488,7 @@ return array(
'OC\\DB\\MigrationException' => $baseDir . '/lib/private/DB/MigrationException.php',
'OC\\DB\\Migrator' => $baseDir . '/lib/private/DB/Migrator.php',
'OC\\DB\\MySQLMigrator' => $baseDir . '/lib/private/DB/MySQLMigrator.php',
+ 'OC\\DB\\MySqlTools' => $baseDir . '/lib/private/DB/MySqlTools.php',
'OC\\DB\\NoCheckMigrator' => $baseDir . '/lib/private/DB/NoCheckMigrator.php',
'OC\\DB\\OCSqlitePlatform' => $baseDir . '/lib/private/DB/OCSqlitePlatform.php',
'OC\\DB\\OracleConnection' => $baseDir . '/lib/private/DB/OracleConnection.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index ec5190bc71d..ff7118e5bb1 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -518,6 +518,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\DB\\MigrationException' => __DIR__ . '/../../..' . '/lib/private/DB/MigrationException.php',
'OC\\DB\\Migrator' => __DIR__ . '/../../..' . '/lib/private/DB/Migrator.php',
'OC\\DB\\MySQLMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/MySQLMigrator.php',
+ 'OC\\DB\\MySqlTools' => __DIR__ . '/../../..' . '/lib/private/DB/MySqlTools.php',
'OC\\DB\\NoCheckMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/NoCheckMigrator.php',
'OC\\DB\\OCSqlitePlatform' => __DIR__ . '/../../..' . '/lib/private/DB/OCSqlitePlatform.php',
'OC\\DB\\OracleConnection' => __DIR__ . '/../../..' . '/lib/private/DB/OracleConnection.php',
diff --git a/lib/private/DB/MySqlTools.php b/lib/private/DB/MySqlTools.php
new file mode 100644
index 00000000000..32f1de887c3
--- /dev/null
+++ b/lib/private/DB/MySqlTools.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2017, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\DB;
+
+use OCP\IDBConnection;
+
+/**
+* Various MySQL specific helper functions.
+*/
+class MySqlTools {
+
+ /**
+ * @param Connection $connection
+ * @return bool
+ */
+ public function supports4ByteCharset(IDBConnection $connection) {
+ foreach (['innodb_file_format' => 'Barracuda', 'innodb_large_prefix' => 'ON', 'innodb_file_per_table' => 'ON'] as $var => $val) {
+ $result = $connection->executeQuery("SHOW VARIABLES LIKE '$var'");
+ $rows = $result->fetch();
+ $result->closeCursor();
+ if ($rows === false) {
+ return false;
+ }
+ if (strcasecmp($rows['Value'], $val) !== 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php
index 9998ca401d9..8290d675500 100644
--- a/lib/private/Setup/MySQL.php
+++ b/lib/private/Setup/MySQL.php
@@ -27,6 +27,7 @@
*/
namespace OC\Setup;
+use OC\DB\MySqlTools;
use OCP\IDBConnection;
class MySQL extends AbstractDatabase {
@@ -36,6 +37,13 @@ class MySQL extends AbstractDatabase {
//check if the database user has admin right
$connection = $this->connect(['dbname' => null]);
+ // detect mb4
+ $tools = new MySqlTools();
+ if ($tools->supports4ByteCharset($connection)) {
+ $this->config->setValue('mysql.utf8mb4', true);
+ $connection = $this->connect();
+ }
+
$this->createSpecificUser($username, $connection);
//create the database