暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

rm -rf 删除Mogdb数据文件异常恢复

原创 由迪 2023-10-11
105

原作者:许玉晨

1.背景概述

在进行Mogdb数据恢复操作过程中,误用omm用户rm -rf命令删除数据库主目录下/dbdata所有数据库相关目录,该目录下保存数据库数据文件,数据库可执行文件,备份文件等,该操作导致Mogdb数据库不可用。
经过24小时连续作业,所有数据表补数完成,业务侧复查数据无缺失。
后持续观察,数据库运行稳定,服务器负载正常,业务测反馈业务服务正常。

2.故障分析

2.1 故障现象

17时,收到用户通知,用户误将某表部分数据update,请求将表数据恢复到16时00分钟左右,使用brm备份进行基于时间点的不完全恢复,跟用户核对数据后,备份表数据,使用trucnate命令删除表数据后,将不完全恢复的数据导入。少时,用户发现某外检表数据也被清理,跟用户沟通后,将数据库数据重新恢复到17点15分。
基于对磁盘空间不足的考虑,准备删除基于16:00的不完全恢复目录,但是在删除时,误切换到上层目录,使用命令rm -rf ./*,删除了整个数据库的主数据目录,所有数据文件被删除。
误操作步骤:

# 建立不完全恢复库
/dbdata/app/brm/brm restore -i mogdb --recovery-target-time='2022-03-30 16:00:00' -D /dbdata/datarev

## 数据导出
vi /dbdata/datarev/postgresql.conf
sed -i s\port = 51000\port = 51002\g /dbdata/datarev/postgres.conf

gs_ctl start -D /dbdata/datarev

gsql -d owner -p 51002 -r
select count(*) from  owner.a;

gs_dump -U owner -W owner@1234 -p 51002 -f /dbdata/dbback/a.sql owner -t a

gs_ctl stop -D /dbdata/datarev

## 删除数据
owner=> truncate table owner.a;
ERROR:  cannot truncate a table referenced in a foreign key constraint
DETAIL:  Table "b" references "a".
HINT:  Truncate table "b" at the same time, or use TRUNCATE ... CASCADE.
owner=> truncate table owner.a cascade;
owner=> select count(*) from owner.a;
 count 
-------
     0
(1 row)


## 导入数据并核对
\i /dbdata/dbback/a.sql

owner=> select count(*) from owner.a;
 count  
--------
 170595
(1 row)

owner=> select status,count(1) from owner.a group by status;
 status | count  
--------+--------
      5 |     17
      3 |     50
      4 | 164774
      7 |     59
      1 |   1505
     -1 |     77
      0 |    118
      2 |    104
     99 |   3891
(9 rows)

## 发现外键表数据缺失,重新建立17:15恢复库 
gs_om -t stop

## 手动备份生产数据库
cp -r /dbdata/data /dbdata/data_bak

# 查看不完全恢复的文件目录
cd /dbdata/datarev
ls -ltr
cd ..
du -sh *

查看不完全恢复目录大小,此时操作目录位于数据文件目录,导致了之后的误操作

## 需要重新进行不完全恢复操作,操作前清理/dbdata/datarev文件目录
## 操作时,没有确认当前目录和目录下文件,就执行了rm -rf命令,导致故障的发生
rm -rf ./*

rm -rf 命令导致数据库运行的必要可执行文件,数据文件,备份文件遗失,引发数据库服务中断。**

2.2 故障处置

故障发生后,通过对现场情况评估后,制定三套故障恢复方案:

方案一:二线专家对当前系统fork住的gsql进程数据进行灾难性挽救
方案二:由专业的数据恢复工程师提供软件对数据目录进行恢复
方案三:从测试数据库提取2月备份数据,作为最后的后备方案
方案一:开始登录远程服务器,进行数据挽救,通过检查gsql fork进程,查询对应打开的句柄文件后,发现数据虽然存在挽救价值。但是句柄文件缓存目录/proc对应的数据文件已经非常琐碎,且存在数据遗失的可能,使用该数据进行数据恢复,存在不可预知性及大量困难。。
方案二:确认测试库2月备份集存在,并验证数据集有效性,开始远程对搭建数据恢复环境工程师开始进行数据镜像的制备,但是由于数据损坏严重,在启动数据库时,频繁出现文件块损坏及数据文件缺失的报错,需要不停试错,导致修复数据库进展缓慢,仍未能恢复数据库服务。
次日,方案二完成镜像,并预备抽取数据。放弃方案一,抽取数据库主目录文件,尝试启动数据库,发现数据恢复的数据库服务虽然较为完整,仍存在小部分文件缺失,制定两个新方案恢复数据库:

方案四:使用镜像抽取的主数据库数据进行恢复
方案五:使用镜像抽取的备份集数据进行恢复
由于方案四可以比较可以快得出结果,优先使用方案四进行数据恢复,1个小时的尝试后,发现进展缓慢后,更换为方案五进行恢复。
从镜像抽取的备份集较多,共4份,除其中一份缺失较为严重外,剩余三份备份集具备恢复价值,从距离故障节点最近的备份集开始依次尝试恢复数据。

恢复过程:

## 清理备份库
cd /dbdata/datarev
pwd

cd /dbdata/datarev_202203282330
pwd
rm -rf datarev/*
rm -rf datarev_202203282330/*

## 新建29日和30日备份库
gs_probackup restore --force --skip-block-validation -B /dbdata/dbback --instance=mogdb --recovery-target-time='2022-03-30 17:15:00' -D /dbdata/datarev

gs_probackup restore --force --skip-block-validation -B /dbdata/dbback --instance=mogdb --recovery-target-time='2022-03-29 23:30:00' -D /dbdata/datarev_202203282330

## 重置参数文件
cp ../pg_hba.conf .
cp ../postgresql.conf .
cp ../recovery.conf .

# 查找xlog对应关系,并将日志目录中的xlog匹配到还原点
cd /dbdata/dbback/wal/mogdb/
mv .. xlog

## 启动数据库
gs_ctl start -D /dbdata/datarev
gs_ctl start -D /dbdata/datarev_202203282330

## 提取对应数据
# 30日数据
gs_dump -h 127.0.0.1 -p 50004 -U owner -W owner@1234 -Fc -f /nas/backup/owner_0329.dump owner
# 29日数据
gs_dump -h 127.0.0.1 -p 41000 -U owner -W owner@1234 -Fc -f /nas/backup/owner_0330.dump owner

## 新建生产数据库

## 分别将数据导入
gs_restore -p 51000 -U owner -W owner@1234 -d owner2 /nas/backup/owner_0329.dump
gs_restore -p 51000 -U owner -W owner@1234 -d owner /nas/backup/owner_0330.dump

截止至晚18点,数据库服务恢复,用户初步确认数据可供业务正常使用。
4月1日早,跟用户沟通后,发现部分表数据有不一致的现象,继续进行数据挖掘,并提供相应的SQL进一步分析确认是否有其他表数据缺失,截至12点,完成所有数据表的比对和数据更新。

## 对比数据量
select relname,n_live_tup from pg_stat_user_tables where schemaname='owner';

select 'select count(*) as '||relname|| ' from '||schemaname||'.'||relname||';' from pg_stat_user_tables where schemaname='owner';

diff -u /home/omm/owner_30.sql /home/omm/owner_29.sql > /home/omm/2.log

## 补数
gs_dump -U owner -W owner@1234 -p 51000 -f /nas/backup/0401_add_02.sql owner2 -a -t a_activity_to_psn -t lib_doc_dn_act -t problem_worklog -t kb_solution_activity -t problem_activity -t kb_solution_comment -t problem_participator -t problem_activity_to_psn -t a_ticket_handler -t kb_knowledge_comment -t lib_doc -t problem_ref_chg -t problem_comment -t kb_knowledge_activity -t problem_handler -t kb_knowledge  

create table ***_0401   as select * from ***_to_psn;
## 重新验证对比数据效果
gsql -p 51000 -U owner -W owner@1234 -d owner -f /nas/backup/0401_add_02.sql

diff -u /home/omm/owner_30.sql /home/omm/owner_29.sql > /home/omm/2.txt

3. 根本解决方案及建议

1、对之后现场的任何变更预写操作脚本,在测试服务器通过验证后。再与用户申请割接时间实施变更
2、谨慎使用“rm -rf *”命令,在rm之前先pwd,并ls验证文件后,使用rf -rf 文件的方式删除,也可以替换为mv命令
3、将数据文件和备份文件目录分离,最小化之间的影响
4、配置主备环境,从库可在主库故障时,开始接替数据服务,实现业务测的无感知切换
5、提供对NBU异地备份集的定期恢复测试

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论