架构说明:
Oracle 主备架构,两个数据库实例,一套数据库文件,不是RAC,也不是DG,数据库文件存放在NFS存储上,通过第三方软件进行故障检测和切换的。
通常情况下只有1个节点挂载NFS存储,open数据库,另一个数据库节点不挂载NFS存储。
数据库切换时,需要停库,将NFS挂载到另一个数据库节点上,然后启库。
疑问:
如果在数据库节点1 open数据库的情况下,节点2挂载NFS存储后,能否可以打开数据库?
1.节点2能否打开数据库,能打开到哪一阶段,nomount?mount?open?
2.节点2如果不能打开数据库,会报什么错误?
3.节点2尝试打开数据库,会对节点1数据库有影响吗?
环境说明:
NFS服务器:
IP 192.168.31.58
用于存放Oracle数据库文件。
数据库服务器1:
Oracle 11.2.0.4.0 单机
IP 192.168.31.100
数据库服务器2:
Oracle 11.2.0.4.0 单机
IP 192.168.31.100
测试过程:
1.NFS服务器上,启动nfs服务
NFS 192.168.31.58
[root@mysql02 oradata]# cat /etc/exports ###/oradata 192.168.8.41(rw,insecure) /oradata *(rw,insecure)
[root@mysql02 oradata]# systemctl status nfs-server.service
2.节点1挂载NFS存储,并启动数据库
192.168.31.100
[root@cjcos02 /]# mount -t nfs -o rw,bg,hard,nointr,nolock,rsize=65536,wsize=65536,tcp,vers=3,timeo=600 192.168.31.58:/oradata /oradata [root@cjcos02 /]# df -h /oradata Filesystem Size Used Avail Use% Mounted on 192.168.31.58:/oradata 47G 33G 15G 70% /oradata
[root@cjcos02 /]# showmount -e 192.168.31.58 Export list for 192.168.31.58: /oradata *
[oracle@cjcos02 ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Sat Oct 15 10:08:39 2022 Copyright (c) 1982, 2013, Oracle. All rights reserved. Connected to an idle instance. SQL> startup ORACLE instance started. Total System Global Area 1152450560 bytes Fixed Size 2252584 bytes Variable Size 738197720 bytes Database Buffers 402653184 bytes Redo Buffers 9347072 bytes Database mounted. Database opened.
3.节点2挂载NFS存储,尝试启动存储,并启动数据库
[root@mysql01 ~]# ls /oradata/ [root@mysql01 ~]# mount -t nfs -o rw,bg,hard,nointr,nolock,rsize=65536,wsize=65536,tcp,vers=3,timeo=600 192.168.31.58:/oradata /oradata [root@mysql01 ~]# ls /oradata/ cjc cjc.tar.gz initcjc.ora spfilecjc.ora
节点2启动数据库
[oracle@mysql01 ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Sat Oct 15 10:28:52 2022 Copyright (c) 1982, 2013, Oracle. All rights reserved. Connected to an idle instance.
可以nomount
SQL> startup nomount ORACLE instance started. Total System Global Area 1152450560 bytes Fixed Size 2252584 bytes Variable Size 738197720 bytes Database Buffers 402653184 bytes Redo Buffers 9347072 bytes
不能mount,更不能open
SQL> alter database mount; alter database mount * ERROR at line 1: ORA-00600: internal error code, arguments: [kccsbck_first], [1], [3760275324], [], [], [], [], [], [], [], [], []
SQL> select status from v$instance; STATUS ------------------------------------ STARTED
查看告警日志
报错:ORA-00600: internal error code, arguments: [kccsbck_first], [1], [3760275324]
具体日志如下:
Sat Oct 15 10:29:33 2022 alter database mount Errors in file /oracle/app/oracle/diag/rdbms/cjc/cjc/trace/cjc_ora_3698.trc (incident=2553): ORA-00600: internal error code, arguments: [kccsbck_first], [1], [3760275324], [], [], [], [], [], [], [], [], [] Incident details in: /oracle/app/oracle/diag/rdbms/cjc/cjc/incident/incdir_2553/cjc_ora_3698_i2553.trc Sat Oct 15 10:29:44 2022 Dumping diagnostic data in directory=[cdmp_20221015102944], requested by (instance=1, osid=3698), summary=[incident=2553]. Sat Oct 15 10:29:45 2022 Use ADRCI or Support Workbench to package the incident. See Note 411.1 at My Oracle Support for error and packaging details. ORA-600 signalled during: alter database mount... Sat Oct 15 10:30:09 2022 Sweep [inc][2553]: completed Sweep [inc2][2553]: completed
查看600错误说明
ORA-600 [kccsbck_first] (Doc ID 139013.1)
两个实例不能同时挂载一套数据库(非RAC、OPS架构),也不会出现数据损坏。
详细信息如下:
DESCRIPTION: We receive this error because we are attempting to be the first thread/instance to mount the database and cannot because it appears that at least one other thread has mounted the database already. We therefore abort the mount attempt and log this error. ARGUMENTS: Arg [a] thread number which has database mounted Arg [b] mount id of the thread FUNCTIONALITY: CONTROL FILE COMPONENT IMPACT: PROCESS FAILURE GENERALLY NON CORRUPTIVE - No underlying data corruption. Although see Alert in Note:137322.1 for Tru64
最后看下最开始的疑问:
如果在数据库节点1 open数据库的情况下,节点2也挂载NFS存储,能否可以打开数据库?
1.节点2能否打开数据库,能打开到哪一阶段,nomount?mount?open?
不能打开数据库,只能到nomount阶段。
2.节点2如果不能打开数据库,会报什么错误?
ORA-00600: internal error code, arguments: [kccsbck_first], [1], [3760275324]
3.节点2尝试打开数据库,会对节点1数据库有影响吗?
无影响。
在复习下Oracle数据库启动过程:
https://docs.oracle.com/en/database/oracle/oracle-database/21/cncpt/oracle-database-instance.html#GUID-189ADDB5-1E71-4924-8371-F5B2EFB5B304
如何启动实例
在执行startup nomount时:
1.读取参数文件以确定初始化参数的值;
2.根据初始化参数设置分配SGA;
3.启动Oracle后台进程;
4.打开警报日志和跟踪文件,并以有效的参数语法将所有显式参数设置写入警报日志。
在这个阶段,没有数据库与实例关联。
需要NOMOUNT状态的场景包括数据库创建以及某些备份和恢复操作。
How an Instance Is Started
When Oracle Database starts an instance, it proceeds through stages.
The stages are as follows:
Searches for a server parameter file in a platform-specific default location and, if not found, for a text initialization parameter file (specifying STARTUP with the SPFILE or PFILE parameters overrides the default behavior)
Reads the parameter file to determine the values of initialization parameters
Allocates the SGA based on the initialization parameter settings
Starts the Oracle background processes
Opens the alert log and trace files and writes all explicit parameter settings to the alert log in valid parameter syntax
At this stage, no database is associated with the instance. Scenarios that require a NOMOUNT state include database creation and certain backup and recovery operations.
如何装载数据库
实例装载数据库以将数据库与此实例关联。
1.要装载数据库,实例将获取control_files初始化参数中指定的数据库控制文件的名称,并打开这些文件。
2.Oracle数据库读取控制文件,以查找打开数据库时将尝试访问的数据文件和联机重做日志文件的名称。
3.在装入的数据库中,数据库是关闭的,只有数据库管理员才能访问。管理员可以在完成特定维护操作时关闭数据库。但是,数据库不可用于正常操作。
如果Oracle数据库允许多个实例并发装载同一数据库,那么CLUSTER_DATABASE初始化参数设置可以使数据库对多个实例可用。数据库行为取决于设置:
(1)如果装载数据库的第一个实例的CLUSTER_DATABASE为false(默认值),则只有此实例才能装载数据库。
(2)如果第一个实例的CLUSTER_DATABASE为true,则其他实例可以装载数据库,前提是其CLUSTER_DATABACE参数设置设置为true。可以装载数据库的实例数受创建数据库时指定的预定最大值的限制。
How a Database Is Mounted
The instance mounts a database to associate the database with this instance.
To mount the database, the instance obtains the names of the database control files specified in the CONTROL_FILES initialization parameter and opens the files. Oracle Database reads the control files to find the names of the data files and the online redo log files that it will attempt to access when opening the database.
In a mounted database, the database is closed and accessible only to database administrators. Administrators can keep the database closed while completing specific maintenance operations. However, the database is not available for normal operations.
If Oracle Database allows multiple instances to mount the same database concurrently, then the CLUSTER_DATABASE initialization parameter setting can make the database available to multiple instances. Database behavior depends on the setting:
If CLUSTER_DATABASE is false (default) for the first instance that mounts a database, then only this instance can mount the database.
If CLUSTER_DATABASE is true for the first instance, then other instances can mount the database if their CLUSTER_DATABASE parameter settings are set to true. The number of instances that can mount the database is subject to a predetermined maximum specified when creating the database.
如何打开数据库
打开装载的数据库可用于正常的数据库操作。
任何有效用户都可以连接到打开的数据库并访问其信息。通常,数据库管理员会打开数据库以供一般使用。
打开数据库时,Oracle数据库将执行以下操作:
1.在非撤消表空间的表空间中打开联机数据文件
2.如果数据库先前关闭时表空间处于脱机状态,则当数据库重新打开时,表空间及其相应的数据文件将处于脱机状态。
3.获取撤消表空间
如果存在多个撤消表空间,则undo_TABLESPACE初始化参数指定要使用的撤消表空间。如果未设置此参数,则选择第一个可用的撤消表空间。
4.打开联机重做日志文件
How a Database Is Opened
Opening a mounted database makes it available for normal database operation.
Any valid user can connect to an open database and access its information. Usually, a database administrator opens the database to make it available for general use.
When you open the database, Oracle Database performs the following actions:
Opens the online data files in tablespaces other than undo tablespaces
If a tablespace was offline when the database was previously shut down, then the tablespace and its corresponding data files will be offline when the database reopens.
Acquires an undo tablespace
If multiple undo tablespaces exists, then the UNDO_TABLESPACE initialization parameter designates the undo tablespace to use. If this parameter is not set, then the first available undo tablespace is chosen.
Opens the online redo log files
只读模式
默认情况下,数据库以读/写模式打开。在此模式下,用户可以更改数据,在联机重做日志中生成重做。
或者,您可以以只读模式打开,以防止用户事务修改数据。
注意:默认情况下,物理备用数据库以只读模式打开。
只读模式将数据库访问限制为只读事务,而只读事务不能写入数据文件或联机重做日志文件。
但是,数据库可以执行恢复或更改数据库状态的操作,而无需生成重做。例如,在只读模式下:
1.数据文件可以脱机和联机。但是,不能使永久表空间脱机。
2.脱机数据文件和表空间可以恢复。
3.控制文件可用于更新数据库状态。
4.使用CREATE Temporary TABLESPACE语句创建的临时表空间是读/写的。
5.可以继续写入操作系统审核跟踪、跟踪文件和警报日志。
Read-Only Mode
By default, the database opens in read/write mode. In this mode, users can make changes to the data, generating redo in the online redo log. Alternatively, you can open in read-only mode to prevent data modification by user transactions.
Note:By default, a physical standby database opens in read-only mode.
Read-only mode restricts database access to read-only transactions, which cannot write to data files or to online redo log files. However, the database can perform recovery or operations that change the database state without generating redo. For example, in read-only mode:
Data files can be taken offline and online. However, you cannot take permanent tablespaces offline.
Offline data files and tablespaces can be recovered.
The control file remains available for updates about the state of the database.
Temporary tablespaces created with the CREATE TEMPORARY TABLESPACE statement are read/write.
Writes to operating system audit trails, trace files, and alert logs can continue.
数据库文件检查
如果实例尝试打开数据库时,任何数据文件或重做日志文件都不存在,或者文件存在但一致性测试失败,则数据库返回错误。可能需要介质恢复。
Database File Checks
If any of the data files or redo log files are not present when the instance attempts to open the database, or if the files are present but fail consistency tests, then the database returns an error. Media recovery may be required.
Open阶段的一致性校验
在数据库Open的过程中,Oracle将会读取数据文件头块和控制文件信息,将两者进行对比,如果满足校验,则可以正常打开数据库;
如果存在异常,则可能抛出相应异常信息,要求用户介入处理。
Oracle在Open阶段将要进行很多校验检查,其中主要的校验包括以下两项:
1.第一次检查数据文件头中的检查点计数(Checkpoint cnt)是否和控制文件中的检查点计数(Checkpoint cnt)一致。
此步骤检查用以确认数据文件是来自同一版本,而不是从备份中恢复而来(因为Checkpoint Cnt不会被冻结,会一直被修改)。
如果检查点计数检查通过,则数据库进行第二次检查。
查询语句如下:
(1)系统检查点SCN、SYSTEM CHECKPOINT SCN
存在控制文件,在系统执行checkpoint后,Oracle会更新当前控制文件中的SYSTEM CHECKPOINT SCN。
该SCAN是全局范围的,当发生文件级别的SCN时,例如表空间改成只读状态,则不会更新此SCN。
SELECT CHECKPOINT_CHANGE# FROM V$DATABASE;
(2)文件检查点SCN、Datafile Checkpoint SCN
存在控制文件,表示该数据文件最近一次执行检查点操作时的SCAN,例如表空间改为只读、BEGIN BACKUP或将某个数据文件设置为OFFLINE等。
SELECT FILE#,CHECKPOINT_CHANGE#,TO_CHAR(CHECKPOINT_TIME,'YYYY-MM-DD HH24:MI:SS') CPTIME FROM V$DATAFILE;
(3)开始SCN、数据文件头SCN、START SCN
存在于各个数据文件头文件
SELECT FILE#,CHECKPOINT_CHANGE# FROM V$DATAFILE_HEADER;
即,检查记录在控制文件中V$DATAFILE表CHECKPOINT_CHANGE#值和记录在数据文件头中V$DATAFILE_HEADER表的CHECKPOINT_CHANGE#是否相同,不相同需要进行介质恢复。
2.第二次检查数据文件头的开始SCN和控制文件中记录的该文件的结束SCN是否一致,如果控制文件中记录的结束SCN等于数据文件头的开始SCN,则不需要对那个文件进行恢复。
如果此前数据库异常崩溃,则结束SCN会保持在最大值(无穷大),数据库必须执行实例恢复以确保一致性。
对每个数据文件都完成检查后,打开数据库,锁定数据文件,同时将每个数据文件的结束SCN设置为无穷大(稍后将详细解释这个过程)。
查询语句如下:
(4)结束SCN(START SCN,END SCN)
存储在控制文件,主要用来检查数据库启动过程中是否需要实例恢复。
当End SCN不等于START SCN,数据库需要实例恢复。
SELECT FILE#,LAST_CHANGE# FROM V$DATAFILE;
即,检查记录在数据文件头中V$DATAFILE_HEADER表的CHECKPOINT_CHANGE#值和记录在控制文件中V$DATAFILE表LAST_CHANGE#是否一致,不相同需要进行实例恢复。
测试数据文件offline。
SQL> select tablespace_name,file_id from dba_data_files order by 2; TABLESPACE_NAME FILE_ID ------------------------------ ---------- SYSTEM1 SYSAUX2 UNDOTBS13 USERS4 CJCTBS5 CHENTBS 6 6 rows selected.
执行offline
SQL> alter database datafile 5 offline;
手动生成检查点
SQL> alter system checkpoint;
系统检查点SCN、SYSTEM CHECKPOINT SCN
SQL> SELECT CHECKPOINT_CHANGE# FROM V$DATABASE; CHECKPOINT_CHANGE# ------------------ 1056968
文件检查点SCN、Datafile Checkpoint SCN
可以看到FILE# 5的SCN不在更新。
SQL> SELECT FILE#,CHECKPOINT_CHANGE#,TO_CHAR(CHECKPOINT_TIME,'YYYY-MM-DD HH24:MI:SS') CPTIME FROM V$DATAFILE; FILE# CHECKPOINT_CHANGE# CPTIME ---------- ------------------ ------------------- 1 1056968 2022-10-15 14:03:51 2 1056968 2022-10-15 14:03:51 3 1056968 2022-10-15 14:03:51 4 1056968 2022-10-15 14:03:51 5 1056438 2022-10-15 13:58:08 6 1056968 2022-10-15 14:03:51 6 rows selected.
开始SCN、数据文件头SCN、START SCN
OFFLINE文件头的SCN不在更新
SQL> SELECT FILE#,CHECKPOINT_CHANGE# FROM V$DATAFILE_HEADER; FILE# CHECKPOINT_CHANGE# ---------- ------------------ 1 1056968 2 1056968 3 1056968 4 1056968 5 1056438 6 1056968 6 rows selected.
结束SCN(START SCN,END SCN)
SQL> SELECT FILE#,LAST_CHANGE# FROM V$DATAFILE; FILE# LAST_CHANGE# ---------- ------------ 1 2 3 4 51056893 6 6 rows selected.