MySQL Permissions Required to Export Procedures

Sat, 28/01/2023 - 16:42 -- James Oakley
MySQL Logo

If you run an application that includes a database, you want to be taking backups regularly. Your backup needs to include tables, views and triggers. It must also include any stored procedures / routines you are using. Otherwise, when you restore from backup, your procedures will be missing.

This article is not about Microsoft SQL Server. This concerns MySQL and its forks MariaDB and Percona.

I've found lots of people asking this question on the web, but not many of the posts I've found have a working answer.

Let's say you run the mysqldump command to export your database to a file. If you're like me, you run that command piped into gzip, to end up with a compressed backup file ending in .sql.gz. I tend to create a mysql user specifically to back up the database, so it only has the permissions it needs. I'll have to save the password for this user in a backup script, or in the .my.cnf file, so I don't want someone to be able to use that login to change the state of the database.

Then you notice the following error as your backup runs:

mysqldump: {user name} has insufficient privileges to SHOW CREATE PROCEDURE `{procedure name}`!

What has gone wrong, and what permissions do you need to give it?

When I create a user to backup a specific database, I tend to give it 6 permissions for that database

  • SELECT
  • LOCK TABLES
  • EVENT
  • TRIGGER
  • SHOW VIEW
  • EXECUTE

But those permissions will not enable that user to export a stored procedure as part of the backup.

I found various online forums where the suggestion was made to add CREATE ROUTINE or ALTER ROUTINE to that list. I've tried, and it doesn't work.

Here's the answer: Stored procedures are stored in the proc table within the database named mysql. This is a system database created when you install MySQL (or a fork) to store various system information.

Your backup user needs SELECT permission on that specific table.

So you need to give your backup user the 6 permissions above on the whole database it is to back up, and then SELECT permission on `mysql`.`proc`.

Command line

If you're administering MySQL through the command line, this is one easy command:

GRANT SELECT ON `mysql`.`proc` TO '{user name}'@'localhost';

phpMyAdmin

There are a great many SQL admin tools out there, but phpMyAdmin is very widely used. It's open-source and ships with popular hosting control panels such as cPanel.

If you're using phpMyAdmin, go to the database server (the left-most item in the breadcrumb, probably "localhost"). Click on User accounts. Click on "Edit privileges" against the user you're using for backups. Initially, you're shown a screen to set global permissions for that user. You want the user to have permissions for just one table (proc) in one database (mysql). So click "Database" to set permissions for a specific database.

Choose "Database"

Your then have to choose which database to grant permissions for. Click "mysql" in the option list, and click "Go"

Choose the mysql database

You don't want to grant permissions to the whole 'mysql' database, just to the 'proc' table. So choose "table" at the top of the screen:

Choose "table"

Now you need to type the name of the table into the box. The table you're assigning is 'proc'. Then click "Go".

Enter the name 'proc'

You want to give SELECT permission to every column in the table. You'll see 4 option boxes for 4 different types of permission, each listing the columns for which the permission will be given. MySQL permissions are very granular. You want the left-hand box for SELECT. Just click "select all" at the bottom of that list. Then click "Go"!

Select all against SELECT

And that's it - your backup script will now include procedures.

Blog Category: 

Comments

Mike's picture
Submitted by Mike on

What version of MySQL are you using?  When I tried that command, I get "Table 'mysql.proc' doesn't exist".  A quick google search and I found: "The mysql.proc table was removed in MySQL 8.0."  So I am at a loss of how to backup my stored procedures.

James Oakley's picture
Submitted by James Oakley on

Hi Mike

I'm using MariaDB, and it seems this is one change MySQL introduced after MariaDB and Percona forked off from it.

There are two answers. One is to give your backup user global permission to SELECT. That's probably not ideal, given you'll be saving that user's password in a file somewhere, although it wouldn't allow anyone to alter anything.

So the preferred way is to give your backup user SHOW_ROUTINE permission for the databases they'll back up. This is a permission, not available in MariaDB (and I wish it was, I'd never have had to write this blog post) for this very purpose. It allows a user to see the definition of stored procedures, and so there's no need to mess about with permissions on specific system tables. It also works if you're on shared hosting and can only give permissions to the databases owned by your hosting account (so not to the mysql.proc table).

You won't be the only person to hit this problem, so other readers will be grateful if you're about to pop back here and confirm this works.

Reference

Mike's picture
Submitted by Mike on

I did a lot more googling and tinkering after that.  And I made several changes before getting it to work.  But yes, I'm fairly certain it was a permission issue.  I never added "SHOW_ROUTINE".  But I can paste my current permissions here for my backup user.  I *think* it was the EVENT,TRIGGER permissions that did it.

GRANT SELECT, PROCESS, EVENT, TRIGGER ON *.* TO "[myuser]"@"[myip]"  
GRANT SELECT, LOCK TABLES, SHOW VIEW ON "[mydb]".* TO "[myuser]"@"[myip]"
REVOKE EVENT, TRIGGER ON "metrics_user_telegraf".* FROM "[myuser]"@"[myip]"
REVOKE EVENT, TRIGGER ON "mysql".* FROM "[myuser]"@"[myip]"
REVOKE EVENT, TRIGGER ON "sys".* FROM "[myuser]"@"[myip]"

Add new comment

Additional Terms