01- Oracle核心架构:理解数据库如何运转

Oracle核心架构:理解数据库如何运转

为什么要先学架构?

你在工作中写SQL、建表、查问题,可能觉得这些已经够用了。但如果不理解Oracle的底层架构,就像开车只会踩油门刹车,不知道发动机怎么运作------遇到性能问题、故障排查时,你只能靠猜,或者把希望寄托在别人身上。

作为DBA,你需要知道:

  • 一条SQL提交后,Oracle内部发生了什么?
  • 为什么有时候数据库很慢?瓶颈在哪?
  • 数据库崩溃了,数据会不会丢?为什么?
  • 如何根据架构特点去调优?

这篇文章会带你建立Oracle的整体认知框架。后面的所有学习,都会基于这个框架不断深入。


核心概念:实例 vs 数据库

很多人搞不清这两个概念,其实很简单:

数据库(Database):物理文件

  • 数据文件(.dbf):存放表、索引等数据
  • 控制文件(.ctl):记录数据库的结构信息
  • 重做日志文件(.log):记录所有变更操作

实例(Instance):内存 + 进程

  • 一堆进程在运行
  • 一块内存在工作
  • 它们读写数据库文件

关系:数据库是静态的文件,实例是动态的程序。你启动Oracle,本质上是启动一个实例去访问数据库文件。

类比:数据库是一本书,实例是正在读这本书的人。书可以被多个人(多个实例)同时读,这就是RAC(Real Application Clusters)的原理。


内存结构:SGA与PGA

Oracle的内存分为两大块:

1. SGA(System Global Area)------ 共享内存

所有用户进程都能访问,主要包含:

① 共享池(Shared Pool)

存放SQL语句的解析结果、PL/SQL代码、数据字典缓存。

为什么重要?因为解析SQL很耗时。如果你的SQL语句每次都要重新解析,性能会很差。这就是为什么推荐用绑定变量------让SQL可以复用解析结果。

② 数据库缓冲区(Database Buffer Cache)

缓存从数据文件读取的数据块。

你查询数据时,Oracle不是直接读磁盘,而是先看缓冲区里有没有。如果有(命中),速度极快;如果没有(未命中),才去读磁盘,然后放进缓冲区。

这个区域的大小直接影响查询性能。太小,命中率低;太大,浪费内存。

③ 重做日志缓冲区(Redo Log Buffer)

临时存放数据变更的日志。

你执行UPDATEINSERT时,变更先写到这里,然后异步刷入重做日志文件。这是Oracle保证数据不丢失的关键机制------即使数据库崩溃,也能通过重做日志恢复。

④ 大池(Large Pool)、Java池等

用于特定操作,比如RMAN备份、并行查询等。初期不用太关注。

2. PGA(Program Global Area)------ 私有内存

每个服务器进程独享,主要用于:

  • 排序操作(ORDER BY、GROUP BY)
  • 哈希连接(Hash Join)
  • 会话信息

如果你的SQL有大量排序,PGA不够用,就会溢出到磁盘(临时表空间),性能暴跌。


进程结构:后台进程干什么的?

Oracle实例启动时,会自动启动一系列后台进程。你在操作系统层面看到的ora_xxxx_<SID>就是它们。

几个核心进程:

SMON(System Monitor)

系统监控进程,负责实例恢复、清理临时段、合并空闲空间等。数据库崩溃重启时,就是它在执行实例恢复。

PMON(Process Monitor)

进程监控,当用户进程异常退出时,它负责清理资源、释放锁。

DBWn(Database Writer)

把脏数据(Buffer Cache中被修改过的数据块)写入数据文件。注意:它是异步、批量写入的,不是你一COMMIT就立刻写磁盘。

LGWR(Log Writer)

把重做日志缓冲区的内容写入重做日志文件。这是同步的、实时的!你COMMIT时,必须等LGWR写完日志,事务才算提交成功。

CKPT(Checkpoint)

触发检查点,通知DBWn刷脏数据,并更新控制文件和数据文件头。检查点是实例恢复的关键------它标记了"哪些数据已经持久化到磁盘"。

ARCn(Archiver)

归档进程,把已写满的重做日志文件复制到归档目录。只有归档模式下才有。归档日志是数据库恢复的基础------没有归档,你只能恢复到最近一次备份,中间的数据全丢。


存储结构:逻辑与物理

Oracle的存储是分层的:

逻辑结构(用户视角)

复制代码
数据库
  └─ 表空间(Tablespace)
       └─ 段(Segment):表、索引
            └─ 区(Extent):连续的数据块
                 └─ 数据块(Block):最小I/O单位,默认8KB

物理结构(操作系统视角)

复制代码
数据文件(.dbf)
  ↑ 对应
表空间

一个表空间可以包含多个数据文件,一个数据文件只能属于一个表空间。

为什么要分表空间?

  • 方便管理:用户数据、系统数据、临时数据、回滚数据分开存放
  • 方便备份:可以只备份某个表空间
  • 性能优化:不同表空间可以放在不同磁盘上,分散I/O

串起来:一条SQL的生命周期

现在我们把所有概念串起来,看看执行SELECT * FROM employees WHERE dept_id = 10时发生了什么:

1. 用户进程发起请求

客户端(SQL*Plus、JDBC等)建立连接,服务器进程被分配。

2. SQL解析(在共享池)

  • 语法检查:SQL写对了吗?
  • 语义检查:表存在吗?列存在吗?权限够吗?
  • 硬解析 vs 软解析
    • 硬解析:第一次执行,要生成执行计划,很慢
    • 软解析:共享池里找到了相同的SQL,直接用,很快

这就是为什么绑定变量很重要------WHERE dept_id = :1WHERE dept_id = 10更容易复用。

3. 执行计划生成

优化器决定怎么执行最快:全表扫描?用索引?用哪个索引?

4. 数据获取(从Buffer Cache或数据文件)

  • 先查Buffer Cache,命中就直接返回
  • 未命中,读数据文件,把数据块放进Buffer Cache

5. 返回结果

数据传回客户端。

如果是UPDATE语句,还会:

  • 在Buffer Cache中修改数据块(变成脏数据)
  • 生成重做日志,写入Redo Log Buffer
  • 生成回滚信息,写入Undo表空间(用于ROLLBACK或一致性读)

6. COMMIT提交时

  • LGWR把Redo Log Buffer刷到重做日志文件(必须等待,确保持久化)
  • 事务标记为已提交
  • DBWn会在后台某个时刻把脏数据写入数据文件(异步的)

7. 检查点发生时

CKPT触发,DBWn加速刷脏数据,更新控制文件。这样下次实例恢复时,只需要重做检查点之后的日志,缩短恢复时间。


关键机制:为什么Oracle能保证数据不丢?

这是面试常考的问题,也是理解Oracle的核心:

Write-Ahead Logging(WAL,先写日志)原则

任何数据变更,必须先写重做日志,再写数据文件。这样即使写数据文件时崩溃了,重做日志里有完整记录,可以重新执行(Redo)。

提交时的保证

COMMIT时,LGWR必须把日志写到磁盘,才返回成功。所以提交成功的事务,数据一定不会丢(只要重做日志文件没坏)。

崩溃恢复流程

  1. 实例重启,SMON启动
  2. 读重做日志,重新执行所有已提交的事务(Roll Forward)
  3. 回滚所有未提交的事务(Roll Back,用Undo数据)
  4. 数据库恢复到崩溃前的一致状态

思考题(可以写下你的理解o)

  1. 为什么COMMIT很快,但大批量INSERTCOMMIT会慢一些?

    提示:想想LGWR要做什么。

  2. 如果Buffer Cache命中率只有50%,意味着什么?怎么优化?

    提示:命中率低是因为缓存太小,还是SQL写得差?

  3. 假设数据库突然断电,正在执行的事务会怎样?已提交但还没写入数据文件的数据会丢吗?

    提示:回顾WAL原则和实例恢复流程。

  4. 你在工作中遇到过哪些性能问题?现在回头看,能定位到是架构中哪个环节的瓶颈吗?

    比如:慢是因为SQL解析慢(共享池问题)?还是I/O慢(Buffer Cache问题)?还是排序慢(PGA问题)?


下一篇预告 :我们会深入SQL执行计划与优化器,学会看懂EXPLAIN PLAN,理解Oracle是如何选择执行路径的------这是性能优化的基础。

相关推荐
TDengine (老段)1 小时前
TDengine IDMP 组态面板 —— 画布
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
buhuimaren_2 小时前
MySQL数据库初体验
数据库·mysql
IvorySQL2 小时前
PostgreSQL 技术日报 (3月20日)|PGConf.dev 2026 日程公布
数据库·postgresql·开源
华农DrLai2 小时前
什么是Prompt工程?为什么提示词的质量决定AI输出的好坏?
数据库·人工智能·gpt·大模型·nlp·prompt
溜达的大象2 小时前
数据库选型不踩坑:从关系型到向量库的全景技术图谱
数据库
白藏y2 小时前
【数据库】SQLite的基础使用
数据库·sqlite
Ne0_bbk2 小时前
# 写了5个Skill,agent一个都不用:OpenClaw + 国产模型的Skill调度踩坑实录
架构
攒了一袋星辰2 小时前
SequenceGenerator高并发有序顺序号生成中间件 - 架构设计文档
java·后端·spring·中间件·架构·kafka·maven
weixin_449290012 小时前
智能盒子-Agent-Skill-执行逻辑架构
网络·架构