InnoDB

mysql优化:覆盖索引(延迟关联)

孤者浪人 提交于 2020-12-22 06:50:16
前言 上周新系统改版上线,上线第二天就出现了较多的线上 慢sql 查询,紧接着dba 给出了定位及解决方案,这里较多的是使用 延迟关联 去优化。 而我对于这个 延迟关联 也是第一次听说(o(╥﹏╥)o),所以今天一定要学习并产出一篇学习笔记。( ^▽^ ) 回表 我们都知道InnoDB采用的B+ tree来实现索引的,索引又分为主键索引(聚簇索引)和普通索引(二级索引)。 那么我们就来看下 基于主键索引和普通索引的查询有什么区别? 如果语句是select * from T where ID=500,即主键查询方式,则只需要搜索ID这棵B+树; 如果语句是select * from T where k=5,即普通索引查询方式,则需要先搜索k索引树,得到ID的值为500,再到ID索引树搜索一次。这个过程称为回表。 举个栗子: 可以看出我们有一个普通索引k,那么两颗B+树的示意图如下: (注:图来自极客时间专栏) 当我们查询 select * from T where k=5 其实会先到k那个索引树上查询k = 5,然后找到对应的id为500,最后回表到主键索引的索引树找返回所需数据。 如果我们查询 select id from T where k=5 则不需要回表就直接返回。 也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。 覆盖索引 解释一

记一次死锁分析过程

﹥>﹥吖頭↗ 提交于 2020-12-21 14:29:03
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction ### The error may involve com.cgd.order.dao.OrderSaleMapper.updateSaleOrderStatus-Inline ### The error occurred while setting parameters ### SQL: update t_order set ORDER_STATUS = ? where ORDER_ID = ? 小盆友,如果你在日志里看到这个是不是像我一样会有很多问号?? 我一个只会写增删改查sql的低层次程序员有了满奶子问号。 但是我相信啊:只要功夫深,李白碰到的老婆婆就能把铁杵磨成针。 1.首先是要了解一些除了增删改查之外的数据库基础知识 从极客上找了门MySQL实战,如果你也想买,请联系我,推荐人买有返现的。 这门课我是觉得很值,这两天为了解决这个死锁又读了一遍有关加锁的章节,发现了一条命令啊,这个命令会输出很多信息,有一节 LATESTDETECTED

MySQL 日志(redo log 和 undo log) 都是什么鬼?

拟墨画扇 提交于 2020-12-21 14:23:34
作者:骏马金龙 出处: https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html innodb事务日志包括redo log和undo log。redo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作。 undo log不是redo log的逆向过程,其实它们都算是用来恢复的日志: 1.redo log通常是物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成怎样怎样,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。 2.undo用来回滚行记录到某个版本。undo log一般是逻辑日志,根据每行记录进行记录。 1.redo log 1.1 redo log和二进制日志的区别 redo log不是二进制日志。虽然二进制日志中也记录了innodb表的很多操作,**也能实现重做的功能,但是它们之间有很大区别。 二进制日志是在 存储引擎的上层 产生的,不管是什么存储引擎,对数据库进行了修改都会产生二进制日志。而redo log是innodb层产生的,只记录该存储引擎中表的修改。 并且二进制日志先于redo log 被记录。具体的见后文group commit小结。 二进制日志记录操作的方法是逻辑性的语句。即便它是基于行格式的记录方式

数据库避免插入重复数据需求解决:MySQL之insert、insert ignore、replace和insert into on duplicate key update区别

为君一笑 提交于 2020-12-20 00:41:55
背景 最近在做项目的时候,简单的后台增删改查,但是每次在做新增数据操作的时候,都需要校验一次数据库中是否存在相同的数据(唯一索引字段),起初同时的做法是每次按照唯一主键作为条件去数据库中进行查询,如果存在,则不进行insert操作,如果不存在,则进行insert操作,这样做有两个弊端: 每次进行insert操作之前都会有一步select操作,我们知道,数据库的io是比较耗性能的,尤其是在数据量比较大的情况下; 本人想偷懒,每次去查询太繁琐; 在并发场景下同意出问题,除非加锁(目前还没有这个场景,博主未验证~) 那么到底有没有什么比较爽的方式可以解决这样的问题呢? 答案是当然的! 下面就来看看博主总结的几种方式,大家可以根据情况自行选取: 1.insert 2.insert ignore 3.replace 4.insert into on duplicate key update 测试代码 创建表 CREATE TABLE `test` ( `id` int NOT NULL AUTO_INCREMENT, `username` varchar(255) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, `age` int DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `index

MySQL 日志系统之 redo log 和 binlog

微笑、不失礼 提交于 2020-12-19 18:42:26
之前我们了解了一条查询语句的执行流程,并介绍了执行过程中涉及的处理模块。一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎。 那么,一条 SQL 更新语句的执行流程又是怎样的呢? 首先我们创建一个表 user_info,主键为 id,创建语句如下: CREATE TABLE `T` ( `ID` int(11) NOT NULL, `c` int(11) DEFAULT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 插入一条数据: INSERT INTO T VALUES ('2', '1'); 如果要将 ID=2 这一行的 c 的值加 1,SQL 语句为: UPDATE T SET c = c + 1 WHERE ID = 2; 前面介绍过 SQL 语句基本的执行链路,这里把那张图拿过来。因为,更新语句同样会走一遍查询语句走的流程。 通过连接器,客户端与 MySQL 建立连接 update 语句会把 T 表上的所有查询缓存结果清空 分析器会通过词法分析和语法分析识别这是一条更新语句 优化器会决定使用 ID 这个索引(聚簇索引) 执行器负责具体执行,找到匹配的一行,然后更新 更新过程中还会涉及 redo log(重做日志)和 binlog(归档日志)的操作

讲真!这些攻击手段你知道吗

你说的曾经没有我的故事 提交于 2020-12-19 15:46:52
世界上最快的捷径,就是脚踏实地,本文已收录【架构技术专栏】关注这个喜欢分享的地方。 网站安全 从从互联网发展开始,各种网络安全问题也就伴随而生。 近些年来有很多网站遭到攻击,如新浪微博遭XSS攻击,以CSDN为代表的多个网站泄露用户密码和个人信息。 特别是后者,因为影响人群广泛,部分受影响网站涉及用户实体资产和交易安全,一时成为舆论焦点。 那么新浪微博是如何被攻击的?CSDN的密码为何会泄露?如何防护网站免遭攻击,保护好用户的敏感信息呢? 常见的攻击与防御 XSS攻击,它和SQL注入攻击构成网站应用攻击最主要的两种手段,全球大约70%的Web应用攻击都来自XSS攻击和SQL注入攻击。此外,常用的Web应用还包括CSRF、Session劫持等手段。 XSS攻击 XSS攻击又称CSS,全称Cross Site Script (跨站脚本攻击),其原理就是攻击者像有XSS漏洞的网站注入恶意HTML脚本,在用户浏览网页时,这段恶意的HTML 脚本会自动执行,从而达到攻击的目的。 常见的XSS攻击类型: 反射型,通过在请求地址上加入恶意的HTML代码 dom型 ,通过一些API向网站注入恶意HTML 持久型,将恶意代码内容发给服务器,服务器没过滤就存储到数据库中了,下次再请求这个页面时就会从数据库中读取出恶意代码拼接到页面HTML上 1、反射型XSS攻击 攻击步骤: 1

震惊,小白看了都知道的!!Mysql6000w数据表的查询优化到0.023S

柔情痞子 提交于 2020-12-19 11:02:37
前言 很抱歉现在才把这篇文章发出来,这几天事情比较多,周四把任务完成才得空写一写,闲话不多说请看下↓↓↓ 详细需求 需求: 系统中有一个专门存车流量的库(没有主键),其中一个历史表数据量太大,表空间占据太大,每天有500w的数据写入,然后老大给我安排了个任务,让我写个按天分表的定时任务,每次把一天的数据转移到按天生成的表中,并删除原表中的数据,主要目的是不想再增长表空间了,保持一个平衡,因为每天删500w也会加500w 表空间和数据量: 实现思路 我本人实现的做法流程,如图 实现伪代码(删减了部分代码): /** * 转移数据 每天凌晨3点 每次只能转移一天的数据 */ @Scheduled ( cron = "0 0 3 * * ?" ) public void dataTransfer ( ) throws Exception { System . out . println ( "定时器开始运行------------------------------------------" ) ; String tabaleName = "XXX" ; String isTable = getTableName ( tabaleName ) ; // 当返回为空时,代表该表不存在,则创建 if ( ObjectUtils . isNull ( isTable ) ) {

MySQL 事务隔离级别

混江龙づ霸主 提交于 2020-12-19 10:39:35
一、事务描述 1、事务的四个特性 ACID   1. A:原子性 = 一个事务或者都成功、或者都失败;   2. C:一致性 = 在整个事务的生命周期里面,查询到的数据是一致的;     MVCC多版本并发控制:利用undo保存某一时刻数据快照,通过版本号来减少锁的争用,保证各个事务互不影响。    3. I: 隔离性 = 隔离级别;   4. D:持久性 = 只要事务commit,这个事务不会因为系统的崩溃而丢失;    持久性和原子性对于所有的支持事务的数据库都是一样的,都满足。 2、常见事务格式 start transaction;   DML ( insert; delete; update; ) commit; 3、MySQL 默认每一条 DML 是一个事务   通过参数 'autocommit' 进行控制是否默认提交事务; mysql > show variables like ' autocommit ' ; + -- -------------+-------+ | Variable_name | Value | + -- -------------+-------+ | autocommit | ON | + -- -------------+-------+ 1 row in set ( 0.01 sec)    SQL 自动提交开启,有一定的危险性(没有

MySQL 8.0.22 GA!

大憨熊 提交于 2020-12-19 08:28:23
作者: Geir Hoydalsvik 翻译:管长龙 本文来源:原文翻译 *爱可生开源社区出品 ,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 MySQL 开发团队非常高兴地宣布,MySQL 8.0.22 现在可以下载了。除了 Bug 的修复,此版本中还添加了一些新功能。可以在 8.0.22 发行说明中找到更改和错误修复的完整列表。以下是该版本主要更新。 Perpared Statements 每个 DML 语句预处理一次(WL#9384) Perpared 语句只在 Perpare 时准备一次,而不是在每次执行时准备一次。同样,存储过程中的语句也将在第一次执行时准备一次。 这项工作的好处是: 性能增强:避免每次执行时进行昂贵的准备; 简化代码:避免繁琐的准备结构回滚。 SHOW PROCESSLIST 重新实现 SHOW PROCESSLIST(WL#9090) SHOW PROCESSLIST 将作为 PERFORMANCE_SCHEMA 中 processlist 表的视图实现,从 Performance Schema 而不是线程管理器中查询活动线程数据。当前的实现在保持全局互斥的同时,从线程管理器中跨活动线程进行迭代,这在繁忙的系统上可能是令人讨厌的。从 Performance Schema 中聚合相同的信息不会以任何方式影响用户负载。 可以通过系统变量: -

MySQL的事务和并发问题浅析

依然范特西╮ 提交于 2020-12-19 05:03:29
数据库的事务(Transaction)处理技术是很重要的概念,下面结合MySQL讲讲自己对这类概念的理解。 一、事务的基本概念 所谓事务是用户定义的、不可分割的一组操作序列,这些操作只能全做或全都不做,不能存在中间状态。涉及到用户定义,MySQL为我们提供了三种定义事务的语句: start transaction | begin # 开始一个新事务 commit # 提交当前事务,并将修改持久化到数据库 rollback # 回滚当前事务,取消所有操作 而MySQL初始设置会将autocommit(自动提交)设置为1,表示用户对数据库的每个操作都作为一个事务自动提交,仅当使用 start transaction 或 begin 开始一个新事务后,autocommit才会临时失效,直到出现事务结束语句(commit | rollback)。(在事务未结束之前开启另一个新事务会自动commit) 注意:DDL语句是不能回滚的,包括create、drop、alter等。 二、事务的四个特性 事务具有4个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),简称ACID特性。 原子性:事务作为数据库的逻辑工作单位,是不可分割的,事务内的操作要么全做,要么全不做。 一致性