Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I gave my mysql user the "GRANT ALL PRIVILEGES ON database_name.* to my_user@localhost" treatment. Now I would like to be more granular, starting with lowering privileges on a specific table.

I am hoping mysql has or can be set to follow a "least amount of privileges" policy, so I can keep the current setup and lower it for the one table. But I have not seen anything like this in the docs or online.

Other than removing the DB level grant and re-granting on a table level, is there a way to get the same result by adding another rule?

share|improve this question
You might consider also asking this on , there might be someone who knows of an alternative technique there. – Joe H. Jan 20 '11 at 11:46

All privileges in MySQL are additive; there is no concept of a subtractive privilege.

You must remove the GRANT ALL ON db.* ... and assign the granular table level permissions you desire.

Keep in mind that you have a very wide set of privileges available to you in MySQL. Perhaps you could start with a database level GRANT SELECT which would provide read-only access to your user. Then you can selectively add the destructive privileges on a per-table basis, as dictated by your needs.

share|improve this answer

Unfortunately, if a user already has database-level privileges, running revoke all on db.table from user@host; does not create all the existing table-level privileges (excepting the one you are revoking) for you.

The best way I can think of doing this is to add all the table-level privileges that you require to the user and then revoke the database-level privilege.

MySQL keeps its privileges in different tables in the mysql database depending on what context the privilege is for.

  • If you grant a privilege on *.* it goes in the mysql.User table.
  • If you grant a privilege on db.* it goes in the mysql.db table.
  • If you grant a privilege on db.table it goes in the mysql.tables_priv table.
  • If you grant column privileges on db.table it goes in the mysql.columns_priv table.

So running the final revoke below only removes the entries from the db table and leaves everything that was already in the tables_priv table.

Example: User already has this:

mysql> grant all on db.* to user@host;

You run this:

mysql> grant all on db.table1 to user@host;
mysql> grant all on db.table2 to user@host;
mysql> grant all on db.table3 to user@host;
mysql> grant all on db.table4 to user@host;
mysql> revoke all on db.* from user@host;

The user will be able to access db.table5 right up until you run that revoke command. The user will have access to the other four tables both before and after the revoke.

The exception to this (there's always an exception) is with column privileges. If you grant column privileges to a user that already has table-level privileges on the same table, they will exist in the columns_priv table but will not show up in a show grants command and will disappear if you run a revoke ... on db.table from user@host; command.

You should be able to script the adding of all the table-level privileges rather than creating them all manually.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.