Mysql知识总结

Mysql知识总结

  • mysql架构
    1.1 逻辑架构图1
    Mysql知识总结_第1张图片
  • Connectors
    指的是不同语言中与SQL的交互
  • Management Serveices & Utilities:
    系统管理和控制工具
  • Connection Pool: 连接池
    1. 管理缓冲用户连接,线程处理等需要缓存的需求。
    2. 负责监听对 MySQL Server 的各种请求,接收连接请求,转发所有连 接请求到线程管理模块。每一个连接上 MySQL Server 的客户端请求都会被分配(或创建)一个连接线程为其单独服务。
    3. 而连接线程的主要工作就是负责 MySQL Server 与客户端的通信,接受客户端的命令请求,传递 Server 端的结果信息等。线程管理模块则负责管理维护这些连接线程。包括线程的创建,线程的 cache 等。
  • SQL Interface: SQL接口
    接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface
  • Parser: 解析器
    SQL命令传递到解析器的时候会被解析器验证和解析。
    主要功能:
    1. 将SQL语句进行语义和语法的分析,分解成数据结构,然后按照不同的操作类型进行分类,然后做出针对性的转发到后续步骤,以后SQL语句的传递和处理就是基于这个结构的。
    2. 如果在分解构成中遇到错误,那么就说明这个sql语句是不合理的
  • Optimizer: 查询优化器
    SQL语句在查询之前会使用查询优化器对查询进行优化。
    它使用的是“选取-投影-联接”策略进行查询。
    用一个例子就可以理解: select uid,name from user where gender = 1;
    1. 这个select 查询先根据where 语句进行选取,而不是先将表全部查询出来以后再进行过滤
    2. 这个select查询先根据uid和name进行属性投影,而不是将属性全部取出以后再进行过滤
    3. 将这两个查询条件联接起来生成最终查询结果
  • Cache和Buffer: 查询缓存
    他的主要功能是将客户端提交给MySQL的 select请求的返回结果集 cache 到内存中,与该 query 的一个 hash 值 做一个对应。该 Query 所取数据的基表发生任何数据的变化之后, MySQL 会自动使该 query 的Cache 失效。在读写比例非常高的应用系统中, Query Cache 对性能的提高是非常显著的。当然它对内存的消耗也是非常大的。

如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等

  • 存储引擎接口
    存储引擎接口模块可以说是 MySQL 数据库中最有特色的一点了。目前各种数据库产品中,基本上只有 MySQL 可以实现其底层数据存储引擎的插件式管理。这个模块实际上只是 一个抽象类,但正是因为它成功地将各种数据处理高度抽象化,才成就了今天 MySQL 可插拔存储引擎的特色。

    从图还可以看出,MySQL区别于其他数据库的最重要的特点就是其插件式的表存储引擎。MySQL插件式的存储引擎架构提供了一系列标准的管理和服务支持,这些标准与存储引擎本身无关,可能是每个数据库系统本身都必需的,如SQL分析器和优化器等,而存储引擎是底层物理结构的实现,每个存储引擎开发者都可以按照自己的意愿来进行开发。
    注意:存储引擎是基于表的,而不是数据库。

1.2 逻辑架构图2
Mysql知识总结_第2张图片
1.3 执行流程图Mysql知识总结_第3张图片
Mysql知识总结_第4张图片
1.4 存储引擎介绍

  • 多存储引擎是mysql有别于其他数据库的一大特性;
  • 存储引擎是针对表的
  • MySQL 5.5之后,默认的存储引擎由MyISAM变为InnoDB。
  • 查看存储引擎:show engines;
    Innodb Myisam
    存储文件 .frm 表定义文件 .frm 表定义文件
    .ibd 数据文件 .myd 数据文件
    .myi 索引文件

锁 表锁、行锁 表锁
事务 ACID 不支持
CRDU 读、写 读多
count 扫表 专门存储的地方
索引结构 B+ Tree B+ Tree

Innodb Myisam
存储文件 .frm 表定义文件 .ibd 数据文件 .frm 表定义文件 .myd 数据文件 .myi 索引文件
表锁、行锁 表锁
事务 ACID 不支持
CRDU 读、写 读多
count 扫表 专门存储的地方
索引结构 B+ Tree B+ Tree

1.5 mysql物理结构

  • MySQL是通过文件系统对数据进行存储和管理的。
  • MySQL从物理结构上可以分为日志文件和数据文件。
  1. 日志文件
    MySQL通过日志记录了数据库操作信息和错误信息。常用的日志文件包括错误日志、二进制日志、查询日志、慢查询日志和 InnoDB 引擎在线 Redo 日志、中继日志等。
  2. 错误日志
  • 默认是开启的,而且从5.5.7以后无法关闭错误日志
  • 记录了运行过程中遇到的所有严重的错误信息,以及 MySQL每次启动和关 闭的详细信息。
  • 默认的错误日志名称:hostname.err
  • 错误日志所记录的信息是可以通过log-error和log-warnings来定义的,其中log-err是定义是否启用错误日志的功能和错误日志的存储位置,log-warnings是定义是否将警告信息也定义至错误日志中。
  • log_error可以直接定义为文件路径,也可以为ON|OFF;log_warings只能使用1|0来定义开关启动
  1. 二进制日志
  • 默认是关闭的,需要通过配置:log-bin=mysql-bin进行开启。其中mysql-bin是binlog日志文件的basename,binlog日志文件的名称:mysql-bin-000001.log
  • binlog记录了数据库所有的ddl语句和dml语句,但不包括select语句内容,语句以事件的形式保存,描述了数据的变更顺序,binlog还包括了每个更新语句的执行时间信息,binlog主要作用是用于恢复数据,因此binlog对于灾难恢复和备份恢复来说至关重要。
  • 如果是DDL语句,则直接记录到binlog日志,而DML语句,必须通过事务提交才能记录到binlog日志中。
  • binlog还用于实现mysql主从复制。
  • binlog还用于数据恢复。
  1. 通用日志
  • 默认情况下通用查询日志是关闭的。
  • 由于通用查询日志会记录用户的所有操作,其中还包含增删查改等信息,在并发操作大的环境下会产生大量的信息从而导致不必要的磁盘IO,会影响mysql的性能的。如若不是为了调试数据库的目的建议不要开启查询日志。
  1. 慢查询日志
  • 默认是关闭的。需要通过设置:slow_query_log=ON进行开启。
  • 记录执行时间超过long_query_time秒的所有查询,便于收集查询时间比较长的SQL语句
  1. 事务日志
  • 事务日志(InnoDB特有的日志)也叫redo日志。
  • 文件名为"ib_logfile0"和“ib_logfile1”,默认存放在表空间所在目录。
  • 还有一个日志文件叫undo 日志,默认存储在ib_data目录下。
  1. 中继日志
  • 是在主从复制环境中产生的日志。
  • 主要作用是为了从机可以从中继日志中获取到主机同步过来的SQL语句,然后执行到从机中。

1.6 数据文件
查看MySQL数据文件:SHOW VARIABLES LIKE ‘%datadir%’;

  • .frm文件:主要存放与表相关的数据信息,主要包括表结构的定义信息
  • .ibd和.ibdata文件:用来存储InnoDB存储引擎的表数据和索引信息
  • .myd文件:主要用来存储使用MyISAM存储引擎的表数据信息。
  • .myi文件:主要用来存储使用MyISAM存储引擎的表数据文件中任何索引的数据树

2.MySQL索引

2.1 介绍

  • 使用索引的主要目的是为了优化查询速度
  • 索引是一种特殊的文件或者叫数据结构(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。

2.2 索引的分类

  • 索引是在存储引擎中实现的,也就是说不同的存储引擎,会使用不同的索引
  • MyISAM和InnoDB存储引擎:只支持BTREE索引, 也就是说默认使用BTREE,不能够更换
  • MEMORY/HEAP存储引擎:支持HASH和BTREE索引
  • 索引的分类
    • 单列索引:
      * 普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。
      * 唯一索引:索引列中的值必须是唯一的,但是允许为空值,
      * 主键索引:是一种特殊的唯一索引,不允许有空值。

    • 组合索引
      *在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些 字段的左边字段时,索引才会被使用,使用组合索引时遵循最左前缀集合。
      *全文索引 全文索引,只有在MyISAM引擎上才能使用,只能在CHAR,VARCHAR,TEXT类型字段上使用全文索引。
      *空间索引:不做介绍,一般使用不到。
      2.3 索引的使用

      • 创建索引
        *单列索引之普通索引
        CREATE INDEX index_name ON table(column(length))
        ALTER TABLE table_name ADD INDEX index_name ON (column(length))
        *单列索引之唯一索引
        CREATE UNIQUE INDEX index_name ON table(column(length))
        *单列索引之全文索引
        CREATE FULLTEXT INDEX index_name ON table(column(length))
        *联合索引
        ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))
  • 删除索引
    DROP INDEX index_name ON table

2.4索引的存储结构
参考链接

  • B Tree和B+ Tree的特点与区别
    *树的高度一般都是在2-4这个高度,树的高度直接影响IO读写的次数。
    *如果是三层树结构—支撑的数据可以达到20G,如果是四层树结构—支撑的数据可以达到几十T
    *B Tree和B+ Tree的最大区别在于非叶子节点是否存储数据的问题。B Tree是非叶子节点和叶子节点都会存储数据。而B+ Tree只有叶子节点才会存储数据,而且存储的数据都是在一行上,而且这些数据都是有指针指向的,也就是由顺序的。
  • 非聚集索引
    *叶子节点只会存储数据行的指针,简单来说数据和索引不在一起,就是非聚集索引。
    *主键索引和辅助索引都会存储指针的值
  • 聚集索引
    *主键索引(聚集索引)的叶子节点会存储数据行,也就是说数据和索引是在一起,这就是聚集索引。
    *辅助索引只会存储主键值
    *如果没有没有主键,则使用唯一索引建立聚集索引;如果没有唯一索引,MySQL会按照一定规则创建聚集索引。
    Mysql知识总结_第5张图片

2.5使用索引的注意事项

  • 尽量创建组合索引(组合索引其实会默认按照最左前缀原则帮我们创建多组索引)
    组合索引(id,name,sex)
  • 索引最左前缀原则
  • 索引覆盖:要查询的列,也要使用索引覆盖住

2.6 MySQL性能优化之查看执行计划explain
2.6.1 介绍

  • MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性优化.
  • 使用explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描,这都可以通过explain命令来查看。
  • 可以通过explain命令深入了解MySQL的基于开销的优化器,还可以获得很多可能被优化器考虑到的访问策略的细节,以及当运行SQL语句时哪种策略预计会被优化器采用。
  • EXPLAIN 命令用法十分简单, 在 SELECT 语句前加上 explain 就可以了, 例如:Mysql知识总结_第6张图片
    2.6.2 参数说明
    expain出来的信息有10列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra,下面对这些字段进行解释:
  • id: SELECT 查询的标识符. 每个 SELECT 都会自动分配一个唯一的标识符.
  • select_type: SELECT 查询的类型.
  • table: 查询的是哪个表
  • partitions: 匹配的分区
  • type: join 类型
  • possible_keys: 此次查询中可能选用的索引
  • key: 此次查询中确切使用到的索引.
  • ref: 哪个字段或常数与 key 一起被使用
  • rows: 显示此查询一共扫描了多少行. 这个是一个估计值.
  • filtered: 表示此查询条件所过滤的数据的百分比
  • extra: 额外的信息

2.6.3 select_type列说明

  • SIMPLE, 表示此查询不包含 UNION 查询或子查询
  • PRIMARY, 表示此查询是最外层的查询
  • UNION, 表示此查询是 UNION 的第二或随后的查询
  • DEPENDENT UNION, UNION 中的第二个或后面的查询语句, 取决于外面的查询
  • UNION RESULT, UNION 的结果
  • SUBQUERY, 子查询中的第一个 SELECT
  • DEPENDENT SUBQUERY: 子查询中的第一个 SELECT, 取决于外面的查询. 即子查询依赖于外层查询的结果.

2.6.4 type列说明
通常来说, 不同的 type 类型的性能关系如下:
ALL < index < range ~ index_merge < ref < eq_ref < const < system

类型 含义
system 表只有一行
const 表最多只有一行匹配,通用用于主键或者唯一索引比较时
eq_ref 每次与之前的表合并行都只在该表读取一行,这是除了system const之外最好的一种,特点是使用=,而且索引的所有部分都参与join且索引是主键或非空唯一键的索引
ref 如果每次只匹配少数行,那就是比较好的一种,使用=或<=>,可以是左覆盖索引或非主键或非唯一键
fulltext 全文搜索
ref_or_null 与ref类似,但包括NULL
index_merge 表示出现了索引合并优化(包括交集,并集以及交集之间的并集),但不包括跨表和全文索引。这个比较复杂,目前的理解是合并单表的范围索引扫描(如果成本估算比普通的range要更优的话
unique_subquery 在in子查询中,就是value in (select…)把形如“select unique_key_column”的子查询替换。PS:所以不一定in子句中使用子查询就是低效的!
index_subquery 同上,但把形如”select non_unique_key_column“的子查询替换
range 常数值的范围
index a.当查询是索引覆盖的,即所有数据均可从索引树获取的时候(Extra中有Using Index)b.以索引顺序从索引中查找数据行的全表扫描(无 Using Index)c.如果Extra中Using Index与Using Where同时出现的话,则是利用索引查找键值的意思;d.如单独出现,则是用读索引来代替读行,但不用于查找
all 全表扫描

3.MySQL性能优化之慢查询

3.1 性能优化思路
首先需要使用慢查询功能,去获取所有查询时间比较长的SQL语句
3.2介绍

  • 数据库查询快慢是影响项目性能的一大因素,对于数据库,我们除了要优化 SQL,更重要的是得先找到需要优化的 SQL。MySQL 数据库有一个“慢查询日志”功能,用来记录查询时间超过某个设定值的SQL,这将极大程度帮助我们快速定位到症结所在,以便对症下药。至于查询时间的多少才算慢,每个项目、业务都有不同的要求。传统企业的软件允许查询时间高于某个值,但是把这个标准放在互联网项目或者访问量大的网站上,估计就是一个bug,甚至可能升级为一个功能性缺陷。MySQL的慢查询日志功能,默认是关闭的,需要手动开启。

3.3开启慢查询功能

  • 查看是否开启慢查询功能
    Mysql知识总结_第7张图片
    参数说明
    *slow_query_log :是否开启慢查询日志,ON 为开启,OFF 为关闭,如果为关闭可以开启。
    *log-slow-queries :旧版(5.6以下版本)MySQL数据库慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件host_name-slow.log
    *slow-query-log-file:新版(5.6及以上版本)MySQL数据库慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件host_name-slow.log
    *long_query_time :慢查询阈值,当查询时间多于设定的阈值时,记录日志,单位为秒。

  • 永久开启慢查询功能
    修改/etc/my.cnf配置文件,重启 MySQL, 这种永久生效.
    [mysqld]
    slow_query_log = ON
    slow_query_log_file = /var/log/mysql/slow.log
    long_query_time = 1
    Mysql知识总结_第8张图片

  • 慢查询日志格式
    Mysql知识总结_第9张图片
    Mysql知识总结_第10张图片
    格式说明:
    *第一行,SQL查询执行的时间
    *第二行,执行SQL查询的连接信息,用户和连接IP
    *第三行,记录了一些我们比较有用的信息,如下解析
    Query_time,这条SQL执行的时间,越长则越慢
    Lock_time,在MySQL服务器阶段(不是在存储引擎阶段)等待表锁时间
    Rows_sent,查询返回的行数
    Rows_examined,查询检查的行数,越长就当然越费时间
    *第四行,设置时间戳,没有实际意义,只是和第一行对应执行时间。
    *第五行及后面所有行(第二个# Time:之前),执行的sql语句记录信息,因为sql可能会很长。

  • 分析慢查询日志
    1.MySQL自带的mysqldumpslow
    [root@localhost mysql]# mysqldumpslow /var/lib/mysql/localhost-slow.log
    2.常用参数说明

    • -s:是表示按照何种方式排序
      Mysql知识总结_第11张图片
    • -t:是top n的意思,即为返回前面多少条的数据
    • -g:后边可以写一个正则匹配模式,大小写不敏感的

实例:
得到按照时间排序的前10条里面含有左连接的查询语句。
mysqldumpslow -s t -t 10 -g “left join” /var/lib/mysql/localhost_slow.log

4.mysql性能分析语句 show profile

通常我们是使用的explain,以及slow query log都无法做到精确分析,但是Query Profiler却可以定位出一条SQL语句执行的各种资源消耗情况,比如CPU,IO等,以及该SQL执行所耗费的时间等

4.1语句使用

  • show profile 和 show profiles 语句可以展示当前会话(退出session后,profiling重置为0) 中执行语句的资源使用情况.

  • show profiles :以列表形式显示最近发送到服务器上执行的语句的资源使用情况.显示的记录数由变量:profiling_history_size 控制,默认15条
    Mysql知识总结_第12张图片
    show profile: 展示最近一条语句执行的详细资源占用信息,默认显示 Status和Duration两列
    Mysql知识总结_第13张图片
    4.2 开启Profile功能

  • Profile 功能由MySQL会话变量 : profiling控制,默认是OFF关闭状态。

  • 查看是否开启了Profile功能:
    select @@profiling;
    Mysql知识总结_第14张图片

  • 开启profile功能
    set profiling=1; --1是开启、0是关闭
    在这里插入图片描述

  • 执行sql语句
    Mysql知识总结_第15张图片

  • 执行 show profiles 查看分析列表
    Mysql知识总结_第16张图片

  • 查询第二条语句的执行情况
    show profile for query 2;
    Mysql知识总结_第17张图片

  • 指定资源类型查询
    show profile cpu,swaps for query 2;
    Mysql知识总结_第18张图片

5.mysql事务处理

5.1 事务概叙

  • 在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
  • 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。
  • 事务用来管理DDL、DML、DCL操作,比如 insert,update,delete 语句

5.2一般来说,事务是必须满足4个条件(ACID):

  • Atomicity(原子性)
    *构成事务的的所有操作必须是一个逻辑单元,要么全部执行,要么全部不执行。
  • Consistency(稳定性、一致性)
    *数据库在事务执行前后状态都必须是稳定的。
  • Isolation(隔离性)
    *事务之间不会相互影响。
  • Durability(可靠性、持久性)
    *事务执行成功后必须全部写入磁盘。

5.3 mysql事务支持

  • BEGIN或START TRANSACTION;显式地开启一个事务;
  • COMMIT;也可以使用COMMIT WORK,不过二者是等价的。COMMIT会提交事务,并使已对数据库进行的所有修改称为永久性的;
  • ROLLBACK;有可以使用ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;

在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。

5.4 事务并发出现的常见问题

  • 脏读:一个事务读取到另一个事务未提交的数据。
  • 不可重复读:一个事务因读取到另一个事务已提交的数据。导致对同一条记录读取两次以上的结果不一致。update操作
  • 幻读:一个事务因读取到另一个事务已提交的数据。导致对同一张表读取两次以上的结果不一致。insert、delete操作

5.5 事务并发出现的问题处理(事务隔离级别)
现在来看看MySQL数据库为我们提供的四种隔离级别(由低到高):

① Read uncommitted (读未提交):最低级别,任何情况都无法保证。
② Read committed (读已提交):可避免脏读的发生。
③ Repeatable read (可重复读):可避免脏读、不可重复读的发生。
④ Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

5.6 默认隔离级别
大多数数据库的默认隔离级别是Read committed,比如Oracle、DB2等。
MySQL数据库的默认隔离级别是Repeatable read。

5.7 查看设置隔离级别

  • 在MySQL数据库中查看当前事务的隔离级别:
    select @@tx_isolation;
  • 在MySQL数据库中设置事务的隔离 级别:
    set [glogal | session] transaction isolation level 隔离级别名称;
    set tx_isolation=’隔离级别名称;’

5.8 注意事项

  • 隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
  • 对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

6.Mysql锁

6.1锁介绍

  • 数据库锁定机制简单来说就是数据库为了保证数据的一致性而使各种共享资源在被并发访问访问变得有序所设计的一种规则。

  • 对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自然也不能例外。

  • MySQL数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎所针对的应用场景特点都不太一样,为了满足各自特定应用场景的需求,每种存储引擎的锁定机制都是为各自所面对的特定场景而优化设计,所以各存储引擎的锁定机制也有较大区别。

  • 总的来说,MySQL各存储引擎使用了三种类型(级别)的锁定机制:行级锁定,页级锁定和表级锁定。下面我们先分析一下MySQL这三种锁定的特点和各自的优劣所在。

6.2 行级锁定

行级锁定最大的特点就是锁定对象的颗粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的。由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力而提高一些需要高并发应用系统的整体性能。
虽然能够在并发处理能力上面有较大的优势,但是行级锁定也因此带来了不少弊端。由于锁定资源的颗粒度很小,所以每次获取锁和释放锁需要做的事情也更多,带来的消耗自然也就更大了。此外,行级锁定也最容易发生死锁。

6.3 表级锁定
和行级锁定相反,表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。该锁定机制最大的特点是实现逻辑非常简单,带来的系统负面影响最小。所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题。
当然,锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高,致使并大度大打折扣。

6.4 页级锁定
页级锁定是MySQL中比较独特的一种锁定级别,在其他数据库管理软件中也并不是太常见。页级锁定的特点是锁定颗粒度介于行级锁定与表级锁之间,所以获取锁定所需要的资源开销,以及所能提供的并发处理能力也同样是介于上面二者之间。另外,页级锁定和行级锁定一样,会发生死锁。

6.5 表级锁

  • MySQL的表级锁定有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。
  • MySQL 实现的表级锁定的争用状态变量:show status like ‘table%’;
    Mysql知识总结_第19张图片
  • table_locks_immediate:产生表级锁定的次数;
  • table_locks_waited:出现表级锁定争用而发生等待的次数;

6.5.1 手动增加表锁

 lock table 表名称 read(write),表名称2 read(write),其他;

6.5.2 查看表锁状况

show open tables;

6.5.3 删除表锁

unlock tables;

6.6 读锁演示
Mysql知识总结_第20张图片
Mysql知识总结_第21张图片
在这里插入图片描述

6.7写锁演示
Mysql知识总结_第22张图片
Mysql知识总结_第23张图片

6.8 InnoDB引擎的锁机制

共享锁(S读锁):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
排他锁(X写锁):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。
意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。
说明:
1)共享锁和排他锁都是行锁,意向锁都是表锁,应用中我们只会使用到共享锁和排他锁,意向锁是mysql内部使用的,不需要用户干预。
2)对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会加任何锁,事务可以通过以下语句显示给记录集加共享锁或排他锁。
共享锁(S):SELECT * FROM table_name WHERE … LOCK IN SHARE MODE。
排他锁(X):SELECT * FROM table_name WHERE … FOR UPDATE。
3)InnoDB行锁是通过给索引上的索引项加锁来实现的,因此InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!。

6.9 InnoDB行锁演示

mysql> create table test_innodb_lock (a int(11),b varchar(16)) engine=innodb;
Query OK, 0 rows affected (0.02 sec)

mysql> create index test_innodb_a_idx on test_innodb_lock(a);
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql> create index test_innodb_lock_b_idx on test_innodb_lock(b);
Query OK, 11 rows affected (0.01 sec)
Records: 11 Duplicates: 0 Warnings: 0

行锁基本演示 Session a Session b
1 mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec) mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec)
mysql> update test_innodb_lock set b = ‘b1’ where a = 1;Query OK, 1 row affected (0.00 sec)Rows matched: 1 Changed: 1 Warnings: 0 更新,但是不提交
2 mysql> update test_innodb_lock set b = ‘b1’ where a = 1;被阻塞,等待
3 mysql> commit; Query OK, 0 rows affected (0.05 sec) 提交
4 mysql> update test_innodb_lock set b = ‘b1’ where a = 1;Query OK, 0 rows affected (36.14 sec)Rows matched: 1 Changed: 0 Warnings: 0 解除阻塞,更新正常进行
无索引升级为表锁演示
5 mysql> update test_innodb_lock set b = ‘2’ where b = 2000;Query OK, 1 row affected (0.02 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update test_innodb_lock set b = ‘3’ where b = 3000;被阻塞,等待
6
7 mysql> commit; Query OK, 0 rows affected (0.10 sec)
8 mysql> update test_innodb_lock set b = ‘3’ where b = 3000;Query OK, 1 row affected (1 min 3.41 sec) Rows matched: 1 Changed: 1Warnings: 0阻塞解除,完成更新
间隙锁带来的插入问题演示
9 mysql> update test_innodb_lock set b = a * 100 where a < 4 and a > 1;Query OK, 1 row affected (0.02 sec) Rows matched: 1 Changed: 1 Warnings: 0
10 mysql> insert into test_innodb_lock values(2,‘200’);被阻塞,等待
11 mysql> commit;Query OK, 0 rows affected (0.02 sec)
12 mysql> insert into test_innodb_lock values(2,‘200’);Query OK, 1 row affected(38.68 sec)阻塞解除,完成插入
使用共同索引不同数据的阻塞示例
13 mysql> update test_innodb_lock set b = ‘bbbbb’ where a = 1 and b = ‘b2’;Query OK,1 row affected (0.00 sec)Rows matched: 1 Changed: 1 Warnings: 0
14 mysql> update test_innodb_lock set b = ‘bbbbb’ where a = 1 and b = ‘b1’; 被阻塞
15 mysql> commit;Query OK, 0 rows affected (0.02 sec)
16 mysql> update test_innodb_lock set b = ‘bbbbb’ where a = 1 and b = ‘b1’; Query OK, 1 row affected (42.89 sec)Rows matched: 1 Changed: 1 Warnings: 0session 提交事务,阻塞去除,更新完成
死锁事例
17 mysql> update t1 set id = 110 where id = 11;Query OK, 0 rows affected (0.00 sec)Rows matched: 0 Changed: 0 Warnings: 0
18 mysql> update t2 set id = 210 where id = 21;Query OK, 1 row affected (0.00 sec)Rows matched: 1 Changed: 1 Warnings: 0
19 mysql>update t2 set id=2100 where id=21;等待sessionb释放资源,被阻塞
20 mysql>update t1 set id=1100 where id=11;Query OK,0 rows affected (0.39sec)Rows matched: 0 Changed: 0 Warnings:0等待sessiona释放资源,被阻塞
两个 session 互相等等待对方的资源释放之后才能释放自己的资源,造成了死锁

7.集群搭建之主从复制

  1. mysql主从复制原理

    • master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;
    • slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件
    • 同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。
  2. 主从复制实践

  • 主服务器配置
    • 第一步:修改my.conf文件:
      在[mysqld]段下添加:
      #启用二进制日志
      log-bin=mysql-bin
      #服务器唯一ID,一般取IP最后一段
      server-id=133

    • 第二步:重启mysql服务
      service mysqld restart

    • 第三步:建立帐户并授权slave
      mysql>GRANT FILE ON . TO ‘backup’@’%’ IDENTIFIED BY ‘123456’;
      mysql>GRANT REPLICATION SLAVE, REPLICATION CLIENT ON . to ‘backup’@’%’ identified by ‘123456’;
      #一般不用root帐号,“%”表示所有客户端都可能连,只要帐号,密码正确,此处可用具体客户端IP代替,如192.168.145.226,加强安全。
      刷新权限
      mysql> FLUSH PRIVILEGES;
      查看mysql现在有哪些用户
      mysql>select user,host from mysql.user;

    • 查询master的状态
      mysql> show master status;

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
| mysql-bin.000001 | 120 | db1 | mysql | |

  • 从服务器配置

    • 第一步:修改my.conf文件
      [mysqld]
      server-id=134
    • 第二步:删除UUID文件
      错误处理:如果出现此错误:
      Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.
      因为是mysql是克隆的系统所以mysql的uuid是一样的,所以需要修改。
      解决方法:
      删除/var/lib/mysql/auto.cnf文件,重新启动服务。
    • 第三步:配置从服务器
      mysql>change master to master_host=‘192.168.25.134’,master_port=3306,master_user=‘backup’,master_password=‘123456’,master_log_file=‘mysql-bin.000001’,master_log_pos=120

注意语句中间不要断开,master_port为mysql服务器端口号(无引号),master_user为执行同步操作的数据库账户,“120”无单引号(此处的120就是show master status 中看到的position的值,这里的mysql-bin.000001就是file对应的值)。

  • 第四步:启动从服务器复制功能
    mysql>start slave;
  • 第五步:检查从服务器复制功能状态:
    show slave status

Slave_IO_Running: Yes //此状态必须YES
Slave_SQL_Running: Yes //此状态必须YES

注:Slave_IO及Slave_SQL进程必须正常运行,即YES状态,否则都是错误的状态

8.集群搭建之读写分离

  1. MySQL-Proxy下载

  2. MySQL-Proxy安装

    • 上传压缩包
    • 解压缩
  3. MySQL-Proxy配置

    • 创建mysql-proxy.cnf文件
      Mysql知识总结_第24张图片
    • 修改rw-splitting.lua脚本
  4. MySQL-Proxy启动域测试

mysql-proxy --defaults-file=mysql-proxy.cnf配置文件的地址
注意事项:如果没有配置profile文件的环境变量,则需要去拥有mysql- proxy命令的目录通过./mysql-proxy进行启动。

9.分库分表之MyCat实现

  1. mycat是什么

    • 一个彻底开源的,面向企业应用开发的“大数据库集群”
    • 支持事务、ACID、可以替代Mysql的加强版数据库
    • 一个可以视为“Mysql”集群的企业级数据库,用来替代昂贵的Oracle集群
    • 一个融合内存缓存技术、Nosql技术、HDFS大数据的新型SQL Server
    • 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
    • 一个新颖的数据库中间件产品

    MyCAT的目标是:低成本的将现有的单机数据库和应用平滑迁移到“云”端,解决数据存储和业务规模迅速增长情况下的数据瓶颈问题。

  2. MyCAT的关键特性

  • 支持 SQL 92标准
  • 支持Mysql集群,可以作为Proxy使用
  • 支持JDBC连接ORACLE、DB2、SQL Server,将其模拟为MySQL Server使用
  • 支持galera for mysql集群,percona-cluster或者mariadb cluster,提供高可用性数据分片集群
  • 自动故障切换,高可用性
  • 支持读写分离,支持Mysql双主多从,以及一主多从的模式
  • 支持全局表,数据自动分片到多个节点,用于高效表关联查询
  • 支持独有的基于E-R 关系的分片策略,实现了高效的表关联查询
  • 多平台支持,部署和实施简单
  1. Mycat架构

Mysql知识总结_第25张图片
如图所示:MyCAT使用Mysql的通讯协议模拟成了一个Mysql服务器,并建立了完整的Schema(数据库)、Table (数据表)、User(用户)的逻辑模型,并将这套逻辑模型映射到后端的存储节点DataNode(MySQL Instance)上的真实物理库中,这样一来,所有能使用Mysql的客户端以及编程语言都能将MyCAT当成是Mysql Server来使用,不必开发新的客户端协议。

  1. Mycat解决的问题
  • 性能问题
  • 数据库连接过多
  • E-R分片难处理
  • 可用性问题
  • 成本和伸缩性问题

Mysql知识总结_第26张图片

  1. 分片策略
    MyCAT支持水平分片与垂直分片:
    • 水平分片:一个表格的数据分割到多个节点上,按照行分隔。
    • 垂直分片:一个数据库中多个表格A,B,C,A存储到节点1上,B存储 到节点2上,C存储到节点3上。
      Mysql知识总结_第27张图片
      MyCAT通过定义表的分片规则来实现分片,每个表格可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法。
  • Schema:逻辑库,与MySQL中的Database(数据库)对应,一个逻辑库中定义了所包括的Table。
  • Table:表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表格需要声明其所存储的逻辑数据节点DataNode。在此可以指定表的分片规则。
  • DataNode:MyCAT的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过DataSource来关联到后端某个具体数据库上
  • DataSource:定义某个物理库的访问地址,用于捆绑到Datanode上
  1. Mycat的下载及安装

    • 下载mycat
      github地址
      https://github.com/MyCATApache

    • Mycat安装

      第一步:把MyCat的压缩包上传到linux服务器
      第二步:解压缩,得到mycat目录
      第三步:进入mycat/bin,启动MyCat
      启动命令:./mycat start
      停止命令:./mycat stop
      重启命令:./mycat restart

注意:可以使用mysql的客户端直接连接mycat服务。默认服务端口为8066

  1. Mycat分片
    • 需求
      把商品表分片存储到三个数据节点上。
    • 配置schema.xml

Schema.xml作为MyCat中重要的配置文件之一,管理着MyCat的逻辑库、表、分片规则、DataNode以及DataSource。弄懂这些配置,是正确使用MyCat的前提。这里就一层层对该文件进行解析。

  • schema 标签用于定义MyCat实例中的逻辑库

  • Table 标签定义了MyCat中的逻辑表

  • dataNode 标签定义了MyCat中的数据节点,也就是我们通常说所的数据分片。

  • dataHost标签在mycat逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句。

    1. 配置schema.xml


	
select user() select user()

  1. Server.xml配置

Mysql知识总结_第28张图片

  1. 配置rule.xml
    rule.xml里面就定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法,或者对表使用相同的算法但具体的参数不同。这个文件里面主要有tableRule和function这两个标签。在具体使用过程中可以按照需求添加tableRule
    和function。
    此配置文件可以不用修改,使用默认即可。

  2. 分片测试

  • mysql客户端连接mycat,创建表。
  • 将文件中的数据插入到数据库。
  • 由于配置的分片规则为“auto-sharding-long”,所以mycat会根据此规则自动分片。每个datanode中保存一定数量的数据。根据id进行分片Datanode1:1~5000000
    Datanode2:5000000~10000000
    Datanode3:10000001~15000000

Mysql知识总结_第29张图片
Mycat读写分离和自动切换机制,需要mysql的主从复制机制配合。

  1. Mycat主从复制和读写分离配置
    Mysql知识总结_第30张图片
    Mysql知识总结_第31张图片
    • 设置 balance="1"与writeType=“0”

Balance参数设置:

  • balance=“0”, 所有读操作都发送到当前可用的writeHost上。
  • balance=“1”,所有读操作都随机的发送到readHost。
  • balance=“2”,所有读操作都随机的在writeHost、readhost上分发

WriteType参数设置:

  • writeType=“0”, 所有写操作都发送到可用的writeHost上。
  • writeType=“1”,所有写操作都随机的发送到readHost。
  • writeType=“2”,所有写操作都随机的在writeHost、readhost分上发。
    “readHost是从属于writeHost的,即意味着它从那个writeHost获取同步数据,因此,当它所属的writeHost宕机了,则它也不会再参与到读写分离中来,即“不工作了”,这是因为此时,它的数据已经“不可靠”了。基于这个考虑,目前mycat 1.3和1.4版本中,若想支持MySQL一主一从的标准配置,并且在主节点宕机的情况下,从节点还能读取数据,则需要在Mycat里配置为两个writeHost并设置banlance=1。”
  1. 设置 switchType=“2” 与slaveThreshold=“100”
    switchType 目前有三种选择:
    -1:表示不自动切换
    1 :默认值,自动切换
    2 :基于MySQL主从同步的状态决定是否切换
    “Mycat心跳检查语句配置为 show slave status ,dataHost 上定义两个新属性: switchType=“2” 与slaveThreshold=“100”,此时意味着开启MySQL主从复制状态绑定的读写分离与切换机制。Mycat心跳机制通过检测 show slave status 中的 “Seconds_Behind_Master”, “Slave_IO_Running”, “Slave_SQL_Running” 三个字段来确定当前主从同步的状态以及Seconds_Behind_Master主从复制时延。“

8.分库分表所带来的问题

  • 跨库join问题

通过业务分析,将不同库的join查询拆分成多个select

建立全局表(每个库都有一个相同的表)

冗余字段(不符合数据库三范式)

E-R分片(将有关系的记录都存储到一个库中)

最多支持跨两张表跨库的join

分布式事务(弱事务)

强一致性事务(同步)

最终一致性事务(异步思想)

分布式主键

redis incr命令

数据库(生成主键)

UUID

你可能感兴趣的:(数据储存,mysql)