InnoDB

详解聚簇索引

こ雲淡風輕ζ 提交于 2020-10-02 16:09:46
一、聚族索引的构造 聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。具体的细节依赖于其实现方式,但InnoDB的聚族索引实际上在同一个结构中保存了B-Tree索引和数据行。当表有聚族索引时,它的数据行存放在索引的叶子页中。术语“聚族”表示数据行和相邻的键值紧凑的存储在一起。因为无法同时把数据行放在两个不同的地方,所以一个表只能有一个聚族索引。 因为是存储引擎负责实现索引,因此不是所有的存储引擎都支持聚族索引。这里我们主要关注InnoDB,但是这里讨论的原理对于任何支持聚族索引的存储引擎都是适用的。 下面展示了聚族索引中的记录是如何存放的。注意到,叶子页包含了行的全部数据,但是节点页只包含了索引列。 在InnoDB中通过主键聚集数据,这也就是说上图中“被索引的列”就是主键列。如果没有定义主键,InnoDB会选择一个唯一的非空索引代替。如果没有这样的索引,InnoDB会隐式定义一个主键来作为聚族索引。InnoDB只聚集在同一个页面中的记录。包含相邻键的页面可能会相距甚远。 聚族主键可能对性能有帮助,但也可能导致严重的性能问题。所以需要仔细的考虑聚族索引,尤其是将表的引擎从InnoDB改成其他引擎的时候。 二、聚族索引的优点 可以把相关数据保存在一起。例如实现电子邮件时,可以根据用户ID来聚集数据,这样只需要从磁盘读取少数的数据页就能获取某个用户的全部邮件。如果没有使用聚族索引

详解MySQL数据类型

大兔子大兔子 提交于 2020-10-02 15:51:08
原文地址http://www.cnblogs.com/xrq730/p/5260294.html,转载请注明出处,谢谢! 前言 很久没写文章,也有博友在我的有些文章中留言,希望我可以写一些文章,公司项目一直很忙,但是每天也尽量腾出一些时间写一些东西,主要针对工作中一些常用的知识点系统性的梳理(可能我们在工作中只是纯粹的使用而已,不会去进行总结、归纳)。 本文写的内容是MySQL数据类型,之前写MySQL系列文章的时候一直忽略的一个知识点,现在想来,我们学习一门语言,无非从两个方面入手: 基本语法,有了语法,我们才可以组织逻辑 数据类型,即在特定场景下选择合适的数据类型,到底是用整型还是浮点型还是字符串,每种数据机构占多少字节,最大值是多少。这点只针对强类型的语言,像js这种弱类型的语言,是不需要考虑这一点的 希望通过一篇文章的梳理,可以把MySQL数据结构这块都归纳清楚。 整型 先从最基本的数据类型整型说起,首先用一张表格归纳一下: 数据类型 字节数 带符号最小值 带符号最大值 不带符号最小值 不带符号最大值 TINYINT 1 -128 127 0 255 SMALLINT 2 -32768 32767 0 65535 MEDIUMINT 3 -8388608 8388607 0 16777215 INT 4 -2147483648 2147483647 0 4294967295

故障分析 | MySQL 优化案例

泪湿孤枕 提交于 2020-10-02 08:38:39
作者:xuty 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 本文关键字:SQL 优化、字符集 一、背景 Server version: 5.7.24-log MySQL Community Server (GPL) 开发联系我,说是开发库上有一张视图查询速度很慢,9000 条数据要查 10s,要求我这边协助排查优化。 二、问题 SQL 这个 SQL 非常简单,定义如下,其中就引用了 view_dataquality_analysis 这张视图,后面跟了两个 where 条件,并且做了分页。 SELECT * FROM view_dataquality_analysis WHERE modelguid = '710adae5-1900-4207-9864-d53ee3a81923' AND configurationguid = '6845d000-cda4-43ea-9fd3-9f9f1f22f95d' limit 20; 我们先去开发库上运行一下这条 SQL,下图中可以看到确实运行很慢,要 8s 左右。 三、执行计划 分析一条慢 SQL,最有效的方法便是分析它的执行计划,看是否存在问题。 下面我们看下这条 SQL 的执行计划,主要由三张表(t、r、b)组成,从 t 开始嵌套连接 r ,再嵌套连接 b 。整个执行逻辑很简单

死锁案例五

拟墨画扇 提交于 2020-10-02 01:32:17
来源:公众号yangyidba 一、前言 死锁其实是一个很有意思也很有挑战的技术问题,大概每个 DBA 和部分开发朋友都会在工作过程中遇见。关于死锁我会持续写一个系列的案例分析,希望能够对想了解死锁的朋友有所帮助。本文是源于生产过程中一个死锁案例。 二、背景知识 官方文档[1]中表述: "REPLACE is done like an INSERT if there is no collision on a unique key. Otherwise, an exclusive next-key lock is placed on the row to be replaced." "如果没有唯一键冲突的时候,replace 操作和insert的加锁方式是一样的。但是如果有唯一键冲突的话,replace语句执行时,系统会在记录上加上 LOCK X next-key lock。" 如果觉得上面翻译比较简单,就看看下面的介绍[2] create table t1( a int auto_increment primary key, b int, c int, unique key (b)); replace into t1(b,c) values (2,3) Step 1 正常的插入逻辑 首先插入聚集索引,在上例中 a 列为自增列,由于未显式指定,每次 Insert

Zabbix_proxy重启无任何相关进程处理

不问归期 提交于 2020-10-01 17:54:41
一次断电意外导致本地使用中的zabbix_proxy无法正常工作,随即进行排查。 一、 通过系统命令查看proxy状态原以为一切正常,但仔细查看zabbix有关服务时,却没有发现发现相应的proxy端口在使用。如图1、2. 图1 图2 那实际上zabbix_proxy是没在工作的。 二、 对其日志文件进行查看,如图3.查看命令:tail -n 1000 zabbix_proxy.log #筛选最新的1000行数据进行查看。 图3 从最新的几行报错可以出看是数据库连接失败引起的问题。 三、 查看数据库状态,图4. 图4 四、 查看指定目录下的是否有对应sock文件,图5 图5 没该文件。 五、 查看数据库报错日志error.log(查看命令使用了“tail -n 1000 error.log”),图6 #如果不清楚位置可使用命令 find / -name error.log 进行全局查找. 图6 可以尝试在my.cnf中配置相应的参数(>0),而打开数据库。 六、 配置数据库配置文件my.cnf,增加一行innodb_force_recovery = 1 ,如图7 图7 innodb_force_recovery 级别 含义 1 (SRV_FORCE_IGNORE_CORRUPT)忽略检查到的corrupt页 2 (SRV_FORCE_NO_BACKGROUND)阻止主线程的运行

mysql innoDB存储引擎中的锁

做~自己de王妃 提交于 2020-10-01 13:45:34
最近在看mysql技术内幕这本书,分享一些阅读笔记 innoDB存储引擎主要实现了以下两种标准的行级锁: 1、共享锁:允许事务读一行数据。 2、排他锁:允许事务删除或更新一行数据。 如果一个事务T1已经获得了行r的共享锁,那么另外的事务T2可以立即获得行r的共享锁,因为读取并没有改变行r的数据,称这种情况为锁的兼容性,若有事务T3想要获得行r的排他锁,则必须等待T1和T2 释放行r的共享锁,这种情况称为锁的不兼容性 以下列出了排他锁X和共享锁S的兼容情况 我们可以发现X锁与任何的锁都不兼容,而S锁和S锁兼容,需要注意的是,S锁和X锁都是行级锁,兼容是指同一记录锁的兼容情况 innoDB还支持了多粒度锁定,这种锁定允许事务在行级上的锁和表级上的锁同时存在,为了满足不同粒度上的骚操作,innoDB引出了一种额外的锁------意向锁,意向锁将锁定的对象分为多个层次,意味着事务希望在更细粒度上加锁 要想事务在细粒度上加锁,则需要先在粗粒度上加锁,这就好比一棵树,先要有根再发芽,如上图所示,如果需要在记录上加锁,则需要在数据库、表、页上加意向锁,如果任何一个部分导致等待,那么该操作需要等待粗粒度锁的完成 举例来说,如果一个事务在对一个记录做了共享锁,那么此时其他事务需要对同一行记录做排他锁的时候,同一行 记录 所在的表上会有一个意向锁,由于共享锁和排他锁的不兼容性

可用性高达99.999%,跨机房秒级传输的数据同步框架建设实践

半城伤御伤魂 提交于 2020-10-01 12:00:58
一、背景 ​ 随着业务的快速发展,对于很多公司来说,构建于单地域的技术体系架构,会面临诸如下面的多种问题: 基础设施的有限性限制了业务的可扩展性。 业务扩大到单个数据中心撑不住,主要机房已经不能再添加机器,但业务却不断要求扩展; 机房、城市级别的故障灾害,影响服务的可持续性。 整个机房级别的故障时有发生,每次都引起业务的不可用,对公司的形象与收入都造成严重的影响。如2015年杭州某数据中心光缆被挖断,造成某产品业务几个小时的中断,导致严重的损失; 跨地域的访问,影响用户体验等。 随着全球化脚步的逼近,试想用户客户端与服务一次交互,一次RTT最少需要10ms,若广州到北京网络延迟一般为40ms,当用户客户端需要与服务器产生多次交互时,对用户体验影响就很大,用户体验非常不友好。 OPPO互联网业务发展快速,已经扩展到全球,随之带来的是技术上的多机房架构,对数据的全球多机房同步在一致性、响应时间、吞吐等方面有更高要求。 为了解决以上问题带来的影响,本文将从异地多活底层,数据层面探索,如何给上层业务提供一个安全、可靠、稳定的数据环境,让上层业务可以集中精力专注业务开发,减少对数据多活的关注。 1、面临的挑战 数据多地写入的冲突解决问题 远距离两地传输网络问题 同步过程中数据一致性问题 数据同步的幂等性问题 作为同步中心,关于数据复用问题 基于上述挑战,调研对比相关的几个主流开源产品

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

喜夏-厌秋 提交于 2020-10-01 11:38:05
前言 上周新系统改版上线,上线第二天就出现了较多的线上 慢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 则不需要回表就直接返回。 也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。 覆盖索引 解释一

为什么MySQL不推荐使用uuid或者雪花id作为主键?

白昼怎懂夜的黑 提交于 2020-10-01 05:07:33
点击上方“朱小厮的博客”,选择“ 设为星标” 后台回复" 书 ",获取 来源:r6a.cn/bZSY 前言 在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一,单机递增),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究竟有什么坏处? 本篇博客我们就来分析这个问题,探讨一下内部的原因。 一、mysql和程序实例 1.1.要说明这个问题,我们首先来建立三张表 分别是user_auto_key,user_uuid,user_random_key,分别表示自动增长的主键,uuid作为主键,随机key作为主键,其它我们完全保持不变. 根据控制变量法,我们只把每个表的主键使用不同的策略生成,而其他的字段完全一样,然后测试一下表的插入速度和查询速度: 注:这里的随机key其实是指用雪花算法算出来的前后不连续不重复无规律的id:一串18位长度的long值 id自动生成表: 用户uuid表 随机主键表: 1.2.光有理论不行,直接上程序,使用spring的jdbcTemplate来实现增查测试: 技术框架:springboot+jdbcTemplate+junit+hutool,程序的原理就是连接自己的测试数据库,然后在相同的环境下写入同等数量的数据

MySQL热点面试题:为什么我使用了索引,查询还是慢?

ε祈祈猫儿з 提交于 2020-10-01 03:09:07
经常有同学问我,我的一个SQL语句使用了索引,为什么还是会进入到慢查询之中呢?今天我们就从这个问题开始来聊一聊索引和慢查询。 另外插入一个题外话,个人认为团队要合理的使用ORM,可以参考 ORM的权衡和抉择。合理利用的是ORM在面向对象和写操作方面的优势,避免联合查询上可能产生的坑(当然如果你的Linq查询能力很强另当别论),因为ORM屏蔽了太多的DB底层的知识内容,对程序员不是件好事,对性能有极致追求,但是ORM理解不透彻的团队更加要谨慎。 案例剖析 言归正传,为了实验,我创建了如下表: CREATE TABLE `T`( `id` int(11) NOT NULL, `a` int(11) DEFAUT NULL, PRIMARY KEY(`id`), KEY `a`(`a`) ) ENGINE=InnoDB; 该表有三个字段,其中用id是主键索引,a是普通索引。 首先SQL判断一个语句是不是慢查询语句,用的是语句的执行时间。他把语句执行时间跟long_query_time这个系统参数作比较,如果语句执行时间比它还大,就会把这个语句记录到慢查询日志里面,这个参数的默认值是10秒。当然在生产上,我们不会设置这么大,一般会设置1秒,对于一些比较敏感的业务,可能会设置一个比1秒还小的值。 语句执行过程中有没有用到表的索引