MySQL用户,权限,索引,事务,存储引擎,日志管理(第40天)

权限:

mysql中的权限可以分为:库级别,表级别,字段级别,管理类权限,程序类级别(是否有执行某些函数,存储过程的权限)


管理类级别的权限有:

CREATE TEMPORARY TABLES

CREATE USER

FILE  读写文件权限

SUPER

SHOW DATABASES

RELOAD

SHUTDOWN

REPLICATION  SLAVE

REPLICATION  CLIENT

LOCK TABLES 锁表权限

PROCESS  进程相关


程序类权限有:

FUNCTION 函数

PROCEDURE  存储过程

TRIGGER  触发器

如上配合CREATE, ALTER, DROP, EXCUTE 使用


库级别和表级别:TABLE or DATABASE

ALTER

CREATE

CREATE VIEW

DOOP

INDEX

SHOW VIEW

GRANT OPTION  把自己获得的权限赠给其他用户一个副本


数据操作权限:

SELECT 查询权限

INSERT  插入数据权限

DELETE  删除权限

UPDATA  更新权限


字段级别:

SELECT(col1, col2, col3, ...)  查询某些字段的权限

UPDATE(col1, col2, col3, ...)

INSERT(col1, col2, col3, ....)


所有权限:

ALL PRIVILEGES


数据库的权限数据保存在元数据库mysql中的,进入mysql时,使用 use mysql;  show tables; 查看具体的权限授权情况, mysql中的授权相关的表有db、host、user,其他的表比如columns_priv、tables_priv, procs_priv


mysql的用户:

mysql的用户格式如下:有两部分组成用户和主机

用户@主机:表示此用户帐号可从@HOST范围内的某主机对此MySQL服务端建立连接;

@HOST: 表示客户端,HOST可以使用通配符(%,_),主机名,ip地址

%:

_:

172.16.0.0/16, 172.16.%.%


创建用户:

CREATE USER 'username'@'host' IDENTIFIED BY 'your_password', ...


删除用户账号:

DRP USER 'username'@'host';


查看用户获得的权限:

SHOW GRANTS FOR 'username'@'host';


用户重命名:

RENAME USER old_user TO new_user;


修改用户的密码:3种方法 (进入mysql中输入help set password  查看帮助)

       进入mysql后使用set命令   SET PASSWORD FOR  username='your password'

       进入mysql后更新mysql数据库中的user表中root用户

         UPDATE mysql.user SET password=PASSWORD('password_for_root') WHERE user='root';  flush privileges;

       在终端中使用mysqladmin  password  'your password' 命令,不需要进入mysql (在终端中输入mysqladmin --help 查看帮助)



忘记mysql管理员密码步骤如下:

1:启动mysqld服务的时候,使用 --skip-grant-tables 和--skip-networking 选项

2:使用如上UPDATE命令修改管理员密码

3:关闭mysqld进程

4:启动mysqld服务




授权操作命令:使用help grant查看帮助信息

GRANT priv1, priv2, ... ON [TABLE|FUNCTION|PROCEDURE] priv_level TO 'username'@'host' [IDENTIFIED BY 'password'] [REQUIRE ssl_option] [WITH with_option]

priv_level 取值如下:

priv_level: {

    *

   *.*

   db_name.*

   db_name.tbl_name

  tbl_name

   db_name.routine_name

}

例如 grant  update on  pythondb.* to  root@localhost;    表示root@localhost用户被授予对于pythondb数据库下的所有表等有更新操作



取消授权操作:

REVOKE priv1,priv2,... ON [TABLE|FUNCTION|PROCEDURE] priv_level  FROM 'username'@'host',...;


mysql的查询缓存:

mysql的查询缓存原理:把查询语句的哈希值作为key,查询结果作为value。


什么样的语句不会缓存?

查询语句中有不确定数据时不会缓存;

一般来主,如果查询中包含用户自定义的函数(UDF)、存储函数、用户变量、临时表、mysql库中表、或者任何包含权限信息表,都不会缓存;



查询缓存相关的mysql的变量有:show global variables like '%query_cache%';  

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

| Variable_name                | Value   |

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

| have_query_cache             | YES     |

| query_cache_limit            | 1048576 |

| query_cache_min_res_unit     | 4096    |

| query_cache_size             | 1048576 |

| query_cache_type             | OFF     |

| query_cache_wlock_invalidate | OFF     |

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

query_cache_limit: MySQL能够缓存的最大查询结果;如果某查询的结果大于此值,则不会被缓存;

query_cache_min_res_unit: 查询缓存中分配内存的最小单位;计算公式:(query_cache_size-Qcache_free_memory)/Qcache_queries_in_cache

query_cache_size: 查询缓存的总体可用空间;其必须为1024的倍数;

query_cache_type: 有3种植可选,ON, OFF, DEMAND

query_cache_wlock_invalidate:当其它会话锁定此次查询用到资源时,是否不能再从缓存中返回数据;




与查询缓存相关的状态变量:SHOW GLOBAL STATUS LIKE 'Qcache%';

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

| Variable_name           | Value    |

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

| Qcache_free_blocks      | 1        |

| Qcache_free_memory      | 16759656 |

| Qcache_hits             | 16       |

| Qcache_inserts          | 71       |

| Qcache_lowmem_prunes    | 0        |

| Qcache_not_cached       | 57       |

| Qcache_queries_in_cache | 0        |

| Qcache_total_blocks     | 1        |

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


Qcache_hits/Com_select = 缓存命中率

衡量缓存是否足够有效的另一种思路:Qcache_hits/Qcache_inserts,如果此比值大于3:1, 说明缓存也是有效的;如果高于10:1,相当理想;


缓存优化的思路:

1、批量写入比单次写入对缓存的影响要小得多;

2、缓存空间不宜过大,大量缓存的同时失效会导致MySQL假死;

3、必要时,使用SQL_CACHE或SQL_NO_CACHE手动控制缓存;

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


碎片整理:FLUSH QUERY_CACHE

清空缓存:RESET QUERY_CACHE


mysql中的索引:

SHOW ENGINES;   显示支持的存储引擎

基本法则:索引应该构建在被用作查询条件的字段上


约束:PRIMARY KEY, UNIQUE KEY, FOREIGN KEY


索引:特殊的数据结构,用于快速找到数据记录(行),mysql中的key(键)可用作索引;并非所有索引都是键;



索引可以创建在一个字段,也可是多个字段上:简单索引、组合索引

例子:索引(姓名,性别)

where name like 'tom%'

where gender = 'female'

where familyname = 'tom' and gender = 'female'



索引类型:B-Tree (B+ Tree) (左前缀), hash (key-value), R-Tree, FullText



B树索引:

B-Tree索引的适用场景:如下:

全值匹配:比较操作符 =, <=>

左前缀匹配:LIKE 'tom%'

列前缀匹配

匹配范围值:

组合索引类型中,精确匹配前一列,并范围匹配后一列;

只访问索引的查询:覆盖索引,从索引就可以直接得到最终结果;



哈希索引适用场景:

哈希索引只包含哈希值和行指针;不是按照索引值顺序存储,无法用于排序;不支持部分索引匹配查找;

哈希索引只支持等值比较查询,包含=, IN(), <=>



空间索引(R-Tree):


全文索引(FULLTEXT):在文本中查找关键词



索引的优点:

大大减少服务器需要扫描的数据量;

索引可以帮助服务器尽量避免进行排序及使用临时表;

索引可以将随机I/O转换为顺序I/O;



索引的使用策略:

1、要使用独立的列:索引列不是表达式的一部分;

SELECT Name FROM students WHERE Age + 2 > 32;

2、前缀索引

索引选择性:单独的索引项与数据表中的记录的总数的比值;取值范围:1/n-1;books, book

3、多列索引

查询条件多用AND,则建议使用多列索引;

查询条件多用OR,建议使用多个简单索引;

4、合适的次序:将选择性高的列写在最左侧;(Name, Gender)

5、聚簇索引:

好处:数据访问更快;

缺点:更新聚簇索引列的代价很高;

6、覆盖索引

SELECT Name FROM students WHERE Name LIKE 'tom%';

7、避免冗余索引

name, (name,gender)



EXPLAIN生成SQL 分析结果,可用于观察查询优化器如何查询:

EXPLAIN SELECT Name,Age FROM students WHERE Name LIKE 's%' or Age > 28\G

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

           id: 1

  select_type: SIMPLE

        table: students

         type: index_merge

possible_keys: Name,Age

          key: Name,Age

      key_len: 152,1

          ref: NULL

         rows: 7

        Extra: Using sort_union(Name,Age); Using where



id: SELECT语句的标识符

select_type有如下几种情况

SIMPLE

PRIMARY

UNION

UNION RESULT:UNION的执行结果

SUBQUERY:子查询

DERIVED:用于FROM子句中的子查询;

table:

查询语句所关系到的表的名字;

type: mysql访问到目标记录使用的方法

system: 表中仅有一行;

const: 表中至多有一行匹配;一般只有用于PRIMARY KEY或UNIQUE KEY(NOT NULL)索引时,此种结果才会出现;

eq_ref: 类似于const,表中至多有一个匹配到的行

ref: 

fulltext: 使用全文索引访问到目标记录

ref_or_null: 

index_merge: 

unique_subquery: 通常出现于IN子查询中

index_subquery: 类似上一个,

range: 带有范围限制的索引;

index: 全索引扫描

ALL:全表扫描


Extra:

using where:

using index:

using index for group by: 

using filesort: 使用外部索引排序


mysql存储引擎:

创建表的时候可以指定存储引擎,存储引擎可以称之为表类型

mysql> SHOW TABLE STATUS LIKE 'stu'\G            查看stu表的状态         

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

           Name: stu                                           

         Engine: InnoDB            InnoDB引擎                       

        Version: 10                                            

     Row_format: Dynamic                                       

           Rows: 6                                             

 Avg_row_length: 2730                                          

    Data_length: 16384                                         

Max_data_length: 0                                             

   Index_length: 0                                             

      Data_free: 0                                             

 Auto_increment: 8                                             

    Create_time: 2019-04-04 10:29:21                           

    Update_time: NULL                                          

     Check_time: NULL                                          

      Collation: utf8_general_ci                               

       Checksum: NULL                                          

 Create_options:                                               

        Comment:                                               

1 row in set (0.00 sec)           


InnoDB存储引擎:(MariaDB使用的是XtraDB)

存储引擎特性:

InnoDB: 设计用于处理大量的短期事务;支持自动的崩溃恢复;

Table Space: 表空间可由一个或多个物理文件组成

支持两种使用风格:

1、将所有innodb表的数据和索引放置同一个表空间中;

默认:数据目录下ibdata1,ibdata2, ibdata3,......

2、每个表使用自己专用的表空间;

表结构定义:tb_name.frm

数据和索引:tb_name.ibd

 

InnoDB基于聚簇索引建立的:基于主键索引查询时,性能较好;

辅助索引中必须包含主键索引;因此,为了节约空间,尽可能使用较小的主键索引;


InnoDB支持自适应hash索引;

支持事务;

支持行级锁;

支持MVCC;

支持热备份



MyISAM存储引擎:

支持全文索引、压缩、空间函数;

不支持事务、行级锁

崩溃后无法安全恢复

支持延迟更新索引键(delayed_key_write)

不支持热备份


myisam表存储格式:每张表都有三个文件(位于数据库目录下)

tb_name.frm: 表格式

tb_name.MYD: 数据

tb_name.MYI: 索引


            


其它存储引擎:

Memory: 早期叫HEAP表,数据保存于内存中

显式支持hash索引;无法持久存储数据


CSV: 文本文件,字段以逗号分隔;

不支持索引;常用于数据交换的场景


MRG_MYISAM: MyISAM的变种,将多个MyISAM表合并表示为一个虚拟表;


Federated:访问其它MySQL服务上的数据的代理

MariaDB上用的FederatedX


Blackhole: 没有任何存储机制,所以会丢弃所有的插入的数据;


PERFORMANCE_SCHEMA:伪存储引擎,mysql性能相关


NDB:Cluster


XtraDB: InnoDB的改进版,MarIaDB使用的存储引擎之一


Aria: 改进的MyISAM


OQGraph: 支持图操作

SphinxSE: 为sphinx全文搜索引擎提供了SQL接口;

Spider: 可以将数据切分成不同的分区,较透明实现分片功能;


PBXT:支持ACID和MVCC


TokuDB: 支持使用分形树的索引结构,适用存储大数据


MYSQL的并发控制机制:通过锁控制

锁:读锁和写锁

读锁:也叫共享锁,一个资源可以被附加多个读锁

写锁:也叫独占锁,一个资源被某个进程附加写锁后,其他进程就无法在附加读锁和写锁


锁粒度:包括表级别锁和行级别锁,锁粒度并非越细越好,锁的管理同样需要消耗时间和资源。每个存储引擎都实现了各自的锁策略和锁粒度,锁的操作一般由存储引擎自己管理。

同样的,mysql在服务器也实现了表级别锁,此锁用户可以显示请求,help lock;  查看帮助

LOCK TABLES                                    

    tbl_name [[AS] alias] lock_type            

    [, tbl_name [[AS] alias] lock_type] ...    

                                               

lock_type: {                                   

    READ [LOCAL]                               

  | [LOW_PRIORITY] WRITE                       

}                                              

                                               

UNLOCK TABLES;  释放锁



上锁的另外一种方法:FLUSH命令:

FLUSH TABLES tb_name[, ....] WITH READ LOCK; 

UNLOCK TABLES;   释放锁



InnoDB存储引擎也支持另外一种显式锁(只锁定挑选出的行):用select语句来上锁

SELECT ... LOCK IN SHARE MODE;   读锁

SELECT ... FOR UPDATE;            写锁

UNLOCK TABLES;   释放锁


MySQL事务机制:

mysql事务:一组原子性的sql查询,事务有如下4中特性:

A:atomicity,原子性,这个事务中的所有操作要么全部完成,要么失败全部回滚至操作之前的状态

C:consistency,一致性,数据库总是从一个一致性状态转移到另一个一致性状态

I:isolation,隔离性  一个事务所做的操作在提交之前,不能为其他事务所见     

隔离级别:4个级别

D:durability,持久性,一旦事务提交,其所作的修改会永久保存于数据库中



事务的流程如下:

启动事务的命令:start transaction;  之后是一系列的业务sql语句;然后是使用命令 commit;  提交,或者是失败则使用命令 rollback; 回滚到开启事务之前的状态。

建议在启用事务之前关闭数据库的自动提交,通过设置autocommit变量为off或者0来关闭自动提交      SET SESSION autocommit=off;  



事务还支持保存点(SAVEPOINT):保存点可以理解为是在事务执行过程中插入的铆钉,保存点可以依据业务需求插入,回滚的时候可以回滚到指定的保存点,这样一来,就不用每次都回滚到事务开启之前。(help savepoint;  查看帮助信息)

SAVEPOINT identifier    设置一个保存点  

ROLLBACK [WORK] TO [SAVEPOINT] identifier  回滚到指定的保存点

RELEASE SAVEPOINT identifier    撤销保存点




事务的4大隔离级别:演示时必须至少两个客户端连接mysqld服务,两边都设置相同的事务级别,然后两边都启动事务:

READ-UNCOMMITTED(读未提交):最低隔离级别,会产生“脏读”;就是可以读取别人未提交的数据

READ-COMMITTED(读提交):“这个值会导致不可重复读”;别人提交过的数据,我们才能读取到,别人未提交的数据,我们是读取不到的,所以叫做读提交。

REPEATABLE-READ(可重读):“这个值会产生幻读”;在我们的事务过程中,我们读取到的数据从始至终都是事务启动前的状态,不管对方提交已否。

SERIALIZABLE(可串行化):加锁读,事务只能串行,这是最高隔离级别


tx_isolation 是服务器变量,其值就是上面之一,mysql通过设置改变量来设置隔离级别,默认是REPEATABLE-READ

SHOW GLOBAL  VARIABLES LIKE 'tx_isolation';   查看事务级别

SHOW SESSION VARIABLES LIKE 'tx_isolation';   查看当前事务级别

SELECT @@global.tx_isolation;   查看事务级别

SELECT @@session.tx_isolation;   查看事务级别


SET tx_isolation=READ-UNCOMMITTED;   设置事务级别为READ-UNCOMMITTED  


MVCC: 多版本并发控制:通过保存数据在某个时间的快照实现。无论事务执行多长时间,其看到的数据都是一致的。MVCC仅在第二、第三隔离级别下有效。


事务日志:事务日志的写入类型为"追加", 所以,事务日志是顺序I/O, 如此一来,这就将随机I/O转换为顺序I/O,以提升事务操作效率;事务日志也称为Write-Ahead Logging(预写日志). 事务提交之后,所有的事务过程中的操作都会写入事务日志中。

事务日志文件:ib_logfile0, ib_logfile1


事务日志相关的变量:

SHOW GLOBAL  VARIABLES LIKE 'innodb_log%';

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

| Variable_name               | Value     |

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

| innodb_log_buffer_size      | 8388608   |

| innodb_log_checksums        | ON        |

| innodb_log_compressed_pages | ON        |

| innodb_log_file_size        | 268435456 |

| innodb_log_files_in_group   | 2         |

| innodb_log_group_home_dir   | .\        |

| innodb_log_write_ahead_size | 8192      |

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


MySQL死锁问题:

比如:


MySQL的日志:








                          




















评论

此博客中的热门博文

OAuth 2教程

网格策略

apt-get详细使用