《Anatomy of a Database System》这篇发表于87年、一共48页的论文据说是DBA入门必看,但是找了全网没有找到中文翻译。这篇文章对关系型数据库确实有提纲挈领的作用,看完能带来融会贯通的感觉,值得抄写一遍,如有任何抄写不当的地方请诸位看官留言。

1. 文章结构

 
文章把数据库划分为4块,chap2、4、5、6都对应上图每一块;chap3浅显的讲了磁盘存储的设计。
 
 

2. Process Manager

这一章讲数据库的并发模型,稍微翻下chap2的图片就能明白,下面只简要贴出自己感兴趣的部分:

2.1 各并发模型对比

2.2 线程间传递数据

理想的服务器处理架构有非阻塞异步I/O、有dispatcher threads将客户端连接分发给worker threads,这就引来一个问题:数据如何在进程货线程间传递?答案通常是:使用buffer。

buffer类型  描述  
Disk I/Obuffer

1. 来自DB的I/O请求:缓冲池
缓冲池是堆内数据结构,所有数据库都有缓冲池。刷盘时,线程生成包含当前页frame地址、空frame指针的I/O请求,实际刷盘、读到缓冲池的操作都是一步的
2. 日志文件I/O请求:log tail
数据库事务执行过程中日志被写在log tail内存队列里,由FIFO顺序随机(比如事务提交/事务组提交触发、log buffer满触发、DML触发等)刷入磁盘。

 
Client communication buffer

适用于pull模型,客户端主动拉取。一笔查询的worker thread包含指向结果队列的指针:
1. 每个客户端连接有一个socket,则worker线程引用socket内队列;
2. 客户端连接与网络socket多对多,则为每个client维护一个通信队列(放SQL结果),并有一个专门的调度agent处理来自client的fetch请求。

 

2.3 数据库线程与OS处理器的映射

大多数DB起源于70年代,商业化于80年代,很多OS特性在当时是不支持的,例如文件系统缓冲控制、异步I/O;还有就是以前的OS线程包并不高效。出于这些历史遗留、移植性、性能等考虑,很多DB自己做了操作系统应该做的事情,例如非阻塞的异步接口(用来处理慢任务如I/O)、事件流编程、任务切换、线程状态管理、调度等。然而,使用DB级的线程包引出一些设计问题:给定的DB线程组,应该有多少个OS处理器?那些DB任务需要有单独的线程?如何给线程分配处理器?

为了讨论以上问题,首先将问题简化为:只有DB线程和OS处理器两个单元参与、没有OS线程支持的情况。这种情况下DB包含以下处理器:

  1. 1-n个processes给SQL处理线程,通常dba可调。
  2. 1-n个dispatcher processes。监听网络端口、分发连接请求给其他process的线程、为连接创建session,通常dba可调。
  3. 与数据库磁盘数对应的I/O proccesses。如果OS不支持异步I/O,需要数据库为每个数据库磁盘起一个process来处理I/O请求。
  4. 与log磁盘数对应的I/O processes。如3。
  5. 与client session数对应的调度器代理process。有的系统中,需要为client session分配一个处理器来维护session状态、处理客户通信;有的系统中,不需要分配处理器,有单独的数据结构供db线程访问就行了。
  6. 后台工具。如统计、监控、日志归档、物理结构优化,每个任务,由调度器动态的启一个专门处理器。

现代操作系统的线程切换仍然比DB希望的还有重量级,但是多处理器下效率比古典操作系统有很多提升。历史上看,DB首先是多进程单线程的,后来随着OS多线程能力的提升DB将多进程改为多线程,这样的好处是编程方便。当代DB“ are written in this manner, and can be run over either processes or threads.”,把线程视为可调度单元。那么为什么还有现代DB还坚持着多进程的并发模型呢?当前的硬件,例如x86的Linux一个进程只能支持到3GB ram,多进程可以减轻这个问题。

例举几种数据库的并发模型

  Oracle DB2 SQL Server
Unix环境 Process-Per-User Process-Per-User 不支持
Window环境 以线程为调度单元 以线程为调度单元 thread-per-session,但是thread可复用

2.4 并发、进程模型、内存协调

  描述 pros cons
shared memory 由于OS通常支持可调度单元(线程或进程)在多处理器之间的透明调度,且共享内存可全部被读到 简便 硬件行业摇钱树
shared Nothing

由PC机(一般是刀片)组成;某CPU不能直接访问另一个CPU的内存或磁盘;由于便宜、扩展性好,这类机器常用于数据仓库;
硬件共享上没有抽象,因此要求DBMS能调度如此多的机器:除运行服务进程,还需要支持单个请求在多台机器上并行执行。
数据上,一般水平切割;查询调度器负责分派查询任务、传播数据,不需要动到每个机器的线程状态、或其他底层信息。
数据拆分并不能保证事务、负载均衡、维护任务(如死锁检测、两阶段提交),因此既要有额外逻辑保障以上功能,又不能让以上逻辑成为瓶颈。
无共享架构下节点故障三种情况:
1. 整个系统挂机
2. 若看中可用性强过一致性,允许查询宕机节点以外数据
3. 通过冗余如链式分解保证可用性。链式分解目前只实现了粗糙的方案,例如数据库复制。

便宜、扩展性好

贵,因为license按软件包收费,例如IBM SP2、NCR WorldMark机器;
按数据拆分,DBA运维压力大;

shared disk

single-box数据库,分布式部署在多台服务器上。随着NAS的流行,这种数据库也流行开来。
例如MemSQL,例如Oracle不支持sharednothing但是支持shared disk。

1. 比起shared nothing,DBA不需要考虑数据分片;
2. 比起shared memory,不用担心丢失调度单元
3.节点故障完全不影响其他节点;但是存储的可靠性非常重要。

数据的共享需要软件去协调:所有节点都能从磁盘拷贝到自己内存,都有自己的锁、buffer pool页。因此至少需要:
1. 分布式锁管理机制
2. cache-coherency缓存一致性协议来管理分布的buffer pool。
以上代码复杂,可能成为瓶颈。

NUMA

在NUMA架构中,每个Node有多个Core,Node内CPU与内存通过片内总线连接,Node间通过互联网模块进行连接。每个core地位是平等的,都可以访问所有内存,访问其它节点内存耗时用node-distance衡量,一般比访问本机慢3倍。IBM这类厂商提供NUMA架构的机器。
虽与shared-memory同为共享内存架构的并行机器,NUMA一般被看作比较贵的Shared-nothing架构机器:
1. 像shared-nothing一样轻巧的Node:Node一般是4通道CPU
2. DBMS通常忽略其共享内存的特性,这是因为本机/跨机内存访问速率不一致。

  所有数据库都被NUMA坑过,例如MySQL swap insanity,其原因基本上“CPU亲和策略导致内存分配不均”或者“NUMA Zone Clain内存回收”

2.5 准入控制

“如何支持并发的请求”。为什么说准入控制是必要的?因为当负载拆过临界点后,系统就会开始抖动,从OS层面看,抖动多数情况由DBMS的buffer pool不停换入换出导致的,DBMS在执行排序、hash join,或者锁竞争、事务死锁的情况下尤其消耗内存。 准入控制可以使服务优雅降级:事务延迟会随着请求速率慢慢降低,但系统吞吐量维持在峰值。
如何做DB准入控制?
1. 限流。要求dispatcher进程保障客户连接数载某个数字以内,这样既可以保证不过度消耗网络连接资源,也可以使查询解析器和查询优化器掉用量比较小。有些DB把这个功能甩锅给其它应用,如应用服务器、事务监视器TPM、Web服务器。
2. 执行准入控制器execution admission controller,需要再DBMS查询处理器内部实现。执行控制器用于决策一个查询要立即执行还是延迟执行,是在查询被解析、优化后调用的,因为它需要优化器产生的查询计划里的信息来估算资源,这些信息包括:

2.1 有哪些磁盘访问
2.2 每块设备的随机/次序IO的预期CPU负载
2.3 查询内存占用,尤其是排序和hash表 ***

2.3是execution admission controller最重要的决策信息,因为内存压力才是抖动的主要原因。

2.6 小结

1. 当代DBMS既有Process-per-User又有“Server process”模型。前者简单;后者可支持更高性能。
2. 有些DBMS自己实现了线程包(如Oracle、Informix),因此以线程为可调度单元。
3. 不同OS上可调度单元不同,有的OS以进程为可调度单元,有的OS以单进程内的线程为可调度单元。
并发架构上,市面上有Shared-Nothing、Shared-Memory和Shared-Disk的架构。其中,Shared-nothing善于高性价比的处理海量数据的复杂查询,因此在协作决策支持系统中占据高端地位;其它两种善于处理多个小事务。将单处理器DB应用到shared-nothing架构难度较高,很多数据库公司宁愿直接开发新产品线,如Oracle直接不支持Shared-Nothing架构。

Anatomy of a Database System学习笔记 - 概论、并发控制的更多相关文章

  1. Anatomy of a Database System学习笔记 - 查询

    查询解析 解析会生成一个查询的内部展示.格式检查包含在解析过程中. 每次解析一个SELECT,步骤如下:1. 从FROM里找到表名,转换成schema.tablename.这一步需要调用目录管理器ca ...

  2. Anatomy of a Database System学习笔记 - 公共模块、结语

    公共模块 1. 使用基于上下文的内存分配器进行内存分配 除了教材里常提到的buffer pool,数据库还会为其他任务分配大量内存,例如,Selinger-style查询优化需要动态的规划查询:has ...

  3. Anatomy of a Database System学习笔记 - 事务:并发控制与恢复

    这一章看起来是讲存储引擎的.作者抱怨数据库被黑为“monolithic”.不可拆分为可复用的组件:但是实际上除了事务存储引擎管理模块,其他模块入解析器.重写引擎.优化器.执行器.访问方式都是代码相对独 ...

  4. Anatomy of a Database System学习笔记 - 存储管理

    使用裸设备,还是使用文件系统?   描述 pros cons 裸设备 顺序读磁盘快比随机要快10-100倍,DB比OS更懂磁盘负载,因此很多DB是直接管理数据块如何存放的. DB对裸设备的管理,比文件 ...

  5. A.Kaw矩阵代数初步学习笔记 5. System of Equations

    “矩阵代数初步”(Introduction to MATRIX ALGEBRA)课程由Prof. A.K.Kaw(University of South Florida)设计并讲授. PDF格式学习笔 ...

  6. Deap Learning (吴恩达) 第一章深度学习概论 学习笔记

    Deap Learning(Ng) 学习笔记 author: 相忠良(Zhong-Liang Xiang) start from: Sep. 8st, 2017 1 深度学习概论 打字太麻烦了,索性在 ...

  7. system generator学习笔记【02】

    作者:桂. 时间:2018-05-20  23:28:04 链接:https://www.cnblogs.com/xingshansi/p/9059668.html 前言 继续学习sysgen.接触s ...

  8. System类学习笔记

    最近在学习源码的过程中发现:很多深层次的代码都用到了一个类System类,所以决定对System类一探究竟 本文先对System类进行了剖析,然后对System类做了总结 一.首先对该类的中的所有字段 ...

  9. 学习笔记之操作系统(Operating System)

    学习笔记之多线程 - 浩然119 - 博客园 https://www.cnblogs.com/pegasus923/p/5554565.html 用三个线程按顺序循环打印ABC三个字母 - 浩然119 ...

随机推荐

  1. HBase应用快速开发

    有人说过“让Hadoop开发像家庭作业一样简单”,容器技术的出现让这成为可能,可以用Docker封装HBase运行环境,通过统一的接口来运行.本文将介绍如何在十分钟内跑起你的HBase应用. 首先,我 ...

  2. ES6的一些知识学习

    一.基础 ES6 - 类: class A{ constructor(name,color){ this.name = name; this.color = color; } toString(){ ...

  3. vue day8 table page

    @{ ViewBag.Title = "Home Page"; Layout = null; } <!DOCTYPE html> <html> <he ...

  4. ionic上拉加载组件 ion-infinite-scroll自动调用多次的问题

    参考文章地址:http://www.cnblogs.com/luleixia/p/6402418.html ionic 一个上拉刷新的组件 ion-infinite-scroll,如果页面未填充满页面 ...

  5. jquery 蔚蓝网

    $(document).ready(function(){ //提交表单 $("#registerBtn").click(function(){ var email=documen ...

  6. 去重和分类后缀asp、php等路径 用python3写的

    我们在做渗透的时候肯定会用上扫描器的,本人一般会用御剑,当然你也会喜欢别的工具. 很多时候,能否渗透成功其实还挺依赖与字典的,如果把后台给扫出来了,恰好还弱口令,那么岂不是美滋滋. 因此,有一个好的字 ...

  7. 找出n之内的完全数, 并输出其因子

    定义: 完全数:所有的真因子(即除了自身以外的约数)的和,恰好等于它本身.例如:第一个完全数是6,它有约数1.2.3.6,除去它本身6外,其余3个数相加,1+2+3=6.第二个完全数是28,它有约数1 ...

  8. c++ 创建线程以及参数传递

    //创建线程,传递参数 DWORD dwThreadID = ; HANDLE hThread = CreateThread(NULL, , MonitorThreadFunction, , & ...

  9. LEB128相关知识

    LEB128相关知识 介绍 LEB128(little endian base 128)是一种变长的整数压缩编码形式,它是出自于DWARF debug file format.在Android的Dal ...

  10. edgedb 内部pg 数据存储的探索 (一)基本环境搭建

    edgedb 是基于pg 上的对象关系数据库,已经写过使用docker 运行的demo,为了探索内部的原理,做了一下尝试,开启pg 访问 后边会进一步的学习 环境准备 为了测试,使用yum 安装 安装 ...