测试9——为何在数据库在mount阶段可以查询v$datafile_header 视图

大家都知道只有当数据库进入到OPEN状态时,数据文件才被打开,才能读取其中的内容.那在mount状态下,就可以读取v$datafile_header中的信息,为什么呢?

这说明当从nomount状态进入mount状态时,还是扫描了一下数据文件头中的内容的,而且将相应的信息存储到了控制文件中(因为有网友说通过dump control file可以看到http://www.itpub.net/thread-1153987-1-1.html)。

我试着做了一个实验,首先,把所有数据文件全部移走,然后mount数据库:

SQL> startup mount;
ORACLE instance started.


Total System Global Area 1653518336 bytes
Fixed Size    2228904 bytes
Variable Size  956304728 bytes
Database Buffers  687865856 bytes
Redo Buffers    7118848 bytes
Database mounted.
SQL> select checkpoint_change#,checkpoint_time from v$datafile_header;


CHECKPOINT_CHANGE# CHECKPOIN
------------------ ---------
0
0
0
0

发现此时,已经读取不到数据文件头部的checkpoint_change#,checkpoint_time等信息。因为没有数据文件可以供扫描了。

然后我又把数据文件移动回来,再重新mount,就可以看到啦:

SQL> shutdown abort
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.


Total System Global Area 1653518336 bytes
Fixed Size    2228904 bytes
Variable Size  956304728 bytes
Database Buffers  687865856 bytes
Redo Buffers    7118848 bytes
Database mounted.
SQL> select checkpoint_change#,checkpoint_time from v$datafile_header;


CHECKPOINT_CHANGE# CHECKPOIN
------------------ ---------
  1104824 27-OCT-14
  1104824 27-OCT-14
  1104824 27-OCT-14
  1104824 27-OCT-14


顺便总结下,到底什么时候需要进行数据恢复:

在数据库启动的时候,会检查v$database视图,v$datafile视图,v$datafile_header视图 里的checkpoint_change#,当然这三个视图的数值来源是不同的。v$database视图,v$datafile视图 里的scn是来自控制文件的,而v$datafile_header视图 里的scn是来自数据文件头的。

所以当数据库启动的时候,如果发现v$datafile_header的scn小于v$database(或v$datafile)里的值,就需要进行实例或者介质恢复。


以下是改进后的脚本,添加了详细的日志记录功能,并将日志保存到文件中: ```bash #!/bin/bash # 配置日志文件 LOG_FILE="/var/log/rsync_disk_mount_dd_$(date +'%Y%m%d_%H%M%S').log" mkdir -p "$(dirname "$LOG_FILE")" exec > >(tee -a "$LOG_FILE") 2>&1 # 日志函数 log() { local level="$1" local msg="$2" echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $msg" } # 配置参数 USER_NAME="nvidia" USER_IP="10.100.51.114" USER_PASSWD="nvidia" FILE_DIR="/home/udeer/vscode/vscode_projects/hard_disk_flush" FILE_NAME="disk_mount_dd.sh" DISK_MOUNT="/opt/production" DEST_DIR="${DISK_MOUNT}/auto" # 检查源文件是否存在 log "INFO" "Checking if source file exists: ${FILE_DIR}/${FILE_NAME}" if [ ! -f "${FILE_DIR}/${FILE_NAME}" ]; then log "ERROR" "Source file not found: ${FILE_DIR}/${FILE_NAME}" exit 1 fi log "INFO" "Source file found: ${FILE_DIR}/${FILE_NAME}" # 检查目标目录是否存在,不存在则创建 log "INFO" "Checking if destination directory exists: ${DEST_DIR}" sshpass -p "${USER_PASSWD}" ssh "${USER_NAME}@${USER_IP}" "[ -d '${DEST_DIR}' ]" || { log "INFO" "Destination directory does not exist, creating..." sshpass -p "${USER_PASSWD}" ssh "${USER_NAME}@${USER_IP}" "mkdir -p '${DEST_DIR}'" || { log "ERROR" "Failed to create destination directory: ${DEST_DIR}" exit 1 } log "INFO" "Destination directory created successfully: ${DEST_DIR}" } # 执行rsync操作 log "INFO" "Starting rsync operation..." sshpass -p "${USER_PASSWD}" rsync -avzP "${FILE_DIR}/${FILE_NAME}" "${USER_NAME}@${USER_IP}:${DEST_DIR}/" || { log "ERROR" "rsync operation failed" exit 1 } log "INFO" "rsync operation completed successfully" # 验证文件是否传输成功 log "INFO" "Verifying file transfer..." sshpass -p "${USER_PASSWD}" ssh "${USER_NAME}@${USER_IP}" "[ -f '${DEST_DIR}/${FILE_NAME}' ]" || { log "ERROR" "File not found on remote server: ${DEST_DIR}/${FILE_NAME}" exit 1 } log "INFO" "File verified successfully on remote server" # 设置文件权限 log "INFO" "Setting file permissions..." sshpass -p "${USER_PASSWD}" ssh "${USER_NAME}@${USER_IP}" "chmod +x '${DEST_DIR}/${FILE_NAME}'" || { log "WARNING" "Failed to set executable permission on remote file" } log "INFO" "File permissions set successfully" log "INFO" "All operations completed successfully" log "INFO" "Detailed log saved to: $LOG_FILE" ``` ### 改进说明: 1. **日志系统**: - 添加了完整的日志函数,记录时间戳和日志级别 - 所有操作都会记录到日志文件和终端输出 - 日志文件名包含时间戳,避免覆盖 2. **错误处理**: - 每个关键步骤都有错误检查 - 失败时会记录错误并退出 - 使用 `||` 进行条件执行 3. **远程操作验证**: - 检查目标目录是否存在,不存在则创建 - 传输完成后验证文件是否存在 - 设置远程文件的可执行权限 4. **日志文件管理**: - 日志保存在 `/var/log/` 目录下 - 文件名包含时间戳,便于追踪 ### 使用建议: 1. 建议将脚本保存为 `/usr/local/bin/rsync_disk_mount_dd.sh` 2. 添加执行权限:`chmod +x /usr/local/bin/rsync_disk_mount_dd.sh` 3. 可以考虑添加到 cron 定时任务中定期执行 4. 日志文件可以通过 logrotate 进行轮转管理 ### 相关问题: 1. 如何设置 logrotate 来自动清理旧的日志文件? 2. 如何将日志同时发送到 syslog 服务器? 3. 如何添加邮件通知功能,在操作失败时发送警报? 4. 如何优化 rsync 传输速度? 5. 如何验证远程服务器上的文件权限是否正确设置?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值