3.1 基于磁盘数据库的弱项
事务数据库的特性包括原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和
持久性(Durability),简称 ACID。前 3 个特性因为和业务结合得相对比较紧密,通常会在无意中
考虑得更多,第 4 个特性持久性,除了 DBA 和数据库内核开发人员外,大部分开发人员只关心逻
辑上应该如此,并不关注实现上能否满足业务要求,以及如何借助它更加高效地实现业务功能,这
也是本节要讲的内容。这里假设读者已经掌握 ACID。
对于基于磁盘的数据库来说,持久性是涉及最后物理磁盘操作的。前面章节介绍了普通商用服
务器各组件之间的性能差异,磁盘相对于内存来说要慢好几个数量级,所以对于任何满足 ACID 特
性的基于磁盘的数据库来说,最小化不必要的持久性是让数据库保持高性能的关键之一。需要注意
的是,不仅写入是持久化,写入的数据最终是为了读取,所以读的成本也需要算进去。
由于硬盘速度慢是目前无法突破的物理限制,而一个事务中通常会包含不止对一个数据块的修
改,如修改账户余额要同时记录资金流水,因此对于修改后数据库的存储,现代数据库等都采用先
写日志(Write Ahead Logging, WAL)技术,尽可能将数据块的随机写转换为 Redo 日志的顺序写
来提高整体的吞吐量。
而读则基于相邻的数据通常会被一起访问的原则,尽可能采取预读技术,将多个连续但是当前
没有明确请求的块一次性读取到内存来提高读的速度。例如,在 Oracle 中,可以通过初始化参数
控制全表扫描和快速全索引扫描时每次读的块数。相对于随机读 / 写来说,顺序读 / 写的速度则要
快数倍到数十倍。
为了让读者更加深刻地理解并加深记忆,可以进行一个测试。对于 Insert 单表操作,如果直
接访问磁盘, Oracle 的 TPS 能达到多少?为了不让 Oracle sga 缓存,同时尽量模拟随机写,使用 6 张
分别在不同表空间的表,这些表空间已经包含 500MB~5GB 初始数据,因为不同的 filesystemio_options
会导致不同的结果,这里以 Linux 下默认值 None 为例。测试数据和表结构如下:
create table io_test_1(id int,text1 char(2000),text2 char(2000),text3
char(2000))storage(initial 100m) tablespace SOE;
create table io_test_2(id int,text1 char(2000),text2 char(2000),text3
char(2000))storage(initial 100m) tablespace USERS;
展开