mysqldump: Couldn’t execute ‘FLUSH TABLES’: Access denied; you need (at least one of) the RELOAD or FLUSH_TABLES privilege(s) for this operation (1227)

This article is a copy/paste/modify of mysqldump: Error: ‘Access denied; you need (at least one of) the PROCESS privilege(s) for this operation’ when trying to dump tablespaces.

See also Creating read-only PostgreSQL database users for pg_dump and pg_dumpall. I’m linking this because I use both articles on a regular basis.

The error

After a recent upgrade of MySQL server from 5.7.40 to 8.0.32, my database backups started encountered this error:

mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need (at least one of) the RELOAD or FLUSH_TABLES privilege(s) for this operation (1227)

The search

Searching, I found a mysqldump.guru post which suggested adding RELOAD, PROCESS permissions.

First, what permissions does my user have?

mysql> SHOW GRANTS for rsyncer;
+---------------------------------------------------+
| Grants for rsyncer@%                              |
+---------------------------------------------------+
| GRANT SELECT, LOCK TABLES ON *.* TO `rsyncer`@`%` |
| GRANT SHOW_ROUTINE ON *.* TO `rsyncer`@`%`        |
+---------------------------------------------------+
2 rows in set (0.00 sec)

mysql> 

That’s interesting, because if you look at my previous post on this, the user had PROCESS privileges.

OK, let’s try adding the suggested RELOAD.

mysql> GRANT RELOAD, PROCESS ON *.* TO 'rsyncer'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GRANTS for rsyncer;
+------------------------------------------------------------+
| Grants for rsyncer@%                                       |
+------------------------------------------------------------+
| GRANT SELECT, PROCESS, LOCK TABLES ON *.* TO `rsyncer`@`%` |
| GRANT SHOW_ROUTINE ON *.* TO `rsyncer`@`%`                 |
+------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> 

The failed attempt

Don’t do this. See below.

Let’s try their suggestion:

mysql> GRANT PROCESS, SELECT, LOCK TABLES ON *.* TO 'rsyncer'@'%';
Query OK, 0 rows affected (0.04 sec)

mysql> SHOW GRANTS for rsyncer;
+------------------------------------------------------------+
| Grants for rsyncer@%                                       |
+------------------------------------------------------------+
| GRANT SELECT, PROCESS, LOCK TABLES ON *.* TO 'rsyncer'@'%' |
+------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> 

For MySQL 8.0, I did this:

The failed test

Did that work?

[rsyncer@mysql01 ~]$ ~/bin/backup.sh
dumping db_nagiosql_v34
mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need (at least one of) the RELOAD or FLUSH_TABLES privilege(s) for this operation (1227)
backup of db_nagiosql_v34 failed
dumping fruityext
mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need (at least one of) the RELOAD or FLUSH_TABLES privilege(s) for this operation (1227)
backup of fruityext failed
dumping fruityint
mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need (at least one of) the RELOAD or FLUSH_TABLES privilege(s) for this operation (1227)
backup of fruityint failed
dumping librenms
mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need (at least one of) the RELOAD or FLUSH_TABLES privilege(s) for this operation (1227)
backup of librenms failed
receiving incremental file list
database-backup/mysql/
database-backup/mysql/db_nagiosql_v34.sql
            793 100%  774.41kB/s    0:00:00 (xfr#1, to-chk=3/8)
database-backup/mysql/fruityext.sql
            787 100%  768.55kB/s    0:00:00 (xfr#2, to-chk=2/8)
database-backup/mysql/fruityint.sql
            787 100%  768.55kB/s    0:00:00 (xfr#3, to-chk=1/8)
database-backup/mysql/librenms.sql
            786 100%  767.58kB/s    0:00:00 (xfr#4, to-chk=0/8)

Number of files: 8 (reg: 5, dir: 3)
Number of created files: 0
Number of deleted files: 0
Number of regular files transferred: 4
Total file size: 3,153 bytes
Total transferred file size: 3,153 bytes
Literal data: 0 bytes
Matched data: 3,153 bytes
File list size: 267
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 166
Total bytes received: 475

sent 166 bytes  received 475 bytes  1,282.00 bytes/sec
total size is 3,153  speedup is 4.92

For more information on that script, see below.

The successful attempt

See above where I’m using @’%’ in the GRANT command? Let’s use localhost instead.

No. Hmm, let’s try this instead:

mysql> GRANT FLUSH_TABLES ON *.* TO 'rsyncer'@'localhost';
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GRANTS for rsyncer@localhost;
+--------------------------------------------------------------------+
| Grants for rsyncer@localhost                                       |
+--------------------------------------------------------------------+
| GRANT SELECT, PROCESS, LOCK TABLES ON *.* TO `rsyncer`@`localhost` |
| GRANT FLUSH_TABLES,SHOW_ROUTINE ON *.* TO `rsyncer`@`localhost`    |
+--------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> 

The successful test

And then:

[rsyncer@mysql01 ~]$ ~/bin/backup.sh
dumping db_nagiosql_v34
dumping fruityext
dumping fruityint
dumping librenms
receiving incremental file list
database-backup/mysql/
database-backup/mysql/db_nagiosql_v34.sql
     13,794,729 100%   57.70MB/s    0:00:00 (xfr#1, to-chk=3/8)
database-backup/mysql/fruityext.sql
        216,847 100%  916.73kB/s    0:00:00 (xfr#2, to-chk=2/8)
database-backup/mysql/fruityint.sql
        282,546 100%    1.14MB/s    0:00:00 (xfr#3, to-chk=1/8)
database-backup/mysql/librenms.sql
     28,300,394 100%   38.28MB/s    0:00:00 (xfr#4, to-chk=0/8)

Number of files: 8 (reg: 5, dir: 3)
Number of created files: 0
Number of deleted files: 0
Number of regular files transferred: 4
Total file size: 42,594,516 bytes
Total transferred file size: 42,594,516 bytes
Literal data: 42,591,716 bytes
Matched data: 2,800 bytes
File list size: 275
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 166
Total bytes received: 42,602,571

sent 166 bytes  received 42,602,571 bytes  28,401,824.67 bytes/sec
total size is 42,594,516  speedup is 1.00
[rsyncer@mysql01 ~]$ 

Success!

Backing out my error.

You can ignore this if you didn’t follow my error above.

Let’s back out that first command:

mysql> REVOKE PROCESS ON *.* FROM 'rsyncer'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GRANTS for rsyncer;
+---------------------------------------------------+
| Grants for rsyncer@%                              |
+---------------------------------------------------+
| GRANT SELECT, LOCK TABLES ON *.* TO 'rsyncer'@'%' |
+---------------------------------------------------+
1 row in set (0.00 sec)

mysql> 

Testing ~/bin/backup.sh again, still works.

Backup scripts

You can find the mysql backup script mentioned above in my sundry scripts repo. Look for:

  • rsyncer-backup.sh – runs on the MySQL server, but could run remotely. I prefer to dump on the server, then rsync somewhere else.
  • rsync-backup-from-mysql01.sh – run on the dbclone server (the one which receives all the backups). It is invoked from the MySQL server, by the same user who ran the backup).

Thank you.

Leave a Comment

Scroll to Top