I want to understand the priority of executing MySQL grants privileges.

For e.g.:

I want to grant two different types of privileges on a single db Demo.

1.GRANT SELECT ON Demo.table1 TO abc@123;


As per my assumption, no 2 grant will overwrite the limitations of no 1 grant, therefore, ends up giving access to all tables including table1 to abc user.

And if I want to give SELECT privilege for table1 then I should change the order of executing permissions so that they don't get overwritten by *.

I'm not sure if this is how MySQL manages such permissions. Anyone with a different opinion?

Thanks in advance.

  • This is not a matter of opinion; the manual clearly describes the logic of authorization checking, and it has nothing to do with the order in which you may or may not execute GRANTs.
    – mustaccio
    Commented Jun 24, 2019 at 16:49
  • No order. Assume all privileges checked in random order until ALLOW found or all grants checked. If not found - no access. It's because no DENY privilege.
    – Akina
    Commented Jun 24, 2019 at 18:00
  • @Akina - But the algorithm could be that it sees #1 and decides that your only permission is for SELECT on table1, then stops.
    – Rick James
    Commented Jun 24, 2019 at 22:21
  • A side note: REVOKE removes an identical GRANT, but otherwise does nothing. (This is elaborating on Akina's comment about DENY.)
    – Rick James
    Commented Jun 24, 2019 at 22:22
  • @RickJames t sees #1 and decides that your only permission is for SELECT on table1, then stops When server looks for SELECT permission, it is true. But when it looks for, for example, UPDATE permission, it's false.
    – Akina
    Commented Jun 25, 2019 at 7:20

1 Answer 1


According to MySQL 5.7 Documentation under Privileges Provided by MySQL

The privileges granted to a MySQL account determine which operations the account can perform. MySQL privileges differ in the contexts in which they apply and at different levels of operation:

  • Administrative privileges enable users to manage operation of the MySQL server. These privileges are global because they are not specific to a particular database.

  • Database privileges apply to a database and to all objects within it. These privileges can be granted for specific databases, or globally so that they apply to all databases.

  • Privileges for database objects such as tables, indexes, views, and stored routines can be granted for specific objects within a database, for all objects of a given type within a database (for example, all tables in a database), or globally for all objects of a given type in all databases.

From this, the order is:

  • Global Privileges
  • Database Privileges
  • Table Privileges

The tables that drive the order are:

  • mysql.user
  • mysql.db
  • mysql.tables_priv
  • mysql.columns_priv

With regard to an identical username @ host, please note what pages 486,487 state about mysql's authentication algorithm from MySQL 5.0 Certification Study Guide

enter image description here

There are two stages of client access control:

In the first stage, a client attempts to connect and the server either accepts or rejects the connection. For the attempt to succeed, some entry in the user table must match the host from which the client connects, the username, and the password.

In the second stage (which occurs only if a client has already connected sucessfully), the server checks every query it receives from the client to see whether the client has sufficient privileges to execute it.

The server matches a client against entries in the grant tables based on the host from which the client connects and the user the client provides. However, it's possible for more than one record to match:

Host values in grant tables may be specified as patterns contains wildcard values. If a grant table contains entries from myhost.example.com, %.example.com, %.com, and %, all of them match a client who connects from myhost.example.com.

Patterns are not allowed for the User values in grant table entries, but a username may be given as an empty string to specify an anonymous user. The empty string matches any username and thus effectively acts as a wildcard.

When the Host and the User values in more than one user table record match a client, the server must decide which one to use. It does this by sorting records with the most specific Host and User column values first, and choosing the matching record that occurs first in the sorted list, Sorting take place as follows:

In the Host Column, literal values such as localhost,, and myhost.example.com sort ahead of values such as %.example.com that have pattern characters in them. Pattern values are sorted according to how specific they are. For example, %.example.com is more specific than %.com, which is more specific than %.

In the User column, non-blank usernames sort ahead of blank usernames. That is, non-anonymous users sort ahead of anonymous users.

The server performs this sorting when it starts. It reads the grant tables into memory, sorts them, and uses the in-memory copies for access control.

When you look at these two perspectives, mysqld should always go top down when evaluating grants. Keep in mind that

  • GRANT SELECT ON Demo.table1 TO abc@123; is stored in mysql.tables_priv
  • GRANT ALL PRIVILEGES ON Demo.* TO abc@123; is stored in mysql.db
  • For more information, please see my older post Unable to remove permission for mysql.user


  • Has it been a decade since End-of-life for 5.0?? (OK, most of the contents is still valid.)
    – Rick James
    Commented Jun 25, 2019 at 18:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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