📕
innohub
  • KEEP LEARNING
  • WebInfo
    • JS 部分运算符操作
    • javascript 中的object array
    • 错误处理以及异常捕获
    • JavaScript Bases
    • LaoZi & Confucius
  • PyInfo
    • Python3 输入与输出
    • Python3OS
    • python 修饰器的使用
    • python3 与mysql数据库连接使用实例
    • Format-specifier
    • CGI初学踩坑
    • Django 项目测试
    • Assert-info
    • 使用ngnix和uWSGI配置Django
    • write|SVN​
    • Matplotlib 基本使用
    • 重读 Python 官方文档
    • Python3 Base
    • python3 多线程
    • Python3 函数解析
    • python3 str 对象的基本操作
    • protocl buffers
    • Iterator-Generator
    • Django base
    • Decorator 2
    • Export to wheel or egg-info
    • 三. 运算、数据及逻辑
  • GoInfo
    • Info
      • Select 语句使用
      • First class function
      • Work Pools
      • StructTag
      • Go struct
      • 常用函数
      • Strings操作
      • Golang Bases
      • 数组以及切片
      • 文件操作
      • Golang 中的指针类型
      • Golang Map 类型
      • Reflection
      • 函数闭包
      • 接口
      • Panic and Recover
      • Go中的错误处理
      • 并发
      • defer usage
      • Method in golang
      • Object-oriented Programming
      • Goalng 包管理机制
  • RustInfo
    • Info
      • 包、crate、模块
      • Rust 中的错误处理
      • 智能指针
      • 泛型 generics
      • 数据布局与内存对齐
      • Functions and methods
      • 无畏并发
      • Actix-web 基本使用
      • Got from guessing game
      • 结构体的使用
      • Rust 中的函数式语言功能
      • 集合类型
      • 枚举以及模式匹配
      • Slice 类型
      • 生命周期
      • 测试
      • Rust 中的所有权
      • trait
      • 不安全 Rust
      • Format_print
      • Rust 通用编程概念
      • Macro
  • OS
    • info
      • 内存屏障 -- Part 1
      • 内存屏障 -- Part 2
      • CPU 上下文切换
      • 文件读写与零拷贝
      • ELF 文件
  • MySql
    • info
      • MySql 架构与历史
      • 02-key
  • kubernetes
    • 第二章 k8s 基本概念
    • 第一章 Kubernetes -- 伟大舵手
  • Redis
    • info
      • Redis 总览
      • 02-underline-ds
  • Shell&CInfo
    • GCC 与make的使用
    • C++ 中 malloc 与 new
    • 位运算符操作
    • Base of C macro
    • C 语言中 extern 关键字的用法
  • Distributed
    • info
      • 分布式理论概述
  • Java
    • info
      • Java 内存模型
  • Prometheus
    • Prometheus -- 不灭之火
Powered by GitBook
On this page
  • 1. 逻辑架构
  • 2. 并发控制
  • 2.1 事务
  • 2.2 隔离级别
  • 2.3 死锁
  • 2.4 事务日志
  • 2.5 MVCC

Was this helpful?

  1. MySql
  2. info

MySql 架构与历史

PreviousinfoNext02-key

Last updated 3 years ago

Was this helpful?

[TOC]

1. 逻辑架构

arch

Mysql 是C/S架构,总共可以分为三层:

  • 最上层客户端,mysql的图形化连接软件和各种编程语言的mysql连接模块,例如Python的MySQLdb模块,还有API接口等等

  • 第二层就是mysql的核心服务,也称为service层。包括:查询解析、分析、优化、缓存以及所有的内置函数(例如:日期、时间、数学和加密函数)。同时,所有的跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等

  • 第三层为存储层,包含了存储引擎,存储引擎负责数据的存储与提取,服务器通过API与存储引擎进行通信,这些接口屏蔽了不同存储引擎之间的差异,使得这些差异对于上层的查询过程透明。

2. 并发控制

每一个客户端都会在服务器中拥有一个线程,这个连接的查询只会在该线程中进行,这个线程只会轮流在某一个cpu核心或者cpu上运行,服务器负责缓存线程。只要有多个查询需要同时操作数据都会有并发控制问题。mysql在服务器层、存储引擎层进行并发控制。

  • 读写锁(共享锁、排他锁)

  • 锁粒度: 行级锁、表级锁 不同类型的存储引擎会实现各自的锁策略以及锁粒度。ALTER TABLE 操作服务器层会使用表锁忽略存储引擎的锁机制;而存储引擎中的行锁实现对于服务器层也是不可见的

  • 事务: 一组原子性的SQL查询,或者一个独立的工作单元

2.1 事务

一个运行良好的事务管理系统,需要具有ACID属性:

  • 原子性(Atomicity): 一个事务是一个最小的可操作单元,要么成功,要么回滚,不可能只执行一部分

  • 一致性(Consistency):数据库总是从一个一致性状态转移到另一个一致性状态

  • 隔离性(Isolation):通常来说,一个事务所做的修改在提交之前对于其他事务是不可见的;在不同的隔离级别下,事务具有不同的可见性

  • 持久性(Durability):事务一旦提交,所做的修改就会永久保存在数据库中

2.2 隔离级别

每种存储引擎实现的隔离级别不尽相同,主要有以下隔离级别:

  • 未提交读(Read Uncommited):

    事务的修改即使没有提交,对于其他事务也是可见的,也称为脏读。这个隔离级别会导致很多问题,从性能上讲,并不会比其他隔离级别好太多,实际很少使用。

  • 提交读(Read Commited):

    一个事务开始时只能看到其他事务已提交的结果,换句话说,一个事物未提交时所做的操作修改对于其他事务都是不可见的。又称为不可重复读,两次执行查询的结果可能不一致。

  • 可重复读(Repeatable Read):

    解决了脏读的问题,该级别保证同一个事务多次读取同样记录的结果是一致的。但是理论上可重复读不能解决幻读(Phantom Read)*的问题, 幻读是指 当事务读取某一范围的数据时,另一个事务在该范围插入了新的记录,导致之前事务再次读取该范围的数据时会产生幻行 。 InnoDB通过多版本并发控制(MVCC, Multiversion Concurrency Control) 解决幻读问题 可重复读也是Mysql默认的隔离级别

  • 可串行化(Serializable):

    最高隔离级别,强制事务串行执行,避免幻读问题。可串行化通过对于每一行数据加锁,会导致大量的超时以及锁竞争问题。只有在非常需要确保数据一致,而且接受没有并发的情况下使用。

2.3 死锁

多个事务在同一资源上相互占用,并且请求锁定对方占用的资源,从而导致恶性循环的现象。多个事务试图以不同顺序锁定多个资源时就会产生死锁。数据库有多种死锁检测以及死锁超时机制。死锁发生后只有部分或者完全回滚其中一个事务才可以打破死锁。

2.4 事务日志

事务日志可以帮助提高事务的效率,进行数据修改时,只修改其内存拷贝,修改记录持久化到事务日志中,不需要立即将修改数据持久化到硬盘,之后依据日志异步进行数据持久化。事务日志采用追加方式,写日志操作只涉及一小块区域内的顺序io,效率更高。称为预写式日志(Write-Ahead Logging)

2.5 MVCC

大多数存储引擎都实现了MVCC,可以认为MVCC是行级锁的一个变种,但在很多情况下避免了加锁操作,因此开销更低。MVCC通过保存数据在某一个时间点的快照实现的,从而保证同一个事务看到的数据一致。典型的实现有乐观的并发控制以及悲观的并发控制。

InnoDB的mvcc通过在每一行记录的后面保存两个隐藏的列实现的。分别保存行的创建时间、删除时间。保存的并不是实际的时间戳,而是系统版本号。每开始一个事务,系统版本号都会加一,事务开始时刻的系统版本号作为事务版本号:

对于事务A,版本号 Va

  • SELECT

    a. 创建版本号小于等于事务版本号Va的行

    b. 行的删除版本号未定义或者大于Va,确保事务读取的行在事务开始前未被删除

  • INSERT

    插入的每一行使用系统版本号作为创建版本号

  • DELETE

    为删除的行保存当前系统版本号作为行删除标志

  • UPDATE

    相当于删除原有记录,创建一条新的记录。新插入一行使用系统版本号作为创建版本号,并将原有行的删除版本号置为系统版本号