01- Oracle核心架构:理解数据库如何运转
Oracle核心架构理解数据库如何运转为什么要先学架构你在工作中写SQL、建表、查问题可能觉得这些已经够用了。但如果不理解Oracle的底层架构就像开车只会踩油门刹车不知道发动机怎么运作——遇到性能问题、故障排查时你只能靠猜或者把希望寄托在别人身上。作为DBA你需要知道一条SQL提交后Oracle内部发生了什么为什么有时候数据库很慢瓶颈在哪数据库崩溃了数据会不会丢为什么如何根据架构特点去调优这篇文章会带你建立Oracle的整体认知框架。后面的所有学习都会基于这个框架不断深入。核心概念实例 vs 数据库很多人搞不清这两个概念其实很简单数据库Database物理文件数据文件.dbf存放表、索引等数据控制文件.ctl记录数据库的结构信息重做日志文件.log记录所有变更操作实例Instance内存 进程一堆进程在运行一块内存在工作它们读写数据库文件关系数据库是静态的文件实例是动态的程序。你启动Oracle本质上是启动一个实例去访问数据库文件。类比数据库是一本书实例是正在读这本书的人。书可以被多个人多个实例同时读这就是RACReal Application Clusters的原理。内存结构SGA与PGAOracle的内存分为两大块1. SGASystem Global Area—— 共享内存所有用户进程都能访问主要包含① 共享池Shared Pool存放SQL语句的解析结果、PL/SQL代码、数据字典缓存。为什么重要因为解析SQL很耗时。如果你的SQL语句每次都要重新解析性能会很差。这就是为什么推荐用绑定变量——让SQL可以复用解析结果。② 数据库缓冲区Database Buffer Cache缓存从数据文件读取的数据块。你查询数据时Oracle不是直接读磁盘而是先看缓冲区里有没有。如果有命中速度极快如果没有未命中才去读磁盘然后放进缓冲区。这个区域的大小直接影响查询性能。太小命中率低太大浪费内存。③ 重做日志缓冲区Redo Log Buffer临时存放数据变更的日志。你执行UPDATE、INSERT时,变更先写到这里,然后异步刷入重做日志文件。这是Oracle保证数据不丢失的关键机制——即使数据库崩溃,也能通过重做日志恢复。④ 大池Large Pool、Java池等用于特定操作比如RMAN备份、并行查询等。初期不用太关注。2. PGAProgram Global Area—— 私有内存每个服务器进程独享主要用于排序操作ORDER BY、GROUP BY哈希连接Hash Join会话信息如果你的SQL有大量排序PGA不够用就会溢出到磁盘临时表空间性能暴跌。进程结构后台进程干什么的Oracle实例启动时会自动启动一系列后台进程。你在操作系统层面看到的ora_xxxx_SID就是它们。几个核心进程SMONSystem Monitor系统监控进程负责实例恢复、清理临时段、合并空闲空间等。数据库崩溃重启时就是它在执行实例恢复。PMONProcess Monitor进程监控当用户进程异常退出时它负责清理资源、释放锁。DBWnDatabase Writer把脏数据Buffer Cache中被修改过的数据块写入数据文件。注意它是异步、批量写入的不是你一COMMIT就立刻写磁盘。LGWRLog Writer把重做日志缓冲区的内容写入重做日志文件。这是同步的、实时的你COMMIT时必须等LGWR写完日志事务才算提交成功。CKPTCheckpoint触发检查点通知DBWn刷脏数据并更新控制文件和数据文件头。检查点是实例恢复的关键——它标记了哪些数据已经持久化到磁盘。ARCnArchiver归档进程把已写满的重做日志文件复制到归档目录。只有归档模式下才有。归档日志是数据库恢复的基础——没有归档你只能恢复到最近一次备份,中间的数据全丢。存储结构逻辑与物理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 :1比WHERE dept_id 10更容易复用。3. 执行计划生成优化器决定怎么执行最快全表扫描用索引用哪个索引4. 数据获取从Buffer Cache或数据文件先查Buffer Cache命中就直接返回未命中读数据文件把数据块放进Buffer Cache5. 返回结果数据传回客户端。如果是UPDATE语句还会在Buffer Cache中修改数据块变成脏数据生成重做日志写入Redo Log Buffer生成回滚信息写入Undo表空间用于ROLLBACK或一致性读6. COMMIT提交时LGWR把Redo Log Buffer刷到重做日志文件必须等待确保持久化事务标记为已提交DBWn会在后台某个时刻把脏数据写入数据文件异步的7. 检查点发生时CKPT触发DBWn加速刷脏数据更新控制文件。这样下次实例恢复时只需要重做检查点之后的日志缩短恢复时间。关键机制为什么Oracle能保证数据不丢这是面试常考的问题也是理解Oracle的核心Write-Ahead LoggingWAL先写日志原则任何数据变更必须先写重做日志再写数据文件。这样即使写数据文件时崩溃了重做日志里有完整记录可以重新执行Redo。提交时的保证你COMMIT时LGWR必须把日志写到磁盘才返回成功。所以提交成功的事务数据一定不会丢只要重做日志文件没坏。崩溃恢复流程实例重启SMON启动读重做日志重新执行所有已提交的事务Roll Forward回滚所有未提交的事务Roll Back用Undo数据数据库恢复到崩溃前的一致状态思考题可以写下你的理解o为什么COMMIT很快但大批量INSERT后COMMIT会慢一些提示想想LGWR要做什么。如果Buffer Cache命中率只有50%意味着什么怎么优化提示命中率低是因为缓存太小还是SQL写得差假设数据库突然断电正在执行的事务会怎样已提交但还没写入数据文件的数据会丢吗提示回顾WAL原则和实例恢复流程。你在工作中遇到过哪些性能问题现在回头看能定位到是架构中哪个环节的瓶颈吗比如慢是因为SQL解析慢共享池问题还是I/O慢Buffer Cache问题还是排序慢PGA问题下一篇预告我们会深入SQL执行计划与优化器学会看懂EXPLAIN PLAN理解Oracle是如何选择执行路径的——这是性能优化的基础。