博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hbase Table already exists
阅读量:5743 次
发布时间:2019-06-18

本文共 2838 字,大约阅读时间需要 9 分钟。

问题描述:前端时间用pinpoint采集数据保存到Hbase,脏数据比较多,想清空数据库重新测试,发现Hbase清空表只能先删除表再重建,不能只清空数据;删除后重建表的时候就报Table already exists,用list查看发现表已经被删了,所以懵逼了~

解决方法

  • 1、通过./hbase zkcli命令进入zookeeper client模式
  • 2、输入ls /hbase/table命令看到zombie table
  • 3、使用rmr /hbase/table/TABLE_NAME命令删除zombie table
  • 4、重启Hbase

如果是直接rmr /hbase会报非空错误:rmr /hbase Node not empty: /hbase/

所以需要再进一级去删除

问题分析

首先在list的时候,没有显示之前建的表,也就是没有感知到之前建的表,但是create时候却感知到了之前建的表,所以很自然需要看一下list和create的时候,server执行的逻辑。只要清楚了这个逻辑,问题便一清二楚了。

1、list时server端的逻辑其实很简单。list的时候master端执行的逻辑的入口函数是listTableDescriptors。核心代码如下:

// request for all TableDescriptors        Collection
htds; if (namespace != null && namespace.length() > 0) { htds = tableDescriptors.getByNamespace(namespace).values(); } else { htds = tableDescriptors.getAll().values(); } for (HTableDescriptor desc: htds) { if (includeSysTables || !desc.getTableName().isSystemTable()) { descriptors.add(desc); }

可以看到是从tableDescriptors中获取的,而tableDescriptors是根据hbase在hdfs中路径的描述

this.tableDescriptors = new FSTableDescriptors(this.conf, this.fs, this.rootDir, !canUpdateTableDescriptor(), false);

然后可以看到这些信息是从hbase在hdfs中的rootpath下的data目录中获取表相关信息的。所以,list的时候当然看不见之前的表了。

2、create table的时候,在server端最终会使用createTableHandler或者createTableProcedure来处理建表的逻辑。在createTableProcedure中正式建表之前,会调用prepareCreate函数。

private boolean prepareCreate(final MasterProcedureEnv env) throws IOException {    final TableName tableName = getTableName();    if (MetaTableAccessor.tableExists(env.getMasterServices().getConnection(), tableName)) {      setFailure("master-create-table", new TableExistsException(getTableName()));      return false;    }    // During master initialization, the ZK state could be inconsistent from failed DDL    // in the past. If we fail here, it would prevent master to start.  We should force    // setting the system table state regardless the table state.    boolean skipTableStateCheck =        !(env.getMasterServices().isInitialized()) && tableName.isSystemTable();    if (!skipTableStateCheck) {      TableStateManager tsm = env.getMasterServices().getAssignmentManager().getTableStateManager();      if (tsm.isTableState(tableName, true, ZooKeeperProtos.Table.State.ENABLING,          ZooKeeperProtos.Table.State.ENABLED)) {        LOG.warn("The table " + tableName + " does not exist in meta but has a znode. " +               "run hbck to fix inconsistencies.");        setFailure("master-create-table", new TableExistsException(getTableName()));        return false;      }    }    return true;  }

在14行,通过TableStateManager会检查zookeeper对应的表状态是不是enable的,检查zk中的路径是hbase root path下的table目录。由于zk还是之前的zk,所以之前建的表信息还在,很自然这时候会检查已经存在,如是报了Table already exits的错误。Log提示中说用hbck去检查,但是貌似检查不出来是不一致的。

问题解决思路:

本来想通过hbck去检查,然后修复的,但是貌似hbck检查不出来。所以只是简单暴力的把zk中对应的table删除,然后create就没问题了。

转载地址:http://okszx.baihongyu.com/

你可能感兴趣的文章
ms17_0199样本测试
查看>>
asp.net前台获取Session和创建保存Session
查看>>
ASP.NET-FineUI开发实践-9(三)
查看>>
1.计算机基础
查看>>
【笔记】做一个winform时遇到的坑
查看>>
input中的id和name
查看>>
杂谈——杭州考驾照历程
查看>>
Number Sequence http://acm.hdu.edu.cn/showproblem.php?pid=1005
查看>>
求伯君今日套现离场 老一代程序员标杆隐退
查看>>
Mac017--Jenkins 持续集成
查看>>
十天冲刺-02
查看>>
消息队列如何保证幂等性?
查看>>
全排列 ( next_permutation)
查看>>
Nyoj 引水工程(最小生成树)
查看>>
029:url标签使用详解
查看>>
【Codeforces Round #430 (Div. 2) A C D三个题】
查看>>
python繁体中文到简体中文的转换
查看>>
H5缓存-Manifest
查看>>
HTML5之本地存储SessionStorage
查看>>
string对象
查看>>