数据库管理189期 2024-05-13
数据库管理-第189期 在19c上truncate了表咋办(20240513)
作者:胖头鱼的鱼缸(尹海文)
Oracle ACE Associate: Database(Oracle与MySQL)
PostgreSQL ACE Partner
10年数据库行业经验,现主要从事数据库服务工作
拥有OCM 11g/12c/19c、MySQL 8.0 OCP、Exadata、CDP等认证
墨天轮MVP、认证技术专家、年度墨力之星,ITPUB认证专家、专家百人团成员,OCM讲师,PolarDB开源社区技术顾问,OceanBase观察团成员
圈内拥有“总监”、“保安”、“国产数据库最大敌人”等称号,非著名社恐(社交恐怖分子)
公众号:胖头鱼的鱼缸;CSDN:胖头鱼的鱼缸(尹海文);墨天轮:胖头鱼的鱼缸;ITPUB:yhw1809。
除授权转载并标明出处外,均为“非法”抄袭
昨天晚上,接某业务维护人员电话,他们误删了两张表数据,我问是delete还是truncate的,然后来了一句:truncate,好吧,完犊子了,不能用undo来尝试恢复数据了(其实有也不一定能用undo这两张表,都不是很小)。
在第四十二期(仅在CSDN上有)讲过一个19c的表级别数据恢复,在有全量备份+增量/归档备份+归档日志(也许+在线日志)的情况下是可以不通过异机+全量/部分的时间点恢复来将表恢复出来。由于我这边确实没有更多的地方有资源了,只能在一体机上加上NBU的备份进行恢复。虽然还没操作完,但下面是踩坑实录。
1 基本语句
RMAN> recover table username.table_name of pluggable database pdb_name until time "to_date('2024-05-12 20:35:00','yyyy-mm-dd hh24:mi:ss')" auxiliary destination '/path/to/temp/recover_files' datapump destination '/path/to/dumpfile' dump file 'table_name.dmp' notableimport;
复制
这条命令可以把指定表在指定时间点的数据以expdp数据泵的方式导出到指定的位置,生成对应文件名的dmp文件。
2 RMAN-04014/ORA-27106
这里两个报错是连在一起的:
RMAN-04014: startup failed: ORA-27106: system pages not available to allocate memory
复制
首先我们需要了解一下通过RMAN的表级别恢复到底做了些啥,为了恢复数据,RMAN会启动一个辅助实例
initialization parameters used for automatic instance: db_name=DBAAS db_unique_name=wsEz_pitr_pdb_name_DBAAS compatible=19.0.0 db_block_size=8192 db_files=20480 diagnostic_dest=/u01/app/oracle _pdb_name_case_sensitive=false _system_trig_enabled=FALSE sga_target=368428M processes=200 db_create_file_dest=/path/to/temp/recover_files log_archive_dest_1='location=/path/to/dumpfile' enable_pluggable_database=true _clone_one_pdb_recovery=true max_string_size=EXTENDED
复制
这里我们会发现这个辅助实例的sga_target使用的是原本数据库配置的大小,即360G,而数据库服务器只有512G内存,这种情况下当然是无法正常启动辅助实例的,因此我们需要手工创建一个参数文件:
vim /path/to/temp/recover_files/initaux.ora
db_name=DBAAS
db_unique_name=wsEz_pitr_pdb_name_DBAAS
compatible=19.0.0
db_block_size=8192
db_files=20480
diagnostic_dest=/u01/app/oracle
_pdb_name_case_sensitive=false
_system_trig_enabled=FALSE
sga_target=4500M
processes=200
db_create_file_dest=/path/to/temp/recover_files
log_archive_dest_1='location=/path/to/dumpfile'
enable_pluggable_database=true
_clone_one_pdb_recovery=true
max_string_size=EXTENDED
复制
这里需要在恢复命令前加上以下命令:
set auxiliary instance parameter file to '/path/to/temp/recover_files/initaux.ora';
复制
在辅助实例完成启动(mount)后,这个实例将去判定需要恢复的表涉及哪些表空间文件,加上CDB和PDB中的SYSTEM、SYSAUX和UNDO表空间,仅会恢复对应表空间中存在对应数据的这些数据文件。
3 RMAN-06034
为了指定NBU设备信息,按照一般标准需要在恢复语句前后增加通道信息:
run {
allocate CHANNEL c0 TYPE 'SBT_TAPE' SEND 'NB_ORA_SERV=nbumaster,NB_ORA_CLIENT=dbbak02';
...
RELEASE CHANNEL c0;
}
--这里NB_ORA_SERV是对应的NBU管理节点,NB_ORA_CLIENT则是在NBU中配置了的本地用于备份IP对应的主机名
复制
然而又出现了下面的报错信息:
RMAN-06034: at least 1 channel must be allocated to execute this command
复制
这里查了一圈发现一篇文章:
Recover Table Fails with RMAN-06034: at least 1 channel must be allocated to execute this command (Doc ID 2105325.1)
解决方法如下:
--修改RMAN配置
CONFIGURE DEFAULT DEVICE TYPE TO 'SBT_TAPE';
CONFIGURE DEVICE TYPE 'SBT_TAPE' PARALLELISM 4;
CONFIGURE DEVICE TYPE DISK PARALLELISM 4;
CONFIGURE CHANNEL DEVICE TYPE 'SBT_TAPE' SEND 'NB_ORA_SERV=nbumaster,NB_ORA_CLIENT=dbbak02';
--然后不使用指定通道的方式发起恢复,这里会默认使用RMAN配置的信息配置通道
set auxiliary instance parameter file to '/path/to/temp/recover_files/initaux.ora';
recover table username.table_name of pluggable database pdb_name
until time "to_date('2024-05-12 20:35:00','yyyy-mm-dd hh24:mi:ss')"
auxiliary destination '/path/to/temp/recover_files'
datapump destination '/path/to/dumpfile'
dump file 'table_name.dmp'
notableimport;
--注意,这里不要使用SQL 'ALTER SESSION SET NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS"'的方式来匹配时间格式,否则会出现报错ORA-01861: literal does not match format string
复制
4 恢复
最后需要把dmp文件用impdp导入回数据库再恢复即可,这里需要注意,建议remap导入到不同表或不同用户下,亦或是异机导入,再处理数据,避免新的生产数据受到影响。
5 小插曲
最后失败了好几次才成功,主要原因是因为NBU备份一体机的空间不是太够,所以平时备份完成的文件会分通过S3分批转入到对象存储中,而在做恢复时,有概率找不到对应文件,也需要在多个S3中浪费大量时间进行轮询,失败概率挺高的,这里需要NBU那边配置好对应的解析,避免出现这一问题。
在数据的内存配置占主机内存总量较高的机器上运行表级恢复,辅助实例内存配置太大了无法启动,太小了会有各种报错,这个得尝试,但是挺浪费时间的。
总结
本期写了一下在有RMAN备份的情况下如何在19c环境恢复一个被truncate的表。
老规矩,知道写了些啥。