注册
【与达梦同行】糟糕,我把数据库控制文件删了,肿么办?不用跑路,妙招在此!
技术分享/ 文章详情 /

【与达梦同行】糟糕,我把数据库控制文件删了,肿么办?不用跑路,妙招在此!

Tomliu 2022/12/07 1893 10 1

控制文件误删会带来什么影响?

控制文件,对数据库来说是非常重要的,一旦误删,那对于数据库来说是致命的一个问题。
我们模拟两种场景,来验证当控制文件被误删之后,会发生什么。

数据库服务使用中删除控制文件

首先数据库服务正常运行的,我们此时将数据库实例中的dm.ctl控制文件重命名来模拟误删。

[dmdba@DATABASE DAMENG]$ disql SYSDBA/SYSDBA@127.0.0.1:5236

服务器[127.0.0.1:5236]:处于普通打开状态
登录使用时间 : 2.684(ms)
disql V8
SQL> EXIT
[dmdba@DATABASE DAMENG]$ mv dm.ctl dm.ctl.bak
[dmdba@DATABASE DAMENG]$ disql SYSDBA/SYSDBA@127.0.0.1:5236

服务器[127.0.0.1:5236]:处于普通打开状态
登录使用时间 : 1.132(ms)
disql V8
SQL>

此时可以看到数据库服务运行期间删除控制文件后数据库服务还可以正常登录,那面我们再做几个简单的操作。

SQL> create tablespace CTL_TEST DATAFILE 'CTL_TEST.DBF' SIZE 1024 ;
create tablespace CTL_TEST DATAFILE 'CTL_TEST.DBF' SIZE 1024 ;
[-105]:控制文件错误.
已用时间: 52.865(毫秒). 执行号:0.
SQL> CREATE TABLE AA(A INT);
操作已执行
已用时间: 122.386(毫秒). 执行号:502.
SQL> BACKUP DATABASE FULL;
BACKUP DATABASE FULL;
[-105]:控制文件错误.
已用时间: 00:00:02.101. 执行号:0.
SQL> 

从这三个简单的操作来看,似乎对涉及表空间、数据文件这块调用时都会报错,提示控制文件错误。当然其他的ddl、dml操作大家可以去测,到底哪些可以执行哪些不可用。

误删后重启数据库服务

我们紧接着刚才误删操作,直接重启数据库服务看会如何。

[dmdba@DATABASE DAMENG]$ DmServiceDMSERVER restart
Stopping DmServiceDMSERVER:                                [ OK ]
Starting DmServiceDMSERVER:                                [ FAILED ]
file dm.key not found, use default license!
Read ini error, name:CTL_PATH, value:/soft/dmdbms/data/DAMENG/dm.ctl
dmserver startup failed, code = -803 [Invalid ini config value]
nsvr_ini_file_read failed, [code: -803]
[dmdba@DATABASE DAMENG]$ 

果然,数据库服务压根无法启动,原因还是控制文件误删引发的。

通过这两个实验我们可以证实,控制文件的确是至关重要的一个文件,误删所带来的影响是致命的,具体原因我们看看达梦的控制文件的主要作用就知道了:
控制文件中主要记录的是各个表空间路径及相关参数信息,主要包括:

  1. 数据库名称;
  2. 数据库服务器模式;
  3. OGUID 唯一标识;
  4. 数据库服务器版本;
  5. 数据文件版本;
  6. 数据库的启动次数;
  7. 数据库最近一次启动时间;
  8. 表空间信息,包括表空间名,表空间物理文件路径等,记录了所有数据库中使用的表空间,数组的方式保存起来;
  9. 控制文件校验码,校验码由数据库服务器在每次修改控制文件后计算生成,保证控制文件合法性,防止文件损坏及手工修改。

好,下面我们进入正题,如果误删后该怎么办,如果补救?

控制文件恢复方法

通过备份的控制文件恢复

对于控制文件这块达梦做的还是非常好的,会有自己的一个备份机制在里面,当数据库服务重启、涉及数据文件、表空间新建调整等,都会自动备份控制文件到实例目录的ctl_bak中。这个时候,我们可以根据最近的备份文件,重新拷贝重命名为dm.ctl放到实例路径中重启服务。

[dmdba@DATABASE DAMENG]$ ll ctl_bak/
total 88
dm_20221207223012_107029.ctl
-rw-r--r-- 1 dmdba dinstall 6656 Dec  7 23:18 dm_20221207231859_049461.ctl
-rw-r--r-- 1 dmdba dinstall 7168 Dec  7 23:18 dm_20221207231859_050288.ctl
[dmdba@DATABASE DAMENG]$ cp ctl_bak/dm_20221207231859_050288.ctl ./dm.ctl
[dmdba@DATABASE DAMENG]$ 
[dmdba@DATABASE DAMENG]$ DmServiceDMSERVER start
Starting DmServiceDMSERVER:                                [ OK ]

但需要注意,如果最近的备份到误删期间有新建表空间、删除表空间等操作,此时恢复的控制文件相应部分是需要特殊处理的,具体方法可以参考误删恢复的下一种方法。

重建控制文件恢复

控制文件是dm.ctl的二进制文件,是无法直接查看编辑的,不过达梦提供了相应的工具,可以利用dmctlcvt脚本将该二进制文件转为文本格式,通过对文本格式的修改,然后修改后再用dmctlcvt转为二进制文件。

控制文件转换命令介绍

通过bin文件中的dmctlcvt脚本转换,具体可以hlep查看具体用法。

D:\bigProgram\dmdbms\bin>dmctlcvt.exe help
DMCTLCVT V8

格式: dmctlcvt.exe KEYWORD=value
注意: 控制文件名称必须指定为dm.ctl、dmmpp.ctl、dss.ctl

关键字              说明
--------------------------------------------------------------------------------
TYPE                1 转换控制文件为文本文件(源文件路径中控制文件名称必须是dm.ctl或dmmpp.ctl或dss.ctl)
                    2 转换文本文件为控制文件(目标文件路径中控制文件名称必须是dm.ctl或dmmpp.ctl或dss.ctl)
SRC                 源文件路径
DEST                目标文件路径
DCR_INI             dmdcr.ini文件路径
DFS_INI             dmdfs.ini文件路径
HELP                打印帮助信息

示例:
dmctlcvt.exe TYPE=1 SRC=d:\data\dameng\dm.ctl DEST=d:\data\dameng\dmctl.txt
dmctlcvt.exe TYPE=2 SRC=d:\data\dameng\dmctl.txt DEST=d:\data\dameng\dm.ctl

D:\bigProgram\dmdbms\bin>

了解控制文件的内容

这里我们先来找一个控制文件,将其转换为txt文件后看看控制文件中都有哪些内容,为后面的实操做好准备。
举例一个控制文件的具体内容,也就是初始化实例后默认的一个示例:

##############################################################################
## please do not adjust parameter order, ensure the ctl have no difference ###
##########################################################################


# database name
dbname=DAMENG1
# server mode
svr_mode=0
#OGUID
oguid=0
# db server version
version=117507996
# database version
db_version=458763
# pseg version
pseg_version=458762
#SGUID
sguid=2038481189
#NEXT_TS_ID
next_ts_id=5
#RAC_NODES
rac_nodes=1
#NEXT_HTS_ID
next_htsid=129
#TIME_FLAG
time_flag=170
#MDIR_FLAG
mdir_flag=31
#STARTUP_CNT
startup_cnt=1
#LAST_STARTUP_TIME
last_startup_time=DATETIME '2021-10-12 11:48:35'
#DM7_DCT_VERSION
dm7_dct_version=8
#DM8_DCT_VERSION
dm8_dct_version=24

#===============================================
#===============================================

# table space name
ts_name=SYSTEM
 # table space ID
ts_id=0
# table space status
ts_state=0
# table space cache
ts_cache=
# DSC node number
ts_nth=0
# table space create time
ts_create_time=DATETIME '2021-10-12 11:48:13'
# table space modify time
ts_modify_time=DATETIME '2021-10-12 11:48:13'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0

#-----------------------------------------------

# file path
fil_path=D:\bigProgram\dmdbms\data\DAMENG1\SYSTEM.DBF
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-10-12 11:48:13'
# file modify time
fil_modify_time=DATETIME '2021-10-12 11:48:13'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0


#===============================================

# table space name
ts_name=ROLL
 # table space ID
ts_id=1
# table space status
ts_state=0
# table space cache
ts_cache=
# DSC node number
ts_nth=0
# table space create time
ts_create_time=DATETIME '2021-10-12 11:48:13'
# table space modify time
ts_modify_time=DATETIME '2021-10-12 11:48:13'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0

#-----------------------------------------------

# file path
fil_path=D:\bigProgram\dmdbms\data\DAMENG1\ROLL.DBF
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-10-12 11:48:13'
# file modify time
fil_modify_time=DATETIME '2021-10-12 11:48:13'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0


#===============================================

# table space name
ts_name=RLOG
 # table space ID
ts_id=2
# table space status
ts_state=0
# table space cache
ts_cache=
# DSC node number
ts_nth=0
# table space create time
ts_create_time=DATETIME '2021-10-12 11:48:13'
# table space modify time
ts_modify_time=DATETIME '2021-10-12 11:48:13'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0

#-----------------------------------------------

# file path
fil_path=D:\bigProgram\dmdbms\data\DAMENG1\DAMENG101.log
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-10-12 11:48:13'
# file modify time
fil_modify_time=DATETIME '2021-10-12 11:48:13'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0

# file path
fil_path=D:\bigProgram\dmdbms\data\DAMENG1\DAMENG102.log
# mirror path
mirror_path=
# file id
fil_id=1
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-10-12 11:48:13'
# file modify time
fil_modify_time=DATETIME '2021-10-12 11:48:13'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0


#===============================================

# table space name
ts_name=MAIN
 # table space ID
ts_id=4
# table space status
ts_state=0
# table space cache
ts_cache=
# DSC node number
ts_nth=0
# table space create time
ts_create_time=DATETIME '2021-10-12 11:48:13'
# table space modify time
ts_modify_time=DATETIME '2021-10-12 11:48:13'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0

#-----------------------------------------------

# file path
fil_path=D:\bigProgram\dmdbms\data\DAMENG1\MAIN.DBF
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-10-12 11:48:13'
# file modify time
fil_modify_time=DATETIME '2021-10-12 11:48:13'
					  									
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0


#===============================================
# HUGE table space name
htsname=HMAIN
# HUGE table space id
htsid=128
#HUGE table space share flag
htsflag=0
# HUGE table space copy num
hts_copy_num=0
# HUGE table space region size flag
hts_size_flag=0
# HUGE table space create time
hts_create_time=DATETIME '2021-10-12 11:48:13'
# HUGE table space modify time
hts_modify_time=DATETIME '2021-10-12 11:48:13'
# HUGE table space path
htspath=D:\bigProgram\dmdbms\data\DAMENG1\HMAIN

#===============================================

重建控制文件

这里就具体实操来看看如何重建控制文件,当然一定要对自己的数据库足够熟悉,比如都有哪些表空间、哪些数据文件等等,因为这将影响控制文件恢复的完整度。

重建的整体思路:
假设控制文件彻底损坏,我们可以通过该版本的数据库重建一个新的数据库实例,将该实例中的dm.ctl控制文件通过dmctlcvt脚本转换为txt可编辑文本,然后调整数据库名、表空间位置信息、添加缺失表空间信息等,最后将其转为为dm.ctl控制文件,拷贝到缺失的实例中尝试启动恢复即可。
需要注意,该方式需要对实例中所有的表空间信息有清楚的记录,避免信息添加错误导致实例无法启动。

参考案例:通过初始化的控制文件恢复被误删的控制文件,原来误删控制文件的数据库实例新增了TEST、TEST1、NEW1表空间。以下是对初始化的控制文件转换为txt文本文件,然后操作已有的控制文件相应的写法对一些关键点进行修改,同时增加TEST、TEST1、NEW1表空间、数据文件等信息。
以下示例中涉及修改的地方均做了注释。

##############################################################################
## please do not adjust parameter order, ensure the ctl have no difference ###
##########################################################################

# database name
# //修改为实际数据库实例名
dbname=DAMENG
# server mode
svr_mode=0
#OGUID
oguid=0
# db server version
version=117507996
# database version
db_version=458763
# pseg version
pseg_version=458762
#SGUID
#//唯一id,暂不修改
sguid=2038481189
#NEXT_TS_ID
#//下一个表空间id,根据目前最大id+1设置
next_ts_id=8
#RAC_NODES
rac_nodes=1
#NEXT_HTS_ID
next_htsid=129
#TIME_FLAG
time_flag=170
#MDIR_FLAG
mdir_flag=31
#STARTUP_CNT
#//启动次数,暂不调整
startup_cnt=1
#LAST_STARTUP_TIME
#最后一次启动时间,暂不调整
last_startup_time=DATETIME '2021-10-12 11:48:35'
#DM7_DCT_VERSION
dm7_dct_version=8
#DM8_DCT_VERSION
dm8_dct_version=24

#===============================================
#===============================================

# table space name
ts_name=SYSTEM
 # table space ID
ts_id=0
# table space status
ts_state=0
# table space cache
ts_cache=
# DSC node number
ts_nth=0
# table space create time
#//SYSTEM表空间创建和修改时间,暂不修改
ts_create_time=DATETIME '2021-10-12 11:48:13'
# table space modify time
ts_modify_time=DATETIME '2021-10-12 11:48:13'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0

#-----------------------------------------------

# file path
#//SYSTEM文件路径,及文件创建修改时间,只修改文件路径
fil_path=D:\bigProgram\dmdbms\data\DAMENG\SYSTEM.DBF
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-10-12 11:48:13'
# file modify time
fil_modify_time=DATETIME '2021-10-12 11:48:13'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0


#===============================================

# table space name
ts_name=ROLL
 # table space ID
ts_id=1
# table space status
ts_state=0
# table space cache
ts_cache=
# DSC node number
ts_nth=0
# table space create time
#//ROLL表空间创建和修改时间,暂不修改
ts_create_time=DATETIME '2021-10-12 11:48:13'
# table space modify time
ts_modify_time=DATETIME '2021-10-12 11:48:13'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0

#-----------------------------------------------

# file path
#//ROLL文件路径,及文件创建修改时间,只修改文件路径
fil_path=D:\bigProgram\dmdbms\data\DAMENG\ROLL.DBF
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-10-12 11:48:13'
# file modify time
fil_modify_time=DATETIME '2021-10-12 11:48:13'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0


#===============================================

# table space name
ts_name=RLOG
 # table space ID
ts_id=2
# table space status
ts_state=0
# table space cache
ts_cache=
# DSC node number
ts_nth=0
# table space create time
#//RLOG表空间创建和修改时间,暂不修改
ts_create_time=DATETIME '2021-10-12 11:48:13'
# table space modify time
ts_modify_time=DATETIME '2021-10-12 11:48:13'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0

#-----------------------------------------------

# file path
#//RLOG01文件路径,及文件创建修改时间,只修改文件路径
fil_path=D:\bigProgram\dmdbms\data\DAMENG\DAMENG01.log
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-10-12 11:48:13'
# file modify time
fil_modify_time=DATETIME '2021-10-12 11:48:13'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0

# file path
#//RLOG02文件路径,及文件创建修改时间,只修改文件路径
fil_path=D:\bigProgram\dmdbms\data\DAMENG\DAMENG02.log
# mirror path
mirror_path=
# file id
# 同一个表空间,多个数据文件,fil_id区分。
fil_id=1
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-10-12 11:48:13'
# file modify time
fil_modify_time=DATETIME '2021-10-12 11:48:13'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0


#===============================================

# table space name
ts_name=MAIN
 # table space ID
ts_id=4
# table space status
ts_state=0
# table space cache
ts_cache=
# DSC node number
ts_nth=0
# table space create time
#//MAIN表空间创建和修改时间,暂不修改
ts_create_time=DATETIME '2021-10-12 11:48:13'
# table space modify time
ts_modify_time=DATETIME '2021-10-12 11:48:13'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0

#-----------------------------------------------

# file path
#//MAIN文件路径,及文件创建修改时间,只修改文件路径
fil_path=D:\bigProgram\dmdbms\data\DAMENG\MAIN.DBF
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-10-12 11:48:13'
# file modify time
fil_modify_time=DATETIME '2021-10-12 11:48:13'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0


#===================以下新增TEST表空间信息============================

# table space name
ts_name=TEST
 # table space ID
#//ts_id一定要根据情况修改,按顺序走
ts_id=5
# table space status
ts_state=0
# table space cache
ts_cache=NORMAL
# DSC node number
ts_nth=0
# table space create time
ts_create_time=DATETIME '2021-7-1 10:35:12'
# table space modify time
ts_modify_time=DATETIME '2021-7-1 10:35:12'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0

#-----------------------------------------------

# file path
#//根据实际路径设置文件所在路径,也可趁此移动表空间文件。
fil_path=D:\bigProgram\dmdbms\data\DAMENG\TEST.DBF
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-7-1 10:35:12'
# file modify time
fil_modify_time=DATETIME '2021-7-1 10:35:12'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0


#=====================以下新增TEST1表空间==========================				  

# table space name
ts_name=TEST1
 # table space ID
ts_id=6
# table space status
ts_state=0
# table space cache
ts_cache=NORMAL
# DSC node number
ts_nth=0
# table space create time
ts_create_time=DATETIME '2021-7-27 11:32:51'
# table space modify time
ts_modify_time=DATETIME '2021-7-27 11:32:52'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0

#-----------------------------------------------

# file path
fil_path=D:\bigProgram\dmdbms\data\DAMENG\TEST1.DBF
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-7-27 11:32:52'
# file modify time
fil_modify_time=DATETIME '2021-7-27 11:32:52'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=1024

#================以下新增NEW1表空间===============================

# table space name
ts_name=NEW1
 # table space ID
ts_id=7
# table space status
ts_state=0
# table space cache
ts_cache=NORMAL
# DSC node number
ts_nth=0
# table space create time
ts_create_time=DATETIME '2021-10-12 11:36:48'
# table space modify time
ts_modify_time=DATETIME '2021-10-12 11:36:49'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0

#-----------------------------------------------

# file path
fil_path=D:\bigProgram\dmdbms\data\DAMENG\NEW1.DBF
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2021-10-12 11:36:48'
# file modify time
fil_modify_time=DATETIME '2021-10-12 11:36:48'
# the max size of file
#//可以调整默认扩展尺寸和最大限制
fil_max_size=0
# next size of file
fil_next_size=1024

#===============================================	 											
# HUGE table space name
htsname=HMAIN
# HUGE table space id
htsid=128
#HUGE table space share flag
htsflag=0
# HUGE table space copy num
#//未知,应该要变,暂不修改
hts_copy_num=0
# HUGE table space region size flag
#//未知,应该要变,暂不修改
hts_size_flag=0
# HUGE table space create time
hts_create_time=DATETIME '2021-10-12 11:48:13'
# HUGE table space modify time
hts_modify_time=DATETIME '2021-10-12 11:48:13'
# HUGE table space path
htspath=D:\bigProgram\dmdbms\data\DAMENG\HMAIN
#===============================================

控制文件修改后,重新将txt转为dm.ctl的二进制控制文件,启动服务验证即可。

D:\bigProgram\dmdbms\bin>dmctlcvt.exe type=2 src=D:\bigProgram\dmdbms\data\DAMENG1\dmctl.txt dest=D:\bigProgram\dmdbms\data\DAMENG\dm.ctl
DMCTLCVT V8
convert txt to ctl success!

D:\bigProgram\dmdbms\bin>

简单总结

删库跑路肯定是行不通的,更重要的是找到解决方案顺利解决问题,针对此文做以下总结:
1、控制文件误删的恢复并不说只有这两种方法,比如通过备份集恢复数据库后再获取到控制文件理论也是可行的。所以更多是需要我们自己多实践,多总结,做到有备无患。
2、误删如果出现在生产环境,那说明我们的操作规划、管理制度等方面是存在问题的。所以更应该做好规范管理,避免误删的情况。
3、数据库的备份、冗余机制一定要做好。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服