今天给大家分析一下MySQL数据库权限问题

首先科普一下权限相关知识

https://www.cnblogs.com/chenmh/p/4533902.html

https://www.cnblogs.com/Richardzhu/p/3318595.html

https://www.cnblogs.com/wangchaoyuana/p/7545419.html

一、实际场景中遇到的问题:root@localhost权限丢失

用户root@localhost登录MySQL后,自身权限如下:

mysql> show grants for root@localhost\G

*************************** 1. row ***************************

Grants for root@localhost: GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*924D5D0E7327645EF1C7897D4F0C8CF1919EB853' WITH GRANT OPTION

*************************** 2. row ***************************

Grants for root@localhost: GRANT ALL PRIVILEGES ON `jdwin`.* TO 'root'@'localhost'

*************************** 3. row ***************************

Grants for root@localhost: GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION

3 rows in set (0.00 sec)


遇到问题如下root用户无法给*.*库授权,但是可以给库.*授权,这是啥情况?

mysql> grant all on *.* to oldboy@'%' identified by '123456';

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

mysql> grant all on xfzb.* to oldboy@'%' identified by '123456'; 

Query OK, 0 rows affected (0.00 sec)


经过对比分析,发现用户root@localhost并不是all privileges权限,有个权限Create_tablespace_priv被回收了。

正常情况下root@localhost权限和mysql.user表结构应该是如下

mysql> show grants for root@localhost\G

*************************** 1. row ***************************

Grants for root@localhost: GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*DAE6F90B6606FBE10A2000CF3CE713B90FFD1B63' WITH GRANT OPTION

*************************** 2. row ***************************

Grants for root@localhost: GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION

2 rows in set (0.00 sec)

mysql> desc mysql.user;

+------------------------+-----------------------------------+------+-----+---------+-------+

| Field                  | Type                              | Null | Key | Default | Extra |

+------------------------+-----------------------------------+------+-----+---------+-------+

| Host                   | char(60)                          | NO   | PRI |         |       |

| User                   | char(16)                          | NO   | PRI |         |       |

| Password               | char(41)                          | NO   |     |         |       |

| Select_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Insert_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Update_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Delete_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Create_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Drop_priv              | enum('N','Y')                     | NO   |     | N       |       |

| Reload_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Shutdown_priv          | enum('N','Y')                     | NO   |     | N       |       |

| Process_priv           | enum('N','Y')                     | NO   |     | N       |       |

| File_priv              | enum('N','Y')                     | NO   |     | N       |       |

| Grant_priv             | enum('N','Y')                     | NO   |     | N       |       |

| References_priv        | enum('N','Y')                     | NO   |     | N       |       |

| Index_priv             | enum('N','Y')                     | NO   |     | N       |       |

| Alter_priv             | enum('N','Y')                     | NO   |     | N       |       |

| Show_db_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Super_priv             | enum('N','Y')                     | NO   |     | N       |       |

| Create_tmp_table_priv  | enum('N','Y')                     | NO   |     | N       |       |

| Lock_tables_priv       | enum('N','Y')                     | NO   |     | N       |       |

| Execute_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Repl_slave_priv        | enum('N','Y')                     | NO   |     | N       |       |

| Repl_client_priv       | enum('N','Y')                     | NO   |     | N       |       |

| Create_view_priv       | enum('N','Y')                     | NO   |     | N       |       |

| Show_view_priv         | enum('N','Y')                     | NO   |     | N       |       |

| Create_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |

| Alter_routine_priv     | enum('N','Y')                     | NO   |     | N       |       |

| Create_user_priv       | enum('N','Y')                     | NO   |     | N       |       |

| Event_priv             | enum('N','Y')                     | NO   |     | N       |       |

| Trigger_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Create_tablespace_priv | enum('N','Y')                     | NO   |     | N       |       |

| ssl_type               | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |

| ssl_cipher             | blob                              | NO   |     | NULL    |       |

| x509_issuer            | blob                              | NO   |     | NULL    |       |

| x509_subject           | blob                              | NO   |     | NULL    |       |

| max_questions          | int(11) unsigned                  | NO   |     | 0       |       |

| max_updates            | int(11) unsigned                  | NO   |     | 0       |       |

| max_connections        | int(11) unsigned                  | NO   |     | 0       |       |

| max_user_connections   | int(11) unsigned                  | NO   |     | 0       |       |

| plugin                 | char(64)                          | YES  |     |         |       |

| authentication_string  | text                              | YES  |     | NULL    |       |

+------------------------+-----------------------------------+------+-----+---------+-------+

42 rows in set (0.00 sec)


出问题得这台MySQL数据库表结构如下:对比结构发现少了Create_tablespace_priv这个权限列

mysql> desc mysql.user;

+-----------------------+-----------------------------------+------+-----+---------+-------+

| Field                 | Type                              | Null | Key | Default | Extra |

+-----------------------+-----------------------------------+------+-----+---------+-------+

| Host                  | char(60)                          | NO   | PRI |         |       |

| User                  | char(16)                          | NO   | PRI |         |       |

| Password              | char(41)                          | NO   |     |         |       |

| Select_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Insert_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Update_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Delete_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Create_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Drop_priv             | enum('N','Y')                     | NO   |     | N       |       |

| Reload_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Shutdown_priv         | enum('N','Y')                     | NO   |     | N       |       |

| Process_priv          | enum('N','Y')                     | NO   |     | N       |       |

| File_priv             | enum('N','Y')                     | NO   |     | N       |       |

| Grant_priv            | enum('N','Y')                     | NO   |     | N       |       |

| References_priv       | enum('N','Y')                     | NO   |     | N       |       |

| Index_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Alter_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Show_db_priv          | enum('N','Y')                     | NO   |     | N       |       |

| Super_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Create_tmp_table_priv | enum('N','Y')                     | NO   |     | N       |       |

| Lock_tables_priv      | enum('N','Y')                     | NO   |     | N       |       |

| Execute_priv          | enum('N','Y')                     | NO   |     | N       |       |

| Repl_slave_priv       | enum('N','Y')                     | NO   |     | N       |       |

| Repl_client_priv      | enum('N','Y')                     | NO   |     | N       |       |

| Create_view_priv      | enum('N','Y')                     | NO   |     | N       |       |

| Show_view_priv        | enum('N','Y')                     | NO   |     | N       |       |

| Create_routine_priv   | enum('N','Y')                     | NO   |     | N       |       |

| Alter_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |

| Create_user_priv      | enum('N','Y')                     | NO   |     | N       |       |

| Event_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Trigger_priv          | enum('N','Y')                     | NO   |     | N       |       |

| ssl_type              | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |

| ssl_cipher            | blob                              | NO   |     | NULL    |       |

| x509_issuer           | blob                              | NO   |     | NULL    |       |

| x509_subject          | blob                              | NO   |     | NULL    |       |

| max_questions         | int(11) unsigned                  | NO   |     | 0       |       |

| max_updates           | int(11) unsigned                  | NO   |     | 0       |       |

| max_connections       | int(11) unsigned                  | NO   |     | 0       |       |

| max_user_connections  | int(11) unsigned                  | NO   |     | 0       |       |

+-----------------------+-----------------------------------+------+-----+---------+-------+

39 rows in set (0.01 sec)



在mysql.user表中,Trigger_priv列后面新增权Create_tablespace_priv限列,操作如下:

mysql> alter table mysql.user add Create_tablespace_priv enum('N','Y') COLLATE utf8_bin NOT NULL DEFAULT 'N' after Trigger_priv;

Query OK, 20 rows affected (0.00 sec)

Records: 20  Duplicates: 0  Warnings: 0

mysql> desc mysql.user;

+------------------------+-----------------------------------+------+-----+---------+-------+

| Field                  | Type                              | Null | Key | Default | Extra |

+------------------------+-----------------------------------+------+-----+---------+-------+

| Host                   | char(60)                          | NO   | PRI |         |       |

| User                   | char(16)                          | NO   | PRI |         |       |

| Password               | char(41)                          | NO   |     |         |       |

| Select_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Insert_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Update_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Delete_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Create_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Drop_priv              | enum('N','Y')                     | NO   |     | N       |       |

| Reload_priv            | enum('N','Y')                     | NO   |     | N       |       |

| Shutdown_priv          | enum('N','Y')                     | NO   |     | N       |       |

| Process_priv           | enum('N','Y')                     | NO   |     | N       |       |

| File_priv              | enum('N','Y')                     | NO   |     | N       |       |

| Grant_priv             | enum('N','Y')                     | NO   |     | N       |       |

| References_priv        | enum('N','Y')                     | NO   |     | N       |       |

| Index_priv             | enum('N','Y')                     | NO   |     | N       |       |

| Alter_priv             | enum('N','Y')                     | NO   |     | N       |       |

| Show_db_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Super_priv             | enum('N','Y')                     | NO   |     | N       |       |

| Create_tmp_table_priv  | enum('N','Y')                     | NO   |     | N       |       |

| Lock_tables_priv       | enum('N','Y')                     | NO   |     | N       |       |

| Execute_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Repl_slave_priv        | enum('N','Y')                     | NO   |     | N       |       |

| Repl_client_priv       | enum('N','Y')                     | NO   |     | N       |       |

| Create_view_priv       | enum('N','Y')                     | NO   |     | N       |       |

| Show_view_priv         | enum('N','Y')                     | NO   |     | N       |       |

| Create_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |

| Alter_routine_priv     | enum('N','Y')                     | NO   |     | N       |       |

| Create_user_priv       | enum('N','Y')                     | NO   |     | N       |       |

| Event_priv             | enum('N','Y')                     | NO   |     | N       |       |

| Trigger_priv           | enum('N','Y')                     | NO   |     | N       |       |

| Create_tablespace_priv | enum('N','Y')                     | NO   |     | N       |       |

| ssl_type               | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |

| ssl_cipher             | blob                              | NO   |     | NULL    |       |

| x509_issuer            | blob                              | NO   |     | NULL    |       |

| x509_subject           | blob                              | NO   |     | NULL    |       |

| max_questions          | int(11) unsigned                  | NO   |     | 0       |       |

| max_updates            | int(11) unsigned                  | NO   |     | 0       |       |

| max_connections        | int(11) unsigned                  | NO   |     | 0       |       |

| max_user_connections   | int(11) unsigned                  | NO   |     | 0       |       |

+------------------------+-----------------------------------+------+-----+---------+-------+

40 rows in set (0.00 sec)

修改用户root@localhost权限Create_tablespace_priv为Y,默认为N

mysql> update mysql.user set Create_tablespace_priv='Y' where user='root';

Query OK, 3 rows affected (0.00 sec)

Rows matched: 3  Changed: 3  Warnings: 0

mysql> select * from mysql.user where user='root' and host='localhost'\G

*************************** 1. row ***************************

                  Host: localhost

                  User: root

              Password: *924D5D0E7327645EF1C7897D4F0C8CF1919EB853

           Select_priv: Y

           Insert_priv: Y

           Update_priv: Y

           Delete_priv: Y

           Create_priv: Y

             Drop_priv: Y

           Reload_priv: Y

         Shutdown_priv: Y

          Process_priv: Y

             File_priv: Y

            Grant_priv: Y

       References_priv: Y

            Index_priv: Y

            Alter_priv: Y

          Show_db_priv: Y

            Super_priv: Y

 Create_tmp_table_priv: Y

      Lock_tables_priv: Y

          Execute_priv: Y

       Repl_slave_priv: Y

      Repl_client_priv: Y

      Create_view_priv: Y

        Show_view_priv: Y

   Create_routine_priv: Y

    Alter_routine_priv: Y

      Create_user_priv: Y

            Event_priv: Y

          Trigger_priv: Y

Create_tablespace_priv: Y

              ssl_type: 

            ssl_cipher: 

           x509_issuer: 

          x509_subject: 

         max_questions: 0

           max_updates: 0

       max_connections: 0

  max_user_connections: 0

1 row in set (0.00 sec)

刷新权限生效

mysql> flush privileges;

Query OK, 0 rows affected (0.01 sec)

久违的ALL PRIVILEGES又出现了。

mysql> show grants for root@localhost\G

*************************** 1. row ***************************

Grants for root@localhost: GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*924D5D0E7327645EF1C7897D4F0C8CF1919EB853' WITH GRANT OPTION

*************************** 2. row ***************************

Grants for root@localhost: GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION

2 rows in set (0.00 sec)


尝试给*.*库授权,ok了

mysql> grant all on *.* to oldboy@'%' identified by '123456';

Query OK, 0 rows affected (0.00 sec)


mysql> show grants for oldboy@'%';

+----------------------------------------------------------------------------------------------------------------+

| Grants for oldboy@%                                                                                            |

+----------------------------------------------------------------------------------------------------------------+

| GRANT ALL PRIVILEGES ON *.* TO 'oldboy'@'%' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' |

+----------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)


mysql> drop user oldboy@'%';

Query OK, 0 rows affected (0.01 sec)


mysql> 


从此再也不用担心没有权限给*.*库授权了。