MySQL 8 and Query Cache problem

Mysql 8 - Query Cache Problem

Since Sun Microsystems acquired MySQL, and later Oracle acquired Sun, MySQL has changed significantly.

It has grown into a mature and powerful database engine capable of handling projects with small, medium and even very large amounts of data. MySQL has been on the database market for many years and remains a great tool.

But in my opinion, something went wrong along the way.

The problem is not that MySQL has changed. Software has to evolve. New features, better security and better performance are all welcome.

The problem is that some changes introduced in newer versions have made upgrades much more complicated than they used to be.

Sometimes an upgrade no longer feels like installing a newer version of the same database.

It feels more like migrating to a different database.

The Query Cache

MySQL 5.7 was the last major version to support the Query Cache.

The Query Cache was deprecated in MySQL 5.7.20 and completely removed in MySQL 8.0.

The Query Cache stored the text of a SELECT statement together with its result. If exactly the same query was executed again and the result was still valid, MySQL could return the cached result without parsing and executing the query again.

Of course, the Query Cache had its problems. It could become a bottleneck on systems with a lot of concurrent writes, because changes to tables could invalidate cached results.

I understand why Oracle decided to remove it.

But there is an important distinction here.

The Query Cache was removed, but no direct replacement was introduced.

There are other caching mechanisms in MySQL, most importantly the InnoDB Buffer Pool, and caching can also be implemented at the application or proxy level. But these mechanisms solve different problems.

So if your application relied on the Query Cache, upgrading to MySQL 8.0 meant losing that functionality and potentially redesigning the way caching was handled.

And this was just the beginning.

An upgrade that cannot be undone

Another thing that bothers me is the downgrade path.

Downgrading from MySQL 8.0 to MySQL 5.7 is not supported.

The official documentation is very clear about this. If you upgrade to MySQL 8.0 and later discover that your application is not compatible with it, the supported solution is to restore a backup created before the upgrade.

This makes a database upgrade much more serious.

With a typical application upgrade, you can often install the previous version if something goes wrong.

With a database, the situation is different.

Once the database has been upgraded and its internal structures have changed, going back is not simply a matter of installing the old server binary.

So a MySQL upgrade is something that needs to be treated as a migration, not just an update.

The Data Dictionary

MySQL 8.0 introduced another major internal change: a new global transactional Data Dictionary.

In previous MySQL versions, metadata about database objects was stored using metadata files and non-transactional system tables.

MySQL 8.0 changed this architecture and moved the database metadata into transactional dictionary tables.

This is a significant architectural improvement.

But it also means that MySQL 8.0 is not simply MySQL 5.7 with some new features added.

There are fundamental differences under the hood.

And that matters when you are dealing with existing installations, old applications, backups and recovery procedures.

And then there is the collation problem

One of the easiest problems to demonstrate is the change in default character sets and collations.

MySQL 8.0 changed the default character set from latin1 to utf8mb4.

The default collation also changed to:

utf8mb4_0900_ai_ci

This is a sensible change. Modern applications should generally use utf8mb4.

But now imagine that you have a database running on MySQL 8.0 and you need to restore it on an older MySQL 5.7 server.

You may end up with something like:

Unknown collation: 'utf8mb4_0900_ai_ci'

And suddenly your perfectly valid MySQL 8.0 database dump cannot simply be restored on MySQL 5.7.

The important detail is that MySQL 8.0 does not automatically change the character set and collation of existing database objects during an upgrade. However, new objects can inherit the new defaults if they are not explicitly defined.

This is exactly the kind of problem that may remain invisible for years and appear only when you need to restore a backup on another server.

Authentication changed too

Another important change was the default authentication plugin.

In MySQL 5.7 the default was:

mysql_native_password

Starting with MySQL 8.0, the preferred and default authentication plugin became:

caching_sha2_password

The new mechanism provides stronger security and is a reasonable improvement.

But again, there is a price for changing the default.

Older applications, libraries and connectors may not understand the new authentication mechanism.

That means upgrading the database can suddenly require upgrading the application as well.

Fortunately, MySQL 5.7.23 and later client libraries gained support for connecting to MySQL 8.0 servers using caching_sha2_password, so the situation is not as bad as it could have been. Still, it is another example of how a database upgrade can affect components that, theoretically, have nothing to do with the database engine itself.

And the story continues.

In MySQL 8.4, mysql_native_password is no longer enabled by default on the server.

So applications relying on the old authentication mechanism may face another compatibility problem during a future upgrade.

utf8 is not really UTF-8

There is another interesting historical problem.

For many years MySQL developers used:

CHARACTER SET utf8

assuming that this meant normal UTF-8.

It didn’t.

MySQL’s historical utf8 implementation was actually utf8mb3, which supports a maximum of three bytes per character.

For full UTF-8 support, MySQL uses:

utf8mb4

MySQL 8.0 deprecated utf8mb3 and recommends moving to utf8mb4.

Again, this is technically the right direction.

But it demonstrates something important: the meaning and recommended usage of things that have existed in MySQL for years can change over time.

That can be perfectly acceptable for a new project.

It can be considerably more complicated for a ten-year-old application.

The real problem

None of these changes are necessarily bad on their own.

Removing Query Cache can make sense.

Introducing a transactional Data Dictionary makes sense.

Using utf8mb4 by default makes sense.

Using stronger authentication makes sense.

So what exactly is my problem?

It is the accumulation of changes.

A database is not an isolated piece of software.

It sits underneath an entire ecosystem:

Application
    ↓
Database driver
    ↓
Connection library
    ↓
MySQL Server
    ↓
Database files
    ↓
Backup / Restore
    ↓
Monitoring / Administration tools

When the database changes significantly, all of these layers may be affected.

And unlike an ordinary application, a database contains something that is extremely difficult to replace:

your data.

Upgrade or migration?

This is where I think the terminology becomes important.

An upgrade suggests something relatively simple:

MySQL 5.7
    ↓
MySQL 8.0

Install the new version, start the server and continue working.

But in reality, a production upgrade may look more like this:

MySQL 5.7
    ↓
check application compatibility
    ↓
check drivers and connectors
    ↓
check authentication
    ↓
check character sets and collations
    ↓
check deprecated SQL syntax
    ↓
check database structure
    ↓
check backup and restore procedures
    ↓
test application
    ↓
create a rollback plan
    ↓
upgrade
    ↓
hope everything works

At this point, I would no longer call it a simple upgrade.

It is a migration.

Was MySQL 5.7 better?

I don’t think the answer is simply “yes”.

MySQL 8.x has many improvements. Security is better, the internal architecture has improved, the optimizer has evolved, and the default configuration is more appropriate for modern applications.

MySQL 8.0 was a major technological step forward.

But being technologically better does not automatically mean being easier to maintain.

And this is the part that bothers me.

MySQL used to feel like a database that you could upgrade.

Today, major-version upgrades require considerably more planning, testing and knowledge about internal changes.

Maybe that is simply the price of a mature database system.

Maybe this is what happens when a product that was originally known for its simplicity grows into an enterprise database.

But I still miss the days when upgrading MySQL felt like an upgrade — rather than a migration project.

Leave a Reply

Your email address will not be published. Required fields are marked *