Using reserved words in MySQL 8

Overview

MySQL reserves certain keywords for its own use. If a table or column in your database is named with one of these words, queries that refer to it must escape the name, or the query fails.

MySQL 8.0

MySQL 8.0 already reserved a longer list of words, including GROUPS, EMPTY, RANK, and SYSTEM. Those rules haven't changed. For the complete list, see MySQL Keywords and Reserved Words.

What changed in MySQL 8.4?

MySQL 8.4 adds four reserved words that were not reserved in MySQL 8.0:

  • MANUAL

  • PARALLEL

  • QUALIFY

  • TABLESAMPLE

If a table or column in your database uses one of these names, queries that refer to it by name need to be updated.

Most sites are not affected. WordPress, Drupal, and most plugins and themes escape identifiers automatically. This usually only affects custom-built code that queries the database directly.

How do I know if my site is affected?

The typical symptom is that one page or feature on your site stops working, while the rest of the site continues to work normally. The affected page may appear blank, show a partial layout, or display a database error.

If you have access to your site's error logs, you'll see a MySQL syntax error:

ERROR 1064 (42000): You have an error in your SQL syntax

Please note that your data is safe. The table still exists and its contents are unchanged. The query is being rejected because of how it's worded, not because anything was lost.

How do I fix it?

Find the query in your site's code and wrap the reserved word in backticks.

Before:

SELECT manual FROM products

 After:

SELECT `manual` FROM products

The same applies when the reserved word is a table name:

SELECT * FROM `manual`

The character is a backtick (), not a single or double quotation mark. 'manual' and "manual"` mean the text "manual" and will not work.

Don't rename your table or column, and don't change anything in the database. The fix is in your site's code. Renaming means every other query that uses the old name has to be updated too.

If your site's custom features were built by someone else, forward this article to your developer.

Why does SELECT * still work?

When a query uses * to select every column, no column is named, so there's nothing for MySQL to misread:

SELECT * FROM products

 This works even if products contains a column named MANUAL. The error only appears when a query names that column specifically.

This does not apply to table names. A table name is always written out in the query, so a table named with a reserved word always needs backticks.

FAQs

What MySQL version does my database server use?

To check the version:

  1. Log in to phpMyAdmin from your panel.

  2. Click the SQL tab.

  3. Run the following:

    SELECT VERSION();

The following table shows you the MySQL version on which each database server runs, based on its operating system:

Database serverOperating systemMySQL version
MySQL SharedN/A8.0
MySQL VPSUbuntu Noble8.0
MySQL VPSUbuntu Resolute8.4
DedicatedUbuntu Noble8.0
DedicatedUbuntu Jammy8.0
DedicatedUbuntu Resolute8.4

Can I upgrade to MySQL 8.4?

It depends on the hosting plan:

  • VPS — Contact support to request an upgrade to MySQL 8.4.

  • Dedicated — Proactive migrations to MySQL 8.4 are underway. Customers can also request an OS upgrade to Ubuntu Resolute, which includes the MySQL 8.4 package.

  • Shared hosting — A manual upgrade cannot be requested. Servers are migrated to MySQL 8.4 on a proactive schedule. Customers who need 8.4 sooner can add a MySQL VPS and migrate their databases over manually.

Why do errors occur when importing a database with mysqlimport?

DreamHost has implemented some newer features in MySQL 8, which may cause an error to occur when using the command-line program mysqlimport:

mysqlimport: Error: 1227 Access denied; you need (at least one of) the SUPER, SYSTEM_VARIABLES_ADMIN, or SESSION_VARIABLES_ADMIN privilege(s) for this operation

The mysqlimport command causing the error may look something like this:

[server]$ /usr/bin/mysqlimport --host hostname --user user --password password --local --fields-terminated-by='|' database /path/to/file

It may also use an options file (recommended) instead, which would look like this:

[server]$ /usr/bin/mysqlimport --defaults-extra-file=/path/to/file --local --fields-terminated-by='|' database /path/to/file

Fixing the error

If this error occurs, using the mysql client instead of mysqlimport will allow this feature to work. Here is an example of the above commands.

Keep in mind the table name needs to be specified, where previously, mysqlimport determined that from the file name.

[server]$ echo "LOAD DATA LOCAL INFILE '/PATH/TO/FILE' into table tablename fields-terminated-by='|' mysql --host hostname --user username --password password database
[server]$ echo "LOAD DATA LOCAL INFILE '/PATH/TO/FILE' into table tablename fields-terminated-by='|' mysql --defaults-extra-file=/path/to/file

What custom modifications has DreamHost made for WordPress users?

DreamHost has made modifications to its MySQL 8 configuration to provide broader support for most sites and software. The following are default settings in MySQL 8 that have been modified in DreamHost's configuration:

SettingDefaultDreamHost
Encryption plugincaching_sha2_passwordmysql_native_password
Character setutf8mb4utf8

See also

Still not finding what you're looking for?