Oracle 数据库面试题
15 道题- 分类
- 数据库
- 题目数
- 15 道
1 Oracle 数据库的体系结构总览
答案:
Oracle 数据库体系结构由**数据库(Database)和实例(Instance)**两大部分构成,采用经典的客户端-服务器架构,在物理上由存储在磁盘上的数据文件集合组成,在内存中由内存结构与后台进程共同协作。
核心组成:
| 组件 | 职责 |
|---|---|
| Database(数据库) | 物理层,磁盘上的数据文件、控制文件、重做日志文件、归档日志文件、参数文件、密码文件等物理文件集合 |
| Instance(实例) | 逻辑层,由内存结构(SGA + PGA)与后台进程(DBWn、LGWR、CKPT、ARCn、SMON、PMON 等)组成 |
| User Process | 客户端应用进程,提交 SQL 请求 |
| Server Process | 服务器进程,代表会话执行 SQL,读取数据、返回结果 |
实例与数据库的对应关系:
- 单实例单库(Single Instance):1 个 Instance 对应 1 个 Database,常见于中小型生产或开发环境。
- RAC(Real Application Clusters):多个 Instance 同时挂载并打开同一个 Database,所有实例共享存储,节点间通过 Cache Fusion 机制同步 SGA 中的数据块。
- Data Guard:通过主库(Primary)的 Redo 传输到备库(Standby)实现数据保护,备库可挂载为物理备库(Physical Standby,受 Redo Apply 应用)或逻辑备库(Logical Standby,受 SQL Apply 应用)。
多租户架构(Multitenant Architecture,12c+):
12c 引入 CDB(Container Database)+ PDB(Pluggable Database)架构,23ai 起 CDB 为唯一架构(非 CDB 不再支持)。1 个 CDB 包含 1 个根容器(CDB$ROOT)、1 个种子容器(PDB$SEED)和 0 到 N 个应用 PDB。CDB 统一管理内存、进程与系统表空间,PDB 之间通过插拔(Plug/Unplug)实现快速迁移,多租户显著降低单位 PDB 的资源消耗与运维成本。
典型连接路径:
graph LR
A["Client (sqlplus/JDBC)"] -->|"tnsnames.ora"| B["Listener"]
B -->|"spawn"| C["Server Process"]
C --> D["SGA / PGA"]
D --> E["Datafiles / Redo / Controlfile"]
2 表空间(Tablespace)与数据文件(Datafile)的关系
答案:
表空间是 Oracle 逻辑存储的最高层抽象,由一个或多个物理**数据文件(Datafile)**组成。表空间作为段(Segment)、区(Extent)、块(Block)的逻辑容器,屏蔽了底层物理文件分布的复杂性,简化了存储管理与空间配额控制。
存储层次结构:
| 层次 | 单位 | 说明 |
|---|---|---|
| Tablespace | 表空间 | 逻辑容器,跨多个数据文件 |
| Segment | 段 | 表、索引、LOB、LobPartition 等对象占用的空间集合 |
| Extent | 区 | 连续的数据块集合,由 PCTINCREASE 控制增长 |
| Data Block | 数据块 | 最小 I/O 单位(默认 8KB),对应 OS 多个 block |
表空间类型:
| 类型 | 用途 | 说明 |
|---|---|---|
| SYSTEM | 数据字典 | 必须在任何时候都可用的核心系统表空间 |
| SYSAUX | 辅助系统表空间 | 12c+ 承载 AWR、Enterprise Manager Data 等组件 |
| UNDO | 撤销表空间 | 存储 Undo Segment,提供事务回滚与读一致性 |
| TEMP | 临时表空间 | 处理大规模排序、Hash Join、全局临时表 |
| USERS | 默认用户表空间 | 存储用户数据 |
| Bigfile | 单文件大表空间 | 8K 块可达 32TB,简化大对象管理 |
关键管理操作:
-- 创建表空间
CREATE TABLESPACE tbs_app
DATAFILE '/u01/oradata/ORCL/tbs_app01.dbf' SIZE 10G AUTOEXTEND ON NEXT 1G MAXSIZE 32G
EXTENT MANAGEMENT LOCAL
SEGMENT SPACE MANAGEMENT AUTO;
-- 增加数据文件
ALTER TABLESPACE tbs_app ADD DATAFILE '/u01/oradata/ORCL/tbs_app02.dbf' SIZE 10G;
-- 重命名数据文件(MOUNT 状态下)
ALTER DATABASE RENAME FILE '/old/path.dbf' TO '/new/path.dbf';
-- 在线/离线表空间
ALTER TABLESPACE tbs_app ONLINE;
ALTER TABLESPACE tbs_app OFFLINE NORMAL; -- 正常离线前做检查点
SYSTEM 与 SYSAUX 表空间不可 OFFLINE,普通表空间通过 OFFLINE NORMAL/IMMEDIATE 切换状态(IMMEDIATE 不做检查点,恢复时需介质恢复)。
3 SGA 与 PGA 的内存结构详解
答案:
Oracle 实例的内存由 **SGA(System Global Area,系统全局区)**和 **PGA(Program Global Area,程序全局区)**两大部分组成。SGA 是实例共享内存,所有 Server Process 共享访问;PGA 是 Server Process 私有内存,每个会话独占。
SGA 核心组件:
| 组件 | 作用 | 关键参数 |
|---|---|---|
| Database Buffer Cache | 缓存数据块,逻辑读先于物理读命中此处 | DB_CACHE_SIZE |
| Shared Pool | 缓存 SQL、PL/SQL 执行计划、数据字典、库缓存 | SHARED_POOL_SIZE |
| Redo Log Buffer | 缓存 Redo 条带,事务提交前由 LGWR 写入 Redo Log | LOG_BUFFER |
| Large Pool | RMAN、并行执行、共享服务器会话内存 | LARGE_POOL_SIZE |
| Java Pool | Java Stored Procedure 内存区域 | JAVA_POOL_SIZE |
| Streams Pool | Streams / XA / GoldenGate 复制缓存 | STREAMS_POOL_SIZE |
| Fixed SGA | 固定控制结构 | 内部维护 |
| In-Memory Area(12c+) | 列式内存存储,OLAP 加速 | INMEMORY_SIZE |
PGA 关键组成:
| 组件 | 作用 |
|---|---|
| Session Memory | 会话变量、登录信息 |
| Private SQL Area | 持久区(绑定变量信息)+ 运行时区(执行状态) |
| SQL Work Areas | 排序区(Sort Area)、Hash Join Area、Bitmap Create Area、Bitmap Merge Area |
自动内存管理:
- AMM(Automatic Memory Management,11g+):
MEMORY_TARGET统一管理 SGA + PGA,Oracle 自动调优组件比例。 - ASMM(Automatic Shared Memory Management):
SGA_TARGET设定后由 Oracle 自动调整 Buffer Cache、Shared Pool、Large Pool、Java Pool 内部比例(需为非零)。 - Automatic PGA Management:
PGA_AGGREGATE_TARGET设定后由 Oracle 自动按需分配工作区,替代_PGA_MAX_SIZE手动控制。
-- 启用 ASMM
ALTER SYSTEM SET SGA_TARGET = 8G SCOPE=SPFILE;
ALTER SYSTEM SET SHARED_POOL_SIZE = 0; -- 0 表示由 ASMM 自动管理
-- 启用 AMM(需使用 /dev/shm 或 HUGE 页)
ALTER SYSTEM SET MEMORY_TARGET = 16G SCOPE=SPFILE;
ALTER SYSTEM SET MEMORY_MAX_TARGET = 16G SCOPE=SPFILE;
OLTP 与 DSS 系统内存分配差异:
OLTP 系统以Buffer Cache为最大开销(数据随机访问频繁),DSS/数据仓库系统以Large Pool + PGA Work Area为最大开销(大规模排序与 Hash Join)。
4 关键后台进程 DBWn/CKPT/LGWR/ARCn 的协作机制
答案:
Oracle 关键后台进程通过协作完成事务持久化与实例恢复两大核心职责,是 Oracle 写入路径的核心引擎。
进程职责:
| 进程 | 全称 | 核心职责 |
|---|---|---|
| DBWn | Database Writer | 将 Database Buffer Cache 中脏块(Dirty Buffer)写回数据文件,进程数由 DB_WRITER_PROCESSES 控制 |
| LGWR | Log Writer | 将 Redo Log Buffer 中的 Redo 条带顺序写入 Online Redo Log,事务提交必须等待 LGWR 写入完成(Log Force at Commit) |
| CKPT | Checkpoint Process | 触发检查点,通知 DBWn 写脏块,更新数据文件头与控制文件的 SCN 信息 |
| ARCn | Archiver | 归档模式(ARCHIVELOG)下将已满的 Online Redo Log 复制到归档日志(Archive Log),支持时间点恢复 |
| SMON | System Monitor | 实例恢复、清理临时段、合并空闲区 |
| PMON | Process Monitor | 进程异常清理、回滚未提交事务、释放锁与资源、注册监听 |
| MMON/MMNL | Manageability Monitor | AWR 快照收集、ADDM、告警、ASH 采样 |
| RECO | Recoverer | 分布式两阶段提交(2PC)中的 in-doubt 事务恢复 |
| LMSn(RAC) | Lock Manager Service | Cache Fusion 跨实例块传输,集群 GCS/GES 服务 |
写入路径与协作:
sequenceDiagram
participant U as User Process
participant S as Server Process
participant LB as Redo Log Buffer
participant LG as LGWR
participant BC as Buffer Cache
participant DB as DBWn
participant DF as Datafile
participant OL as Online Redo Log
U->>S: COMMIT
S->>LB: 写入 Redo 条带
S->>LG: 触发 LGWR
LG->>OL: 写入 Online Redo Log
LG-->>S: 写盘成功(Log Force at Commit)
S-->>U: COMMIT 成功
Note over DB,DF: 脏块由 DBWn 异步写回
DB->>BC: 扫描脏块
DB->>DF: 写入数据文件
关键协作点:
- LGWR 写入先行(Write-Ahead Logging):DBWn 写脏块前,对应 Redo 必须先由 LGWR 写入 Online Redo Log,确保实例恢复可通过 Redo 重做。
- CKPT 触发 DBWn:CKPT 触发检查点后将更新数据文件头与控制文件的检查点 SCN(
DBA_RCHIVE_LOG、V$DATABASE),减少实例恢复时间。 - ARCn 接力归档:当 LGWR 切换 Log Group 时(Log Switch),ARCn 将已满的 Redo Log 复制到归档目录,是时间点恢复(PITR)的前提。
5 Redo Log 与 Undo 的关系与作用
答案:
**Redo Log(重做日志)**与 **Undo(撤销数据)是 Oracle 事务持久化与读一致性的两大基石,分别承担前滚(Roll Forward)与回滚(Roll Back)**职责,二者缺一不可。
Redo Log 机制:
| 概念 | 说明 |
|---|---|
| Online Redo Log | 实例运行时循环写入的 Redo 文件,至少 2 组(推荐 3 组)互为镜像(Multiplex) |
| Redo Log Group | 一组 Redo Member,组内多 Member 实现镜像防止单点故障 |
| Log Switch | 当前 Group 写满后切换到下一组,触发 ARCn 归档(ARCHIVELOG 模式) |
| Checkpoint | 控制文件 + 数据文件头更新,确保该 SCN 之前的脏块全部写盘 |
Undo 机制:
| 概念 | 说明 |
|---|---|
| Undo Segment | 存储事务前镜像(Before Image)的段,位于 Undo Tablespace |
| Undo Retention | Undo 数据保留时间(UNDO_RETENTION),支持读一致性与 Flashback Query |
| Guarantee Retention | RETENTION GUARANTEE 表空间属性,确保 Undo 不被覆盖(牺牲空间利用率) |
| ORA-01555 | “Snapshot too old” 错误,Undo 被覆盖导致读一致性查询失败 |
两者协作实现实例恢复:
graph TD
A["实例崩溃"] --> B["SMON 执行实例恢复"]
B --> C["Cache Recovery(缓存恢复)"]
C --> D["重做(Roll Forward)
应用 Redo Log"]
D --> E["回滚(Roll Back)
应用 Undo 回滚未提交事务"]
E --> F["数据库一致性"]
- 前滚(Cache Recovery):用 Redo Log 重做已提交但未写入数据文件的事务。
- 回滚(Transaction Recovery):用 Undo 回滚未提交的事务,恢复一致性。
闪回技术(Flashback)基于 Undo:
| Flashback 技术 | 依赖机制 |
|---|---|
| Flashback Query | Undo 数据 |
| Flashback Table | Undo 数据 + FLASHBACK TABLE |
| Flashback Database | Flashback Logs(与 Undo 独立,由 RVWR 进程写入 Flash Recovery Area) |
| Flashback Drop | Recycle Bin(dba_recyclebin) |
6 锁(Lock)与闩锁(Latch)的区别
答案:
锁(Lock)与闩锁(Latch)是 Oracle 并发控制的两个层级,前者面向业务数据,保证事务级 ACID,由队列管理;后者面向内存结构,保护内存数据结构的互斥访问,粒度极轻、持续时间极短。
对比分析:
| 维度 | Lock(锁) | Latch(闩锁) |
|---|---|---|
| 保护对象 | 业务数据(行、表、字典定义) | 内存数据结构(Buffer Cache Hash Chain、Library Cache、Shared Pool LRU) |
| 粒度 | 行级(TM、TX)、表级(TM) | 极细(Buffer Hash Bucket、Library Cache Latch) |
| 持有者 | 事务(v$lock 关联 v$transaction) | Server Process / 后台进程 |
| 持有时间 | 毫秒~秒~分钟(事务提交) | 纳秒~微秒 |
| 队列 | FIFO 队列,无死锁则按队列顺序获取 | Willing-to-Wait(_spin_count 自旋后睡眠)或 Immediate(不等待) |
| 死锁检测 | 有(自动检测 + ORA-00060 报错 + 回滚) | 无,依赖自旋超时 |
| 查询视图 | v$lock、dba_lock、v$session | v$latch、v$latchholder |
| 可释放 | 事务 Commit / Rollback | 进程逻辑块执行结束 |
| 争用表现 | enq: TX - row lock contention | latch: shared pool、cache buffers chains |
锁的类型:
| 锁 | 模式 | 含义 |
|---|---|---|
| TM(DML Enqueue) | RS/RX/S/SRX/X | 表级锁,由 DML 自动获取,X 互斥 DML |
| TX(Transaction) | X(排他) | 事务锁,锁住事务相关的 Undo Segment 与行 |
| ST(Space Transaction) | - | 字典管理表空间的区间分配锁 |
| TT / DL / UL | - | 临时表 / Direct Loader / User-defined Locks |
闩锁争用诊断:
-- 顶级闩锁争用统计
SELECT latch#, name, gets, misses, sleeps, immediate_misses, immediate_gets
FROM v$latch
ORDER BY (misses - immediate_misses) DESC
FETCH FIRST 10 ROWS ONLY;
-- Buffer Busy Waits(闩锁级)热点块
SELECT objd, object_name, file#, dbablk, count(*)
FROM v$bh b JOIN dba_objects o ON b.objd = o.data_object_id
WHERE b.class# = 1
GROUP BY objd, object_name, file#, dbablk
ORDER BY count(*) DESC;
7 Oracle 的多版本并发控制(MVCC)与读一致性
答案:
Oracle 通过Undo-based MVCC实现语句级与事务级读一致性,查询不会阻塞写入,写入也不会阻塞读,这是 Oracle 在高并发场景下保持高吞吐的核心机制。
核心原理:
当一个查询在某一时刻启动时,Oracle 记录当前 SCN(System Change Number),查询过程中访问每个数据块时都校验块的 SCN:
- 数据块 SCN ≤ 查询 SCN:块中数据可见,直接返回。
- 数据块 SCN > 查询 SCN:块在查询启动后被修改,Oracle 通过**一致性读(Consistent Read)**机制构造 CR Copy(Consistent Read Copy),从 Undo 中逐层回滚到查询 SCN 对应的前镜像。
两种读一致性级别:
| 级别 | 触发条件 | 行为 |
|---|---|---|
| Statement-Level Read Consistency | 单一 SELECT 默认 | 读一致性只到当前语句结束 |
| Transaction-Level Read Consistency | 同一事务内多次 SELECT(默认) | 读一致性延伸到整个事务(基于会话的 SCN/TIMESTAMP) |
Flashback Query 可通过 as of timestamp/as of scn 显式指定读一致性时间点。
关键争用与错误:
- ORA-01555: Snapshot too old:Undo 已被覆盖,CR Copy 无法构造。调大
UNDO_RETENTION、启用RETENTION GUARANTEE、优化大查询减少 Undo 访问。 - ORA-30036: unable to extend segment in undo tablespace:Undo 表空间不足,无法为新事务分配 Undo Segment。
- 事务回滚段(Rollback)竞争:高频小事务在 Undo 表空间内分配大量 Segment,导致空间碎片与
undo segment tx slot争用。
对比其他数据库:
| 数据库 | MVCC 实现 | 一致性读取 |
|---|---|---|
| Oracle | Undo Segment | CR Copy 按需构造,无版本链增长 |
| PostgreSQL | Heap Tuple + xmin/xmax + Visibility Map | 行级版本链,VACUUM 清理旧版本 |
| MySQL InnoDB | Undo Log + ReadView | ReadView 快照,B+Tree 不存放旧版本 |
| MongoDB | WiredTiger MVCC | 文档级快照 |
8 AWR 与 ASH 性能诊断方法
答案:
**AWR(Automatic Workload Repository)**与 **ASH(Active Session History)**是 Oracle 内置的性能数据仓库,是企业级性能诊断的事实标准,由 MMON/MMNL 进程自动收集与维护。
核心组件:
| 组件 | 职责 | 存储 |
|---|---|---|
| AWR | 周期性快照(默认 60 分钟,保留 8 天)的性能数据集合 | SYSAUX 表空间 |
| ASH | 每秒采样活跃会话的等待事件与 SQL 信息(每秒 1 次),默认保留 1 小时 | SYSAUX + 内存循环缓冲 |
| ADDM | 自动数据库诊断监视器,基于 AWR 快照自动给出根因建议 | 由 AWR 触发 |
| SQL Tuning Advisor | 自动 SQL 调优建议 | AWR 快照中的 SQL 统计 |
AWR 关键视图:
| 视图 | 用途 |
|---|---|
DBA_HIST_SNAPSHOT | 快照元数据 |
DBA_HIST_SYS_TIME_MODEL | DB Time / DB CPU 分解 |
DBA_HIST_SYSTEM_EVENT | 系统等待事件汇总 |
DBA_HIST_SQLSTAT | SQL 性能历史 |
DBA_HIST_SESSMETRIC_HISTORY | 会话级历史指标 |
DBA_HIST_TBSPC_SPACE_USAGE | 表空间使用历史 |
核心报告:
-- AWR 报告(指定快照区间)
@$ORACLE_HOME/rdbms/admin/awrrpt.sql
-- 输入 begin_snap、end_snap、report_type (HTML/TEXT)
-- ASH 报告(默认采样区间)
@$ORACLE_HOME/rdbms/admin/ashrpt.sql
-- ADDM 报告
@$ORACLE_HOME/rdbms/admin/addmrpt.sql
-- SQL 详细报告
@$ORACLE_HOME/rdbms/admin/sqlrpt.sql
关键性能指标:
| 指标 | 含义 | 异常阈值(OLTP) |
|---|---|---|
| DB Time | 数据库总耗时(CPU + 等待) | DB Time/CPU > 4 表示明显等待 |
| Average Active Sessions (AAS) | DB Time / Elapsed | 接近 CPU 核数说明饱和 |
| Buffer Hit Ratio | 缓存命中率 | > 95% 健康 |
| Library Cache Hit Ratio | 软解析命中率 | > 95% 健康 |
| Soft Parse % | 软解析占比 | > 95% 优秀 |
| Log File Sync | 提交等待 LGWR | 平均 > 5ms 需关注 |
典型诊断流程:
- AWR Top 5 Event → 定位主导等待事件(
db file sequential read、latch: shared pool、enq: TX)。 - ASH → 拉取特定时间段内的活跃会话 + SQL 文本。
- SQL 报告 → 分析执行计划、Buffer Gets、Disk Reads。
- Segment 统计 → 定位热点对象(
DBA_HIST_SEG_STAT_OBJ)。
9 RMAN 备份与恢复体系
答案:
**RMAN(Recovery Manager)**是 Oracle 官方推荐的备份恢复工具,深度集成数据库内核,支持增量备份、块级损坏检测、自动化恢复脚本与时间点恢复(PITR),是企业级数据保护的事实标准。
核心概念:
| 概念 | 说明 |
|---|---|
| Channel(通道) | RMAN 到备份介质(磁盘/磁带)的 I/O 数据流,可分配并发度 |
| Backup Set | 一个或多个 Backup Piece 的逻辑集合,默认压缩 |
| Image Copy | 数据文件镜像副本(类似 OS cp),可直接用作增量备份的 Level 0 基线 |
| Full / Incremental Backup | 全备 / 增量备份(Level 0-4),Level 0 等价于 Full |
| Block Change Tracking | 启用增量备份时记录数据块变更(BCT 文件),加速增量 |
| Recovery Catalog | 独立 Schema 存储 RMAN 元数据,可集中管理多库 |
| FRA(Fast Recovery Area) | 闪回恢复区,统一管理备份、归档、Flashback Logs |
常用备份策略:
# 全量备份 + 归档
RMAN> CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON;
RMAN> CONFIGURE BACKUP OPTIMIZATION ON;
RMAN> CONFIGURE DEVICE TYPE DISK PARALLELISM 4 BACKUP TYPE TO COMPRESSED BACKUPSET;
# Level 0 增量基线
RMAN> BACKUP INCREMENTAL LEVEL 0 DATABASE PLUS ARCHIVELOG;
# Level 1 差异增量(累积:CUMULATIVE 或差异:DIFFERENTIAL)
RMAN> BACKUP INCREMENTAL LEVEL 1 CUMULATIVE DATABASE PLUS ARCHIVELOG;
典型恢复场景:
| 场景 | 恢复命令 |
|---|---|
| 数据文件损坏 | RESTORE DATAFILE '<file#>'; RECOVER DATAFILE '<file#>'; |
| 不完全恢复(时间点) | SHUTDOWN; STARTUP MOUNT; SET UNTIL TIME "TO_DATE(...)"; RESTORE DATABASE; RECOVER DATABASE; ALTER DATABASE OPEN RESETLOGS; |
| Tablespace Point-in-Time Recovery | RECOVER TABLESPACE <ts> UNTIL TIME ...; |
| 灾难恢复(Data Guard Switchover/Failover) | Data Guard 角色切换 |
| RMAN 块介质恢复 | RECOVER CORRUPTION LIST;(V$DATABASE_BLOCK_CORRUPTION) |
最佳实践:
- 启用 Block Change Tracking 加速增量。
- 配置 FRA 统一管理备份空间。
- 使用 RMAN Catalog 集中管理多库。
- 定期演练异机恢复,验证备份完整性。
- 备份完成后执行
RESTORE VALIDATE与VALIDATE BACKUPSET验证可恢复性。
10 Data Guard 高可用与灾备架构
答案:
Data Guard是 Oracle 企业级高可用与灾备(HADR)核心方案,通过 Redo 传输与应用实现 Primary 与 Standby 的实时同步,提供**Switchover(计划内切换)与Failover(故障切换)**两大灾难保护能力。
角色与拓扑:
| 角色 | 说明 |
|---|---|
| Primary Database | 主库,承担读写业务,生成 Redo |
| Physical Standby | 物理备库,Redo Apply(MRP 进程应用 Redo),块对块同步,可挂载为只读 |
| Logical Standby | 逻辑备库,SQL Apply(LSP 进程将 Redo 转换为 SQL),可同时承担部分查询业务 |
| Snapshot Standby | 快照备库,物理备库的衍生形态,可读写但 Redo 不应用,回切后丢弃修改 |
| Active Data Guard(11g+) | 物理备库在应用 Redo 同时支持只读查询(OPEN READ ONLY + REDO APPLY) |
| Cascaded Standby | 级联备库,从其他 Standby 接收 Redo,降低 Primary 压力 |
| Far Sync Standby | 远距离同步站,承接 Primary 的 SYNC Redo 再异步传给远端 Standby |
Redo 传输与服务:
| 模式 | 特性 | 数据丢失风险 | 网络要求 |
|---|---|---|---|
| Maximum Protection | SYNC 同步双写,失败则 Primary 关闭 | 零丢失 | 低延迟高带宽 |
| Maximum Availability | SYNC 同步双写,失败降级为 ASYNC | 接近零(依赖切换) | 低延迟高带宽 |
| Maximum Performance(默认) | ASYNC 异步传输 | 可能有数据丢失 | 无特殊要求 |
| Maximum Performance with SYNC | LGWR SYNC + ASYNC Fallback | 接近零丢失(Far Sync 模式) | 远距离可用 Far Sync 缓解 |
Data Guard Broker:
DGMGRL(Data Guard Broker CLI)将 Primary / Standby / Observer 抽象为统一配置(DGConfig),支持快速 Switchover / Failover、自动化健康监控与 FSFO(Fast-Start Failover)。
DGMGRL> CREATE CONFIGURATION dg_config AS PRIMARY DATABASE IS primary CONNECT IDENTIFIER IS primary_tns;
DGMGRL> ADD DATABASE standby AS CONNECT IDENTIFIER IS standby_tns MAINTAINED AS PHYSICAL;
DGMGRL> ENABLE CONFIGURATION;
DGMGRL> SWITCHOVER TO standby;
DGMGRL> FAILOVER TO standby; -- 需启用 Fast-Start Failover
Active Data Guard 优势:
- 备库实时查询分担主库读负载。
- 备库持续应用 Redo,RPO 接近 0。
- 与 RMAN 集成在备库做备份(
BACKUP ... FROM ACTIVE DATABASE),减轻主库负担。
11 Oracle GoldenGate(OGG)双向复制与异构同步
答案:
Oracle GoldenGate(OGG)是 Oracle 战略级的逻辑复制产品,基于Redo Log 挖掘捕获增量变更,通过 TCP/IP 实时投递到目标端并应用,支持同构 / 异构、一对一 / 多对一 / 一对多 / 双向等复杂拓扑。
核心组件:
| 组件 | 进程 | 职责 |
|---|---|---|
| Extract | 抽取进程 | 读取源端 Redo Log / Archive Log,捕获 DML / DDL,生成 Trail 文件 |
| Data Pump | 二级抽取(可选) | 将 Trail 投递到目标端,跨网络时起到缓冲作用 |
| Manager | 管理进程 | 端口管理、进程启停、Trail 清理 |
| Replicat | 复制进程 | 在目标端读取 Trail,转换为 SQL/批量操作,提交目标库 |
| Collector | 接收服务(Manager 启动) | 接收 Data Pump 投递的网络数据 |
| Trail Files | 队列文件 | 磁盘上顺序写的捕获队列(dirdat/) |
复制模式:
| 模式 | 适用场景 |
|---|---|
| Integrated Capture | 与数据库 LogMiner 集成(11.2.1+),捕获效率高,支持更多数据类型 |
| Classic Capture | 直接读 Redo Log,向后兼容 |
| Integrated Replicat | 与数据库集成(12c+),支持并行应用、依赖性分析与冲突检测 |
| Classic Replicat | 单线程 SQL 应用,简单但吞吐低 |
| Coordinated Replicat | 协调多 Replicat 并行,按依赖关系分发事务 |
双向复制与冲突处理:
-- 双向复制(Active-Active)需要为每张表补充主键
-- 并配置冲突检测与解决(CDR:Conflict Detection and Resolution)
-- 配置 CDR
TABLE hr.employee, COLMAP (resolved_by = "GG_RESOLV_COLUMN"),
KEYCOLS (employee_id),
FILTER (resolve_conflict(employ_id, employee_id, employee_id_delta, ...));
| 冲突类型 | 处理策略 |
|---|---|
| Insert Conflict | 唯一索引冲突 → USEMAX、DISCARD |
| Update Conflict | 时间戳比较 → USEMAX(最新时间戳胜出) |
| Delete Conflict | 行已删除 → IGNORE |
| Resolution Columns | 标记列(如 last_modified_by、last_modified_ts)辅助决策 |
异构复制:
- Oracle → MySQL / PostgreSQL / Kafka(用作 CDC 数据管道)
- MySQL → Oracle
- SQL Server → Oracle
- Kafka Connect Connector for Oracle(基于 OGG)
OGG 已成为大型企业实现实时数据集成、容灾备份、数据湖实时入湖的核心中间件。
12 SQL 优化方法论与执行计划分析
答案:
Oracle SQL 优化是综合性工程,需要从执行计划、统计信息、索引设计、SQL 改写、Hint 控制、参数调优等多维度切入,遵循"先诊断、后优化、再验证“的工程化方法。
优化器与执行计划:
| 优化器 | 适用版本 | 特点 |
|---|---|---|
| RBO(Rule-Based Optimizer) | 9i 之前 | 已废弃,仅保留兼容性 |
| CBO(Cost-Based Optimizer) | 10g+ | 默认优化器,基于统计信息计算代价 |
| Adaptive Plans | 12c+ | 运行中动态调整子计划(Nested Loop → Hash Join) |
| SQL Plan Management (SPM) | 11g+ | 计划基线管理,防止性能回退 |
| SQL Plan Directives | 12c+ | 自动反馈列相关性,指导统计信息扩展 |
执行计划获取:
-- EXPLAIN PLAN(预估)
EXPLAIN PLAN FOR
SELECT * FROM orders o JOIN customers c ON o.cust_id = c.id WHERE c.region = 'APAC';
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(format => 'ALL +ADAPTIVE'));
-- 实际执行计划(更准确)
SELECT /*+ GATHER_PLAN_STATISTICS */ ...
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST'));
-- AWR 历史执行计划
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR(sql_id => 'abc123', plan_hash_value => NULL));
核心执行计划操作:
| 操作 | 含义 | 优化点 |
|---|---|---|
| TABLE ACCESS FULL | 全表扫描 | 大表高频查询需建索引 |
| INDEX RANGE SCAN | 索引范围扫描 | 索引选择性好(选择性 > 5%) |
| INDEX FAST FULL SCAN | 索引全扫描 | 替代 FTS,仅访问索引列 |
| INDEX FULL SCAN | 有序索引全扫 | ORDER BY 列匹配 |
| NESTED LOOPS | 嵌套循环连接 | 驱动表小、关联列有索引 |
| HASH JOIN | 哈希连接 | 大表关联,OPT_ESTIMATE 决定 |
| SORT MERGE JOIN | 排序合并连接 | 两表均已排序 |
| FILTER | 行级过滤 | 存在子查询不能展开 |
| VIEW | 视图合并 | 检查 _complex_view_merging |
统计信息管理:
-- 收集表 / Schema 统计信息
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(
ownname => 'HR',
tabname => 'ORDERS',
estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,
method_opt => 'FOR ALL COLUMNS SIZE AUTO',
cascade => TRUE,
degree => 4
);
END;
/
-- 收集直方图(数据分布偏斜)
DBMS_STATS.GATHER_TABLE_STATS(..., method_opt => 'FOR COLUMNS SIZE 254 region');
-- 动态采样(统计信息缺失时)
SELECT /*+ DYNAMIC_SAMPLING(o 4) */ ...
SQL 改写核心技巧:
| 改写方式 | 原理 |
|---|---|
| 绑定变量 | 减少硬解析,提升 Library Cache 命中率 |
| UNION ALL 替代 UNION | 避免去重排序 |
| EXISTS 替代 IN | 子查询命中索引时效率高 |
| NOT EXISTS 替代 NOT IN | NOT IN 无法使用索引 |
| 函数下推陷阱规避 | WHERE SUBSTR(name,1,3)='ABC' 改为 WHERE name LIKE 'ABC%' |
| 标量子查询改写为 JOIN | 减少重复执行 |
| DECODE / CASE 在聚合中的妙用 | 一次扫描完成多维度聚合 |
Hint 进阶:
SELECT /*+ INDEX(o idx_orders_region) USE_NL(o c) PARALLEL(o 4) */
o.order_id, c.cust_name
FROM orders o JOIN customers c ON o.cust_id = c.id
WHERE o.region = 'APAC';
| 类别 | 常用 Hint |
|---|---|
| 优化器目标 | ALL_ROWS、FIRST_ROWS(N)、RULE |
| 访问路径 | FULL、INDEX、INDEX_FFS、NO_INDEX |
| 连接方式 | USE_NL、USE_HASH、USE_MERGE、LEADING |
| 并行 | PARALLEL、PARALLEL_INDEX、NO_PARALLEL |
| 其他 | QB_NAME、MONITOR、GATHER_PLAN_STATISTICS |
13 表分区(Partitioning)策略与性能
答案:
表分区(Table Partitioning)是 Oracle 处理海量数据的核心技术,通过将大表按规则拆分为多个物理 Segment(Partition),在查询裁剪(Partition Pruning)、并行执行、数据维护三大场景下显著提升性能与可维护性。
分区类型:
| 类型 | 语法 | 适用场景 |
|---|---|---|
| RANGE | PARTITION BY RANGE (col) | 时间序列(按月 / 按天) |
| LIST | PARTITION BY LIST (col) | 离散值(地区、状态) |
| HASH | PARTITION BY HASH (col) | 数据均匀分布,避免热点 |
| INTERVAL(11g+) | PARTITION BY RANGE ... INTERVAL(NUMTOYMINTERVAL(1,'MONTH')) | 自动按需创建 RANGE 分区 |
| COMPOSITE | RANGE-HASH、RANGE-LIST | 先按时间分区,再按 HASH / LIST 子分区 |
| REFERENCE(11g+) | PARTITION BY REFERENCE (fk) | 父子表分区联动(数据仓库星型模型) |
| SYSTEM | - | 手动控制分区(高级) |
RANGE 分表示例:
CREATE TABLE orders (
order_id NUMBER,
order_date DATE,
cust_id NUMBER,
amount NUMBER
)
PARTITION BY RANGE (order_date) (
PARTITION p202401 VALUES LESS THAN (TO_DATE('2024-02-01','YYYY-MM-DD')),
PARTITION p202402 VALUES LESS THAN (TO_DATE('2024-03-01','YYYY-MM-DD')),
PARTITION p202403 VALUES LESS THAN (TO_DATE('2024-04-01','YYYY-MM-DD')),
PARTITION p_max VALUES LESS THAN (MAXVALUE)
)
ENABLE ROW MOVEMENT -- 分区键更新时自动迁移行
PARALLEL 4;
-- INTERVAL 自动分区(11g+)
CREATE TABLE orders_interval (
...
)
PARTITION BY RANGE (order_date)
INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'))
(PARTITION p_init VALUES LESS THAN (TO_DATE('2024-01-01','YYYY-MM-DD')));
性能优势:
| 优势 | 说明 |
|---|---|
| Partition Pruning | 查询 WHERE order_date >= '2024-03-01' AND order_date < '2024-04-01' 仅扫描 1 个分区 |
| Partition-wise Join | 两表同分区策略关联时按分区并行处理(避免数据倾斜) |
| 并行加载 | 分区交换(EXCHANGE PARTITION)实现快速数据加载 |
| 滚动窗口 | 历史分区 DROP 释放空间,新分区由 INTERVAL 自动创建 |
| 在线维护 | 单个分区 MOVE / REBUILD / SPLIT 不影响其他分区访问(部分场景需要 DML 锁) |
关键运维操作:
-- 新增分区
ALTER TABLE orders ADD PARTITION p202405 VALUES LESS THAN (TO_DATE('2024-06-01','YYYY-MM-DD'));
-- 分区 SPLIT(拆分)
ALTER TABLE orders SPLIT PARTITION p_max AT (TO_DATE('2024-12-01','YYYY-MM-DD')) INTO (PARTITION p202412, PARTITION p_max);
-- MERGE 合并
ALTER TABLE orders MERGE PARTITIONS p202401, p202402 INTO PARTITION p2024_q1;
-- 交换分区(极速加载:归档表 → 分区表)
ALTER TABLE orders EXCHANGE PARTITION p202401 WITH TABLE orders_archive INCLUDING INDEXES;
-- DROP 分区(秒级)
ALTER TABLE orders DROP PARTITION p202401;
-- TRUNCATE 分区(保留表结构)
ALTER TABLE orders TRUNCATE PARTITION p202401;
索引策略:
| 索引类型 | 说明 |
|---|---|
| LOCAL Index | 与分区同步,每个分区独立索引,自动维护(推荐) |
| Global Range Index | 全局索引,跨分区,但分区维护(EXCHANGE/DROP)会失效 |
| Global Hash Index | 全局 HASH 索引(不常用) |
| Partitioned Index | 显式分区索引 |
-- LOCAL 索引
CREATE INDEX idx_orders_cust ON orders(cust_id) LOCAL PARALLEL 4;
-- 分区索引(不与表分区一致)
CREATE INDEX idx_orders_global ON orders(order_id) GLOBAL PARTITION BY RANGE (order_id) (...);
14 字符集(Character Set)与 NLS 国际化
答案:
Oracle 字符集体系涵盖数据库字符集与国家字符集两个维度,决定了数据的存储编码与跨库、跨语言交互的正确性。配置错误将导致字符乱码、数据截断、导入导出失败等长期隐患。
字符集分级:
| 级别 | 参数 | 用途 |
|---|---|---|
| Database Character Set | NLS_CHARACTERSET | CHAR / VARCHAR2 / CLOB 等数据类型 |
| National Character Set | NLS_NCHAR_CHARACTERSET | NCHAR / NVARCHAR2 / NCLOB,Unicode 编码 |
| Client Character Set | NLS_LANG 客户端环境变量 | 客户端与服务器之间的转换 |
常见字符集:
| 字符集 | 字节 | 覆盖 | 用途 |
|---|---|---|---|
| US7ASCII | 1 | 纯英文 | 遗留英文系统 |
| WE8MSWIN1252 | 1 | 西欧 | 欧洲国家 |
| ZHS16GBK | 1-2 | 简体中文 | 国内遗留系统(GBK) |
| AL32UTF8 | 1-4 | 全 Unicode(推荐) | 国际化、多语言 |
| AL16UTF16 | 2/4 | Unicode(国家字符集) | NCHAR 默认 |
| UTF8 | 1-3 | 早期 UTF-8(已废弃) | Oracle 9i 之前 |
AL32UTF8 与 UTF8 的区别:
AL32UTF8(推荐):完整 Unicode,支持 4 字节字符(如 emoji)。UTF8(已弃用):仅支持 1-3 字节,无法存储部分辅助平面字符。
字符集迁移:
# 完整字符集迁移(WE8ISO8859P1 -> AL32UTF8)
csscan CHARACTER_SET WE8ISO8859P1 FULL=Y TOCHAR=AL32UTF8 LOG=csscan.log
# CSSCAN 输出无 Convertible / Truncation 错误后执行迁移
csalter CHARACTER_SET AL32UTF8 ASSM=TRUE
# 跨字符集导入导出(避免乱码)
expdp system/*** DIRECTORY=dp DUMPFILE=exp.dmp LOGFILE=exp.log \
CONTENT=ALL
# 客户端设置 NLS_LANG 与源库一致
NLS 体系(National Language Support):
| 参数 | 默认 | 作用 |
|---|---|---|
NLS_LANGUAGE | AMERICAN | 服务器消息语言、SORT 行为、星期 / 月份名称 |
NLS_TERRITORY | AMERICA | 日期格式、货币符号、小数点符号 |
NLS_DATE_FORMAT | 派生 | 日期显示格式 |
NLS_TIMESTAMP_FORMAT | 派生 | 时间戳格式 |
NLS_NUMERIC_CHARACTERS | 派生 | 数字分组 / 小数符号 |
NLS_CALENDAR | GREGORIAN | 日历系统 |
NLS_SORT | 派生 | 二进制 / 语言学排序(影响 ORDER BY) |
NLS_COMP | BINARY | 比较行为(BINARY/LINGUISTIC) |
NLS_LENGTH_SEMANTICS** | BYTE | 字符串长度单位(BYTE / CHAR) |
NLS 三层设置:
- 数据库初始化参数(
SPFILE中):所有会话默认。 - 实例 ALTER SESSION:会话级覆盖。
- 客户端 NLS_LANG 环境变量:客户端转换行为。
-- 实例级修改 NLS
ALTER SYSTEM SET NLS_LANGUAGE = 'SIMPLIFIED CHINESE' SCOPE = SPFILE;
ALTER SYSTEM SET NLS_TERRITORY = 'CHINA' SCOPE = SPFILE;
-- 会话级
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
ALTER SESSION SET NLS_SORT = 'SCHINESE_PINYIN_M'; -- 按拼音排序
常见故障与排查:
| 现象 | 根因 | 解决方案 |
|---|---|---|
| 中文乱码 | 客户端 NLS_LANG 与服务器字符集不一致 | 客户端设置 NLS_LANG=AMERICAN_AMERICA.AL32UTF8 |
ORA-12899: value too large for column | 字符集字节长度不一致(如 ZHS16GBK → AL32UTF8) | 评估字段长度,扩展 VARCHAR2 长度 |
| 中文排序乱序 | NLS_SORT=BINARY 按字符编码排序 | 设置 NLS_SORT=SCHINESE_PINYIN_M |
| expdp 文件无法导入到不同字符集库 | 字符集转换不兼容 | 升级源端字符集至 AL32UTF8,或分阶段迁移 |
15 RAC 集群与 Cache Fusion 机制
答案:
Oracle RAC(Real Application Clusters)是 Oracle 集群数据库方案,多个实例(Instance)同时挂载并打开同一个 Database(共享存储),对外表现为单一逻辑数据库,提供水平扩展与高可用能力。
核心组件:
| 组件 | 职责 |
|---|---|
| Clusterware(集群件) | Oracle Clusterware + 投票盘(Voting Disk) + OCR(Oracle Cluster Registry) |
| 共享存储 | ASM(推荐)/ OCFS2 / NFS / SAN 多节点共享 |
| Cache Fusion | 跨实例 SGA 块传输,GCS(Global Cache Service)协议 |
| GCS / GES | 全局缓存服务 / 全局锁服务(LMSn、LMON、LMD) |
| VIP / SCAN | 虚拟 IP 与 Single Client Access Name,连接层漂移 |
| Service | 应用服务抽象,可绑定到指定实例 + 运行时切换 |
Cache Fusion 工作机制:
sequenceDiagram
participant N1 as Instance-1 (持有块)
participant N2 as Instance-2 (请求块)
participant D as 共享存储
N2->>N1: 请求块(consistent read / current read)
N1->>N2: 通过 LMS 私有网络传送块(Cache-to-Cache)
Note over N2: 块到达后获取对应模式的锁
N1->>D: 块被写脏后写回磁盘
GCS 三种资源模式:
| 模式 | 含义 | 跨实例传输 |
|---|---|---|
| NULL | 节点无此块 | 直接从磁盘读取 |
| Shared (S) | 多实例共享最新读 | 一致性读通过 LMS 复制 |
| Exclusive (X) | 单实例持有可写 | 其他实例请求时由持有者传送 |
GES 锁类型(PCM 锁):
| 模式 | 缩写 | 含义 |
|---|---|---|
| None | N | 无锁 |
| Shared | S | 多节点读共享 |
| Exclusive | X | 单节点排他写 |
RAC 高可用能力:
| 能力 | 实现 |
|---|---|
| Instance Failure Protection | 节点故障后,VIP 漂移、Service 重定位、剩余节点接管连接 |
| Load Balancing | 运行时连接负载均衡(CLB_GOAL_SHORT / LONG) + 节点间 Fanout 负载均衡 |
| Online Maintenance | Patch Set / PSU 可滚动升级(opatch auto / DBMS_ROLLING) |
| Rolling Restart | 实例逐个重启实现节点维护(需 Clusterware + Database 兼容) |
RAC vs Data Guard 对比:
| 维度 | RAC | Data Guard |
|---|---|---|
| 目的 | 水平扩展、高可用 | 灾备、读写分离 |
| 拓扑 | 多实例同库(共享存储) | 主备库(独立存储) |
| 延迟 | 微秒级(Cache Fusion) | 秒级(Redo Apply) |
| 数据保护 | 节点级故障 | 站点级故障 |
| 扩展性 | 增加节点即可扩展 SGA/CPU | 仅可按拓扑扩展 |
| 成本 | 高(共享存储 + 高速互联) | 中(独立存储) |
RAC 调优要点:
- 私有网络(Interconnect):建议 10Gbps+ RDMA(RoCE / iWARP),延迟 < 1ms。
- DRM(Dynamic Resource Management):缓存融合请求路径优化。
- LMS 进程数:
GCS_SERVER_PROCESSES控制,建议 4-8 个(高争用环境增加)。 - 大块大小:减少 LMS 消息数量,建议
DB_BLOCK_SIZE = 16K或32K。 - Service 设计:不同业务(OLTP / Batch / DSS)拆分 Service,绑定到专属实例避免相互干扰。