一、MySQL用户管理 

1、用户帐号格式

        username@hostname, password 


2、用户帐号管理常用的命令

  • CREATE USER:创建用户

  • DROP UESER:删除用户

  • RENAME USER:更改用户名

  • SET PASSWORD:设定用户密码


3、命令说明

  • 创建用户命令:CREATE USER

语法:CREATE USER username@hostname[ IDENTIFIED BY [PASSWORD] 'password' ]

举例:

创建用户bols,并且访问的主机IP为192.168.1.100-192.168.1.199。

MariaDB [hellodb]> CREATE USER 'bols'@'192.168.1.1__' IDENTIFIED BY 'redhat';

重读授权表:

MariaDB [hellodb]> FLUSH PRIVILEGES;

用户bols登录mysql,然后查看其权限:

[root@example.com ~]# mysql -ubols -h192.168.1.8 -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.0.21-MariaDB-log Source distribution

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| test               |
+--------------------+
2 rows in set (0.00 sec)

MariaDB [(none)]> SHOW GRANTS FOR 'bols'@'192.168.%.%';  //查看改用户权限的命令
+---------------------------------------------------------------------------------------------------------------+
| Grants for bols@192.168.%.%                                                                                   |
+---------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'bols'@'192.168.%.%' IDENTIFIED BY PASSWORD '*84BB5DF4823DA319BBF86C99624479A198E6EEE9' |
+---------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)


  • 用户改名命令:RENAME USER

举例:

将用户bols改为bobols,注意改名需要有管理权限的用户才能执行,同时改名后若该用户还在线在不使用用户方面的操作时是不会有影响的,若该用户退出系统再次登录后就需要用新的用户名才能登录:

MariaDB [hellodb]> RENAME USER 'bols'@'192.168.%.%' TO 'bobols'@'192.168.%.%';

  • 更改用户密码命名:SET PASSWORD

举例:

MariaDB [hellodb]> SET PASSWORD FOR 'bobols'@'192.168.%.%'=PASSWORD('REDHAT');


二、MySQL的权限管理

1、权限类别分类

  • 库级别

  • 表级别

  • 字段级别

  • 管理类

  • 程序类


2、管理类权限关键字

  • CREATE TEMPORARY TABLES:创建临时表,该表保存在内存中

  • CREATE USER:创建用户

  • FILE:在服务器上能够读取和写入文件

  • SUPER:杂项管理类的命令

  • SHOW DATABASES:用户是否能执行SHOW DATABASES命令,默认就赋予了

  • RELOAD:能够使用FLUSH和RESET命令

  • SHUTDOWN:关闭服务器

  • REPLICATION SLAVE:授权用户能够有复制的权限

  • REPLICATION CLIENT:向服务器查询该主机有哪些客户端

  • LOCK TABLES:显示施加表锁

  • PROCESS:查看线程列表,命令为SHOW PROCESSLIST;


3、库级别和表级别权限关键字

  • ALTER:修改表

  • ALTER ROUTINE:修改存储历程,包括存储过程和存储函数

  • CREATE:创建表和库

  • CREATE ROUTINE:创建存储过程和存储函数

  • CREATE VIEW:创建视图

  • DROP:删除表和库

  • EXECUTE:执行存储过程和存储函数

  • GRNAT OPTION:把自己获得的权限转赠给他人

  • INDEX:创建和删除索引

  • SHOW VIEW:查看一个视图是怎么被创建的

数据操作(表级别)权限关键字:

  • SELECT:查询

  • INSERT:插入

  • UPDATE:更改

  • DELETE:删除

字段级别权限关键字:

  • SELECT(col1,...)

  • UPDATE(col1,...)

  • INSERT(col1,...)

所有权限:

   ALL [PRIVILEGES]


4、权限管理命令

  • GRANT:授权命令

命令格式: GRANT priv_type [(column_list)]

        [, priv_type [(column_list)]] ...

        ON [TABLE|FUNCTION|PROCEDURE] priv_level

        TO username@hostname [IDENTIFIED BY 'password'], [username@hostname [],...]

        [REQUIRE SSL]   //必须基于SSL连接访问

        [WITH with_option ...]

  priv_level:

      *     //所有

    | *.*   //所有库的所有对象

    | db_name.*   //指定库的所有对象

    | db_name.tbl_name  //指定库的指定表

    | tbl_name  //指定表

    | db_name.routine_name  //指定库的存储历程,包括存储过程和存储函数

  with_option:

      GRANT OPTION  //将自己的权限转赠给别人

    | MAX_QUERIES_PER_HOUR count   //每小时执行最多查询请求的个数

    | MAX_UPDATES_PER_HOUR count  //每小时执行最多更新的个数

    | MAX_CONNECTIONS_PER_HOUR count  //每小时最多建立连接次数

    | MAX_USER_CONNECTIONS count   //使用同一个帐号同时最多连接几个窗口


举例:

给bols用户在test库中能创建表的权限:

MariaDB [hellodb]> GRANT CREATE ON test.* TO 'bobols'@'192.168.%.%';
Query OK, 0 rows affected (0.08 sec)

用户bols登录后确实能创建表:

MariaDB [test]> CREATE TABLE tt(ID TINYINT UNSIGNED);
Query OK, 0 rows affected (0.18 sec)

但是却不能执行别的操作:

MariaDB [test]> DESC tt;
ERROR 1142 (42000): SELECT command denied to user 'bobols'@'example.com' for table 'tt'

下面就赋予用户bobols能在test库中能执行查询、插入、更改、删除的操作:

MariaDB [(none)]> GRANT SELECT,INSERT,UPDATE,DELETE,DROP ON test.* TO 'bobols'@'192.168.%.%';
Query OK, 0 rows affected (0.00 sec)

为避免授权信息延迟,可重读授权表:

MariaDB [hellodb]> FLUSH PRIVILEGES;

登录bobols用户,发现可以执行授权的操作:

MariaDB [test]> INSERT INTO tt VALUE(1);
Query OK, 1 row affected (0.08 sec)

MariaDB [test]> SELECT * FROM tt;
+------+
| ID   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

查看用户bobols所能执行的操作:

MariaDB [test]> SHOW GRANTS FOR 'bobols'@'192.168.%.%';
+-----------------------------------------------------------------------------------------------------------------+
| Grants for 
bobols@192.168.
%.%                                                                                   |
+-----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'bobols'@'192.168.%.%' IDENTIFIED BY PASSWORD '*CF765C66943E70F85E078F2DF976EA317BF166C9' |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON `test`.* TO 'bobols'@'192.168.%.%'                        |
+-----------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
  • REVOKE: 收回授权

语法: REVOKE priv_type [(column_list)]

      [, priv_type [(column_list)]] ...

      ON [object_type] priv_level

      FROM user [, user] ...

   REVOKE ALL PRIVILEGES, GRANT OPTION

      FROM user [, user] ...

举例:

收回用户bobols在test库中的创建权限:

MariaDB [(none)]> REVOKE CREATE ON test.* FROM 'bobols'@'192.168.%.%';
Query OK, 0 rows affected (0.00 sec)

查看用户bobols的权限,发现没有了创建权限:

MariaDB [test]> SHOW GRANTS FOR 'bobols'@'192.168.%.%';
+-----------------------------------------------------------------------------------------------------------------+
| Grants for 
bobols@192.168.
%.%                                                                                   |
+-----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'bobols'@'192.168.%.%' IDENTIFIED BY PASSWORD '*CF765C66943E70F85E078F2DF976EA317BF166C9' |
| GRANT SELECT, INSERT, UPDATE, DELETE, DROP ON `test`.* TO 'bobols'@'192.168.%.%'                                |
+-----------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

上面是取消指定的权限,若想取消bobols用户的所以权限可以使用ALL选项:

MariaDB [(none)]> REVOKE ALL  ON test.* FROM 'bobols'@'192.168.%.%';
Query OK, 0 rows affected (0.00 sec)


5、几个跟用户授权相关的表

  • db: 库级别权限;

  • host: 主机级别权限,已废弃;

  • tables_priv: 表级别权限;

  • colomns_priv:列级别的权限;

  • procs_priv:存储过程和存储函数相关的权限;

  • proxies_priv:代理用户权限;


三、MySQL查询缓存

1、作用

   用于保存MySQL查询语句返回的完整结果。被命中时,MySQL会立即返回结果,省去解析、优化和执行等阶段。 实际使用中是把SELECT语句本身做hash计算,计算的结果作为key,查询结果作为value。


2、工作流程

  • 服务器接收SQL,以SQL和一些其他条件为key查找缓存表(额外性能消耗) 

  • 如果找到了缓存,则直接返回缓存(性能提升) 

  • 如果没有找到缓存,则执行SQL查询,包括原来的SQL解析,优化等. 

  • 执行完SQL查询结果以后,将SQL查询结果存入缓存表(额外性能消耗) 


3、什么样的语句不会被缓存

   查询语句中有一些不确定数据时,不会缓存:例如NOW(), CURRENT_TIME();一般来说,如果查询中包含用户自定义函数、存储函数、用户变量、临时表、mysql库中系统表、或者任何包含权限的表,一般都不会缓存;


4、缓存的使用时机

衡量打开缓存是否对系统有性能提升是一个很难的话题 ,下面就是如何判断缓存的性能:

  • 通过缓存命中率判断, 缓存命中率 = 缓存命中次数 (Qcache_hits) / (查询次数 (Com_select) +缓存命中次数(Qcache_hits))

  • 通过缓存写入率, 写入率 = 缓存写入次数 (Qcache_inserts) / 查询次数 (Qcache_inserts) 

  • 通过 命中-写入率 判断, 比率 = 命中次数 (Qcache_hits) / 写入次数 (Qcache_inserts), 高性能MySQL中称之为比较能反映性能提升的指数,一般来说达到3:1则算是查询缓存有效,而最好能够达到10:1


5、缓存参数说明

查询系统关于缓存的参数:

MariaDB [mysql]> SHOW GLOBAL VARIABLES LIKE 'query_cache%';
+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 4096     |
| query_cache_size             | 16777216 |
| query_cache_strip_comments   | OFF      |
| query_cache_type             | ON       |
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+
6 rows in set (0.00 sec)
  • query_cache_type:查询缓存类型;是否开启缓存功能,开启方式有三种{ON|OFF|DEMAND}; 

       DEMAND:意味着SELECT语句明确使用 SQL_CACHE 选项时才会缓存; 

  • query_cache_size:总空间,单位为字节,大小必须是1024的整数倍。MySQL启动时,会一次分配并立即初始化这里指定大小的内存空间;这意味着,如果修改此大小,会清空缓存并重新初始化的。 

  • query_cache_min_res_unit:存储缓存的最小内存块;(query_cache_size-Qcache_free_memory)/Qcache_queries_in_cache能够获得一个理想的值。 

  • query_cache_limit:单个缓存对象的最大值,超出时则不预缓存;手动使用SQL_NO_CACHE可以人为地避免尝试缓存返回结果超出此参数限定值的语句。 

  • query_cache_wlock_invalidate:如果某个表被其它用户连接锁住了,是否仍然从缓存中返回结果。OFF表示返回。 


6、GLOBAL STAUS 中关于缓存的参数解释

  MariaDB [hellodb]> SHOW GLOBAL STATUS LIKE 'Qcache%';
  +-------------------------+----------+
  | Variable_name           | Value    |
  +-------------------------+----------+
  | Qcache_free_blocks      | 1        |
  | Qcache_free_memory      | 16757008 |
  | Qcache_hits             | 4        |
  | Qcache_inserts          | 2        |
  | Qcache_lowmem_prunes    | 0        |
  | Qcache_not_cached       | 18       |
  | Qcache_queries_in_cache | 2        |
  | Qcache_total_blocks     | 6        |
  +-------------------------+----------+
  • Qcache_free_blocks:缓存池中空闲块的个数 

  • Qcache_free_memory:缓存中空闲内存量 

  • Qcache_hits:缓存命中次数 

  • Qcache_inserts:缓存写入次数 

  • Qcache_lowmen_prunes:因内存不足删除缓存次数 

  • Qcache_not_cached:查询未被缓存次数,例如查询结果超出缓存块大小,查询中包含可变函数等 

  • Qcache_queries_in_cache:当前缓存中缓存的SQL数量 

  • Qcache_total_blocks:缓存总block数


7、减少碎片策略 

  • 选择合适的block大小;

  • 使用 FLUSH QUERY CACHE 命令整理碎片。这个命令在整理缓存期间,会导致其他连接无法使用查询缓存。

        PS:清空缓存的命令式 RESET QUERY CACHE。


8、计算命中率

MariaDB [hellodb]> SHOW GLOBAL STATUS WHERE Variable_name='Qcache_hits' OR Variable_name='Com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select    | 15    |
| Qcache_hits   | 4     |
+---------------+-------+
2 rows in set (0.00 sec)

计算公式:Qcache_hits/(Com_select+Qcache_hits)


9、缓存优化使用思路 

  • 批量写入而非多次单个写入; 

  • 缓存空间不宜过大,因为大量缓存同时失效时会导致服务器假死; 

  • 必要时,使用SQL_CACHE和SQL_N0_CACHE手动控制缓存; 

  • 对写密集型的应用场景来说,禁用缓存反而能提高性能;


10、查询缓存问题分析

当开启了查询缓存的功能后,可以通过一些参数以及状态值来观察查询缓存的使用情况。 流程以及涉及到的参数参见下图:

wKiom1XnCgSits2AAAL5Cp7ibHY911.jpg