Skip to main content

How to Reload MySQL TLS Certificates Without a Restart

· 4 min read
Jagdish Kumawat
Founder @ Dewiride

MySQL reads its certificate files when it starts, so replacing a file changes nothing by itself. ALTER INSTANCE RELOAD TLS makes it read them again, with no restart, and connections already open aren't touched.

What You Need​

A MySQL account with the CONNECTION_ADMIN right, such as root, and new certificate files in place, under the same names MySQL already uses. For a certificate with a new name, see How to Give a MySQL Docker Container a Certificate with the Right Host Name.

Step 1: Reload, and Check​

Compare the certificate's end date, before and after:

mysql>
SHOW GLOBAL STATUS LIKE 'Ssl_server_not_after';
ALTER INSTANCE RELOAD TLS;
SHOW GLOBAL STATUS LIKE 'Ssl_server_not_after';
Output
+----------------------+--------------------------+
| Variable_name | Value |
+----------------------+--------------------------+
| Ssl_server_not_after | Nov 3 06:02:30 2036 GMT |
+----------------------+--------------------------+
1 row in set (0.007 sec)
Query OK, 0 rows affected (0.001 sec)

+----------------------+--------------------------+
| Variable_name | Value |
+----------------------+--------------------------+
| Ssl_server_not_after | Feb 8 06:04:42 2029 GMT |
+----------------------+--------------------------+
1 row in set (0.000 sec)

Ssl_server_not_after showing the old end date, ALTER INSTANCE RELOAD TLS, then the new certificate's end date.

The date changed, so new connections now get the new certificate.

Step 2: Know What Happens If the Files Are Bad​

The plain statement is safe. With the wrong key in place, it refuses, and it changes nothing:

Output
ERROR 3888 (HY000): Failed to set up SSL because of the following SSL library error: Unable to get private key

The manual says it "rolls back with an error and has no effect", and "The previous context values continue to be used for new connections."

There's also an option to skip that protection, and you'll rarely want it:

Output
Query OK, 0 rows affected, 1 warning (0.001 sec)

That looks like it worked. In fact, the warning says MySQL couldn't load the files, and now it has no TLS at all for new connections.

Who Can Run It​

An ordinary account gets this:

Output
ERROR 1227 (42000): Access denied; you need (at least one of) the CONNECTION_ADMIN privilege(s) for this operation

It Doesn't Survive on Its Own​

The statement reads the files named by the ssl_ca, ssl_cert and ssl_key variables. If you've changed those with SET GLOBAL, a restart forgets them, so keep them in your configuration or use SET PERSIST. If you've only replaced the files themselves, as here, a restart reads the same new files.

Common Mistakes​

MistakeWhat happensDo this instead
Replacing a file and not reloadingMySQL keeps using the old certificateReload, and check Ssl_server_not_after
Adding NO ROLLBACK ON ERROR out of habitBad files turn TLS offLeave it out
Restarting insteadEvery connection dropsReload
Treating 1 warning as nothingThat warning can be the failure itselfRun SHOW WARNINGS

Troubleshooting​

SymptomLikely causeFix
ERROR 3888 … Unable to get private keyThe key doesn't match, or can't be readThe fix
ERROR 1227 … CONNECTION_ADMINYour account can't reloadUse an administrator
A client still sees the old certificateIt's using a connection from beforeNew connections get the new one

Conclusion​

Replace the files, run ALTER INSTANCE RELOAD TLS, and check Ssl_server_not_after. If anything's wrong with the files, the old certificate stays in use.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.