
内存结构主要包括 Buffer Pool、Change Buffer、Adaptive Hash Index和 Log Buffer 四大组件
缓冲池,简称BP。BP以 Page 页为单位,默认大小 16 K。BP的底层采用链表数据结构管理 Page。
在 InnnoDB 访问表记录和索引是会在 Page 页中缓存,以后使用可以减少磁盘IO操作,提升效率。
Page根据状态可以分为三种类型:
针对上述三种 Page 类型,InnoDB通过三种链表结构来维护和管理
mysql> show engine innodb status \G;

每当有新的 page 数据读取到 buffer pool时,InnoDB 引擎会判断是否有足够空闲页,如果有,就将 free page 从 free list 列表删除,放入到 LRU 列表中。没有空闲页,就会根据 LRU算法淘汰 LRU 链表末尾的页,将内存空间释放分配给新的页
mysql> show variables like '%innodb_page_size%';
mysql> select @@innodb_page_size;
+--------------------------------+-----------+
| Variable_name | Value |
+ -------------------------------+-----------+
| innodb_page_size | 16384 |
+ -------------------------------+-----------+
mysql> show variables like '%innodb_old%';
+--------------------------------+-----------+
| Variable_name | Value |
+ -------------------------------+-----------+
| innodb_old_blocks_pct | 37 |
| innodb_old_blocks_time | 1000 |
+ -------------------------------+-----------+
mysql> show variables like '%innodb_buffer%';
+-------------------------------------------------+-------------------+
| Variable_name | Value |
+ ------------------------------------------------+-------------------+
| innodb_buffer_pool_chunk_size | 8388608 |
| innodb_buffer_pool_dump_at_shutdownsize | ON |
| innodb_buffer_pool_dump_now | OFF |
| innodb_buffer_pool_dump_pct | 25 |
| innodb_buffer_pool_filename | ib_buffer_pool |
| innodb_buffer_pool_instances | 1 |
| innodb_buffer_pool_load_abort | OFF |
| innodb_buffer_pool_load_at_startup | ON |
| innodb_buffer_pool_load_now | OFF |
| innodb_buffer_pool_size | 8388608 |
+ ------------------------------------------------+-------------------+

写缓冲区,简称CB。在进行 DML 操作是,如果 BP 没有其相应的 Page 数据,并不会立刻将磁盘页加载到缓冲池,而是在 CB 记录缓冲变更,等未来数据被读取时,再将数据合并恢复到 BP 中。
ChangeBuffer占用 Buffer Pool 空间,默认占 25%,最大允许占 50%,可以根据读写业务量来进行调整。
mysql> show variable like '%innodb_change_buffer_max_size%'
+-------------------------------------------------+-------------------+
| Variable_name | Value |
+ ------------------------------------------------+-------------------+
| innodb_change_buffer_max_size | 25 |
+ ------------------------------------------------+-------------------+
mysql> set global innodb_change_buffer_max_size = 20;
当更新一条记录时,该记录在 BufferPool 存在,直接在 BufferPool 修改,一次内存操作;如不存在(没有命中),会直接在 ChangeBuffer 进行一次内存操作(不用再去磁盘查询,避免一次磁盘IO),当下次查询记录是,会先进行磁盘读取,然后再从 ChangeBuffer 中读取信息合并,最终载入 BufferPool 中
写缓冲区仅适用于非唯一普通索引页。因为索引设置唯一性后,在进行修改时,InnoDB必须要做唯一性校验,因此必须查询磁盘做一次IO操作。此时会直接将记录查询到 BufferPool 中,然后在缓冲池修改,因此不会再在 ChangeBuffer 中操作
自适应哈希索引,用于优化对 BP 数据的查询。InnoDB 存储引擎会监控对表索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引,所以称之为自适应。InnoDB 存储引擎会自动根据访问的频率和模式来为某些页建立哈希索引
日志缓冲区,用来保存要写入磁盘 log 文件(Redo/Undo)的数据,日志缓冲区的内容定期刷新到磁盘 log 文件中。日志缓冲区满时会自动将其刷新到磁盘,当遇到 BLOB 或多行更新的大事务操作时,增加日志缓冲区可以节省磁盘I/O
LogBuffer主要是用于记录 InnoDB引擎日志,在 DML 操作时会产生 Redo 和 Undo 日志
LogBuffer空间满时会自动写入磁盘,可以通过将 innodb_log_buffer_size 参数调大,减少磁盘I/O频率
innodb_flush_log_at_trx_commit参数控制日志刷新行为,默认为1
InnoDB磁盘主要包含 Tablespaces、InnoDB Data Dictionary、Doublewrite Buffer、Redo Log 和 Undo Logs
表空间,用于存储表结构和数据。
mysql> show variable like '%innodb_data_file_path%'
+-----------------------------------------+-------------------------+
| Variable_name | Value |
+ ----------------------------------------+-------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
+ ----------------------------------------+-------------------------+
innodb_file_per_table=ON时,表将创建于独立表空间,否则创建于系统表空间mysql> show variable like '%innodb_file_per_table%'
+-----------------------------------------+-------------------------+
| Variable_name | Value |
+ ----------------------------------------+-------------------------+
| innodb_file_per_table | ON |
+ ----------------------------------------+-------------------------+
create tablespace 语法创建的共享表空间。通用表空间可以创建于 mysql 数据目录外的其他表空间,其可以容纳多张表,且支持所有的行格式CREATE TABLESPACE ts1 ADD DATAFILE ts1.ibd Engine=InnoDB; // 创建表空间ts1
CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1; // 将表添加到ts1表空间
innodb_undo_tablespaces 配置选项控制,默认为0。数据字典由内部系统表组成,这些表包含用于查找表、索引和表字段等对象的元数据。元数据物理上位于InnoDB系统表空间中。由于历史原因,数据字典元数据在一定程度上与InnoDB表元数据文件(.frm文件)中存储的信息重叠
双写缓冲区位于系统表空间,是一个存储区域。在 BufferPage 的 page 页刷新到磁盘真正的位置前,会先将数据存在 Doublewrite 缓冲区。如果在 page 页写入过程中出现操作系统、存储子系统或 mysqld 进程崩溃,InnoDB 可以在崩溃恢复期间从 Doublewrite 缓冲区中找到页面的一个好备份。默认启用双写缓冲区。
mysql> show variable like '%innodb_doublewrite%'
+-----------------------------------------+-------------------------+
| Variable_name | Value |
+ ----------------------------------------+-------------------------+
| innodb_doublewrite | ON |
+ ----------------------------------------+-------------------------+
MySQL 的 innodb_flush_method 这个参数控制着 InnoDB 数据文件及 redo log 的打开、刷写模式。
使用 Doublewrite 缓冲区时建议将 innodb_flush_method 设置为 O_DIRECT
重做日志是一种基于磁盘的数据结构,用于在崩溃恢复期间更正不完整事务写入的数据。MySQL 以循环方式写入重做日志文件,记录 innodb 中所有对 Buffer Pool 修改的日志。当出现实例故障(像断电),导致数据未能更新到数据文件,则数据库重启时须redo,重新把数据更新到数据文件。读写事务在执行的过程中,都会不断的产生 redo log。默认情况下,重做日志在磁盘上由两个名为 ib_logfile0 和 ib_logfile1 的文件物理表示
撤销日志是在事务开始之前保存的被修改数据的备份,用于例外情况时回滚事务。撤销日志属于逻辑日志,根据每行记录进行记录。撤销日志存在于系统表空间、撤销表空间和临时表空间中


在 InnoDB 中使用了大量的AIO(Async IO)来做读写处理,这样可以极大提高数据库的性能。在 InnoDB1.0版本之前共有4个IO Thread,分别是write、read、insert buffer和log thread,后来版本将 read 和 write thread分别增大到4个,一共有10个了
mysql> show engine innodb status \G;
---------------------
FILE I/O
---------------------
I/O thread 0 state: wait Windows aio (insert buffer thread)
I/O thread 1 state: wait Windows aio (log thread)
I/O thread 2 state: wait Windows aio (read thread)
I/O thread 3 state: wait Windows aio (read thread)
I/O thread 4 state: wait Windows aio (read thread)
I/O thread 5 state: wait Windows aio (read thread)
I/O thread 6 state: wait Windows aio (write thread)
I/O thread 7 state: wait Windows aio (write thread)
I/O thread 8 state: wait Windows aio (write thread)
I/O thread 9 state: wait Windows aio (write thread)
事务提交之后,其使用的 undo 日志将不再需要,因此需要 purge thread 回收已经分配的 undo 页
mysql> show variables like '%innodb_purge_thread%';
+-----------------------------------------+-------------------------+
| Variable_name | Value |
+ ----------------------------------------+-------------------------+
| innodb_purge_thread | 4 |
+ ----------------------------------------+-------------------------+
作用是将脏数据刷新到磁盘,脏数据刷盘后相应的 redo log 也就可以覆盖,即可以同步数据,又能达到 redo log 循环使用的目的。会调用 write thread 线程处理
mysql> show variables like '%innodb_page_cleaners%';
+-----------------------------------------+-------------------------+
| Variable_name | Value |
+ ----------------------------------------+-------------------------+
| innodb_page_cleaners | 1 |
+ ----------------------------------------+-------------------------+
Master Thread 是 InnoDB 的主线程,负责调度其他各线程,优先级最高。作用是将缓冲池中的数据异步刷新到磁盘,保证数据的一致性。包括:脏页的刷新(page cleaner threa)、undo 页回收(purge thread)、redo日志刷新(log thread)、合并写缓冲等。
内部有两个主处理:
mysql> show variables like '%innodb_max_dirty_pages_pct%';
+-----------------------------------------+-------------------------+
| Variable_name | Value |
+ ----------------------------------------+-------------------------+
| innodb_max_dirty_pages_pct | 75.000000 |
| innodb_max_dirty_pages_pct_lwm | 0.000000 |
+ ----------------------------------------+-------------------------+
mysql> show variables like '%innodb_io_capacity%';
+-----------------------------------------+-------------------------+
| Variable_name | Value |
+ ----------------------------------------+-------------------------+
| innodb_io_capacity | 200 |
| innodb_io_capacity_max | 2000 |
+ ----------------------------------------+-------------------------+


在早期的 InnoDB 版本中,文件格式只有一种,随着 InnoDB 引擎的发展,出现了新文件格式,用于支持新的功能。
mysql> show variables like '%innodb_file_format%';
+-----------------------------------------+-------------------------+
| Variable_name | Value |
+ ----------------------------------------+-------------------------+
| innodb_file_format | Antelope |
| innodb_file_format_check | ON |
| innodb_file_format_max | Antelope |
+ ----------------------------------------+-------------------------+
表的行格式决定了它的行是如何物理存储的,这反过来又会影响查询和 DML 操作的性能。如果在单个 Page 页中容纳更多行,查询和索引查找可以更快地工作,缓冲池中所需的内存更少,写入更新时所需的I/O更少
每个表的数据分成若干页来存储,每个页中采用B数结构存储。如果某些字段信息过长,无法存储在B数节点中,这时会被单独分配空间,此时称为溢出页,该字段被称为页外列
InnoDB 存储引擎支持四种行格式
innodb_large_prefix 参数控制| Row Format | Compact Storage Characteristics | Enhanced Variable-Length Column Storage | Large Index key Prefix Support | Compression Support | Supported Tablespace Types | Required File Format |
|---|---|---|---|---|---|---|
| REDUNANT | No | No | No | No | system, file-per-table | Antelope or Barracuda |
| COMPACT | Yes | No | No | No | system, file-per-table | Antelope or Barracuda |
| DYNAMIC | Yes | Yes | Yes | No | file-per-table | Barracuda |
| COMPRESSED | Yes | Yes | Yes | Yes | file-per-table | Barracuda |
在创建表和索引时,文件格式都被用于每个 InnoDB 表数据文件(其名称与*.ibd匹配)。修改文件格式的方法是重新创建表及其索引,最简单方法是对要修改的每个表使用如下命令
ALTER TABLE 表名 ROW_FORMAT=格式类型;
查看文件存储格式
mysql> SHOW TABLE STATUS
Name : dept
Engine : InnoDB
Version : 10
Row_format : Dynamic
Rows : 3
Avg_row_length : 5461
Data_length : 0
Max_data_length : 0
Index_length : 0
Data_free : 0
Auto_increment : NULL
Create_time : 2022-05-04 11:59:24
Update_time : 2022-05-05 10:29:54
Check_time : NULL
Collation : latin1_swedish_ci
Checksum : NULL
Create_options :
Comment :
mysql> select * from information_schema.innodb_sys_tables where name = 'dept' \G;
TABLE_ID : 71
NAME : dept
FLAG : 33
N_COLS : 5
SPACE : 54
FILE_FORMAT : Barracuda
ROW_FORMAT : Dynamic
ZIP_PAGE_SIZE : 0
SPACE_TYPE : Single
Undo :意为撤销或取消,以撤销操作为目的,返回指定某个状态的操作
Undo Log :数据库事务开始之前,会将要修改的记录存放在 Undo 日志里,当事务回滚时或数据库崩溃时,可以利用 Undo 日志,撤销未提交事务对数据库产生的影响
Undo Log 在事务开始前产生。事务在提交时,并不会立刻删除 Undo Log,InnoDB 会将该事务对应的 Undo Log 放入到删除列表中,后续会通过后台进程 Purge Thread 进行回收处理
Undo Log 属于逻辑日志,记录一个变化过程。例如执行一个 delete,Undo Log 会记录一个 insert;执行一个 update,Undo Log 会记录一个相反的 update
Undo Log 采用段的方式管理和记录。在 InnoDB 数据文件中包含一种 Rollback Segment 回滚段,内部包含 1024 个 Undo Log Segment。可以通过下面一组参数来控制 Undo Log 存储
mysql> show variables like '%innodb_undo%';

事务A手动开启事务,执行更新操作,首先会把更新命中的数据备份到 Undo Buffer 中
事务B手动开启事务,执行查询操作,会读取 Undo 日志数据返回,进行快照读
Redo :就是重做。以恢复操作为目的,在数据库发生意外时重现操作
Redo Log :指事务中修改的任何数据,将最新的数据备份存储的位置(Redo Log),被称为重做日志
随着事务操作的执行,就会生成 Redo Log,在事务提交时会将产生 Redo Log 写入 Log Buffer,并不是随着事务的提交就立刻写入磁盘文件。等事务操作的脏页写入到磁盘后,Redo Log 的使命就完成了,Redo Log 占用的空间就可以重用(被覆盖写入)。
Redo Log 是为了实现事务的持久化而出现的产物。防止在发生故障的时间点,尚有脏页未写入表的 IBD 文件中,在重启 MySQL 服务的时候,根据 Redo Log 进行重做,从而达到事务的未入磁盘数据进行持久化这一特性

- 事务提交,为什么不直接持久化 User 到磁盘,而是要通过 Redo Log 来处理
每次提交事务时,都直接持久化到磁盘,IO频率过高,效率低下。通常优化方案是,多个事务执行后统一持久化- 持久化到 Redo Log 和 直接持久化 User 到磁盘都是 IO 操作,有何区别
假如有两个 User (ID 分别为 1, 8),直接持久化 User,需要分别查找定位到 1 和 8 的用户信息位置,然后再更新,属于随机IO,效率低;而通过 Redo Log 写时是将这两个变更信息顺序的写入到 Redo Log 中,属于顺序IO,效率高
Redo Log 文件内容是以顺序循环的方式写入文件,写满时则回溯到第一个文件,进行覆盖写

每个 InnoDB 存储引擎至少有 1 个重做日志文件组(Group),每个文件组至少有 2 个重做日志文件,默认为 ib_logfile0 和 ib_logfile1。可以通过参数控制 Redo Log 存储
mysql> show variables like '%innodb_log%';
Redo Buffer 持久化到 Redo Log 的策略,可以通过 innodb_flush_log_at_trx_commit 设置
一般建议选择取值 2, 因为 MySQL 挂了数据没有损失,整个服务器挂了才会损失 1 秒的事务提交数据

二进制日志(Binary Log),Binlog 是记录所有数据库表结构变更以及表数据修改的二进制日志,不会记录 SELECT 和 SHOW 这类操作。Binlog 日志是以事件形式记录,还包含语句所执行的消耗时间。
Binlog 文件名默认为“主机名_binlog-序列号”格式,例如 oak_binlog-000001,也可以在配置文件中指定名称。
文件记录模式有:
MySQL 的 binlog 文件中记录的是对数据库的各种修改操作,用来表示修改操作的数据结构是 Log Event。不同的修改操作对应的不同的 Log Event。比较常用的 Log Event 有:Query Event、ROW Event、Xid Event等。binlog文件的内容就是各种 Log Event 的集合

我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我想为我的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
我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时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
我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于
我正在关注Hartl的railstutorial.org并已到达11.4.4:Imageuploadinproduction.我做了什么:注册亚马逊网络服务在AmazonIdentityandAccessManagement中,我创建了一个用户。用户创建成功。在AmazonS3中,我创建了一个新存储桶。设置新存储桶的权限:权限:本教程指示“授予上一步创建的用户读写权限”。但是,在存储桶的“权限”下,未提及新用户名。我只能在每个人、经过身份验证的用户、日志传送、我和亚马逊似乎根据我的名字+数字创建的用户名之间进行选择。我已经通过选择经过身份验证的用户并选中了上传/删除和查看权限的框(而不
我正在使用mechanize登录网站,然后检索页面。我遇到了一些问题,我怀疑这是由于cookie中的某些值造成的。当Mechanize登录网站时,我假设它存储了cookie。如何通过Mechanize打印出存储在cookie中的所有数据? 最佳答案 代理有一个cookie方法。agent=Mechanize.newpage=agent.get("http://www.google.com/")agent.cookiesagent.cookies.to_scookie返回一个Mechanize::Cookiesobject