humanmade / Mercator

WordPress multisite domain mapping for the modern era.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.

webp opened this issue · comments

commented

After WP changes from utf8 to utf8mb4, when trying to create Aliases in Network Admin > Sites > Edit Site screen:

ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.

Caused by mercator.php:

  $schema = "CREATE TABLE {$wpdb->dmtable} (
    id bigint(20) NOT NULL auto_increment,
    blog_id bigint(20) NOT NULL,
    domain varchar(255) NOT NULL,
    active tinyint(4) default 1,
    PRIMARY KEY  (id),
    KEY blog_id (blog_id,domain,active),
    KEY domain (domain)
  );";  

Patched it by changing from:

domain varchar(255) NOT NULL,

change to:

domain varchar(191) NOT NULL,

If domain varchar(192), ERROR 1709 (HY000): Index column size too large, but domain varchar(191) is ok. So max domain varchar is 191.

Reason see: Mechanics of Flite - Prepping your MySQL indexes for a character set change Prepping Your MySQL Indexes for a Character Set Change

When changing a MySQL table or column to a new character set that uses more bytes than the old character set, you need to first check if any schema changes are needed to accomodate the change. For example, changing character sets from latin1 to utf8 is an increase from 1 to 3 bytes, and changing from utf8 to utf8mb4 is an increase from 3 to 4 bytes. .....

I also encoutered this problem:

$ wp eval "define('WP_ADMIN',true); var_dump(Mercator\check_table());"
WordPress-tietokannan virhe Index column size too large. The maximum column size is 767 bytes. kyselylle CREATE TABLE wp_domain_mapping (
        id bigint(20) NOT NULL auto_increment,
        blog_id bigint(20) NOT NULL,
        domain varchar(255) NOT NULL,
        active tinyint(4) default 1,
        PRIMARY KEY  (id),
        KEY blog_id (blog_id,domain,active),
        KEY domain (domain)
    ) Tekijä: include('phar:///usr/local/bin/wp-cli/php/boot-phar.php'), include('phar:///usr/local/bin/wp-cli/php/wp-cli.php'), WP_CLI\Runner->start, WP_CLI\Runner->do_early_invoke, WP_CLI\Runner->_run_command, WP_CLI\Runner->run_command, WP_CLI\Dispatcher\Subcommand->invoke, call_user_func, WP_CLI\Dispatcher\CommandFactory::WP_CLI\Dispatcher\{closure}, call_user_func, Eval_Command->__invoke, eval, Mercator\check_table, dbDelta
string(7) "created"

And got it fixed by running:

$ wp db cli
MariaDB [wordpress]> CREATE TABLE wp_domain_mapping (
    id bigint(20) NOT NULL auto_increment,
    blog_id bigint(20) NOT NULL,
    domain varchar(150) NOT NULL,
    active tinyint(4) default 1,
    PRIMARY KEY  (id),
    KEY blog_id (blog_id,domain,active),
    KEY domain (domain)
  );

I think the longest domain name could be lowered to 191 characters instead. Who domains that long anyway?

This happened because of my charset. I was using utf8mb4 instead of utf8. After I replaced the character set it worked just okay:

MariaDB [wordpress]> describe wp_domain_mapping;
+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| blog_id | bigint(20)   | NO   | MUL | NULL    |                |
| domain  | varchar(150) | NO   | MUL | NULL    |                |
| active  | tinyint(4)   | YES  |     | 1       |                |
+---------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

MariaDB [wordpress]> ALTER TABLE wp_domain_mapping CONVERT TO CHARACTER SET utf8;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [wordpress]> ALTER TABLE wp_domain_mapping CHANGE COLUMN domain domain VARCHAR(255);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

MariaDB [wordpress]> describe wp_domain_mapping;
+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| blog_id | bigint(20)   | NO   | MUL | NULL    |                |
| domain  | varchar(255) | YES  | MUL | NULL    |                |
| active  | tinyint(4)   | YES  |     | 1       |                |
+---------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

@onnimonni thanks for the report! Sorry to get to this so late, I'll update it ASAP - indeed WP core now limits indexes to 191 characters since the move to utf8mb4

...also, fwiw, there is innodb_large_prefix which is evidently going to become default in future (beyond MySQL 5.7.7 | MariaDB 10.2.2)

@wp-networks thanks for the input. I made a start on this but need to introduce a db version option as dbDelta() wasn't updating the indexes.

Sorry for the wait @webp @onnimonni @wp-networks - latest WP has some better dbDelta() handling for updating the column type. I also added the utf8mb4 conversion function call when the db is being updated so database tables should be consistent on an install now.