高级数据库系统 02:数据的访问、存储和事务处理基础

墨尔本大学 COMP90050 课程笔记

Posted by YEY on July 7, 2020

Lecture 02 数据的访问、存储和事务处理基础

参考教材Transaction Processing: Concepts and Techniques, Jim Gray and Andreas Reuter, Morgan Kaufmann, 1993

1. 硬件系统

1.1 基础硬件

内存(Memory)

  • 摩尔定律 (Moore’s law):内存芯片容量 (memory chip capacity) 以一定速度增长(自 1970 年以来每 18 个月翻一番)

    \[=2^{(\text{year}-1970)\times2 / 3} \text{ Kb}/\text{chip}\]

  • 在2012年,每芯片 32 GB 是可行的。

处理器(Processors)

  • 乔伊定律 (Joy’s law):处理器性能以一定速度增长(自 1984 年以来,每两年翻一番)

    \[=2^{(\text{year}-1970) / 2} \text{ mips}\]
  • IBM 的超级计算机 Blue Gene/P 每秒可以进行 1 PB($2^{50}=10^{15}$ 个字节)的浮点运算,它使用了大约 300,000 个 CPU。
  • IBM 的超级计算机 Summit 的峰值性能达到 200 petaflop,即每秒 20 万亿次计算,Summit 的最高速度是 TaihuLight (神威·太湖之光) 的两倍以上。
  • 很快,我们将根据单个 CPU 性能达到其最大极限时的内核数来衡量性能。英特尔目前在售的有支持 36 个线程的 18 核芯片。

字节大小的单位

1.2 内存等级

对于一般传统的单核系统,处理器和 L1 缓存属于片上 (on-chip) 存储器,即在 CPU 芯片上具有存储功能,目的是减少关键/常用数据的等待时间;而 L2 缓存、主存以及磁盘则属于片外 (off-chip) 存储器。

1.3 多核系统

多核系统 (Multi-Core System) 中,有多个 CPU,其中,每个 CPU 都有各自的寄存器和 L1 缓存,并且通过总线接口 (Bus Interface) 连接到其他级别的共享缓存(如 L2、L3 缓存),然后再连接到主存等。

当然,具体情况取决于 CPU 类型,多核芯片并不是必须共享 L2 缓存,它们也可以具有各自专用的 L2 缓存。

目前,L1、L2、L3 缓存通常都在片上 (on-chip)。

可以看到,L1 缓存距离 CPU 最近,其速度最快,但是容量最小 (32KB);其次是 L2,其容量和速度都属于中等水平;L3 缓存由于距离 CPU 最远,其速度最慢,但是其容量是三者中最大的 (8MB)。在三级缓存之后,连接到内存,然后再到磁盘。

2. 数据访问

2.1 访问内存数据

命中率 (Hit Ratio):对于需要访问的数据,已经存在于缓存中的字节数占需要访问的总字节数的比重。我们可以基于缓存命中率来估计访问这些数据所需要的时间。

\[\text{Hit ratio}=\dfrac{\text{references satisfied by cache}}{\text{total references}}\]
  • 命中:直接从缓存中读取到想要的数据。
  • 不命中:缓存中没有想要的数据,还需要到数据库进行一次查询才能读取到想要的数据。

命中率越高,数据库查询的次数就越少。读取缓存的速度远比数据库查询的速度高得多。所以命中率越高,性能越高。

有效内存访问时间 (Effective Memory Access Time) 为:

\[\textit{EA} =H\cdot C+(1-H)\cdot S\]
  • $H$ 为缓存命中率
  • $C$ 为缓存访问时间 (cache access time)
  • $S$ 为内存访问时间 (memory access time)

如果我们可以保证很高的缓存命中率,那么这些数据的内存访问时间将非常小。可以看到,当命中率从 99.90% 下降到 90.00% 时,访问时间增加了 10 倍;当命中率从 90.00% 下降到 50.00% 时,访问时间继续增加了 5 倍,因此,二者之间并非线性关系。

对于不同的系统,时间消耗方面会存在一些差异,上面的结果是 $S=100 C$ 的情况下得到的。另外,我们还可以通过一些策略来保证高缓存命中率,但是这里不再展开讨论。

2.2 访问磁盘数据

有时,我们需要访问的信息并不在缓存或者主存,而是在磁盘中,这种情况下,我们需要访问磁盘。我们先来看一下磁盘的结构:

  • 磁头 (Head)
    • 驱动臂 (Actuator Arm) 的头部部分,用于读/写数据
    • 磁盘盘面 (Platter) 上的磁头
    • 磁头数量 $=$ 盘面数量
  • 磁道 (Track)
    • 磁盘上的圆环区域
    • 数据首先写入最外圈的磁道
    • 一个磁盘上的磁道数量一般在 1000 个以上
  • 扇区 (Sector)
    • 划分磁道上的区域
    • 扇区是一个磁盘上的最小物理存储单位
    • 每个扇区存储 512 个字节的数据
  • 柱面 (Cylinder)
    • 磁盘单元中每个磁盘表面上相同磁道的逻辑分组
    • 磁道在硬盘内产生了柱面
    • 柱面数量 $=$ 单个盘面上的磁道数量
  • 簇/块 (Cluster/Block)
    • 操作系统所使用的扇区组:由于扇区的空间比较小且数目众多,在寻址时比较困难,所以操作系统就将多个的扇区组合在一起,形成一个更大的单位,再对这个单位进行整体的操作。Windows 下的 FAT,FAT32 和 NTFS 文件系统中称为簇(cluster),Linux 下的 Ext4 等文件系统中称为块(block)。
    • 每个簇或者块可以包含 $2^{n}$ 个扇区(例如:64 个扇区)

我们先看一下数据是如何从磁盘中读取的:

当磁头接触扇区时,表示该扇区上正在读/写数据。在磁盘上访问数据的过程可以分为两部分:

  • 寻道时间 (seek time)
    首先,读写头沿径向移动,移到要读取的扇区所在磁道的上方,这段时间称为寻道时间 (seek time)。
  • 旋转时间 (rotational time)
    然后,通过盘片的旋转,使得要读取的扇区转到读写头的下方,这段时间称为旋转延迟时间 (rotational latency time)。

磁盘访问时间 (Disk Access Time) 为:

\[\text{Disk access time} =\text{seek time}+\text{rotational time}+\dfrac{\text{transferlength}}{\text{bandwidth}}\]

它可以分为两部分:

  • 访问时间 (access time):包含寻道时间和旋转时间。
  • 数据传输时间 (data transfer time):需要传输的数据总量除以带宽,即数据读/写时间。

有效磁盘缓冲区高速缓存访问时间 (Effective Disk Buffer Cache Access Time) 为:

\[\textit{EA} =H\cdot C+(1-H)\cdot S\]
  • $H$ 为缓存命中率
  • $C$ 为缓冲区访问时间 (buffer access time)
  • $S$ 为磁盘访问时间 (disk access time)

上面的结果是 $S=1000 C$ 的情况下得到的。可以看到,当缓存命中率从 99.00% 增加到 99.99% 时,访问时间缩短了大约 100 倍,而当缓存命中率从 50.00% 增加到 99.00% 时,访问时间缩短了大约 5 倍,所以,二者之间的关系同样是非线性的。

通常,磁盘容量要比高速缓存的容量大得多。为了获得良好的性能,我们需要非常大的缓冲区高速缓存(数百兆位),但是对于大多数应用程序而言,这会带来很高的成本,同时,在 CPU 上布置大量的片上高速缓存也不现实,因此,很多企业在设计商用芯片时会在高速缓存容量和成本之间进行权衡。另外,可以采取一些策略将需要频繁访问的信息保存在高速缓存中,而将访问频率较低的信息存储在磁盘中。

2.3 例子:HDD 规格参数

Seagate Desktop HDD Specifications:

  • Capacity: 4TB
    • 4TB (ST4000DM000)
    • 8 heads, 4 disks
  • Interface: SATA 6Gb/s
  • Spindle: 5,900 RPM
  • Cache: 64MB
  • Throughput Max: 180 MBs = 1.440Gbs
  • Average Data Rate: 146MB/s
  • Average Latency: 5.16ms
  • Power:
    • Typical Idle Operating: 5W
    • Average Operating: 7.5W
  • Environmental:
    • Operating Temperature: 0 to 60℃
    • Non-operating Temperature: -40 to 70℃
  • Dimensions (LxWxH): 146.99mm × 101.60mm × 26.11mm
  • Weight: 1.345lb (610g)
  • Warranty: 2 years
  • HDD Hard Drive USB 3.0 Powered ~ $169 (2018)

2.4 固态硬盘 (Solid-State Drive/Solid-State Disk, SSD)

  • 没有像 HDD(硬盘驱动器)中那种活动部件
  • 内存是基于硅而非磁性材料,并且重量大约在 55 克(要比 5 枚 20 美分硬币还轻)
  • 没有寻道时间或者旋转延迟的概念(没有移动部件)
  • 2019 年,SSD 最大容量接近 4TB,价格约为 800 美元,而同样容量的 HDD 价格为 169 美元
  • 没有类似 HDD 的启动时间
  • 对于随机访问时间,SSD 通常在 100 微秒内,而 HDD 则需要 2000-3000 微秒
  • 价格相当贵

2.5 例子:SSD 规格参数

  • 容量:4TB SSD(现在甚至有 60TB 的,即 15 × 4TB 打包)
  • 组件:NAND Flash Memory Multi Level Cell (MLC)
  • 重量:< 10 grams
  • 带宽性能(SATA 标准串行)
    • 连续顺序读取:高达 550MB/s ( $=$ 4.4Gb/s)
    • 连续顺序写入:高达 520MB/s ( $=$ 4.16 Gb/s)
  • 读写 IOPS (Input/Output Per Second)
    • 随机 4KB 读取:高达 9,608,000 IOPS
    • 随机 4KB 写入:高达 9,000,000 IOPS

3. 数据存储

3.1 存储系统

存储系统 (Storage systems) 可以决定数据库系统的性能和可靠性,我们将讨论以下类型的存储系统:

  • RAID:独立磁盘冗余阵列(Redundant Array of Independent Disks),曾经非常廉价
  • SAN:存储区域网络(Storage Area Networks)

3.2 平均故障间隔时间

起初,系统开始运行,一段时间后,由于崩溃或者组件故障,系统将宕机,然后需要一段时间进行系统恢复,之后重启。然后,在运行一段时间后,系统再次出现故障宕机,再次进行系统恢复,重启运行。

由于系统宕机时间可能很长,对于某些应用程序可能是无法接受的,因此,我们需要使用诸如 RAID 和 SAN 这样的存储系统来保证即使系统出现故障,存储系统仍然可以使用并提供服务。

3.3 RAID 0(Block 级别分条)

RAID 意为独立磁盘冗余阵列,即我们有很多磁盘来存储信息,因此,即使某块磁盘出现故障,其他磁盘仍然可以正常提供数据访问服务。另外,根据采取的不同顺序或者策略,RAID 又可以进一步细分为 RAID 0 到 RAID 5。其中,RAID 0 是最简单的策略。

  • A 表示块(Block)(4K 或者 8K 的存储字节)
  • MTTF 表示平均失效前时间(mean time to failure),即在故障出现之前,系统正常运行的平均时间。

A0, A1, A2, A3, … 是一个文件中的连续数据块(blocks)。

  • 提供平衡的磁盘驱动器 I/O —— 吞吐量大约翻倍。
  • 任何一个磁盘故障都可能是灾难性的,MTTF 将减少为单个磁盘存储的一半。

RAID 0 通常并不用于数据恢复,而是为了提高数据的吞吐量。在 RAID 0 策略中,我们使用两个磁盘 Disk 1 和 Disk 2。假设某个文件包含很多数据块(blocks),我们将其中第一个块 A0 存储在 Disk 1 上,将第二个块 A1 存储在 Disk 2 上,再将第三个块 A2 存储在 Disk 1 上,将第四个块 A3 存储在 Disk 2 上,以此类推。因此通过这种分布式方法,一个文件的数据块被分开存储在多个磁盘上。

当我们从磁盘中读取文件数据时,可以让两个磁盘并行读取数据,这使得读取一个文件的时间将大大减少,大约可以将吞吐量提高到单个磁盘存储的两倍。

3.4 RAID 1(镜像)

  • A 表示块(Block)(4K 或者 8K 的存储字节)
  • MTTF 表示平均失效前时间(mean time to failure)

A0, A1, A2, A3, … 是一个文件中在逻辑上连续的数据块(blocks)。

  • 提升了读取吞吐量,但是降低了写入吞吐量(写入速度大约是单个磁盘存储方案的一半),并且在存储利用率方面同样会减半。
  • MTTF 增长相当可观(相比单磁盘存储,呈二次方增长,即 MTTF2)。

RAID 1 的策略是使用两个磁盘存储相同的信息,这种方式也被称为 镜像 (mirroring)。同样,RAID 1 也可以通过并行方式提升读取吞吐量,例如:在 Disk 1 上读取 A0 和 A1 的同时,在 Disk 2 上读取 A2 和 A3。但是对于写入操作,吞吐量会减小一半,因为我们需要在两个的磁盘上写入相同的信息。

3.5 RAID 2(bit 级别分条)

  • b 表示位(bit)
  • MTTF 表示平均失效前时间(mean time to failure)

b0, b1, b2, b3, … 是一个文件中的连续数据位(bits)。

  • 分条(Striping)发生在 bit 级别
  • 提供更高的传输速率(是单磁盘存储系统的 2 倍)
  • 和 RAID 0 一样,MTTF 将减少为单磁盘系统的一半
  • 很少使用

相比 RAID 0 和 RAID 1 中在 blocks 级别上处理数据,RAID 2 在 bits 级别处理数据。在 RAID 2 中,假设某个文件包含很多数据位(bits),我们将其中第一个位 b0 存储在 Disk 1 上,将第二个位 b1 存储在 Disk 2 上,再将第三个位 b2 存储在 Disk 1 上,将第四个位 b3 存储在 Disk 2 上等等,这种方式和 RAID 0 类似,只是这里是在 bits 级别而非 blocks 级别。

这种方案通常很少采用,因为我们很难在 bits 层面来维护并读写信息。类似 RAID 0,这种方式提供了很高的传输速率,因为我们可以并行读取数据;并且和 RAID 0 一样,MTTF 相比单磁盘系统减少了一半。

另外注意,虽然这几种方案的实现通常采用 2 个磁盘,但是我们也可以将其扩展到多个磁盘。例如:假如我们在 RAID 0 中采用 3 个磁盘的实现,那么其 MTTF 将是单磁盘系统的 1/3。假如我们在 RAID 1 中采用 3 个磁盘的实现,那么其 MTTF 将是单磁盘系统的三次方,即 MTTF3

3.6 RAID 3(Byte 级别分条)

  • B 表示字节(Byte)(1Byte $=$ 8bits)
  • P 表示奇偶校验位(parity or check bits),用于错误检测
  • MTTF 表示平均失效前时间(mean time to failure)

B0, B1, B2, B3, … 是一个文件中的连续数据字节(Bytes)。

  • 分条发生在 byte 级别
  • 和 RAID 0 类似,提供更高的传输速率
  • MTTF 增长相当可观(是 RAID 1 的 1/3,即 MTTF2/3)
  • P0 是字节 B0 和 B1 的奇偶校验位
  • Pi $=$ B2i $\oplus$ B2i+1,其中 $\oplus$ 在这里表示异或运算
  • 很少使用

RAID 3 在 bytes 级别上处理数据。 数据本身交替存储在 Disk 1 和 Disk 2 两个磁盘上,Disk 3 用来存储一些被称为校验位的额外信息,校验位用于系统崩溃时的数据恢复,以及存储错误检测。尽管 RAID 3 提供了一些容错度,但是很少使用,因为还有其他更强大的 RAID 策略。

3.7 RAID 4(Block 级别分条)

  • A 表示块(Block)(4K 或者 8K 的存储字节)
  • P 表示奇偶校验位(parity or check bits)

A0, A1, A2, A3, … 是一个文件中的连续数据块(blocks)。

  • 和 RAID 0 一样,分条发生在 block 级别
  • 奇偶校验块具有专用磁盘
  • 提供更高的吞吐量,但是写入非常慢。注意:Disk 3 上的写入量要大于 Disk 1 或 Disk 2,因为每次写入操作都必须更新奇偶校验块。
  • MTTF 增长相当可观(和 RAID 3 相同)
  • P0 是块 A0 和 A1 的奇偶校验块
  • Pi $=$ A2i $\oplus$ A2i+1,其中 $\oplus$ 在这里表示异或运算

不同于 RAID 3,这里 RAID 4 在 block 级别上处理数据。数据块交替存储在 Disk 1 和 Disk 2 上,Disk 3 用来存储校验信息,它是通过 Disk 1 和 Disk 2 上的对应位置的数据信息通过异或计算得到的。和 RAID 3 一样,当 Disk 1 或 Disk 2 中的某个磁盘出现故障时,我们可以通过剩下的一个正常磁盘和校验信息进行数据恢复。

对于 RAID 4,其在读取吞吐量方面有所提升,因为可以并行读取数据。但是会降低写入速度,因为我们需要将数据块分到两个磁盘上,并且需要计算相应的奇偶校验块并写入 Disk 3。

3.8 RAID 5(Block 级别分条)

  • A 表示块(Block)(4K 或者 8K 的存储字节)
  • P 表示奇偶校验位(parity or check bits)

A0, A1, A2, A3, … 是一个文件中的连续数据块(blocks)。

  • 和 RAID 0 一样,分条发生在 block 级别
  • 没有用来存储奇偶校验块的专用磁盘,奇偶校验块同样是分条存储的
  • 提供更高的吞吐量和较慢的写入速度,但是要比 RAID 4 的写入快一些。因为在 RAID 5 中,奇偶校验块分布式地存储在所有磁盘上,因此三个磁盘的平均写入操作次数是相等的。
  • MTTF 增长相当可观(和 RAID 3 相同)
  • P0 是块 A0 和 A1 的奇偶校验块
  • Pi $=$ A2i $\oplus$ A2i+1,其中 $\oplus$ 在这里表示异或运算

可以看到,对于前两个数据块 A0 和 A1,它们存储在 Disk 1 和 Disk 2 上,它们的奇偶校验位 P0 存储在 Disk 3 上。而对于接下来的两个数据块 A2 和 A3,它们存储在 Disk 1 和 Disk 3 上,奇偶校验块 P1 存储在 Disk 2 上。因此,每个奇偶校验块依次循环存储在不同的磁盘上。

和 RAID 4 类似,RAID 5 提供更高的吞吐量和较慢的写入速度,但写入速度要略快于 RAID 4。我们可以通过一个例子进行说明:

  • 考虑在 RAID 4 中,假设现在我们需要更改 Disk 1 上的 A2 和 Disk 2 上的 A5 数据块,尽管这种情况下我们可以并行写入数据,但是我们还需要在 Disk 3 上分别更新 P1 和 P2。所以 Disk 3 的写入要比 Disk 1 和 Disk 2 更慢,我们需要等待 Disk 3 完成才能结束整个写入操作。
  • 而对于 RAID 5,假如我们更改了 Disk 1 中的 A2,我们需要更新 Disk 2 中的 P1,假如现在我们又更改了 Disk 3 中的 A5,那么我们可以同时更新 Disk 1 中的 P2。因此,这种情况下,写入操作要略快于 RAID 4。

对于 RAID 4 和 RAID 5,当某个磁盘出现故障时,数据都可以通过剩下两个磁盘进行恢复。

3.9 RAID 6(Block 级别分条)

  • A 表示块(Block)(4K 或者 8K 的存储字节)
  • P 表示奇偶校验位(parity or check bits)

A0, A1, A2, A3, … 是一个文件中的连续数据块(blocks)。

  • 类似 RAID 5,区别是使用了 2 个校验块
  • 可靠性约为 MTTF3/10
  • P0 和 P1 是数据块 A0、A1 和 A2 的校验块。假如我们总共使用 5 个磁盘,那么这种计算方式可以保证在任何两个磁盘同时发生故障的情况下,都可以安全地恢复数据。

RAID 6 策略使用了更多的磁盘,增加了容错度。类似 RAID 5,我们用多个磁盘存储数据块,并且我们将校验块也分布式地存储在多个磁盘上。区别是相比 RAID 5 中只使用一个校验块,这里我们使用 2 个校验块。因此,当任意两个磁盘发生故障时,我们仍然可以通过剩余的磁盘安全地恢复数据。在可靠性方面,RAID 6 对于 MTTF 的提升相当显著。如果我们的应用程序对于数据的可靠性和容错度要求非常高,那么 RAID 6 是一个非常合理的选择。

3.10 SAN(Storage Area Networks)

我们已经介绍了 RAID 类型的存储系统,现在我们来看一下另外一种类型的存储系统:SAN (Storage Area Networks,存储区域网络),它是一种由多个存储设备组成的专用网络。

  • 存储可以被组织为多个 RAID 系统
  • 存储可以被划分和分配给每个系统,并且也可以被共享

在 SAN 中,有一个控制器 (controller) 用来管理存储,并且不同系统可以通过控制器访问这些存储。

3.11 SAN 文件系统

SAN 中有很多不同的磁盘,它们都有各自的备份和管理系统,并且这些系统同时还负责安全方面的协助。另外,还有一个中央平台负责来自不同系统的数据的输入和输出。例如:对于一个银行系统,它包含很多分支系统和 ATM 机等,这些系统需要从中央服务器中访问数据,中央服务器需要存储所有这些事务请求的历史信息,并且需要为这些数据访问提供安全性,并且在经过一段时间后,这些信息需要备份以应对故障情况。

不同的分支可能使用不同的操作系统 (例如:Windows 和 Linux),这些操作系统需要采用不同的协议来进行文件传输 (例如:NFS 和 FTP),而这些采用不同操作系统和文件传输协议的分支在通过中央服务器访问数据时无需知道这些数据具体的存储技术细节,中央服务器将统一处理这些访问请求。在这些分支系统看来,这种网络存储和任何其他普通存储方式 (例如:硬盘) 一样,并无任何区别。

下面是一个访问 SAN 文件系统的例子:

2006 年 3 月 17 日,IBM 对于单个文件的持续读取/写入性能达到了每秒 102GB 以上的新速度记录。该记录是使用 416 个单独的存储控制器与 104 个 Power-based eServer p575 节点组合而成的 (每个 p575 节点具有 8 个双核 2.2GHz POWER5 处理器)。

  • 磁盘数量 $= 416$
  • 处理器数量 $=104 \times 8 \times 2 = 1664$ 个运行在 2.2GHz 的核

读取和写入的过程可以并行化,因此系统在数据的输入和输出方面可能到达非常高的性能。当我们对存储容量需求较高,并且需要通过多个设备访问这些存储,同时保证高速和高可靠性时,这种系统非常有用。中央文件系统将统一管理这些输入/输出的访问请求。

3.12 硬件通信

下面的公式描述了从一个磁盘到系统的传输时间:

\[\text{transmit time} = \text{distance}/\text{Cm} + \text{message}_\text{bits}/\text{bandwidth}\]

其中,$\text{Cm}$ 为媒介中的光速(约 $200 \text{ million meters}/\text{sec}$)

由于数据的传输过程发生在网络上,公式的第一项计算了从磁盘到系统的传播时间,这里假设网络媒介采用光纤,当媒介为其他介质时这一项可能会变化。第二项计算的是数据传输时间,带宽 (bandwidth) 表示单位时间能够传输的数据量。

由于物理距离上的传播延迟是一个常量 (公式中第一项),我们永远无法减少延迟,因此,为了达到高效传输的目的,消息长度应该尽可能大,即一次传输全部数据的效率要高于将数据分段多次传输。

4. 软件系统

目前为止,我们已经介绍了数据库的硬件方面的一些相关技术,包括不同的数据库架构、数据的存储和传输,以及影响数据库性能的一些硬件指标。现在,我们将介绍和数据库相关的一些软件方面的技术。

4.1 进程

进程 (Process):在计算机中运行着许多进程,进程是一个虚拟概念,是运行中的应用程序或者系统调用的一种抽象。

进程地址空间 (Process address space):每个进程在内存中都有一块对应的地址空间,它们是由字节(bytes) 组成的数组。进程可以访问对应的地址空间,并且可以在获得允许的情况下修改这些地址空间。

保护域 (Protection Domain):每个进程还可以访问其对应的保护域,进程地址空间就是保护域的一个组成部分。一个进程可以在自己的保护域中执行任何允许的有效操作,而对于其他域提供的任何功能,则需要显式的控制权转移。

4.2 线程

线程 (Threads) 可以视为一种轻量级的进程。线程通常在运行在进程之上,线程可以由操作系统或者进程本身创建。

一些操作系统可以直接对线程进行 调度 (schedule)。调度意味着一个运行中的线程可以访问某个资源,然后当该线程停止时,另一个线程可以获得该资源的访问权限,操作系统可以决定当前哪个线程可以运行,而其他线程可以停止运行 (具体取决于操作系统采用的协议)。因此,当系统包含多个处理器时,这些线程可以并行运行。

线程可以使编写一些软件开发更加容易,但是调试可能非常困难。

4.3 调度

当操作系统调度不同的线程和进程时,其一般目的是:

  • 最大化资源利用率
  • 最小化响应时间

但是,这两个目的存在冲突,因为当我们最大化资源利用率时,响应时间可能会增加,反之亦然。

一般来说,调度器不应该过于注重资源利用率,因为我们通常更加关心响应时间。

5. 事务处理

我们已经介绍了数据库系统中的硬件和软件的一些相关技术,现在我们将介绍事务处理的一些相关内容。

5.1 事务处理

事务处理 (Transaction Processing):一个事务是需要在物理和抽象应用状态上执行的操作集合。

下面是一个一般的事务结构:

1
2
3
4
5
6
begin_Transaction()
       <Sequence of operations to be performed>
    if (successful)
        commit_Trans()  % Any changes made durable.
    else rollback()     % Any changes made are all undone
end_Transaction()

当一个操作序列成功完成时,会生成一个提交声明 (commit),表示所有的更改都将持久生效。如果任何更改需要返回到硬盘中或者其他一些地方,那么所有这些更改都将是永久的,即使在该事务结束之后,或者系统崩溃时,所有这些持久生效的事务将仍然可用。

如果该操作序列没有完全成功,那么将会执行一个回滚操作 (rollback),这意味着该事务涉及的这些更改将不再是永久的。

事务处理在分布式计算和容错计算中贡献了许多概念。

例如:分布式数据的可靠性 (reliability)、可用性 (availability)、并发性 (concurrency)、性能 (performance) 和 ACID 特性。

5.2 ACID 特性

ACID (atomicity, consistency, isolation, durability) 特性

  • 原子性 (Atomicity):一个事务对于 (数据库) 状态的更改是原子性的,这意味着所有操作要么全部完成,要么全部都不执行。

  • 一致性 (Consistency):事务是 (数据库) 状态的一个正确转换。一个事务将其采取的所有操作视为一个整体,这种做法不会违反应用程序状态的完整性。也就是说,我们假设事务是正确的程序。并发执行事务不会违反数据一致性。
    • 例如:在银行系统中,在一次汇款操作后,汇款方账户余额的减少量应该和收款方账户余额的增加量相等。
  • 隔离性 (Isolation):即使同时执行多个事务,在每个事务 T 看来,其他事务所做出的状态更改要么在 T 之前,要么在 T 之后,但不会和事务 T 同时发生。
    • 例如:在银行系统中,假如同时有两个汇款操作:事务一表示账户 A 汇款给账户 B;事务二表示账户 B 汇款给账户 C。那么,我们将发现要么账户 B 中的余额先增加后减少 (先完成事务一,再完成事务二),要么发现账户 B 中的余额先减少后增加 (先完成事务二,再完成事务一)。
  • 持久性 (Durability):一个事务已经提交的状态更改,即使在系统崩溃或者失效时仍将保留。

5.3 分布式事务处理系统

下面是一个分布式事务处理系统的示意图:

这里,资源 (Resource) 可以是数据库或者共享网络等。应用程序 (Application) 向资源管理器 (Resource Managers) 发出请求 (request) 以访问资源,而事务管理器 (Transaction Manager) 负责处理这些事务,事务包含关于使用这些资源的一系列操作,当所有操作都成功完成时,事务管理器会提交 (commit) 这些更改,否则将进行回滚 (rollback),并放弃 (abort) 所有更改。

以上是发生在单个节点 (例如:Node A) 中的过程。对于分布式事务处理系统,还有一个被称为通信管理器 (Communication Manager) 的模块,它同样负责提交和回滚操作。并且,数据资源在多个节点之间共享。对于两个不同节点的数据库系统,无论一个节点中的某个事务成功与否,都会通过通信管理器告知其他节点,然后其他节点会据此决定该事务是否完成。

5.4 事务处理系统的功能

  • 数据库功能:
    • 提供稳定的存储库
    • 位置独立性(分布式系统)
    • 提供用于数据定义和处理的标准接口,例如:SQL。
    • 数据控制
      • 安全、并发(锁机制)
  • 数据库显示:
    • 提供浏览和报告生成工具
  • 数据库操作实用程序,用于管理数据库:
    • 加载数据库
    • 存档
    • 数据库恢复实用程序
    • 调优
    • 性能监控
    • 应用程序开发工具

6. 总结

数据库系统的性能取决于以下几个方面:

  • 硬件
    • CPU
    • 内存
    • 存储
  • 数据库架构
    • 关系型
    • NoSQL
    • 面向对象系统
    • 集中式/分布式数据库系统
  • 应用程序本身

下节内容:容错基础知识

知识共享许可协议本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 欢迎转载,并请注明来自:YEY 的博客 同时保持文章内容的完整和以上声明信息!