disable table失败的处理

本文深入探讨了HBase集群中常见的disable操作失败问题,详细解释了导致“RegionhasbeenPENDING_CLOSEfortoolong”状态的原因及解决方法。通过分析disable机制,提出了两种可行的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

相信每一个维护hbase集群的运维人员一定碰到过disable失败,陷入无穷的"Region has been PENDING_CLOSE for too long..."状态,此时没有什么好的办法处理。经常需要重启集群。
这个问题产生的原因非常讨厌,经过一段时间的分析和验证,得到了根本原因。要理解它,必须从disable的原理说起:

[list]
[*] disable线程是一个DisableTableHandler类,我们看它的handleDisableTable()方法,在while循环中先获取table的regions列表,然后调用BulkDisabler的bulkAssign()方法,等待bulkAssign()返回为true时则结束
[*] 在bulkAssign()方法中启动线程池,然后等待线程池超时,超时时间由hbase.bulk.assignment.waiton.empty.rit控制
[*] 在每个线程中,先从regions collection中得到regions列表,然后通知rs来处理该region,并且把该region放入RIT列表中,表示该region正在进行处理
[*] rs处理完region以后,将该region状态在zk上置为closing,此时master得到通知
[*] master将这个region从RIT列表中删除,并从regions列表中删除。
[/list]
[img]http://dl.iteye.com/upload/attachment/546540/b7bfd57e-cf86-3be5-8ec7-c8ee6153538e.jpg[/img]
注意以上最后一步,当master把它从RIT中删除以后,还有短暂的时间这个region还在regions列表中,此时另一个线程拿到了这个region,并且此时这个region不处于RIT状态保护,于是另一个线程开始重复以上过程,而前一个线程己经把它从collection中删除了,于是后一个线程再也无法完成closing事件。直到RIT超时(默认30秒)。

于是有两个修改办法:
1 缩短hbase.bulk.assignment.waiton.empty.rit这个时间(默认10分钟,it's too long...),让它重新进行一轮disable,此时会先把RIT的region都处理掉再继续,这样多几次尝试总会成功的。
2 修改代码:([url]https://issues.apache.org/jira/secure/attachment/12487669/HBASE-4064_branch90V2.patch[/url])
Index: src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
===================================================================
--- src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (revision 1150529)
+++ src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (working copy)
@@ -767,14 +767,15 @@
* @param regionInfo
*/
public void regionOffline(final HRegionInfo regionInfo) {
+ // remove the region plan as well just in case.
+ clearRegionPlan(regionInfo);
+ setOffline(regionInfo);
+
synchronized(this.regionsInTransition) {
if (this.regionsInTransition.remove(regionInfo.getEncodedName()) != null) {
this.regionsInTransition.notifyAll();
}
}
- // remove the region plan as well just in case.
- clearRegionPlan(regionInfo);
- setOffline(regionInfo);
}

即在以上步骤5时,先从regions列表中删除,再清除它的RIT状态。
方法2己经测试成功,方法1更简单,各位被这个问题困扰的同学可以一试。
任务描述 本关任务:使用Java代码禁用表、启用表、删除表。 相关知识 要删除HBase中的表,我们需要先禁用它,否则是无法删除的,如果一张已经禁用的表,我们不想删除了,而想重新启用它,这个时候可以使用Java代码实现启用操作。 接下来我们来学习如何使用Java代码实现这些操作。 禁用表、删除表、启用表 三个操作都很简单: 在获取了Admin对象之后,直接使用disableTable(TableName tableName)、deleteTable(TableName tableName)、enableTable(TableName tableName)即可实现表的禁用、删除与启用操作。 示例,删除名为test的表,启用名为demo的表: Configuration config = new Configuration(); Connection conn = ConnectionFactory.createConnection(config); Admin admin = connection.getAdmin(); TableName testName = TableName.valueOf(Bytes.toBytes("test")); TableName demoName = TableName.valueOf(Bytes.toBytes("test")); admin.disableTable(testName); admin.deleteTable(testName); admin.enableTable(demoName); 验证 禁用、删除和启用操作之后,我们会想要验证一下操作是否成功; 如何验证呢? admin.isTableDisabled(tableName)//是否禁用 admin.tableExists(tableName)//是否存在 admin.isTableEnabled(tableName)//是否启用 编程要求 到你了,请在右侧编辑器begin-end中编写代码补全函数,实现函数要实现的功能,具体功能请查看右侧注释。 测试说明 平台将会使用如下代码测试你的程序,调用你编写的方法: String[] tableNames = { "t_emp3", "t_dept3", "t_user3" }; String[] columns = { "data1", "data2", "data3" }; Task task = new Task(); // 创建表 for (String tableName : tableNames) { task.createTable(tableName, columns); } // 删除表 task.deleteTable("t_dept3"); // 禁用表 task.disableTable("t_user3"); task.disableTable("t_emp3"); // 启用表 task.enableTable("t_emp3"); // 显示表的状态 List<TableDescriptor> tableDescriptors = admin.listTableDescriptors(); for (TableDescriptor tableDescriptor : tableDescriptors) { TableName tableName = tableDescriptor.getTableName(); System.out.println("Table: " + tableName); System.out.println("\texists: " + admin.tableExists(tableName)); System.out.println("\tenabled: " + admin.isTableEnabled(tableName)); } 预期输出: Table: t_emp3 exists: true enabled: true Table: t_user3 exists: true enabled: false 开始你的任务吧,祝你成功!
最新发布
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值