Problem/Motivation

The Database Configuration page does not display a version requirement error when attempting to install on a MySQL server that does not support utf8mb4 charset. The install tasks should display the version requirement error instead of throwing the Exception.

SQLSTATE[42000]: Syntax error or access violation: 1115 Unknown character set: 'utf8mb4'.

The root cause of this issue is that the connection throws an exception with a server error code: "1115 Unknown character set: utf8mb4" instead of what the mysql driver is expecting, which is a client error code: "2019 Can't initialize character set 'utf8mb4' (path: 'utf8mb4')".

Proposed resolution

Display the version requirement error when the Exception has the 1115 error code in \Drupal\Core\Database\Driver\mysql\Install\Tasks

This will cause the appropriate error message to be displayed to the user and reduce confusion.

Remaining tasks

  • Determine if the mysql driver should even care about the client error code.
  • Write a patch that catches the 1115 server error code (as well or instead).
  • Manually test patch on systems with unsupported version of MySQL.

User interface changes

None.

API changes

None.

Data model changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Liam Morland created an issue. See original summary.

Liam Morland’s picture

Issue summary: View changes
stefan.r’s picture

Priority: Normal » Major
stefan.r’s picture

Which mysql versions are you using? (server / libmysqlclient?) And which version of drupal 8?

shazbot28’s picture

Version: 8.0.x-dev » 8.0.0-rc1

I'm getting the same error due to the MySQL server version installed but no notification said so. Had to look at the install requirements to see that it required 5.5.3 or higher. Testing with webhost Dreamhost and they have 5.1.56 as a standard so I requested to have the SQL database moved to their beta testing MySQL 5.6.

Drupal: 8.0.0-rc1

MySQL Server version: 5.1.56

stefan.r’s picture

Title: D8 install should check MySQL version » D8 install should check MySQL version (Syntax error or access violation: 1115 Unknown character set: 'utf8mb4')
Liam Morland’s picture

I'm running 8.0.x at revision 1672445, which is 2 commits before -rc1. MySQL 5.1. mysqlnd 5.0.11.

oriol_e9g’s picture

MySQL 5.5.3 is the minium that ini_charset() could just force it to utf8mb4

catch’s picture

Version: 8.0.0-rc1 » 8.0.x-dev

Moving version back to 8.0.x which is where it will get fixed.

mradcliffe’s picture

Issue summary: View changes
Issue tags: +Novice

I updated the issue summary with details about the task.

I do not know if it is still necessary to have the client error code or if we could just replace it with the server error code. Once that is confirmed, then the appropriate patch can be written fairly trivially.

It is also possible to write a test if we want to mock Connection for the driver to return an error message and try to run the install task for the driver.

mradcliffe’s picture

Component: database system » mysql db driver

Changing component to mysql driver.

sumthief’s picture

Status: Active » Needs review
FileSize
1.95 KB

Hi. I've tried to make a patch for this issue.

stefan.r’s picture

Status: Needs review » Needs work

Under what circumstances does the error in #7 appear? I think the problem is the server version rather than the libmysqlclient version? #7 used mysqlnd so the problem there was not libmysqlclient.

We already have some logic in the installer that makes it fall back to utf8, we should probably catch the mentioned exception and use that instead.

Liam Morland’s picture

I was running MySQL 5.1. When I upgraded that, the problem went away.

stefan.r’s picture

Status: Needs work » Needs review
Issue tags: +Needs manual testing
FileSize
1.71 KB
sumthief’s picture

There are updated patch #15. Tested under Windows + MySQL 5.1.67.

stefan.r’s picture

Ah that's right, we need to check for both!

+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Install/Tasks.php
@@ -71,7 +71,8 @@ protected function connect() {
+        || ($e->getCode() == 42000 && $e->errorInfo[1] == Connection::UNKNOWN_CHARSET)) {

Should we add a constant for SQLSTATE error code 42000? (Syntax error or access violation)

+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
@@ -34,6 +34,11 @@ class Connection extends DatabaseConnection {
+   * Error code for "Unknown character set" error.

Should we change this to "Driver-specific error code for "Unknown character set" error."?

see https://secure.php.net/manual/en/pdo.errorinfo.php

sumthief’s picture

One more patch update. With help of @stefan.r.

stefan.r’s picture

Looks great to me! @Liam Morland or anyone else could you please manually test?

Liam Morland’s picture

Testing manually, it works fine.

Attached is a re-roll which uses Tasks::minimumVersion() instead of a hard-coded minimum version in the error message.

It would probably be better if the message "The database server version 5.1.72 is less than the minimum required version 5.5.4." was above the message about utf8mb4 character encoding, though I can see the difficulty in doing this.

stefan.r’s picture

Thanks! Could we re-upload #18? This change would be out of scope here, it's fine to keep it hardcoded as this is about utf8mb4 support which is 5.5.3 always, and it'd need an @placeholder rather than a :placeholder.

sumthief’s picture

Sure we can re-upload patch #18. But why we should leave minimal MySQL server version hardcoded? I think during Drupal 8 life cycle it won't be changed to higher version that will not reflect really minimal version.

sumthief’s picture

Liam Morland’s picture

it's fine to keep it hardcoded as this is about utf8mb4 support which is 5.5.3 always

When the minimum increases again, I wouldn't want someone to upgrade to 5.5.3 to clear the charset issue and then be hit with another error stating they need to upgrade again. However, I do see that this is strictly a separate issue.

stefan.r’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs manual testing

Thanks! In case the minimum changes, the /whole/ message will need to be rewritten. "a version that supports utf8mb4, such as (new minimum version)", wouldn't be correct... so, RTBC'ing re-uploaded #18.

stefan.r’s picture

Status: Reviewed & tested by the community » Needs work

Seems it hasn't been re-uploaded yet, setting back to NW

sumthief’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
1.92 KB

Yeah, looks like it'll be better hardcoded. Re-uploading #18 and RTBCing according to #25.

catch’s picture

Issue tags: +rc target triage
Liam Morland’s picture

#27 Looks good. Thanks.

mradcliffe’s picture

+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Install/Tasks.php
@@ -71,7 +71,8 @@ protected function connect() {
+        || ($e->getCode() == Connection::SQLSTATE_SYNTAX_ERROR && $e->errorInfo[1] == Connection::UNKNOWN_CHARSET)) {

I'm not sure if the line wrapping here is what is done in other places in core.

I looked at the coding standards to make sure, but there are no coding standards with regard to wrapping conditions on the next line so this technically does not need to be fixed.

stefan.r’s picture

#30 we do do it in a few places if you grep for ' ||', let's have a core committer it fix it on commit if necessary.

Liam Morland’s picture

The Line length and wrapping section states "Conditions should not be wrapped into multiple lines". Attached is a patch identical to #27, but with the condition on one line.

stefan.r’s picture

Looks good, thanks

  • webchick committed ce88146 on
    Issue #2582577 by Shlyapkin Grigoriy, Liam Morland, stefan.r, mradcliffe...
webchick’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -rc target triage +rc target

Awesome, thanks a lot for this. I've hit this before, I think on DreamHost and it's a totally inscrutable problem.

Talked this over with the core committers, and we agreed that this is a viable RC target. It's a non-invasive fix, with a lot of impact for users.

Committed and pushed to 8.0.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.