逻辑存储结构图

表空间
表空间文件在Linux下存放在 /var/lib/mysql文件中的 xxx.ibd 文件就是表空间文件
表空间文件用来存储,记录,索引等数据。
段
段分为,数据段(Leaf node segment) ,索引段(Non-leaf node segment),回滚段(Rollback segment),InnoDB是索引组织表,数据段就是B+树的叶子节点,索引段就是非叶子节点,段用来管理Extend(区)。
一个段相当于一张表
区
区是表空间的单元结构,每个区大小为1M,默认情况下InnoDB存储引擎页大小为16k,一个区一共16个连续的页。
页
页,是InnoDB存储引擎磁盘管理的最小单元。
每个区默认16KB,为了保证页的连续性,InnoDB存储引擎每次从磁盘申请4到5个区。
行
行指的是InnoDB存储的数据
表结构中俩个隐藏字段
Trx_id:最后一次操作事务的id
Roll pointer:指针,指向增删改之前的数据,可以拿这个找到修改之前的数据。
MySQL5.5版本后,默认使用InoDB存储引擎。
它擅长事务处理,具有崩溃恢复性特性!
下图为InnoDB架构图,左边为内存结构,右边为磁盘结构。


缓冲池是主内存的一个区域,里面可以缓存磁盘上经常操作的真实数据。
在执行增删改查操作的时候,先操作缓存池中的数据(如果没有,从磁盘加载并且缓存)
然后以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度
在缓存池中有一块一块的,这个是页。
缓存池以页为单位,底层采用链表数据结构管理Page。
根据状态将Page分为三类:
介绍
更改缓存区,主要针对非唯一的二级索引。
在执行DML语句时,如果这些数据页不在Buffer Poor中,不会直接操作磁盘,而是将数据变更在更改缓存区Change Buffer中。
在未来数据被读取的时候,再将数据合并恢复到Buffer Pool中,再将合并后的数据刷新到磁盘中。
意义
和聚集索引不同,二级索引是非唯一的!
并且二级索引以相对随机的顺序插入。
同样的删除和更新可能会影响索引树中不相邻的二级索引页,如果每一次都操作磁盘,会造成大量磁盘IO。
有了ChangeBuffer后,我们可以在缓冲池中进行合并处理减少磁盘IO
日志缓存区,用来保存要写入磁盘中的log日志数据(redo log 、undo log)。
默认大小16MB,日志缓存区的日志会定期刷新到磁盘中。如果需要更新、插入、或删除多行的事务,增加日志缓存区大小可以节约磁盘IO
在系统变量中设置即可
关键字:
innodb_log_buffer_size 缓存区大小
innodb_flush_log_at_trx_commit 日志刷新到磁盘的时机
1代表的是日志在每次事务提交时写入并刷新到磁盘
0代表每秒将日志写入并刷新到磁盘一次
2代表日志在每次事务提交后写入,并且每秒刷新到磁盘一次
自适应哈希索引,用于优化Buffer Pool数据的查询。
InnoDB存储引擎会监控表上各索引页的查询,如果观察到hash索引可以提高速度,就会建立hash索引。
这个叫自适应哈希索引
可以在系统变量中查询是否开启自适应哈希索引
关键字是 adaptive_hash_index

系统表空间是change Buffer的存放区域。
关键字:innodb_data_file_path
系统表空间存放路径
存放每个表的独立表空间
默认是开启的-->开启后代表每一张表都会生成对应的表空间文件。
xxx.ibd结尾的文件都是表的表空间文件
查看变量 innodb_file_per_table看是开的还是关的
里面存放了表结构,表数据,索引
通用表空间,需要手动通过
create tablespace 表空间名 add datafile '表空间对应的磁盘文件.ibd' engine=innodb;
创建通用表空间。
在创建表的时候可以指定该表空间
create table 表名(
字段....
)engine=存储引擎 tablespace 表空间名;
撤销表空间,MYSQL实例在初始化的时候会自动创建俩个默认的undo表空间(初始大小16M)用来存放undo log日志
默认叫 undo_001和undo_002
用来存储用户创建的临时表。
双写缓冲区,innoDB存储引擎会将数据页冲Buffer Pool刷新到磁盘前,先将数据页写入双写缓冲区文件中,便于系统异常时恢复数据。
双写缓冲区文件:xxx.dblwr
用来实现事务的持久性。
该日志文件由俩个部分组成:重做日志缓冲区(redo log buffer)和重做日志文件(redo log)
重做日志缓冲区:是在内存中
重做日志文件:是在磁盘在
事务提交后会把所有修改的信息存放在该日志中,用于刷新脏页到磁盘,发生错误时,进行数据恢复使用
以循环的方式写入重做文件,涉及到俩个文件:ib_logfile0和ib_logfile1
作用:将Innodb缓冲池的数据在合适的时机刷新到磁盘文件中。
分为四类:
Master Thread
核心后台线程,负责调度其他线程。还负责将缓冲池中的数据异步刷新到磁盘中,保持数据的一致性。
还包括,脏页的刷新,合并插入缓冲,undo页的回收
IO Thread
在InoDB存储引擎中大量使用了AIO来处理IO请求,这样可以极大提高数据库性能,IO Thread主要负责以下IO请求的回调
| 线程类型 | 默认个数 | 责任 |
|---|---|---|
| Read thread | 4 | 负责读操作 |
| write thread | 4 | 负责写操作 |
| Log thread | 1 | 负责将日志缓冲区刷新到磁盘 |
| Insert buffer thread | 1 | 负责将写缓冲区内容刷新到磁盘 |
关于AIO(异步IO)和IO(同步IO)
同步就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。也就是必须一件一件事做,等前一件事做完了才能做下一件事。
异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果(在此期间,调用者可以去干一些别的事情)。实际处理这个调用的部件在完成后,通过状态、通知和回调。
Purge Thread
主要用于回收事务已经提交的undo log,在事务提交之后,undo log可能不需要了,就用这个来回收。
Page Cleaner Thread
协助Master Thread刷新脏页到磁盘的线程,他可以减轻Master Thread的工作压力,减少阻塞。
在增删改查的时候,会操作内存结构区域,如果里面没有数据就从。磁盘结构中加载,然后进行操作。
最后在特定时间会自动从内存结构中刷新到磁盘中。在磁盘中进行持久化保存下来
事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有操作作为一个整体一起向系统提交撤销操作请求。
这些操作要么同时成功要么同时失败。
原子性
事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
一致性
事务完成时,必须使所有的数据保持一致性。
隔离性
数据库系统提高隔离机制,保证事务在不受外部并发操作影响的独立环境运行。
持久性
事务一旦提交或回滚,他对数据库的数据改变就是永久的。
事务的原子性,一致性,持久性都是由redo log和undo log实现的
事务的隔离性是由 锁机制和MVCC实现的。
重做日志,记录的是事务提交时数据页的物理修改,用来实现事务的持久性。
该日志文件由俩部分组成:
重做日志缓冲(redo log buffer)
在内存中
重做日志文件(redo log file)
在磁盘中
当事务提交后会把所有修改信息都存放到该日志文件中,用于在刷新脏页到磁盘中,发生错误时,进行数据的恢复。
大概流程:
客户端A对innoDB存储引擎的表进行增删改事务操作
先访问内存结构中的缓冲池,如果增删改数据在其中不存在,
就会从磁盘中读取数据再刷新到缓冲池(这个数据必须是唯一索引,否则会先进入到更改缓冲区)
在缓冲池中变成脏页,并记录在redolog buffer中,后直接刷新到磁盘中
如果脏页在一段时间后刷新到磁盘中报错了,可以通过redo log进行恢复。

使用redo log直接刷新到磁盘结构的好处
事务一般是一组多条的增删改查操作,故事务提交的时候会随机的操作多条的记录。
这些记录会操作多条数据页,这样会产生大量的随机磁盘IO
而直接将redo log文件异步刷新到磁盘io中,由于它是日志文件,日志文件都是追加的,此时是顺序磁盘IO,这样会节约大量的磁盘IO
这种机制叫WAL(Write-Ahead Logging)(先写日志)
然后过一段时间脏页日志才会刷新到磁盘中。
故俩份日志是循环清理的
事务的redo log日志是为了解决脏页刷新到磁盘出错时进行数据的恢复使用的,用来保证数据的持久性
undo log日志是用来保证事务的原子性的。
undo log也叫回滚日志,用于记录数据被修改前的信息,作用为:提供回滚和MVCC
redo log记录的是物理日志!
undo log记录的是逻辑日志,可以认为当执行delete 一条记录时,undo log中会记录一条对应的insert记录,反之同理。
当执行rollback时,就可以从undo log中的逻辑记录读取到对应内容,从而进行回滚。
Undo log销毁
undo log在事务执行时产生,事务提交时,并不会马上删除undo log,因为这些日志可能还用于MVCC
Undo log存储
undo log采用,段的方式进行管理和记录,存放在前面介绍的rollback segment回滚中,内部包含了1024个undo log segment
这个段是逻辑存储结构的段哦~
我们读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁,
对于我们日常的操作,如:select...lock in share mode(共享锁),select...for update,update,insert,delete(排他锁)
都是一种当前读。
案例:
在RR的隔离级别下
简单的select(不加锁)就是快照读,读取的是记录数据的可见版本,可能是历史数据,不加锁是非阻塞读。
全称Multi-Version Concurrency Control 多版本并发控制。
指的是维护一个数据的多个版本,使得读写操作没有冲突。
快照读为MYSQL实现MVCC提供了一个非阻塞读功能,MVCC的具体实现,还需要依赖,数据库的三个隐藏字段、
undo log日志、readView
当我们创建了表除了自己本身创建的字段,innoDB引擎会自动给我们创建三个字段
分别是:
| 隐藏字段 | 含义 |
|---|---|
| DB_TRX_ID | 最近修改事务ID,记录插入这条记录或者最后一次修改该记录的ID(事务id) |
| DB_ROLL_PTR | 回滚指针,指向这条记录的上一个版本,用于配合undo log指向上一个版本 |
| DB_ROW_ID | 隐藏主键,如果表结构没有指定主键,就会生成该隐藏字段 |
可以查看表空间文件内容来查看隐藏字段信息
事务id是自增的!
在MYSQL中提供了一个命令来查看表空间文件的记录信息
ibd2sdi xxx.ibd
回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志
当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。
当update、delete的时候,产生的undo log日志不只是回滚时需要,在快照读时也需要,不会被立即删除。
Undo log版本链
不同事务或相同事务对同一条记录进行修改,会导致该记录的undo log生成一个记录的版本链表,链表的头部是最新的旧记录,链表的尾部是最早的旧记录。

执行顺序:
从上到下代表执行顺序。在同一行代表同一时间执行。
ReadView(读视图)是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id
ReadView中包含了四个核心字段
| 字段 | 含义 |
|---|---|
| m_ids | 当前活跃的事务id集合 |
| min_trx_id | 最小活跃的事务ID |
| max_trx_id | 预分配事务ID,当前最大事务ID+1(因为事务ID是自增的) |
| creator_trx_id | ReadView创建者的事务ID |
版本链数据访问规则
trx_id 代表的是当前事务的id
用这个id和ReadView的四个核心字段进行比对
trx_id == creator_trx_id 可以访问该版本 这个条件成立代表数据是当前这个事务更改的
trx_id < min_trx_id 可以访问该版本 这个条件成立,说明数据已提交
trx_id > max_trx_id 不可以访问该版本 这个条件成立,说明事务是在ReadView生成之后才开启的
min_trx_id <= trx_id <= max_trx_id 如果trx_id不在m_ids中,就可以访问该版本
这个条件成立,说明数据已经提交。
根据隔离级别的不同ReadView生成时机不同
在Read Committed隔离级别下
在事务第一次执行快照读时都生成一个Read view
在Repeatable read隔离级别下
在事务第一次执行快照读时生成,后续复用这个Read view
在事务第一次执行快照读时都生成一个Read view
第一个快照读,读取情况

这个快照读,根据规则,读取的是0x00002这个地址的数据,对应着事务2修改后的数据内容。
第二个快照读,读取情况

这个快照读,根据规则读取到的是,0x00003地址的数据内容,就是事务3修改后的数据。
在RR隔离级别下,只有事务在第一次执行快照读的时候生成ReadView,后续复用这个ReadView

具体的和RC规则一致,不重复讲解。
隐藏字段+Undo log版本链+ReadView组成MVCC
MVCC+锁构成事务的隔离机制
事务的一致性由Redo log和undo log共同保证
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll
我想为我的Rails网络应用程序提供推荐功能。特别是,我想向新注册的用户推荐他可能想要关注的其他用户。Rails中是否有用于此目的的引擎/gem?如果没有,我应该从哪里开始构建它?谢谢。 最佳答案 有Coletivogemhttps://github.com/diogenes/coletivo我试了一下。在MySQL上运行。Neo4jhttp://neo4j.org真的很容易实现一个“跟随谁”。事实上,大多数展示其能力的样本都涉及“跟随谁”。快速提示-只有在JRuby上运行时,Neo4j.rb才会很酷。如果不是-使用Neograph
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
我已经看到了一些其他的问题,尝试了他们的建议,但没有一个对我有用。我已经使用Rails大约一年了,刚刚开始一个新的Rails项目,突然遇到了问题。我卸载并尝试重新安装所有Ruby和Rails。Ruby很好,但Rails不行。当我输入railss时,我得到了can'tfindgemrailties。我当前的Ruby版本是ruby2.2.2p95(2015-04-13修订版50295)[x86_64-darwin15],尽管我一直在尝试通过rbenv设置ruby2.3.0。如果我尝试rails-v查看我正在运行的版本,我会得到同样的错误。我使用的是MacOSXElCapitan版本10