首页 > 编程知识 正文

mysql集群架构,mysql使用MVCC来解决幻读

时间:2023-05-04 05:12:02 阅读:166598 作者:1195

MySQL结构

MySQL模式映射很容易理解MySQL。

MySQL架构

顶级连接线程处理提供给客户端,包括连接处理、许可证验证和安全性。

第2层是MySQL核心服务,包括查询分析、分析、优化、缓存和所有内置函数(日期、时间、数学、加密函数等),存储引擎之间的所有功能都在此层实现。 存储过程、触发器、视图等。

第3层包含存储引擎。 存储引擎负责存储和提取MySQL中的数据。 每个存储引擎都有优势和劣势,服务器通过API与存储引擎进行通信。 这些API对高层查询处理是透明的,因为它们阻止了不同存储引擎之间的差异。 存储引擎不会分析SQL,也不会在不同的存储引擎之间进行通信,它只是响应上级服务器的请求。

优化和执行

MySQL分析查询并创建和优化分析树,包括查询重写、表读取顺序和选择适当的索引。 一般来说,它使用explain请求优化程序描述SQL执行过程。 优化程序不在乎表正在使用的是哪个存储引擎。 但是,存储引擎会影响优化查询,优化程序会向存储引擎请求容量或操作开销信息以及表数据统计信息。

对于SELECT语句,服务器在解析查询之前会检查查询缓存。 如果找到相应的查询,服务器就不需要执行查询解析。 整个优化过程只需直接返回结果集。

同时控制

只要多个SQL同时读写数据,就存在并发性问题。 MySQL通过锁定机制解决了并发性问题。

读写锁

有两种类型的锁定:读锁定和写锁定。 读锁定共享而不相互阻塞,写锁定是独占的,一个写锁定会阻塞其他写锁定和读锁定。 这是为了防止其他用户在用户执行写入操作时读取和写入统一资源。

写锁定请求可能会插入在读锁定之前,因为写锁定的优先级高于读锁定。

使用锁还需要获取锁、检查锁和解除锁等资源。 因此,必须在资源消耗(性能)和数据安全之间取得平衡。 MySQL提供了多种选择,每个存储引擎都可以实现自己的锁定策略。 在所有锁定策略中,最重要的是以下两个策略:

钟表锁

表锁是MySQL中最基本的锁策略,也是开销最小的锁。 桌子锁会锁定整个桌子。 一个用户必须先获取锁,然后才能向表写入,获取锁会阻止其他用户对表的读/写操作。

在某些场景中,表锁定策略具有较好的性能,例如READ LOCAL表锁定支持特定类型的并发写入。

服务器管理自己的锁,而MySQL本身使用表锁来实现各种目的。 例如,服务器使用ALTER TABLE语句的表锁定,而忽略存储引擎本身的锁定机制。

行级锁定

行锁定最大限度地支持并发处理,但会带来最大的开销。 存储引擎InnoDB实现行级锁,而行级锁仅在存储引擎中实现,而不是在MySQL服务器层实现。

事务

最基本和最重要的是事务和隔离级别。 一提到学习Hibernate,一提到学习MyBatis,一提到学习Spring事务,就觉得耳朵里起了风筝。 附上自己写的报道。 SPRING事务

死锁

如果多个事务尝试以不同的顺序锁定资源,则会发生死锁;如果多个事务尝试同时锁定同一资源,则会发生死锁。 为了解决这一问题,数据库实现了各种死锁检测和死锁超时机制。 越复杂的系统越能检测到死锁(如InnoDB存储引擎),并会立即返回错误。 发生死锁后,需要部分或完全回滚事务才能打破死锁。 对于事务型系统,死锁是不可避免的,因此必须考虑如何处理死锁。 在大多数情况下,只需重新执行通过死锁回滚的事务即可。

事务日志

事务日志有助于提高事务效率。 使用事务日志,存储引擎可以在更改表数据时将更改行为传递到永久存储在硬盘上的事务日志中,而不是每次更改内存副本并将更改的数据永久存储在磁盘上

事务日志采用了附加方法,因此速度很快,因为顺序I/O只在磁盘的小空间内进行。 事务日志持久化后,内存中已更改的数据将逐渐刷新到磁盘。

如果数据更改被记录并永久保存,并且数据本身还未写入磁盘,系统将崩溃,存储引擎可以在重新启动时自动恢复部分更改的数据。 具体的恢复方法因存储引擎而异。

MySQL事务

MySQL提供了两种事务性存储引擎: InnoDB和ndb群集。

自动提交

MySQL缺省处于自动提交模式。 如果启动了未显示的事务,则每个查询将作为事务提交。

show variables like 'autocommit '; -询问当前模式

设置自动命令=0; -关闭自动提交,打开1或打开,关闭0或关闭

如果关闭自动提交,则所有查询都位于一个事务中,在显式执行COMMIT或ROLLBACK之前,事务将结束并开始新事务。

更改非事务型表(如MyISAM )不会产生影响。 这样的表没有事务概念,这意味着启用了autocommit。

设置隔离级别

MySQL的缺省隔离级别为REPEATABLE-READ,可以使用以下命令设置隔离级别: 新的隔离级别将在下一个事务开始时生成

效。

select @@global.tx_isolation; -- 查询当前隔离级别

set session transacton isolation level read committed; -- 只改变当前会话隔离级别

set global transacton isolation level read uncommitted; -- 设置当前系统的隔离级别

也可以在配置文件中设置整个数据库的隔离级别,MySQL识别4个ANSI隔离级别,InnoDB支持所有隔离级别。

MVCC

MySQL的大多数事务存储引擎实现都不是简单的行级锁,一般是实现了多版本并发控制(MVCC)。可以认为MVCC是行级锁的一个变种,它在很多情况下避免了加锁操作,因此开销更低,在进行读操作时不需要阻塞,写操作只锁定必要的行。

MVCC的实现

MVCC的实现,是通过保存数据在某个时间点的快照实现的。这样就保证了不管事务不管运行多长时间,在同一个事务中看到的数据是一致的。

不同存储引擎的MVCC实现是不同的,典型的有乐观锁并发控制和悲观并发控制。在InnoDB的MVCC,是乐观锁并发控制,通过在每行记录后面保存两个隐藏的列来实现的。这两个列保存了行创建时的系统版本号和删除时的删除版本号,每开始一个新的事务,系统版本号都会自动递增。系统版本号会作为事务的版本号,用来和查询每行记录的版本号进行比较。

InnoDB在REPEATABLE READ隔离级别下,不同具体操作如下:

SELECT

查找的数据必要符合下面两个条件:

查找系统版本号小于等于当前事务版本号的数据行,这样可以确保事务读取的行要么是事务开始前已经存在的行,要么是事务自身插入或修改的

删除版本号未指定或大于当前事务版本号的数据行,确保数据读取到的行在事务开始前未被删除。

INSERT

新插入的每一行保存当前事务版本号

DELETE

将当前事务版本号保存为删除版本号

UPDATE

原有的数据行的删除版本号记录为当前事务版本号,然后插入一条新的记录

MVCC的总结

保存了这两个版本号,使大多数读操作都不用加锁,这样设计操作简单,提升了性能,保证了只会读取到符合标准的行。不足的地方是每行记录都需要额外的存储空间,需要做更多的检查工作,以及额外的维护工作。

MVCC只在REPEATABLE READ和READ COMMIT两个隔离级别下工作,对于READ UNCOMMITTED和SERIALIZABLE不兼容,前者只读取最新的数据行,后者对读取的所有数据行都加锁。

存储引擎

InnoDB

InnoDB是MySQL默认的存储引擎,也是最重要,使用最广泛的存储引擎,它被设计用来处理短期事务,另外InnoDB还有性能优势和自动崩溃恢复特性。在日常开发中,除非有特别的原因,否则优先考虑InnoDB。

特性

1.InnoDB采用MVCC来支持高并发,实现了四个标准的隔离级别。默认级别是REPEATABLE READ,通过间隙锁策略防止幻读的出现。间隙锁使得InnoDB不仅仅锁定查询涉及到的行,还会对索引中的间隙进行锁定,防止幻影行的插入。

2.InnoDB表是基于聚簇索引建立的,聚簇索引对主键查询有很高的性能。不过它的二级索引中必须包含主键列,所以如果主键列很大的话,其他所有索引都会很大。因此索引较多的话,主键应当尽可能的小。

3.InnoDB支持在线热备份。

4.InnoDB在崩溃的情况下发生损坏的概率低,恢复速度快。

MyISAM

在MySQL5.1版本之前,MyISAM是默认的存储引擎,它提供了大量的特性,包括全文索引,压缩,空间函数等,但它不支持事务和行级锁,最重要的是崩溃后无法安全恢复。

特性

MyISAM对整张表加锁,而不是针对行。读取时会对需要读到的所有表加读锁,写入时对表加写锁。

MyISAM引擎设计简单,数据以紧密格式存储,在某些场景下性能很好。

其他内建引擎

Archive、CVS、Memory、Merge等等。

除了内建引擎外,还有一些第三方的存储引擎,以插件的形式供MySQL使用。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。