HDFS文件误删怎么办,一招教你恢复回来,再也不用担心删库跑路了_hdfs表被删了,怎么看操作记录(1)

最后

Python崛起并且风靡,因为优点多、应用领域广、被大牛们认可。学习 Python 门槛很低,但它的晋级路线很多,通过它你能进入机器学习、数据挖掘、大数据,CS等更加高级的领域。Python可以做网络应用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

👉Python所有方向的学习路线👈

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

👉Python必备开发工具👈

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

👉Python全套学习视频👈

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

👉实战案例👈

学python就与学数学一样,是不能只看书不做题的,直接看步骤和答案会让人误以为自己全都掌握了,但是碰到生题的时候还是会一筹莫展。

因此在学习python的过程中一定要记得多动手写代码,教程只需要看一两遍即可。

👉大厂面试真题👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

int totalReplicateBlocks = nodeinfo.getNumberOfReplicateBlocks();
int totalECBlocks = nodeinfo.getNumberOfBlocksToBeErasureCoded();
int totalBlocks = totalReplicateBlocks + totalECBlocks;
if (totalBlocks > 0) {
  int numReplicationTasks = (int) Math.ceil(
      (double) (totalReplicateBlocks * maxTransfers) / totalBlocks);
  int numECTasks = (int) Math.ceil(
      (double) (totalECBlocks * maxTransfers) / totalBlocks);

  if (LOG.isDebugEnabled()) {
    LOG.debug("Pending replication tasks: " + numReplicationTasks
        + " erasure-coded tasks: " + numECTasks);
  }
  // check pending replication tasks
  List<BlockTargetPair> pendingList = nodeinfo.getReplicationCommand(
      numReplicationTasks);
  if (pendingList != null && !pendingList.isEmpty()) {
    cmds.add(new BlockCommand(DatanodeProtocol.DNA_TRANSFER, blockPoolId,
        pendingList));
  }
  // check pending erasure coding tasks
  List<BlockECReconstructionInfo> pendingECList = nodeinfo
      .getErasureCodeCommand(numECTasks);
  if (pendingECList != null && !pendingECList.isEmpty()) {
    cmds.add(new BlockECReconstructionCommand(
        DNA_ERASURE_CODING_RECONSTRUCTION, pendingECList));
  }
}

// check block invalidation
Block[] blks = nodeinfo.getInvalidateBlocks(blockInvalidateLimit);
if (blks != null) {
  cmds.add(new BlockCommand(DatanodeProtocol.DNA_INVALIDATE, blockPoolId,
      blks));
}
// cache commands
addCacheCommands(blockPoolId, nodeinfo, cmds);
// key update command
blockManager.addKeyUpdateCommand(cmds, nodeinfo);

// check for balancer bandwidth update
if (nodeinfo.getBalancerBandwidth() > 0) {
  cmds.add(new BalancerBandwidthCommand(nodeinfo.getBalancerBandwidth()));
  // set back to 0 to indicate that datanode has been sent the new value
  nodeinfo.setBalancerBandwidth(0);
}

if (slowPeerTracker != null) {
  final Map<String, Double> slowPeersMap = slowPeers.getSlowPeers();
  if (!slowPeersMap.isEmpty()) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("DataNode " + nodeReg + " reported slow peers: " +
          slowPeersMap);
    }
    for (String slowNodeId : slowPeersMap.keySet()) {
      slowPeerTracker.addReport(slowNodeId, nodeReg.getIpcAddr(false));
    }
  }
}

if (slowDiskTracker != null) {
  if (!slowDisks.getSlowDisks().isEmpty()) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("DataNode " + nodeReg + " reported slow disks: " +
          slowDisks.getSlowDisks());
    }
    slowDiskTracker.addSlowDiskReport(nodeReg.getIpcAddr(false), slowDisks);
  }
}

if (!cmds.isEmpty()) {
  return cmds.toArray(new DatanodeCommand[cmds.size()]);
}

return new DatanodeCommand[0];

}


**定时轮循+limit 1000个块删除**的特性决定了hdfs删除数据并不会立即真正的执行物理删除,并且一次删除的数量也有限,**所以出现误删操作需要立即停止HDFS**,虽然有的数据在轮循中已被删除,所以事发后停止HDFS集群越早,被删的数据越少,损失越小!


#### EditLog


EditLog记录了hdfs操作的每一条日志记录,包括当然包括删除,我们所熟知的文件操作类型只有增、删、改,但是在 HDFS 的领域里,远远不止这些操作,我们看看 EditLog 操作类型的枚举类**org.apache.hadoop.hdfs.server.namenode.FSEditLogOpCodes**  
  



/**

  • Licensed to the Apache Software Foundation (ASF) under one
  • or more contributor license agreements. See the NOTICE file
  • distributed with this work for additional information
  • regarding copyright ownership. The ASF licenses this file
  • to you under the Apache License, Version 2.0 (the
  • “License”); you may not use this file except in compliance
  • with the License. You may obtain a copy of the License at
  • http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software
  • distributed under the License is distributed on an “AS IS” BASIS,
  • WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  • See the License for the specific language governing permissions and
  • limitations under the License.
    */
    package org.apache.hadoop.hdfs.server.namenode;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.hdfs.server.namenode.FSEditLogOp.*;

/**

  • Op codes for edits file
    */
    @InterfaceAudience.Private
    @InterfaceStability.Unstable
    public enum FSEditLogOpCodes {
    // last op code in file
    OP_ADD ((byte) 0, AddOp.class),
    // deprecated operation
    OP_RENAME_OLD ((byte) 1, RenameOldOp.class),
    OP_DELETE ((byte) 2, DeleteOp.class),
    OP_MKDIR ((byte) 3, MkdirOp.class),
    OP_SET_REPLICATION ((byte) 4, SetReplicationOp.class),
    @Deprecated OP_DATANODE_ADD ((byte) 5), // obsolete
    @Deprecated OP_DATANODE_REMOVE((byte) 6), // obsolete
    OP_SET_PERMISSIONS ((byte) 7, SetPermissionsOp.class),
    OP_SET_OWNER ((byte) 8, SetOwnerOp.class),
    OP_CLOSE ((byte) 9, CloseOp.class),
    OP_SET_GENSTAMP_V1 ((byte) 10, SetGenstampV1Op.class),
    OP_SET_NS_QUOTA ((byte) 11, SetNSQuotaOp.class), // obsolete
    OP_CLEAR_NS_QUOTA ((byte) 12, ClearNSQuotaOp.class), // obsolete
    OP_TIMES ((byte) 13, TimesOp.class), // set atime, mtime
    OP_SET_QUOTA ((byte) 14, SetQuotaOp.class),
    // filecontext rename
    OP_RENAME ((byte) 15, RenameOp.class),
    // concat files
    OP_CONCAT_DELETE ((byte) 16, ConcatDeleteOp.class),
    OP_SYMLINK ((byte) 17, SymlinkOp.class),
    OP_GET_DELEGATION_TOKEN ((byte) 18, GetDelegationTokenOp.class),
    OP_RENEW_DELEGATION_TOKEN ((byte) 19, RenewDelegationTokenOp.class),
    OP_CANCEL_DELEGATION_TOKEN ((byte) 20, CancelDelegationTokenOp.class),
    OP_UPDATE_MASTER_KEY ((byte) 21, UpdateMasterKeyOp.class),
    OP_REASSIGN_LEASE ((byte) 22, ReassignLeaseOp.class),
    OP_END_LOG_SEGMENT ((byte) 23, EndLogSegmentOp.class),
    OP_START_LOG_SEGMENT ((byte) 24, StartLogSegmentOp.class),
    OP_UPDATE_BLOCKS ((byte) 25, UpdateBlocksOp.class),
    OP_CREATE_SNAPSHOT ((byte) 26, CreateSnapshotOp.class),
    OP_DELETE_SNAPSHOT ((byte) 27, DeleteSnapshotOp.class),
    OP_RENAME_SNAPSHOT ((byte) 28, RenameSnapshotOp.class),
    OP_ALLOW_SNAPSHOT ((byte) 29, AllowSnapshotOp.class),
    OP_DISALLOW_SNAPSHOT ((byte) 30, DisallowSnapshotOp.class),
    OP_SET_GENSTAMP_V2 ((byte) 31, SetGenstampV2Op.class),
    OP_ALLOCATE_BLOCK_ID ((byte) 32, AllocateBlockIdOp.class),
    OP_ADD_BLOCK ((byte) 33, AddBlockOp.class),
    OP_ADD_CACHE_DIRECTIVE ((byte) 34, AddCacheDirectiveInfoOp.class),
    OP_REMOVE_CACHE_DIRECTIVE ((byte) 35, RemoveCacheDirectiveInfoOp.class),
    OP_ADD_CACHE_POOL ((byte) 36, AddCachePoolOp.class),
    OP_MODIFY_CACHE_POOL ((byte) 37, ModifyCachePoolOp.class),
    OP_REMOVE_CACHE_POOL ((byte) 38, RemoveCachePoolOp.class),
    OP_MODIFY_CACHE_DIRECTIVE ((byte) 39, ModifyCacheDirectiveInfoOp.class),
    OP_SET_ACL ((byte) 40, SetAclOp.class),
    OP_ROLLING_UPGRADE_START ((byte) 41, RollingUpgradeStartOp.class),
    OP_ROLLING_UPGRADE_FINALIZE ((byte) 42, RollingUpgradeFinalizeOp.class),
    OP_SET_XATTR ((byte) 43, SetXAttrOp.class),
    OP_REMOVE_XATTR ((byte) 44, RemoveXAttrOp.class),
    OP_SET_STORAGE_POLICY ((byte) 45, SetStoragePolicyOp.class),
    OP_TRUNCATE ((byte) 46, TruncateOp.class),
    OP_APPEND ((byte) 47, AppendOp.class),
    OP_SET_QUOTA_BY_STORAGETYPE ((byte) 48, SetQuotaByStorageTypeOp.class),
    OP_ADD_ERASURE_CODING_POLICY ((byte) 49, AddErasureCodingPolicyOp.class),
    OP_ENABLE_ERASURE_CODING_POLICY((byte) 50, EnableErasureCodingPolicyOp.class),
    OP_DISABLE_ERASURE_CODING_POLICY((byte) 51,
    DisableErasureCodingPolicyOp.class),
    OP_REMOVE_ERASURE_CODING_POLICY((byte) 52, RemoveErasureCodingPolicyOp.class),

// Note that the current range of the valid OP code is 0~127
OP_INVALID ((byte) -1);

private final byte opCode;
private final Class<? extends FSEditLogOp> opClass;

/**

  • Constructor
  • @param opCode byte value of constructed enum
    */
    FSEditLogOpCodes(byte opCode) {
    this(opCode, null);
    }

FSEditLogOpCodes(byte opCode, Class<? extends FSEditLogOp> opClass) {
this.opCode = opCode;
this.opClass = opClass;
}

/**

  • return the byte value of the enum
  • @return the byte value of the enum
    */
    public byte getOpCode() {
    return opCode;
    }

public Class<? extends FSEditLogOp> getOpClass() {
return opClass;
}

private static final FSEditLogOpCodes[] VALUES;

static {
byte max = 0;
for (FSEditLogOpCodes code : FSEditLogOpCodes.values()) {
if (code.getOpCode() > max) {
max = code.getOpCode();
}
}
VALUES = new FSEditLogOpCodes[max + 1];
for (FSEditLogOpCodes code : FSEditLogOpCodes.values()) {
if (code.getOpCode() >= 0) {
VALUES[code.getOpCode()] = code;
}
}
}

/**

  • Converts byte to FSEditLogOpCodes enum value
  • @param opCode get enum for this opCode
  • @return enum with byte value of opCode
    */
    public static FSEditLogOpCodes fromByte(byte opCode) {
    if (opCode >= 0 && opCode < VALUES.length) {
    return VALUES[opCode];
    }
    return opCode == -1 ? OP_INVALID : null;
    }
    }

总计54种操作类型!打破了人们印象中文件只有增删改读的几种操作。在hadoop的配置参数**`dfs.namenode.name.dir`**可以找到路径


![](https://img-blog.csdnimg.cn/20210925135224167.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAVmlja3lfVGFuZw==,size_20,color_FFFFFF,t_70,g_se,x_16)


 这里EditLog文件是序列化后的二进制文件不能直接查看,hdfs自带了解析的命令,可以解析成xml明文格式



hdfs oev -i edits_0000000000035854978-0000000000035906741 -o edits.xml


![](https://img-blog.csdnimg.cn/20210925135614473.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAVmlja3lfVGFuZw==,size_17,color_FFFFFF,t_70,g_se,x_16)


对 hdfs 的每一个操作都会记录一串 RECORD,RECORD 里面不同的操作包含的字段属性也不同,但是所有操作都具备的属性是 OPCODE,对应上面的枚举类**`org.apache.hadoop.hdfs.server.namenode.FSEditLogOpCodes`**中的操作


#### hdfs元数据的加载


hdfs 启动时,NameNode 会加载 Fsimage,Fsimage 记录了 hdfs 现有的全量的路径信息,启动过程中仅仅加载 Fsimage?这句话不完全正确!启动的同时,还会加载未被合并成 fsimage 的EditLog。关于 fsimage 具体细节这里不展开。举个栗子:


假设Hadoop 3分钟checkpoint一次生成Fsimage文件,EditLog 1分钟生成一个文件,下面是依次生成的文件:  
  



fsimage_1
editlog_1
editlog_2
editlog_3
fsimage_2
editlog_4
editlog_5


当NameNode启动时,会加载后缀时间戳最大的那个fsimage文件和它后面产生的editlog文件,也就是会加载**fsimage\_2、editlog\_4、editlog\_5**进NameNode内存。


### 恢复方法


假设我们执行 hdfs dfs -rmr xxx 命令的操作记录在了 editlog\_5 上面,那么,重启 NameNode 后,我们查看hdfs无法再查看到xxx路径,如果我们把fsimage\_2删掉,NameNode则会加载fsimage\_1、editlog\_1、editlog\_2,此时的元数据里面xxx还未被删除,如果此时DataNode未物理删除block,则数据可以恢复,但是editlog\_4、editlog\_5对应的hdfs操作会丢失。有没有更好的方法呢?


#### 方案一:


删掉 fsimage\_2,从上一次 checkpoint 的地方也就是 fsimage\_1 恢复,我们集群的实际配置,是一个小时生成一次 fsimage 文件,也就是说,这种恢复方案会导致近一小时 hdfs 新增的文件全部丢失,这一个小时不知道发生了多少事情,可想而知的后果是恢复之后一堆报错,显然不是最好的方案


#### 方案二:


修改**editlog\_5**,把删除`xxx`那条操作改成其它安全的操作类型,这样重启NameNode后,又可以看到这个路径。


**步骤:**


* 关闭HDFS集群
* 解析editlog

 找到删除操作时间点范围内所属的editlog文件,解析

 

hdfs oev -i edits_0000000000000000336-0000000000000000414 -o edits.xml

 查看editlog.xml,执行删除操作的日志已经记录在里面了


![](https://img-blog.csdnimg.cn/20210925141212319.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAVmlja3lfVGFuZw==,size_20,color_FFFFFF,t_70,g_se,x_16)


* 替换删除操作


        把OP\_DELETE操作替换成比较安全的操作,例如



OP_DELETE 374 0 /hbase/oldWALs/test%2C16020%2C1630456996531.1630464212306 1630724840046 d1e2ae59-ba0c-4385-87d4-4da3d9ec019b 1049

**注意:只能改变OPCODE,其他不能修改!!!**


* 反解析成editlog



反解析更改后的xml文件成editlog

hdfs oev -i editlog.xml -o edits_0000000000000000336-0000000000000000414.tmp -p binary

重命名掉之前的editlog

mv edits_0000000000000000336-0000000000000000414 edits_0000000000000000336-0000000000000000414.bak

替换反解析后的editlog

mv edits_0000000000000000336-0000000000000000414.tmp edits_0000000000000000336-0000000000000000414


* 使用 scp 将修改后的 editlog 同步到其他 JournalNode 节点


学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!



### 一、Python所有方向的学习路线



Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。



![](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)



### 二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。



![](https://img-blog.csdnimg.cn/img_convert/8c4513c1a906b72cbf93031e6781512b.png)



### 三、全套PDF电子书



书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

![](https://img-blog.csdnimg.cn/img_convert/46506ae54be168b93cf63939786134ca.png)



### 四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。



![](https://img-blog.csdnimg.cn/afc935d834c5452090670f48eda180e0.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5bqP5aqb56eD56eD,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)



### 五、实战案例



光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。



![](https://img-blog.csdnimg.cn/img_convert/252731a671c1fb70aad5355a2c5eeff0.png)



### 六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。



![](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)  

![](https://img-blog.csdnimg.cn/img_convert/d2d978bb523c810abca3abe69e09bc1a.png)




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618317507)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【为什么学PythonPython 是当今非常热门的语言之一,2020年的 TIOBE 编程语言排行榜中 ,Python名列第一,并且其流行度依然处在上升势头。 在2015年的时候,在网上还经常看到学Python还是学R的讨论,那时候老齐就选择了Python,并且开始着手出版《跟老齐学Python》。时至今日,已经无需争论。Python给我们带来的,不仅仅是项目上的收益,我们更可以从它“开放、简洁”哲学观念中得到技术发展线的启示。 借此机会,老齐联合CSDN推出了本课程,希望能影响更多的人走进Python,踏入编程的大门。 【课程设计】 本课程共包含三大模块: 一、基础知识篇 内置对象和基本的运算、语句,是Python语言的基础。本课程在讲解这部分知识的时候,不是简单地将各种知识做简单的堆砌,而是在兼顾内容的全面性的同时,更重视向学习者讲授掌握有关知识的方法,比如引导学习者如何排查错误、如何查看和理解文档等。   二、面向对象篇 “面向对象(OOP)”是目前企业开发主流的开发方式,本课程从一开始就渗透这种思想,并且在“函数”和“类”的学习中强化面向对象开发方式的学习——这是本课程与一般课程的重要区别,一般的课程只在“类”这里才提到“对象”,会导致学习者茫然失措,并生畏惧,乃至于放弃学习。本课程则是从开始以“润物细无声”的方式,渗透对象概念,等学习到本部分的时候,OOP对学习者而言有一种“水到渠成”的感觉。   三、工具实战篇 在项目实战中,除了前述的知识之外,还会用到很多其他工具,至于那些工具如何安装?怎么自己做工具?有那些典型工具?都是这部分的内容。具体来说,就是要在这部分介绍Python标准库的应用以及第三方包的安装,还有如何开发和发布自己的工具包。此外,很多学习Python的同学,未来要么从事数据科学、要么从事Web开发,不论哪个方向,都离不开对数据库的操作,本部分还会从实战的角度,介绍如何用Python语言操作常用数据库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值