关于Mysql(5.6)的一些思考

事物级别

  • MySQL 默认事物级别是可重复读;Oracle默认为读已提交
>> SELECT @@global.tx_isolation; 
>> REPEATABLE-READ
  • 事务级别的优先级:
    1:读未提交
直接返回记录行上的最新记录;没有视图的概念

2:读已提交

视图是在每个sql语句开始时创建的。

3:可重复读

事物开启会建立视图,依据视图做到事务隔离

4:串行化

读写均加锁来实现

5:事务隔离的实现-可重复度级别


回滚日志.png
实际上每条记录在更新的时候都会同时记录一条回滚操作。记录上的最新值,通过回滚操作,都可以得到前一个状态的值。建议尽量不要写长事物。

6:查找时间超过 60s的事物

select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>=60;

7: 没有特殊逻辑;尽量不要对Read进行事务管理
性能测试如下:https://www.percona.com/blog/2019/07/15/mysql-the-impact-of-transactions-on-query-throughput/

Impact-of-Transactions.png

一条查询SQL的执行计划

逻辑架构图.png

Mysql大致可以分为Server层和存储引擎层
1:连接器

负责跟客户端建立连接、获取权限、维持和管理连接:
例如如下:
mysql -h$ip -P$port -u$user -p
mysql> show processlist;
+-----+-------------+---------------------------------------------+-------------+---------+--------+-----------------------------------------------------------------------------+------------------+
| Id  | User        | Host                                        | db          | Command | Time   | State                                                                       | Info             |
+-----+-------------+---------------------------------------------+-------------+---------+--------+-----------------------------------------------------------------------------+------------------+
|   1 | system user |                                             | NULL        | Connect | 173583 | Waiting for master to send event                                            | NULL             |
|   2 | system user |                                             | NULL        | Connect |     -1 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL             |
|  63 | demo        | bjwfj-67p109-mediaforce-42.bfdabc.com:61820 | bfd_mf_data | Sleep   |     16 |                                                                             | NULL             |
| 118 | root        | localhost                                   | NULL        | Query   |      0 | init                                                                        | show processlist |
+-----+-------------+---------------------------------------------+-------------+---------+--------+-----------------------------------------------------------------------------+------------------+
对 druid中链接数进行查看如下:
当前连接池中的数目:1
这里涉及到一个问题,如果客户端太长时间没动静,连接器会自动断开,这个参数是由参数:wait_timeout控制,默认是 8 小时。目前业务端是基于连接池的,本省就是就可以控制connection的活跃数目;所以可将该值调整为 24小时。避免 Lost Connection to Mysql server during query 的异常;当然这里也存在问题;如果客户端Connection异常关闭,那么Mysql 端的连接也去就无法释放;所以有更加优雅的方式:
1: 定期断开长连接
2: Mysql 5.7+ 支持 mysql_reset_connection 来重新初始化链接

2:查询缓存

缓存的 key就是查询语句,Value就是缓存的行记录。但是大多数情况下不建议使用查询缓存,因为查询缓存往往弊大于利。缓存失效非常频繁,只要对一个表的更新,这表上所有的查询缓存都会清空。Mysql提供啦一种按需使用的方式,可以将 query_cache_type设置为DEMAND,这样默认的查询语句都不会使用缓存;可以显示指定SQL_CACHE 参数:
mysql> select SQL_CACHE * from T where ID=10;
Mysql8.0 已彻底将该功能移除并废弃掉

3:分析器

分析器做的就是词法分析,检验sql语句的合法性

4:优化器

优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。

5:执行器

MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。经常看到的rows_examined 就是执行中的指标。

一条更新Sql的执行计划

1:redo log


redo log.png
 redo log 是innoDB引擎特有的日志。redo log其实就是Mysql中经常提到的WAL(Write-Ahead Logging)技术;关键点就是先写日志,在写磁盘,这样就大大降低啦磁盘的IO成本、查找成本。

2: binlog
binlog(归档日志)服务于server层,是逻辑日志,记录的是该语句的原始逻辑,同时是可以追加写;达到一定文件大小后会切换到下一个。
3:update 执行流程图


update流程图.png
这个就涉及到Mysql的两阶段提交事务

索引

1: 覆盖索引

目的是优化索引查询; 减少回表次数
eg:
select id from t where index_age between 2 and 5; # 查询的Id已经在索引index_age树上,不需要回表
同时假如你的业务有大量的类似于:依据 身份证号查找姓名;其实可以 为 身份证号 + 姓名为联合索引;极大的减少回表需求 

2: 最左前缀原则

最左前缀原则的实现是依据 B+树索引来实现的
(name,age)索引示意图.jpg

3: 索引下推
而 MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数;

你可能感兴趣的:(关于Mysql(5.6)的一些思考)