【进阶篇】MySQL的MVCC实现机制详解
文章目录
- 0.前言
- 1.基础介绍
- 1.1. 什么是MVCC?
- 1.1. 什么是当前读和快照读?
- 1.1. 当前读,快照读和MVCC的关系
- 1.1. MVCC能解决什么问题,好处是?
- 1.1.1. 提高并发性能
- 1.1.2. 避免死锁
- 1.1.3. 解决脏读、不可重复读和幻读等问题
- 1.1.4. 实现非阻塞读
- 1.1.5. 提供一致性视图
- 2. MVCC的实现原理
- 2.1. 隐式字段
- 2.1. undo日志
- 场景示例
- 2.1. Read View(读视图)
- 基本介绍
- 场景示例
- 原理
- readview如何判断版本链中的哪个版本可用呢?(重点!)
- 2.1. 整体流程
- 3. MVCC相关问题
- 3.1. RR是如何在RC级的基础上解决不可重复读的?
- 3.1.RC,RR级别下的InnoDB快照读有什么不同?
- 参考资料
0.前言
在数据库领域,对数据进行并发操作是常见的需求。为了保证数据的一致性和事务的隔离性,不同的数据库系统采用了不同的并发控制技术。其中,多版本并发控制(MVCC,Multiversion Concurrency Control)是MySQL中InnoDB存储引擎采用的一种非常重要的并发控制技术。
MVCC通过创建数据在某个时间点的"快照",让事务能够访问到一个一致的数据视图,而不会被其他事务操作影响。这样不仅可以提高并发性能,而且可以避免在读取数据时进行加锁,大大增强了数据库的并发处理能力。
在本篇博客中,我们深入探讨MySQL的MVCC实现机制,包括Undo日志、Read View以及事务链等概念。我们将详解MVCC如何在保证数据一致性的同时,提高数据库的并发处理能力。 理解和掌握MySQL中MVCC的工作原理,以更好地进行数据库设计和优化。
虽然我们的标题是 MySQL的MVCC实现机制详解,大家不要误认为MVCC机制是MySQL独有的。
MVCC 不是MySQL的特有机制,除了MySQL 使用了MVCC机制,其他数据库版本也使用了
以下是一些采用了多版本并发控制(MVCC)策略的数据库:
PostgreSQL:它使用 MVCC 提供多个并发用户间的一致性视图。
MySQL:在可重复读取隔离级别下,MySQL的InnoDB存储引擎利用 MVCC 解决读写冲突,提供快照数据而非最新数据。
Oracle:尽管Oracle使用了MVCC,但其实现方法与PostgreSQL和MySQL的InnoDB不同。在Oracle中,读操作不会阻塞写操作,反之亦然。
SQLite:SQLite使用了"snapshot isolation",它的核心概念与MVCC相似,都是在事务开始时提供一个快照,而非实时数据。
CouchDB 和 MongoDB:这两个NoSQL数据库也采用了MVCC或类似技术。
Apache HBase:作为开源的非关系型分布式数据库,HBase是Google BigTable的Java实现,也使用了MVCC。
Apache Cassandra:这是Facebook开发的一款开源分布式NoSQL数据库系统,用于满足高速读写需求,如Inbox搜索,它也实现了MVCC。
MariaDB:作为MySQL的一个开源分支版本,MariaDB的InnoDB存储引擎也使用了MVCC。
Microsoft SQL Server:在读已提交快照和快照隔离级别下,SQL Server使用了MVCC。
1.基础介绍
1.1. 什么是MVCC?
MVCC,全称是多版本并发控制(Multi-Version Concurrency Control),是一种用来解决数据库并发问题的方法。在高并发的场景下,为了提高性能,采用MVCC是一种比单纯的加锁更有效的方式。
MVCC的工作原理是,每次对数据进行更新操作,都不会直接覆盖原有数据,而是为数据添加一个新的版本。并且,每个事务都可以看到一个一致的快照版本,这个版本在该事务启动时就已经确定。
这样,就可以实现在不阻塞读操作的前提下进行写操作,也就是实现了读写分离,提高了数据库的并发处理能力。
MVCC实现机制主要包括以下几个方面:
数据版本化:每一条数据都有一个版本号,每次修改数据,都会生成一个新的版本。查询时,只要在版本列表中找到对应的版本即可,而不需要等待数据修改完成。
读视图:每一次事务开始时,都会生成一个读视图,这个读视图记录了开始该事务时,正在执行的所有其他事务的事务ID。在进行查询操作时,只查询在读视图记录的事务ID之前开始的事务对应的数据版本。
undo日志:在修改数据时,会把修改前的数据版本写入undo日志。如果有其他事务需要访问修改前的数据版本,可以直接从undo日志中获取。
MVCC只在READ COMMITTED和REPEATABLE READ两个隔离级别下工作。在这两个隔离级别下,读操作不会产生任何锁,大大提高了查询性能,降低了锁冲突的概率,从而使得更多的应用可以并发运行。
1.1. 什么是当前读和快照读?
在数据库中,读操作主要分为两种:当前读(Current Read)和快照读(Snapshot Read)。
-
当前读:就是读取记录的最新版本,也就是最新的数据。如果数据在读取过程中被其他事务修改了,那么会读取到最新的数据内容。当前读会对读取的数据加锁,阻止其他事务对数据进行修改。当前读主要出现在UPDATE、DELETE、INSERT、SELECT…FOR UPDATE这些需要进行写操作的SQL语句中。
-
快照读:读取的是记录在事务开始时的版本,也就是读取快照中的数据。即使在读取过程中数据被其他事务修改,读取到的数据内容也不会改变。快照读不会对读取的数据加锁,不会阻止其他事务对数据进行修改。快照读主要出现在普通的SELECT语句中。
这两种读操作的主要区别在于是否对读取的数据加锁,以及读取的是数据的哪个版本。
1.1. 当前读,快照读和MVCC的关系
当前读和快照读都是MySQL中的读操作,它们的区别在于读取的数据版本和是否加锁。然而,这两种读操作并不能完全满足并发控制的需求。这就是MVCC(多版本并发控制)的作用。
MVCC是一种用于实现事务并发控制的机制。在MVCC中,每次对数据的修改都会创建一个新的数据版本。不同的事务会看到不同版本的数据,这取决于事务开始的时间以及事务的隔离级别。
当进行快照读(非锁定读)时,MVCC允许事务读取一个旧的数据版本。这意味着在同一时间点,不同的事务可以看到同一行数据的不同版本,避免了因等待锁而导致的阻塞。这在幻读(phantom read)和非可重复读(non-repeatable read)这两种情况下特别有用。
当进行当前读(锁定读)时,如UPDATE或SELECT FOR UPDATE,会读取最新版本的数据,并对其加锁以防止其他事务进行修改。
因此,MVCC、当前读和快照读是密切相关的。MVCC通过提供一种机制,使得当前读和快照读能够在并发事务中同时有效地工作,从而提高数据库的整体性能。
1.1. MVCC能解决什么问题,好处是?
1.1.1. 提高并发性能
MVCC允许多个读操作与写操作同时进行,无需等待锁,因此可以大大提高并发性能。
在传统的数据库并发控制中,为了保证数据的一致性,通常会使用锁来阻止其他事务在当前事务完成之前读取或修改数据。这种方式虽然可以保证数据的一致性,但是其并发性能较差,因为读操作和写操作之间存在阻塞。
而在MVCC机制中,对于读操作,系统会创建一个数据版本的快照,而不是直接对数据加锁,这样即使有其他事务正在对数据进行修改,当前事务也可以进行读操作。举例来说,假设我们有一个在线购物系统,当用户A查看某个商品的信息时,即使此时商家正在修改这个商品的价格,用户A也可以正常查看商品信息,不会被阻塞。
对于写操作,MVCC通过生成旧版本数据的拷贝来避免直接修改数据。这样当其他事务需要读取数据时,即使数据已经被修改,也可以通过读取这个旧版本数据的拷贝来获取数据,而不需要等待写操作完成。比如上述在线购物系统中,当商家修改商品价格时,如果此时有用户正在查看这个商品,那么用户看到的仍然是旧的价格,无需等待商家修改价格的操作完成。
1.1.2. 避免死锁
由于读操作不需要加锁,所以减少了产生死锁的可能。
在传统的锁定机制中,如果两个或更多的事务在相互等待对方所持有的锁,就会发生死锁。例如,如果事务A锁定了资源1并试图获得资源2,而事务B已经锁定了资源2并试图获得资源1,那么就会出现死锁,因为每个事务都在等待对方释放其需要的资源。
而在MVCC中,由于读操作不需要加锁,事务可以在不影响其他事务的情况下读取数据。这就意味着读操作不会因为等待其他事务释放锁而被阻塞,从而减少了死锁的可能性。
例如,假设有两个事务,事务A和事务B,它们都需要读取和修改同一条数据。在MVCC中,事务A可以先创建一个数据的快照进行读操作,此时即使事务B也开始修改这条数据,事务A的读操作也不会被阻塞。而当事务A要进行写操作时,只有当事务B的写操作已经完成并且事务已经提交,事务A的写操作才会被阻塞。这样就大大降低了死锁的可能性。
1.1.3. 解决脏读、不可重复读和幻读等问题
通过在每个事务处理其自己的快照,并在需要时创建对象的新版本,MVCC能够解决脏读、不可重复读和幻读等事务隔离问题。
在MVCC(多版本并发控制)模型中,每个事务处理的都是数据库在某个时间点的快照,并且在多个事务处理同一个数据项时,会生成该数据项的新版本。这种机制能有效解决一系列事务隔离的问题:
脏读:脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。在MVCC机制中,每个事务都只读取事务开始时的数据快照,不会读取到其他未提交事务的数据,因此避免了脏读。
不可重复读:不可重复读是指在一个事务内,多次读同一数据时,由于其他事务的提交,导致多次读取的结果不一致。MVCC通过在每个事务开始时创建数据的快照,并在事务运行过程中一直使用此快照,确保了在同一事务中多次读取同一数据总是返回同一个结果,避免了不可重复读。
幻读:幻读是指在一个事务内部,先后执行两个查询操作,第二个查询出现了第一个查询不存在的记录,或者之前的记录消失,这种现象称为幻读。可重复读(RR)隔离级别下的InnoDB能通过MVCC来防止幻读,事务会看到一个一致的快照,这个快照在事务开始时创建,并在事务运行期间不会更改,从而避免了幻读。
1.1.4. 实现非阻塞读
在MVCC模型下,读操作不会阻塞写操作,写操作也不会阻塞读操作。
1.1.5. 提供一致性视图
使用MVCC,每个事务都在其开始时获取一个快照,然后在该快照上执行所有操作,这样可以保证事务执行过程中看到的数据是一致的。
2. MVCC的实现原理
2.1. 隐式字段
InnoDB引擎在MVCC实现过程中,会在每行数据后面添加额外的系统隐藏字段;
根据官方文档中描述是三个字段 DB_ROW_ID
, DB_TRX_ID
,DB_ROLL_PTR
。但是从有的博客文章中看到还有一个字段DELETED_BIT
。我在相关官方文档中没有证实。如果哪位同仁找到官方的相关描述记得@一下我,非常感谢
我在mysql5.7和8.0版本的官方文档和代码里都去求证未果。
5.7版本 mvcc 官方文档
https://dev.mysql.com/doc/refman/5.7/en/innodb-multi-versioning.html8.0版本 mvcc 官方文档
https://dev.mysql.com/doc/refman/8.0/en/innodb-multi-versioning.html- MySQL源码地址 https://github.com/mysql/mysql-server/tree/8.0
DB_ROW_ID
: 6bytes,隐含的自增ID(隐藏主键)。如果数据表没有主键,InnoDB会自动以DB_ROW_ID
产生一个聚簇索引。DB_TRX_ID
: 6bytes,最近修改(修改/插入)事务ID。记录创建这条记录或最后一次修改该记录的事务ID。DB_ROLL_PTR
: 7bytes,回滚指针。指向这条记录的上一个版本(存储于Undo Log里)。DELETED_BIT
: 1byte,【我暂未证实存在,只是在一些博客帖子中看到有同学在解释】该字段标识该行是否被删除。记录被更新或删除,并不意味真的删除,而是删除标志位变更。
通过这种方式,InnoDB存储引擎通过DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID等隐式字段,结合Undo Log,实现了MVCC的功能,同时保证了事务的ACID性质(原子性、一致性、隔离性、持久性)。
2.1. undo日志
Undo日志在MySQL的InnoDB中是用于实现数据一致性、事务回滚以及多版本并发控制(MVCC)的重要组成部分。Undo日志主要由以下几部分组成:
-
Undo日志记录:每个Undo日志记录包含了一个数据版本的信息。当一个事务对数据库中的某个记录进行修改时,InnoDB会在Undo日志中生成一个包含这个记录修改前信息的Undo日志记录。
-
Undo日志段(Undo Log Segment):Undo日志记录被分组存储在Undo日志段中。每个事务在开始时会在Undo段中创建一个新的Undo日志记录,这个记录包含了事务开始时候的数据状态。
-
回滚段(Rollback Segment):回滚段是Undo日志段的容器,每个回滚段可以包含多个Undo日志段。InnoDB中默认存在128个回滚段。
-
Undo表空间(Undo Tablespace):Undo表空间是存储Undo日志的物理空间,可以存储多个回滚段。
在InnoDB中,Undo日志的生命周期从事务开始到事务结束。如果一个事务在执行过程中失败或者被显式回滚,InnoDB将使用Undo日志记录来恢复数据的原始状态,确保数据的一致性。如果事务执行成功并提交,相关的Undo日志记录将被标记为可回收,并在之后的清理操作中被删除。
概念和理论相对比较苦涩,我们以商城系统中的商品表为示例。
场景示例
比如有个商品表。
第一步:有个事务插入商品表插入了一条新记录,记录如下,名称为萝卜, price为1,隐式主键是1,事务ID和回滚指针,我们假设为NULL。
第二步:现在来了一个事务1对该记录的name做出了修改,改为黄瓜。
第三步:又来了个事务2修改商品表的同一个记录,将price修改为2.5 。
我们可以推测出 undo日志的存储过程 和表内容变化如下
- 商品表的初始状态如下:
名称 | 价格 | 隐式主键 | 事务ID | 回滚指针 |
---|---|---|---|---|
萝卜 | 1 | 1 | NULL | NULL |
- 然后,事务1对名称字段做出了修改。这时,对应的undo日志记录如下:
事务ID | 表名 | 行ID | 操作类型 | 旧值 | 新值 |
---|---|---|---|---|---|
1 | 商品表 | 1 | 更新 | 萝卜 | 黄瓜 |
- 商品表的状态变为:
名称 | 价格 | 隐式主键 | 事务ID | 回滚指针 |
---|---|---|---|---|
黄瓜 | 1 | 1 | 1 | 指向事务1的undo日志 |
- 接着,事务2对价格字段做出了修改。对应的undo日志记录如下:
事务ID | 表名 | 行ID | 操作类型 | 旧值 | 新值 |
---|---|---|---|---|---|
2 | 商品表 | 1 | 更新 | 1 | 2.5 |
- 商品表的状态变为:
名称 | 价格 | 隐式主键 | 事务ID | 回滚指针 |
---|---|---|---|---|
黄瓜 | 2.5 | 1 | 2 | 指向事务2的undo日志 |
这个过程中,InnoDB会为每一次的修改操作生成一条undo日志记录。如果之后需要回滚事务,InnoDB就可以利用这些undo日志记录恢复数据的原始状态。
2.1. Read View(读视图)
基本介绍
Read View或读视图是用来实现一致性非锁定读(即MVCC,多版本并发控制中的读操作)的一种机制。
当一个事务需要执行一致性非锁定读操作时,InnoDB会为该事务生成一个读视图。这个读视图包含了当前正在活动的所有事务的事务ID,这些事务在生成读视图的时间点之后如果有新的数据改动,都不会被该读视图所看到。换句话说,只有在生成读视图时已经提交的事务改动的数据,才会被该读视图看到。
具体来说,当一个事务开始执行SELECT操作时,如果该事务是在READ COMMITTED隔离级别下,那么InnoDB会在每个SELECT语句之前为该事务生成一个新的读视图。如果该事务是在REPEATABLE READ隔离级别下,那么InnoDB只会在事务开始时生成一个读视图,然后在整个事务期间都使用这个读视图。
场景示例
假设我们有一个简单的银行账户表,包含"账户ID"和"余额"两个字段:
账户ID | 余额 |
---|---|
1 | 500 |
2 | 1000 |
3 | 1500 |
现在,假设我们有两个并发的事务,事务A和事务B。
1. 事务A开始,它想要查看账户1和账户2的余额,所以它执行一个SELECT语句。由于事务A是在REPEATABLE READ隔离级别下执行的,所以InnoDB为它生成一个读视图。这个读视图捕获了数据库在事务A开始时的状态,即账户1的余额为500,账户2的余额为1000。
2. 此时,事务B开始,并且它向账户1汇入了100元,然后提交了事务。数据库的实际状态变为了账户1的余额为600,账户2的余额为1000。
3. 事务A再次执行SELECT语句,想要再次查看账户1和账户2的余额。但是,由于事务A在执行SELECT时使用的是在它开始时生成的读视图,所以它看到的账户1的余额仍然是500,账户2的余额仍然是1000,而不是数据库的实际状态。这就是读视图如何实现一致性非锁定读的。
在这个例子中,尽管事务B在事务A执行过程中改变了数据库的状态,但是由于读视图的存在,事务A看到的数据仍然是一致的,不会受到事务B的影响。这就是InnoDB如何通过使用读视图来实现MVCC的。
原理
在一个readview快照中主要包括以下这些字段:
m_ids:活跃的事务就是指还没有commit的事务。
max_trx_id:例如m_ids中的事务id为(1,2,3),那么下一个应该分配的事务id就是4,max_trx_id就是4。
creator_trx_id:执行select读这个操作的事务的id。
readview如何判断版本链中的哪个版本可用呢?(重点!)
从上到下分别为(1)(2)(3)(4),依次进行解释
trx_id表示要读取的事务id
(1)如果要读取的事务id等于进行读操作的事务id,说明是我读取我自己创建的记录,那么为什么不可以呢。
(2)如果要读取的事务id小于最小的活跃事务id,说明要读取的事务已经提交,那么可以读取。
(3)max_trx_id表示生成readview时,分配给下一个事务的id,如果要读取的事务id大于max_trx_id,说明该id已经不在该readview版本链中了,故无法访问。
(4)m_ids中存储的是活跃事务的id,如果要读取的事务id不在活跃列表,那么就可以读取,反之不行
通过这种方式,InnoDB可以为每个事务提供一个它自己的一致性视图,这样即使数据库中的数据在事务执行过程中发生了改变,事务看到的数据也会保持一致,不会受到其他事务的影响。从而实现了事务的一致性读,也就是所谓的snapshot(快照)读,这是实现MVCC的关键。
2.1. 整体流程
MySQL的MVCC多版本并发控制主要涉及以下几个步骤:
-
事务启动:当一个事务启动并执行第一个操作时,系统会为该事务分配一个唯一的事务ID。
-
读操作:在发生读操作时,InnoDB会创建一个Read View(读视图)。这个读视图记录了启动时所有正在执行的事务ID,该事务在执行过程中,只能看到在读视图创建之前已经提交的事务所做的修改,对于在读视图创建之后其他事务所做的修改,该事务是无法看到的。
-
写操作:当事务进行写操作时,InnoDB不会直接覆盖旧的数据,而是将旧数据复制一份保存到undo日志中,并生成一个新的版本数据,新的数据上会记录下创建该版本的事务ID。同时,InnoDB还会在多版本链表中插入一个新的版本,链表中的版本按照事务ID从大到小的顺序进行排序。
-
事务提交:当事务提交时,系统会将该事务的ID号从全局的活动事务列表中删除。
-
版本回收:当系统判断某个版本的数据已经不再需要时(即没有任何一个活动的事务需要访问这个版本的数据),就会回收这个版本的数据以释放存储空间。
6.整体执行流程 如下
3. MVCC相关问题
3.1. RR是如何在RC级的基础上解决不可重复读的?
RC(Read Committed)级别和RR(Repeatable Read)级别是两种常见的事务隔离级别。
在RC级别,每次读取都会读取到该行最新的数据,因此,一个事务在不同时间执行相同的查询,可能会得到不一样的结果,这就是所谓的“不可重复读”。
为了解决RC级别下的“不可重复读”问题,RR级别的事务在开始时会创建一个快照(snapshot),也就是一个数据的副本。在事务进行过程中,即使其他事务修改了数据,由于每次读取都是读取的这个快照,因此在一个事务内,多次读取同一数据,得到的都是一样的结果。
这就是RR级别如何在RC级别的基础上解决不可重复读问题的。这是通过牺牲一定的并发性能,增加了数据一致性。不过在很多场景下,数据一致性比并发性能更加重要,因此RR级别也被广泛使用。
3.1.RC,RR级别下的InnoDB快照读有什么不同?
既然我们已经了解了RC(Read Committed)和RR(Repeatable Read)的差异,那么,这两个隔离级别下的InnoDB快照读又有什么不同呢?
主要的区别在于快照读的创建时间。
-
在RC级别下,每一次语句执行之前都会创建一个新的Read View(快照),而无论这个事务执行了多少语句,只要它还在执行,就会持续创建新的Read View。因此,即使在同一事务中,多次读取同一行数据可能会读取到不同版本的数据,即出现“不可重复读”。
-
而在RR级别下,只有在事务刚开始执行第一个语句时会创建一个Read View,之后在这个事务中的所有操作,都只会看到这个Read View所代表的数据版本。其他事务在这之后做的修改,对当前事务来说是不可见的,因此在同一事务中,多次读取同一数据总是能够读到相同的结果,即保证了“可重复读”。
-
RC和RR级别下InnoDB快照读的差异,主要是由RC和RR的隔离级别特性决定的,RR级别相比RC级别提供了更高的数据一致性,但是在并发性能上可能会有所下降。
参考资料
-
官方文档:MySQL官方网站提供了关于各种存储引擎的详细文档,包括InnoDB和MyISAM等。https://dev.mysql.com/doc/refman/8.0/en/storage-engines.html
-
书籍《高性能MySQL》是一本非常全面的关于MySQL性能优化、架构设计和内部机制的书籍,其中包含了大量关于存储引擎的内容。
-
知乎大佬写的 https://zhuanlan.zhihu.com/p/447372441
相关文章:
【进阶篇】MySQL的MVCC实现机制详解
文章目录 0.前言1.基础介绍1.1. 什么是MVCC?1.1. 什么是当前读和快照读?1.1. 当前读,快照读和MVCC的关系1.1. MVCC能解决什么问题,好处是?1.1.1. 提高并发性能1.1.2. 避免死锁1.1.3. 解决脏读、不可重复读和幻读等问题1.1.4. 实现…...
Git 命令行查看仓库信息
目录 查看系统config 编辑查看当前用户(global)配置 查看当前仓库配置信息 查看系统config git config --system --list 1 查看当前用户(global)配置 git config --global --list 1 查到的是email , name 等ssl签名信息&a…...
【爬虫】8.1. 深度使用tesseract-OCR技术识别图形验证码
深度使用tesseract-OCR技术识别图形验证码 文章目录 深度使用tesseract-OCR技术识别图形验证码1. OCR技术2. 准备工作3. 简单作用了解3.1. 验证码图片爬取-screenshot_as_png3.2. 识别测试-image_to_string3.2.1. 正确识别3.2.2. 错误识别3.2.3. 灰度调节 3.3. 识别实战-使用im…...
【PythonRS】基于GDAL修改栅格数据的DN值
遥感工作者离不开栅格数据,有时候我们可能需要修改栅格数据的值,但ENVI和ArcGIS中并没有直接修改DN值的工具,只有栅格计算器、Band math这些工具去计算整个波段的值,或者Edit Classification Image工具可以修改ENVI分类后的像元值…...
mysql课堂笔记 mac
目录 启动mac上的mysql 进入mysql mac windows 创建数据库 创建表 修改字段数据类型 修改字段名 增加字段 删除字段 启动mac上的mysql sudo /usr/local/mysql/support-files/mysql.server start 直接输入你的开机密码即可。 编辑 进入mysql mac sudo /usr/local…...
2023年数学建模国赛A 定日镜场的优化设计思路分析
构建以新能源为主体的新型电力系统,是我国实现“碳达峰”“碳中和”目标的一项重要措施。塔式太阳能光热发电是一种低碳环保的新型清洁能源技术[1]。定日镜是塔式太阳能光热发电站(以下简称塔式电站)收集太阳能的基本组件,其底座由…...
【QT】QMessageBox消息框的使用(16)
在实际项目中,弹出消息框是一个很常见的操作,包含错误信息提示、警告信息提示、关于信息提示、还包括判断信息选择等操作,那么今天通过这一节来好好了解下消息框的使用方法。 一.环境配置 1.python 3.7.8 可直接进入官网下载安装…...
XL-LightHouse 与 Flink 和 ClickHouse 流式大数据统计系统
一个Flink任务只能并行处理一个或少数几个数据流,而XL-LightHouse一个任务可以并行处理数万个、几十万个数据流; 一个Flink任务只能实现一个或少数几个数据指标,而XL-LightHouse单个任务就能支撑大批量、数以万计的数据指标。 1、XL-LightHo…...
【postgresql 基础入门】创建数据库的方法,存储位置,决定自己的数据的访问用户和范围
创建数据库 专栏内容: postgresql内核源码分析手写数据库toadb并发编程 开源贡献: toadb开源库 个人主页:我的主页 管理社区:开源数据库 座右铭:天行健,君子以自强不息;地势坤,君…...
科技云报道:AI时代,对构建云安全提出了哪些新要求?
科技云报道原创。 随着企业上云的提速,一系列云安全问题也逐渐暴露出来,云安全问题得到重视,市场不断扩大。 Gartner 发布“2022 年中国 ICT 技术成熟度曲线”显示,云安全已处于技术萌芽期高点,预期在2-5年内有望达到…...
如何让 Llama2、通义千问开源大语言模型快速跑在函数计算上?
:::info 本文是“在Serverless平台上构建AIGC应用”系列文章的第一篇文章。 ::: 前言 随着ChatGPT 以及 Stable Diffusion,Midjourney 这些新生代 AIGC 应用的兴起,围绕AIGC应用的相关开发变得越来越广泛,有呈井喷之势,从长远看这波应用的爆…...
Linux内核源码分析 (B.2)虚拟地址空间布局架构
Linux内核源码分析 (B.2)虚拟地址空间布局架构 文章目录 Linux内核源码分析 (B.2)虚拟地址空间布局架构一、Linux内核整体架构及子系统二、Linux内核内存管理架构 一、Linux内核整体架构及子系统 Linux内核只是操作系统当中的一部分,对下管理系统所有硬件设备&…...
Spring系列文章:Spring使用JdbcTemplate
一、简介 JdbcTemplate是Spring提供的⼀个JDBC模板类,是对JDBC的封装,简化JDBC代码。 当然,你也可以不⽤,可以让Spring集成其它的ORM框架,例如:MyBatis、Hibernate等。 第一步:引入依赖 <d…...
[matlab]cvx安装后测试代码
测试环境: windows10 x64 matlab2023a 代码来自官方网站:CVX: Matlab Software for Disciplined Convex Programming | CVX Research, Inc. m 20; n 10; p 4; A randn(m,n); b randn(m,1); C randn(p,n); d randn(p,1); e rand; cvx_beginva…...
【css】margin:auot什么情况下失效
margin:auto只对块级元素有效果,并且在正常文档流margin:automargin:0 auto,css默认在正常文档流里面margin-top和margin-bottom是0 为什么margin: auto能实现水平居中,而垂直居中不行? 一般子…...
linux的dirty page回写磁盘过程中是否允许并发写入更新page?
概述 众所周知Linux内核write系统调用采用pagecache机制加速写入过程,避免write系统调用长时间block应用进程,用户态进程执行write调用的时候,内核只是将用户态buffer copy到内核的pagecache当中,write系统调用就返回了,完全不需要等待数据完全写入存储设备,因为存储设备…...
Docker-基础命令使用
文章目录 前言命令帮助命令执行示意图docker rundocker psdocker inspectdocker execdocker attachdocker stopdocker startdocker topdocker rmdocker prune参考说明 前言 本文主要介绍Docker基础命令的使用方法。 命令帮助 Docker命令获取帮助方法 # docker -h Flag shor…...
【Python 程序设计】Python 中的类型提示【06/8】
目录 一、说明 二、什么是动态类型? 2.1 为什么要使用类型提示? 2.2 局限性 三、基本类型提示 3.1 声明变量的类型 3.2 函数注释 四、Python 中的内置类型 4.1 原子类型与复合类型 五、函数注释 5.1 如何指定函数的参数类型和返回类型 5.2 在函数签名中…...
78 # koa 中间件的实现
上上节实现了上下文的,上一节使用了一下中间件,这一节来实现 koa 的中间件这个洋葱模型。 思路: 储存用户所有的 callback将用户传递的 callback 全部组合起来(redux 里的 compose)组合成一个线性结构依次执行&#…...
国产操作系统麒麟v10中遇到的一些问题
下载pycharm:直接在应用商店 目标:主机1安装了虚拟机,主机2要ping通主机1安装的虚拟机。 前提:主机1,主机2在同一局域网下,同一网段。 网络配置 因为虚拟机的网段不在局域网网段内,局域网下…...
Gridea+GitPage+Gittalk 搭建个人博客
👋通过GrideaGitPage 搭建属于自己的博客! 👻GitPage 负责提供 Web 功能! 😽Gridea 作为本地编辑器,方便 push 文章! 🏷本文讲解如何使用 GrideaGitPage 服务域名(可选&a…...
代码质量保障第2讲:单元测试 - 浅谈单元测试
代码质量保障第2讲:单元测试 - 浅谈单元测试 本文是代码质量保障第2讲,浅谈单元测试。单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。这是基础,所以围绕着单元测试,我从…...
“五度晟企通”企业发展服务平台正式发布,帮扶企业行稳致远!
在数字中国建设的大背景下,“五度易链”以企业实际发展需求为牵引,以帮扶企业行稳致远为目标,基于全体量产业大数据,运用NLP、AI等新一代信息技术,打造了数字化ToB企业发展服务平台“五度晟企通”,旨在以数…...
Java类和对象(七千字详解!!!带你彻底理解类和对象)
目录 一、面向对象的初步认知 1、什么是面向对象 2、面向对象和面向过程 (1)传统洗衣服的过程 (2)现代洗衣服过程 编辑 二、类的定义和使用 1、类的定义格式 三、类的实例化 1、什么是实例化 2、类和对象说明 四、t…...
机器学习笔记:node2vec(论文笔记:node2vec: Scalable Feature Learning for Networks)
2016 KDD 1 intro 利用graph上的节点相似性,对这些节点进行embedding 同质性:节点和其周围节点的embedding比较相似 蓝色节点和其周围的节点结构等价性 结构相近的点embedding相近 比如蓝色节点,都处于多个簇的连接处 2 随机游走 2.1 介绍…...
go基础10 -字符串的高效构造与转换
前面提到过,Go原生支持通过/操作符来连接多个字符串以构造一个更长的字符串,并且通过/操作符的字符串连接构造是最自然、开发体验最好的一种。 但Go还提供了其他一些构造字符串的方法,比如: ● 使用fmt.Sprintf; ● 使…...
VR钢铁实训 | 铁前事业部虚拟仿真培训软件
随着科技的发展,虚拟现实技术在各个行业中的应用越来越广泛。在钢铁冶炼行业中,VR技术也逐渐得到了应用,其中铁前事业部虚拟仿真培训软件就是一项非常有优势的技术。 铁前事业部虚拟仿真培训软件是广州华锐互动打造的《钢铁生产VR虚拟培训系统…...
DevOps
DevOps 是开发 (Dev) 和运营 (Ops) 的复合词,它将人、流程和技术结合起来,不断地为客户提供价值。 DevOps 对团队意味着什么? DevOps 使以前孤立的角色(开发、IT 运营、质量工程和安全)可以协调和协作,以生…...
IJ中PHP环境的搭建和使用教程
目录 目录 前言 思维导图 1,PHP环境下载 1.下载链接 2.进行安装 3,自定义路径 4.进行相关的一些库的选择下载 2,进行IJ中PHP环境的配置 2.1,下载PHP插件 2.2,下载过程中的注意事项 3,为什么这么做呢? 3.1,原因 3.2,进行代码…...
java开发之个人微信的二次开发
简要描述: 修改我在某群的昵称 请求URL: http://域名/updateIInChatRoomNickName 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参…...
武汉建网站公司怎么样/郑州网站开发公司
freemarker使用时间类型注意事项 1、在配置文件中约束 freemarker的显示样式可以在配置文件中配置 <!-- 配置freemarker模板路径 --><bean id"freemarkerConfig" class"org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"…...
赣州做网站建设/东莞seo建站如何推广
前言 在上一篇开始Java8之旅(六) -- 使用lambda实现Java的尾递归中,我们利用了函数的懒加载机制实现了栈帧的复用,成功的实现了Java版本的尾递归,然而尾递归的使用有一个重要的条件就是递归表达式必须是在函数的尾部,但是在很多实…...
常州做网站公司排名/微博搜索引擎优化
原文地址为: ASP.NET Web API系列教程(目录)注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP.NET Web API。这是一个用来在.NET平台上建立HTTP服务的Web API框架,是微软的又一项令人振奋的技术。目前&…...
wordpress破解插件/安徽seo优化
这个问题真的好纠结,数据保存到数据库后读出来的时候显示在页面上的却是一大段含有html标签的文字。整了好久代码明明就没错误显示出来怎么就成这样子呢,自己气的差点要吐血。后来才知道原来是struts标签的问题。普通的html标签是不会有这个问题的。 解决…...
如何做问卷调查网站/网站关键词优化排名外包
开源项目学习流程 1.首先大概了解项目实现的功能有哪些(有没有readme或者doc文件); 2.尝试编译/安装,搞懂测试实例; 3.然后找到整个程序入口(库一类的没有); 4.然后搞懂项目结构(使用了哪种项目管理配置工具makefile?…...
wordpress清理/黄山网站建设
http://www.cnblogs.com/leesf456/p/6063694.html zk的应用: https://baijiahao.baidu.com/s?id1576906164723309054&wfrspider&forpc...