大家好,这里是 Lucifer三思而后行 ,专注于提升数据库运维效率。
@TOC
前言 作为一名 DBA,应该都玩过 Oracle 数据库,最熟悉的操作应该就是开关库了:
1 2 3 4 5 SQL > startupSQL > shutdown immediate
但是执行这两个命令,数据库到底做了什么?相信很多人都没有研究过,本系列打算详解一下 Oracle 数据库的启动和关闭过程,静心看完,相信一定可以帮助大家更加深入了解 Oracle 数据库。
介绍 Oracle 数据库启动分为三个阶段:
nomount :读取参数文件,启动实例,分配 SGA,启动部分进程。
mount :实例启动后读取控制文件,挂载数据库。
open :读取数据文件和日志文件,启动数据库。
本文先讲数据库的第一个启动阶段:nomount 阶段,我这里演示环境是 11GR2 数据库。
nomount 阶段 nomount 阶段是数据库启动的第一个阶段,需要参数文件,会启动一个实例,在这个过程中会分配内存区域 SGA 以及启动一些后台进程。
参数文件 参数文件分为:
init<SID>.ora
spfile.ora
spfile<SID>.ora
单实例数据库存放在 $ORACLE_HOME/dbs 目录下,启动默认的查找顺序为:spfile<SID>.ora ---> spfile.ora ---> init<SID>.ora。
可以发现当前数据库优先使用的是 spfile<SID>.ora 方式启动:
1 2 3 4 5 6 7 8 9 [oracle@rhel6 :/ home/ oracle]$ cd $ORACLE_HOME/ dbs [oracle@rhel6 :/ u01/ app/ oracle/ product/ 11.2 .0 / db/ dbs]$ ll - rw- rw- rw- r- rw- r- rw- r- rw- r- rw- r- rw- r
验证一下,启动数据库实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 SQL > startup nomountORACLE instance started. Total System Global Area 4275781632 bytes Fixed Size 2260088 bytes Variable Size 2801795976 bytes Database Buffers 1459617792 bytes Redo Buffers 12107776 bytes SQL > select status from v$instance;STATUS STARTED SQL > show parameter spfileNAME TYPE VALUE spfile string / u01/ app/ oracle/ product/ 11.2 .0 / db/ dbs/ spfilelucifer.ora
可以看到默认启动的参数文件是 spfilelucifer.ora,此时查看 alert 日志中参数文件相关的部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 Using parameter settings in server-side spfile /u01/app/oracle/product/11.2.0/db/dbs/spfilelucifer.ora System parameters with non-default values: processes = 2000 resource_limit = TRUE event = "28401 trace name context forever,level 1" event = "10949 trace name context forever,level 1" sga_max_size = 4G streams_pool_size = 1312M resource_manager_plan = "force:" sga_target = 4G _memory_imm_mode_without_autosga= FALSE control_files = "/oradata/lucifer/control01.ctl" control_files = "/u01/app/oracle/fast_recovery_area/lucifer/control02.ctl" control_file_record_keep_time= 31 db_block_size = 8192 compatible = "11.2.0.4.0" log_archive_dest_1 = "location=/oradata/archivelog" log_archive_format = "%t_%s_%r.dbf" _use_adaptive_log_file_sync= "FALSE" db_files = 5000 db_create_file_dest = "/oradata" db_recovery_file_dest = "/u01/app/oracle/fast_recovery_area" db_recovery_file_dest_size= 5532M enable_goldengate_replication= TRUE _datafile_write_errors_crash_instance= FALSE _cleanup_rollback_entries= 2000 undo_tablespace = "UNDOTBS1" _undo_autotune = FALSE undo_retention = 10800 _partition_large_extents = "FALSE" _index_partition_large_extents= "FALSE" sec_case_sensitive_logon = FALSE remote_login_passwordfile= "EXCLUSIVE" db_domain = "" dispatchers = "(PROTOCOL=TCP) (SERVICE=luciferXDB)" session_cached_cursors = 300 parallel_max_servers = 64 _PX_use_large_pool = TRUE audit_file_dest = "/u01/app/oracle/admin/lucifer/adump" audit_trail = "NONE" db_name = "lucifer" open_cursors = 1000 _optimizer_null_aware_antijoin= FALSE _b_tree_bitmap_plans = FALSE _optimizer_extended_cursor_sharing= "NONE" _optimizer_extended_cursor_sharing_rel= "NONE" _optimizer_adaptive_cursor_sharing= FALSE pga_aggregate_target = 1256M deferred_segment_creation= FALSE _optimizer_use_feedback = FALSE enable_ddl_logging = TRUE diagnostic_dest = "/u01/app/oracle"
所以,数据库实例启动的第一步就是找到参数文件,并且读取参数配置。
分配 SGA 通过第一步读取参数文件配置,可以获取到内存相关配置,包括 SGA 相关参数:
1 2 3 sga_max_size = 4G streams_pool_size = 1312M sga_target = 4G
在启动数据库实例过程中会输出以下信息:
1 2 3 4 5 Total System Global Area 4275781632 bytes Fixed Size 2260088 bytes Variable Size 2801795976 bytes Database Buffers 1459617792 bytes Redo Buffers 12107776 bytes
以上这些提示信息分别是什么意思呢?大家如果知道 SGA 有哪些组件,应该一下就能明白:
参考 11GR2 官方文档 Database Concepts:Memory Architecture
下面就详解一下启动数据库实例时输出的每一行的意思:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 Total System Global Area 4275781632 bytes SQL > select sum (value ) from v$sga;SUM (VALUE )4275781632 SQL > select sum (bytes) from v$sgastat;SUM (BYTES)4275780728 SQL > select sum (value ) from v$sga;SUM (VALUE )5318374384 SQL > select sum (bytes) from v$sgastat;SUM (BYTES)5318374384 Fixed Size 2260088 bytes SQL > select * from v$sgainfo where name = 'Fixed SGA Size' ; NAME BYTES RESIZEABL Fixed SGA Size 2260088 No Variable Size 2801795976 bytes SQL > select * from v$sgainfo where name in ('Shared Pool Size' ,'Java Pool Size' ,'Large Pool Size' ,'Streams Pool Size' ); NAME BYTES RESIZEABL Shared Pool Size 587202560 Yes Large Pool Size 805306368 YesJava Pool Size 33554432 Yes Streams Pool Size 1375731712 Yes SQL > select sum (bytes) from v$sgainfo where name in ('Shared Pool Size' ,'Java Pool Size' ,'Large Pool Size' ,'Streams Pool Size' ); SUM (BYTES)2801795072 Database Buffers 1459617792 bytes SQL > select * from v$sgainfo where name = 'Buffer Cache Size' ;NAME BYTES RESIZEABL Buffer Cache Size 1459617792 Yes Redo Buffers 12107776 bytes SQL > select * from v$sgainfo where name = 'Redo Buffers' ; NAME BYTES RESIZEABL Redo Buffers 12107776 No
以上 SGA 组件内存分配的相关信息可以从 v$sgainfo 中查看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 SQL > select * from v$sgainfo;NAME BYTES RESIZEABL Fixed SGA Size 2260088 No Redo Buffers 12107776 No Buffer Cache Size 1459617792 Yes Shared Pool Size 587202560 Yes Large Pool Size 805306368 YesJava Pool Size 33554432 Yes Streams Pool Size 1375731712 Yes Shared IO Pool Size 0 Yes Granule Size 16777216 No Maximum SGA Size 4275781632 No Startup overhead in Shared Pool 498329672 No Free SGA Memory Available 0
这部分内容无法从 alert 日志中获取相关信息,所以直接打印在 sqlplus 启动过程中,也可以通过 show sga 查看:
1 2 3 4 5 6 7 SQL > show sgaTotal System Global Area 4275781632 bytes Fixed Size 2260088 bytes Variable Size 2801795976 bytes Database Buffers 1459617792 bytes Redo Buffers 12107776 bytes
上面是将数据库层面的 SGA 内存分配,其实在操作系统层面也可以看出个大概:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [oracle@rhel6:/home/oracle]$ ipcs -a ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 0 root 644 80 2 0x00000000 32769 root 644 16384 2 0x00000000 65538 root 644 280 2 [oracle@rhel6:/home/oracle]$ ipcs -m ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 0 root 644 80 2 0x00000000 32769 root 644 16384 2 0x00000000 65538 root 644 280 2 0x00000000 917507 oracle 640 33554432 17 0x00000000 950276 oracle 640 4261412864 17 0x467a6680 983045 oracle 640 2097152 17
注意:上面的输出中,关于共享内存段的列的意思如下:
key:共享内存段的键值,用于标识。 shmid:共享内存段的ID。 owner:共享内存段的所有者。 perms:共享内存段的权限,通常以4位八进制数表示。 bytes:共享内存段的大小,单位是字节。 nattch:当前附加到这个共享内存段的进程数。 status:共享内存段的状态,可能包含额外的信息或为空。
综上发现,数据库实例启动的第二步是分配 SGA 组件内存。
启动进程 查看进程启动情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 SQL > ! env | grep ORACLE_SIDORACLE_SID= lucifer SQL > ! ps - ef| grep - v grep| grep luciferSQL > ! ps - ef| grep - v grep| grep luciferoracle 57755 1 0 16 :56 ? 00 :00 :00 ora_pmon_lucifer oracle 57757 1 0 16 :56 ? 00 :00 :00 ora_psp0_lucifer oracle 57759 1 2 16 :57 ? 00 :00 :40 ora_vktm_lucifer oracle 57763 1 0 16 :57 ? 00 :00 :00 ora_gen0_lucifer oracle 57765 1 0 16 :57 ? 00 :00 :00 ora_diag_lucifer oracle 57767 1 0 16 :57 ? 00 :00 :00 ora_dbrm_lucifer oracle 57769 1 0 16 :57 ? 00 :00 :06 ora_dia0_lucifer oracle 57771 1 0 16 :57 ? 00 :00 :00 ora_mman_lucifer oracle 57773 1 0 16 :57 ? 00 :00 :00 ora_dbw0_lucifer oracle 57775 1 0 16 :57 ? 00 :00 :00 ora_lgwr_lucifer oracle 57777 1 0 16 :57 ? 00 :00 :00 ora_ckpt_lucifer oracle 57779 1 0 16 :57 ? 00 :00 :00 ora_smon_lucifer oracle 57781 1 0 16 :57 ? 00 :00 :00 ora_reco_lucifer oracle 57783 1 0 16 :57 ? 00 :00 :00 ora_mmon_lucifer oracle 57785 1 0 16 :57 ? 00 :00 :03 ora_mmnl_lucifer oracle 57787 1 0 16 :57 ? 00 :00 :00 ora_d000_lucifer oracle 57789 1 0 16 :57 ? 00 :00 :00 ora_s000_lucifer oracle 61552 61551 0 17 :29 ? 00 :00 :00 oraclelucifer (DESCRIPTION= (LOCAL = YES)(ADDRESS= (PROTOCOL= beq))) SQL > ! ps - ef| grep - v grep| grep ora_| wc - l17
可以看到当 Oracle 启动到 nomount 状态后,有以下后台进程被启动:
pmon (Process Monitor):监视其他后台进程,并在服务器或调度程序进程异常终止时执行进程恢复。
psp0 (Process Spawner Process):初始实例启动后生成 Oracle 后台进程。
vktm (Virtual Keeper of Time Process):提供一个秒级更新的数据库时钟,减少数据库和操作系统的交互。
gen0 (General Task Execution Process):为数据库提供了一个执行通用任务的进程,进程的主要目标是分担进程中某些可能造成阻塞的处理过程,并将他们放在后台完成。
diag (Diagnostic Capture Process):数据库诊断进程,负责维护管理各种用于诊断的转储文件,并执行 oradebug 命令。
dbrm (Database Resource Manager Process):数据库资源管理进程,负责设置资源计划和其他的资源管理的工作。
dia0 (Diagnostic Process):数据库诊断进程,负责检测 Oracle 数据库中的挂起(hang)和死锁的处理。
mman (Memory Manager Process):实现共享内存自动管理。
dbw0 (Database Writer Process):数据库写入程序,主要职责是将数据块写入磁盘,还负责处理检查点、文件打开同步以及块写入记录的日志记录。
lgwr (Log Writer Process):日志写入程序,将重做日志条目按顺序写入重做日志文件。
ckpt (Checkpoint Process):在检查点处发出 DBWn 信号并更新数据库的所有数据文件和控制文件以指示最近的检查点。
smon (System Monitor Process):执行关键任务(如实例恢复和死事务恢复)以及维护任务(如临时空间回收、数据字典清理和撤消表空间管理)。
reco (Recoverer Process):解决由于分布式数据库中的网络或系统故障而挂起的分布式事务。
mmon (Manageability Monitor Process):MMON 执行许多与可管理性相关的任务,包括获取自动工作负载存储库快照和执行自动数据库诊断监视器分析。
mmnl (Manageability Monitor Lite Process):是 AWR 新增的进程,主要作用是将 AWR 数据从内存中刷新到表中。
d000 (Dispatcher Process):允许用户进程共享有限的服务器进程(SERVER PROCESS)。
s000 (Shared Server Process):负责与用户进程通信,并与 Oracle 交互,以代表相关的用户进程执行任务。
注意:以上后台进程具体可参考官方文档:Background Processes
查看数据库 alert 日志中与进程启动相关的信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 Mon Aug 26 16:56:59 2024 PMON started with pid=2, OS id =57755 Mon Aug 26 16:56:59 2024 PSP0 started with pid=3, OS id =57757 Mon Aug 26 16:57:00 2024 VKTM started with pid=4, OS id =57759 at elevated priority VKTM running at (1)millisec precision with DBRM quantum (100)ms Mon Aug 26 16:57:00 2024 GEN0 started with pid=5, OS id =57763 Mon Aug 26 16:57:00 2024 DIAG started with pid=6, OS id =57765 Mon Aug 26 16:57:00 2024 DBRM started with pid=7, OS id =57767 Mon Aug 26 16:57:00 2024 DIA0 started with pid=8, OS id =57769 Mon Aug 26 16:57:00 2024 MMAN started with pid=9, OS id =57771 Mon Aug 26 16:57:00 2024 DBW0 started with pid=10, OS id =57773 Mon Aug 26 16:57:00 2024 LGWR started with pid=11, OS id =57775 Mon Aug 26 16:57:00 2024 CKPT started with pid=12, OS id =57777 Mon Aug 26 16:57:00 2024 SMON started with pid=13, OS id =57779 Mon Aug 26 16:57:00 2024 RECO started with pid=14, OS id =57781 Mon Aug 26 16:57:00 2024 MMON started with pid=15, OS id =57783 Mon Aug 26 16:57:00 2024 MMNL started with pid=16, OS id =57785
可以发现,数据库实例启动的第三步是启动进程。
总结 综上所述,可以总结出 nomount 阶段的启动过程大致如下:
查找参数文件,搜索顺序为:spfile<SID>.ora ---> spfile.ora ---> init<SID>.ora
读取参数文件,并启动数据库实例
分配 SGA 内存段
启动后台进程和前台进程
在这个阶段,不涉及控制文件以及数据文件,只需要参数文件即可,通常用于数据库创建、控制文件重建、特定的备份恢复等。
往期精彩文章推荐
Oracle RAC 修改系统时区避坑指南(深挖篇) Ubuntu 22.04 一键安装 Oracle 11G RAC 使用 dbops 快速部署 MySQL 数据库 Oracle RAC 启动顺序,你真的了解吗? 达梦数据库一键安装脚本(免费) 一篇文章让你彻底掌握 Python 🔥一篇文章让你彻底掌握 Python 一篇文章让你彻底掌握 Shell 🔥Oracle 监控 EMCC 13.5 安装部署超详细教程 🔥Oracle 一键巡检自动生成 Word 报告 🔥Oracle一键安装脚本的 21 个疑问与解答 🔥Oracle一键巡检脚本的 21 个疑问与解答 🔥全网首发:Oracle 23ai 一键安装脚本 🔥Oracle 19C 最新 RU 补丁 19.24 ,一键安装! 🔥Oracle Linux 6 一键安装 Oracle 11GR2 RAC Oracle Linux 7.9 一键安装 Oracle 19C Oracle Linux 8.9 一键安装 Oracle 19C RAC Oracle Linux 9.4(aarch64) 一键安装 Oracle 19C 🔥openEuler 20.03 LTS SP4 一键安装 Oracle 19C 🔥openEuler 22.03 LTS SP4 一键安装 Oracle 19C RAC RHEL 7.9 一键安装 Oracle 19C 19.23 RAC Redhat 8.4 一键安装 Oracle 11GR2 RedHat 9.4(aarch64) 一键安装 Oracle 19C 龙蜥 Anolis 7.9 一键安装 Oracle 19C 19.23 龙蜥 Anolis OS 8.8 一键安装 Oracle 19C SUSE 15 SP5 一键安装 Oracle 19C 统信 UOS V20 1070(a) 一键安装 Oracle 11GR2 Ubuntu 22.04 一键安装 Oracle 19C Ubuntu 14.04 一键安装 Oracle 19C 银河麒麟 Kylin V10 SP3 一键安装 Oracle 19C 🔥银河麒麟 Kylin V10 SP3 一键安装 Oracle 11GR2 RAC Oracle DataGuard GAP 修复手册 🔥优化 Oracle:最佳实践与开发规范 DBA 必备:Linux 软件源配置全攻略 🔥Linux 一键配置时钟同步全攻略 🔥Starwind 配置 ISCSI 共享存储 SUSE 15 SP3 安装 Oracle 19C RAC 数据库 达梦 8 数据库安装手册 🔥Oracle 12CR2 RAC 安装避坑宝典 Linux7 安装 Oracle 19C RAC 详细图文教程 🔥Oracle ADG 搭建 RAC to Single 详细教程 Oracle DataGuard GAP 修复手册 🔥Oracle 分区表之在线重定义 AutoUpgrade 快速升级 Oracle 数据库 Oracle 数据库巡检命令手册 🔥Oracle 数据坏块的 N 种修复方式 🔥数据库 SQL 开发入门教程 超全 Linux 基础命令总结 🔥VMware 虚拟机安装 Linux 系统 Linux 安装 MySQL 详细教程 教你玩转 SQLPLUS,工作效率提升 200%
感谢您的阅读,这里是 Lucifer三思而后行 ,欢迎 点赞+关注 ,我会持续分享数据库知识、运维技巧。