mysql 5.1版本无innodb trx_MySQL 5.7: Innodb 事务子系统优化-阿里云开发者社区

MySQL5.7 : Innodb 事务子系统优化

之前写了篇博客介绍了Percona Server对Read View的优化,顺带简单提到了MySQL5.7的事务子系统优化,详细见http://mysqllover.com/?p=834 。 另外一篇博客http://mysqllover.com/?p=1087 也有所涉及。

本文总体介绍了几个和事务子系统相关的worklog以及其代码实现。这部分代码值得细读,因为他们是5.7 Innodb比较核心的改动,极大的提升了只读场景下的性能。

这个worklog包含几点变化:

第一,无需显示的开启只读事务,所有的事务开始默认为只读事务,当遇到读写SQL时,自动加入读写列表。

第二,只读事务不为其分配事务ID,因此如果SHOW ENGINE INNODB STATUS时看到大量事务的ID表现的很怪异时(非常大的整数值),不要觉得奇怪。

该改进带来的最大的好处是你无需修改你的业务SQL。其实这才是用户能接受的特性,如果没有量级别的提升,谁会愿意去改代码呢?

不过显而易见的,这个优化也带了某些 运维的‘退化’,例如你再也无法从SHOW ENGINE INNODB STATUS中发现一个活跃的长时间不提交的只读事务(例如:BEGIN;SELECT;SELECT…),你需要去查询INNODB_TRX表来获得这些信息。

我们以一个典型的例子来开启这个话题,首先准备一个简单的表。隔离级别为READ-COMMIT

CREATE TABLE t1 (a INT PRIMARY KEY, b INT);

INSERT INTO t1 VALUES (1,RAND()*100),(2,RAND()*100);

BEGIN;

以BEGIN显式开启一个事务;

b) SELECT * FROM t1;

分配一个事务句柄:

ha_innobase::open

ha_innobase::info_low

update_thd

check_trx_exists

innobase_trx_allocate

trx_allocate_for_mysql

新分配的事务句柄会加入到trx_sys->mysql_trx_list,并重复使用。

开始一个只读事务,开启的事务,不分配事务ID, 不分配回滚段

row_search_mvcc->trx_start_if_not_started->trx_start_low

Assign Read View

row_search_mvcc

trx_assign_read_view

MVCC::view_open

分配的read view会拷贝当前的活跃事务ID,设置最高和最低可见事务ID,然后加入到活跃事务的read view链表上(MVCC::m_views)

c) UPDATE t1 SET b=b+1 WHERE a=2;

row_search_mvcc

lock_table

trx_set_rw_mode

将事务转换成读写事务模式,分配回滚段,分配事务ID。加入读写事务链表(trx_sys->rw_trx_ids, trx_sys->rw_trx_set, trx_sys->rw_trx_list)。

d) COMMIT; 事务提交

代码:

在该worklog种优化了read view的创建,对MVCC控制视图部分的代码进行了重构。

具体包括以下几个方面:

在之前版本中,read view的创建的复杂度为O(N),因为需要扫描读写事务链表;

现在创建一个read view 需要以下几步:

Step 1:

view->prepare(trx->id);

拷贝事务ID(不包含自己的事务ID),相当于做一个当前活跃读写事务的快照存放在视图中,直接使用memcpy的方式 (copy_trx_ids(trx_sys->rw_trx_ids)),这一点和percona的优化是一样的。

设置m_low_limit_no ,m_low_limit_id

Step 2:

view->complete();

设置视图的m_up_limit_id,表示所有小于这个值的修改都可见

Step 3:

UT_LIST_ADD_FIRST(m_views, view);

将视图加入到活跃视图链表中。

b) 在之前版本中是在持有trx_sys mutex时创建的read view。

为了降低分配/释放read view的开销,维护了两个read view链表,一个用于放当前活跃的视图链表,一个用于放空闲的、可分配的视图链表。

当系统启动时,会初始化一定数量的read view放到空闲链表上。

Percona实现了类似的方案,不同的是Percona的read view在事务完成后不是放到空闲链表,而是下次继续重用(但从活跃链表移除,不管是否是读写事务)

c) 对于autocommit的只读事务,即时当前没有活跃事务,也可能因为创建read view ,而大量别的线程在释放read view,导致trx_sys mutex冲突。

针对该问题,实际上我已经在博文http://mysqllover.com/?p=1087中描述过了,对于自动提交的查询,在关闭read view时是不从视图链表上移除的,在再次开启事务重用该read view时,如果这期间没有读写事务,都无需重新初始化read view,直接使用即可。 因此如果一台实例上的都是自动提交的只读事务,完全可以避免trx_sys mutex的开销。

d) 需要持有trx_sys mutex来遍历rw_trx_list,以判断更改是否可见,或者根据事务id获取事务对象trx_t

由于已经保存了事务ID的快照,因此直接根据二分查找查找有序数组即可,无需遍历读写事务链表

参考函数ReadView::changes_visible

trx_sys_t新增成员rw_trx_set,用于维护从trx_id到trx_t的映射。这样可以根据事务ID快速找到对应的事务对象而无需扫描事务链表。参考函数trx_get_rw_trx_by_id

主要更改:

在完成上述修改后,无需再维持ro_trx_list了,因为所有事务默认都被当做只读事务,这个链表开销完全可以忽略掉的。

该worklog主要实现了隐式锁向现式锁转换的一个优化点。在获取活跃事务对象时,无需持有lock_sys mutex锁。

在连续内存中预分配事务对象,保持内存的连续性有利于编译器或者CPU做出某些优化,例如内存预取之类的(不是很了解这一块,不展开叙述)

为了实现事务对象内存分配,回收等,在底层分装了一些pool类,事务对象实际上被管理在一个池结构中。

后面我再单独写一篇博客来介绍新加的这些底层结构。

在启动时,初始化trx_pools (trx_pool_init),初始化时分配4M内存,在shutdown时释放(trx_pool_close())

为了管理事务对象池,设计了三个类:TrxFactory,TrxPoolLock,TrxPoolManagerLock

获取事务对象:trx_create_low —-> trx_pools->get()

释放事务对象:trx_free —-> trx_pools->free(trx)

相关代码:

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/5753

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/563488.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql hex 和 c_什么是MySQL HEX()函数,它与CONV()函数有何不同?

实际上,HEX()函数将十进制或字符串值转换为十六进制值。转换后,MySQL返回该十六进制值的字符串表示形式。语法HEX(Num or Str)众所周知,HEX()函数可以转换数字或字符串,因此语法中的“ Num”表示要转换为十六进制的数字&#xff0…

mysql日期为00_MySQL 8.0.13 设置日期为0000-00-00 00:00:00时出现的问题

刚开始学习 数据库 操作,今天存数据时发现,保存的时候报错 (Error 1292: Incorrect datetime value: 0000-00-00 for column deleted_at at row 1),之后就搜索了下原因,是因为 MySQL存日期时不允许出现这种格式导致的。下面记录下…

MySQL编程技巧_MySQL学习笔记---MySQL开发技巧

SQL语句分类DDL:数据定义语言 --- CREATE、ALTER、DROP、TRUNCATETPL:事务处理语言 --- COMMIT、ROLLBACK、SAVEPOINT、SET TRANSACTIONDCL:数据控制语言 --- GRANT、REVOKEDML:数据操作语言 --- SELECT、UPDATE、INSERT、DELETEj…

cockroachdb mysql_CockroachDB学习笔记——[译]CockroachDB中的SQL:映射表中数据到键值存储...

CockroachDB学习笔记——[译]CockroachDB中的SQL:映射表中数据到键值存储原文标题:SQL in CockroachDB: Mapping Table Data to Key-Value Storage原作者:Peter Mattis , Tamir Duberstein原文日期:Sep 16, 2015译:zif…

kafka topic 目录存放在哪_Kafka系列文章之安装测试-第2篇

前言上篇文章讲解了 Kafka 的基础概念和架构,了解了基本概念之后,必须得实践一波了,所谓“实践才是检验真理的唯一办法”,后续系列关于 Kafka 的文章都以 kafka_2.11-0.9.0.0 为例;另外为了让大家快速入门,…

java开发分支_如何选择Java 的分支?

问题阐述听说Java 无所不能,从简单的手机游戏到世界500 强的官方网站都能开发,作为一名Java 的初学者,我该如何入手?专家解答自诞生之日起,Java 语言就处于不断的发展中。目前,其主要分为以下3 个分支。. J…

蚂蚁爬杆 java_java蚂蚁爬杆

import java.util.List;import java.util.ArrayList;import java.math.BigDecimal;/*-作者:volcano_hosan*-----------蚂蚁爬杆*有一根300厘米的细木杆,在第30厘米、80厘米、110厘米、160厘米、250厘米这五个位置上各有一只蚂蚁。*木杆很细,不能同时通过…

java制作加载界面_Java如何制作启动界面?

展开全部大概的思路就是使用线程来计算耗时的32313133353236313431303231363533e58685e5aeb931333337613133操作,在前段显示启动的窗口,示例如下:java 代码/** To change this template, choose Tools | Templates* and open the template in…

java 生成客户端代码_swagger-codegen生成java客户端代码

前后端分离的时候,需要建立契约,Swagger可达到该目的(略)。建立Rest接口后,通过swagger-codegen项目可以自动生成对应的客户端代码(c、php、java、js、node等等),关于swagger-codegen项目的使用,发现中文文档较少&…

mysql无法启动修复_记一次MySQL无法启动及修复经历

记得有次本地的MySQL无法启动,网上说,去删掉InnoDB日志就行,我就傻乎乎的去删掉了InnoDB相关的文件,果然,没有任何问题,正常启动了。可是谁曾想,过了几天,故障复现了,我就…

mysql的操作语句_Mysql最常用的操作语句收集

Mysql中常用语句简单易学springboot微服务是现在流行的框架,目前大多数做java的人都在使用,java的生态一直很好,各种插件各种第三方jar包推动着java的运行。Mysql是Springboot最常用的数据库,主要原因是Mysql免费而且轻量。考虑性…

java获取网络带宽_Linux Java 获取CPU使用率,内存使用率,磁盘IO,网络带宽使用率等等...

/*** 获取带宽上传下载速度* return*/public String getNetWorkSpeed() {boolean result false;String detailInfo "";DecimalFormat df new DecimalFormat("0.00");String dl "";String ul "";System.out.println("开始收集…

java周期_java 周期时期计算

package org.apple.date;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;/*** 周期时间* author shaoyu**/public class CycleDate {public static void main(String[] args) {SimpleDateFormat dateformatnew SimpleDateFormat("yy…

python实现qq登录界面_使用Python编写一个QQ办公版的图形登录界面!

最近,QQ的办公版本——TIM进行了一次更新升级。本次更新升级大幅修改了界面的样式,看起来更加的清爽、简洁和高效了。这种界面州的先生还是比较喜欢的,没有QQ那么花里胡哨,也比微信那些残缺的功能更加丰富。并且这次的登录界面还新…

python算法详解豆瓣_豆瓣爬虫实践-python版

豆瓣登录,无验证码版:import requests#starturl "https://www.douban.com/accounts/login"loginurl "https://accounts.douban.com/login"headers {User-Agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KH…

python项目打包部署到ios_Python iOS 自动打包脚本(包含上传到fir)

Python iOS自动打包脚本使用说明1.1 使用python3编写,没有python3 环境的需要下载python3python官网下载1.2 通过Homebrew安装Python31.2.1 先搜索$ brew search python输出:app-engine-python micropython python3boost-python python wxpythongst-pyth…

stlink 升级固件以后失败_ST-Link不能下载程序的几种解决办法

一直在用J-LINK,最近改用ST-Link,出现了不少无法下载程序的情况,这里列出几种解决的办法(针对STM32F103系列):1#是不是你没有选择Flash算法?什么都没有加的话,会提示“找不到Flash算法”的哦2#是不是你JTAG…

cnsl是什么意思_VS2010下创建静态链接库和动态链接库

VS2010下创建静态链接库和动态链接库类封装成dll如果你的工作长期与某个领域相关,比如说长期做直接体绘制 (DVR)方面的开发,那么你可能经常使用自己的传递函数类,如果每一个工程你都把传递函数类的.h和.cpp文件添加进去会比较麻烦&#xff0c…

java hash取余_为什么Java的hash表的长度一直是2的指数次幂?为什么这个(hash(h-1)=hash%h)位运算公式等价于取余运算?...

1.什么是hash表?答:简单回答散列表,在hash结构散列(分散)存放的一种数据集结构。2.如何散列排布,如何均匀排布?答:取余运算3.Java中如何实现?答:hash&(h-1)4.为什么hash&(h-…

java .net 3des_Java.net3DES差异及互通

主要差异如下:1、 对于待加密解密的数据,各自的填充模式不一样C#的模式有:ANSIX923、ISO10126、None、PKCS7、Zero,而Java有:NoPadding、PKCS5Padding、SSL3Padding2、 各自默认的3DES实现,模式和填充方式…