Unexpected state导致HMaster abort

本文探讨了HBase中MasterAbort的问题,特别是由于压缩算法不兼容导致的Unexpectedstate错误。通过详细分析日志,揭示了RegionServer与Master之间的交互过程及故障原因。

线上和开发集群都遇到过master abort的情况,而且错误都是Unexpected state导致的FATAL错误

2014-01-08 13:44:40,770 FATAL org.apache.hadoop.hbase.master.HMaster: Master server abort: loaded coprocessors are: []

2014-01-08 13:44:40,771 FATAL org.apache.hadoop.hbase.master.HMaster: 69 Unexpected state : usertable2,,1389159324467.a37e60fd78a3bff2bddac6270f6b317c. state=PENDING_OPEN, ts=1389159880770, server=localhost.localdomain,60020,1389159296923 .. Cannot transit it to OFFLINE.

java.lang.IllegalStateException: 69 Unexpected state : usertable2,,1389159324467.a37e60fd78a3bff2bddac6270f6b317c. state=PENDING_OPEN, ts=1389159880770, server=localhost.localdomain,60020,1389159296923 .. Cannot transit it to OFFLINE.

 

在本地测试可以复现了这种情况,创建一个表,设置压缩算法,但是压缩算法本地不支持,这样master abort很容易复现。

create 'usertable2', { NAME=>'cf', VERSIONS=> 1, COMPRESSION => 'LZO', BLOCKCACHE => true}, { SPLITS => ['user']}

我们来看下HRegionServer的日志:

RegionServer:

2014-01-08 13:44:40,661 DEBUG org.apache.hadoop.hbase.zookeeper.ZKAssign: regionserver:60020-0x1437058a1d60001 Successfully transitioned node a37e60fd78a3bff2bddac6270f6b317c from M_ZK_REGION_OFFLINE to RS_ZK_REGION_OPENING

 

2014-01-08 13:44:40,669 DEBUG org.apache.hadoop.hbase.zookeeper.ZKAssign: regionserver:600

接着我们来看HMaster的日志:

Master:

2014-01-08 13:44:40,671 DEBUG org.apache.hadoop.hbase.master.AssignmentManager: 28 Handling transition=RS_ZK_REGION_FAILED_OPEN, server=localhost.localdomain,60020,1389159296923, region=a37e60fd78a3bff2bddac6270f6b317c

 

2014-01-08 13:44:40,679 DEBUG org.apache.hadoop.hbase.master.AssignmentManager: 28 Handling transition=RS_ZK_REGION_FAILED_OPEN, server=localhost.localdomain,60020,1389159296923, region=a37e60fd78a3bff2bddac6270f6b317c

RegionServer产生了两个zk事件,一个是RS_ZK_REGION_OPENING,一个是RS_ZK_REGION_FAILED_OPEN。而Master处理这两个事件的时间比较晚,所以读取到的数据都是RS_ZK_REGION_FAILED_OPEN,导致执行两次ClosedRegionHandler。

这两个ClosedRegionHandler同时执行,有一定的概率导致Unexpected state,进而master abort,看下面master的日志。

2014-01-08 13:44:40,677 DEBUG org.apache.hadoop.hbase.master.handler.ClosedRegionHandler: 68 Handling CLOSED event for a37e60fd78a3bff2bddac6270f6b317c

2014-01-08 13:44:40,677 DEBUG org.apache.hadoop.hbase.master.AssignmentManager: 68 Forcing OFFLINE; was=usertable2,,1389159324467.a37e60fd78a3bff2bddac6270f6b317c. state=CLOSED, ts=1389159880663, server=localhost.localdomain,60020,1389159296923

2014-01-08 13:44:40,677 DEBUG org.apache.hadoop.hbase.zookeeper.ZKAssign: master:60000-0x1437058a1d60005 Creating (or updating) unassigned node for a37e60fd78a3bff2bddac6270f6b317c with OFFLINE state

 

2014-01-08 13:44:40,683 DEBUG org.apache.hadoop.hbase.master.handler.ClosedRegionHandler: 69 Handling CLOSED event for a37e60fd78a3bff2bddac6270f6b317c

2014-01-08 13:44:40,683 DEBUG org.apache.hadoop.hbase.master.AssignmentManager: 69 Forcing OFFLINE; was=usertable2,,1389159324467.a37e60fd78a3bff2bddac6270f6b317c. state=CLOSED, ts=1389159880663, server=localhost.localdomain,60020,1389159296923

 

 

2014-01-08 13:44:40,736 DEBUG org.apache.hadoop.hbase.master.AssignmentManager: 68 Found an existing plan for usertable2,,1389159324467.a37e60fd78a3bff2bddac6270f6b317c. destination server is localhost.localdomain,60020,1389159296923

2014-01-08 13:44:40,736 DEBUG org.apache.hadoop.hbase.master.AssignmentManager: 68 Using pre-existing plan for region usertable2,,1389159324467.a37e60fd78a3bff2bddac6270f6b317c.; plan=hri=usertable2,,1389159324467.a37e60fd78a3bff2bddac6270f6b317c., src=, dest=localhost.localdomain,60020,1389159296923

2014-01-08 13:44:40,736 DEBUG org.apache.hadoop.hbase.master.AssignmentManager: 68 Assigning region usertable2,,1389159324467.a37e60fd78a3bff2bddac6270f6b317c. to localhost.localdomain,60020,1389159296923

 

 

2014-01-08 13:44:40,762 DEBUG org.apache.hadoop.hbase.zookeeper.ZKAssign: master:60000-0x1437058a1d60005 Creating (or updating) unassigned node for eff0a14a56f0750278268d6bb49f35e0 with OFFLINE state

2014-01-08 13:44:40,770 DEBUG org.apache.hadoop.hbase.master.AssignmentManager: 68 update region usertable2,,1389159324467.a37e60fd78a3bff2bddac6270f6b317c. to PENDING_OPEN

2014-01-08 13:44:40,770 FATAL org.apache.hadoop.hbase.master.HMaster: Master server abort: loaded coprocessors are: []

2014-01-08 13:44:40,771 FATAL org.apache.hadoop.hbase.master.HMaster: 69 Unexpected state : usertable2,,1389159324467.a37e60fd78a3bff2bddac6270f6b317c. state=PENDING_OPEN, ts=1389159880770, server=localhost.localdomain,60020,1389159296923 .. Cannot transit it to OFFLINE.

java.lang.IllegalStateException: 69 Unexpected state : usertable2,,1389159324467.a37e60fd78a3bff2bddac6270f6b317c. state=PENDING_OPEN, ts=1389159880770, server=localhost.localdomain,60020,1389159296923 .. Cannot transit it to OFFLINE.

        at org.apache.hadoop.hbase.master.AssignmentManager.setOfflineInZooKeeper(AssignmentManager.java:1896)

        at org.apache.hadoop.hbase.master.AssignmentManager.assign(AssignmentManager.java:1700)

 

这里也就可以解释为什么master收到了同一个region的两个RS_ZK_REGION_FAILED_OPEN事件,不是zk导致的,而是时序导致的。

<think>好的,我现在要处理用户的问题:“updateDailyNetworkEnabled unexpected state or invalid subid:1”。首先,我需要理解这个错误信息的具体含义。用户提供的错误信息显示在更新每日网络启用状态时遇到了意外的状态或无效的订阅ID(subid:1)。这可能涉及到Android系统中的网络管理或订阅服务相关的代码。 首先,我需要确定这个错误出现的上下文。通常,这类错误可能发生在处理移动数据或网络设置时,特别是在多SIM卡设备上。subid(订阅ID)用于唯一标识不同的SIM卡订阅。如果subid无效,可能是由于SIM卡未正确注册、服务未启动,或者代码中存在逻辑错误导致无法正确处理该subid。 接下来,我需要考虑可能的错误原因。可能的原因包括: 1. **订阅ID无效**:subid=1可能不存在或未激活,例如SIM卡未插入或处于飞行模式。 2. **状态异常**:设备可能处于不适当的状态,例如网络服务未启动或处于中间状态(如正在切换网络模式)。 3. **代码逻辑错误**:处理网络启用的代码可能有缺陷,未能正确验证subid的有效性或处理异常情况。 4. **权限问题**:应用或服务可能没有足够的权限访问网络设置或订阅信息。 5. **资源竞争或并发问题**:多个线程或进程同时修改网络状态,导致状态不一致。 为了深入分析,我需要参考Android系统中相关的模块,如Telephony、ConnectivityService等。例如,updateDailyNetworkEnabled可能涉及NetworkPolicyManagerService或DataUsageController,这些组件负责管理网络数据的启用和统计。 接下来,我应该考虑如何验证这些可能的错误原因。例如: - 检查设备上是否插入了SIM卡,并确认subid=1是否有效。 - 查看系统日志中是否有其他相关错误或警告,可能提供更多的上下文信息。 - 检查代码中处理subid的地方是否有空指针异常或无效的参数检查。 - 确认调用updateDailyNetworkEnabled的方法是否传入了正确的subid,并且在调用前进行了有效性验证。 - 查看权限声明,确保应用或服务具有必要的权限,如MODIFY_PHONE_STATE或ACCESS_NETWORK_STATE。 此外,可能需要参考Android的源码,特别是涉及网络启用和订阅管理的部分。例如,在NetworkPolicyManagerService中,可能会有处理网络启用状态的方法,检查这些方法是否正确处理了各种subid的情况。 如果这是一个厂商定制的ROM,可能存在特定的实现差异,需要检查厂商的补丁或修改是否引入了问题。例如,厂商可能在更新网络状态时添加了额外的条件检查,导致某些情况下subid被错误地视为无效。 对于开发者来说,解决这个问题可能需要: 1. **日志分析**:检查完整的日志,寻找导致subid无效的前置条件或错误链。 2. **代码审查**:查看updateDailyNetworkEnabled方法及其调用栈,确认参数传递和状态检查的正确性。 3. **单元测试**:编写测试用例,模拟不同的subid状态和设备状态,验证代码的健壮性。 4. **补丁应用**:如果发现问题代码,可能需要添加subid有效性检查,或处理异常状态的逻辑。 最后,我需要确保提供的解答和相关问题符合用户的要求,即使用中文回答,并在末尾列出3-5个相关问题,格式正确。</think>该日志记录了Android系统网络管理模块中`updateDailyNetworkEnabled`方法执行时遇到的异常状态或无效订阅ID(subid:1)错误。以下是深度解析: --- ### **1. 核心信息解析** - **错误场景**:网络启用状态更新失败 - **关键参数**: - `subid:1` → 订阅ID=1(通常对应主SIM卡) - `unexpected state` → 当前设备或网络服务处于异常状态 --- ### **2. 关键字段深度解读** #### **(1) 订阅ID有效性验证** ```java // 订阅ID检查逻辑(伪代码) if (!SubscriptionManager.isValidSubscriptionId(subId)) { Log.e("NetworkPolicy", "invalid subid: " + subId); return false; } // 订阅状态同步检查 if (!isSubIdRegistered(subId) || isSubIdInactive(subId)) { Log.w("NetworkPolicy", "subscription not ready: " + subId); scheduleRetry(); // 延迟重试机制 } ``` #### **(2) 网络状态异常处理** ```java // 网络服务状态机检查 if (networkServiceState != SERVICE_ACTIVE) { Log.e("Connectivity", "service not active: " + networkServiceState); throw new NetworkStateException("Service in invalid state"); } ``` --- ### **3. 关键流程关联分析** #### **(1) 典型错误触发场景** | 场景 | 日志特征 | 技术原因 | |---------------------|------------------------------|------------------------------| | SIM卡未就绪 | `subid:1 but SIM_ABSENT` | 物理SIM卡未插入或检测失败 | | 多订阅冲突 | `subid:1 vs active subid:2` | 双卡设备订阅状态不同步 | | 网络服务初始化中 | `NetworkPolicy not ready` | 服务启动未完成时的早期调用 | | 权限不足 | `Permission Denial` | 缺少`MODIFY_NETWORK_STATE`权限 | #### **(2) 状态转换路径** ``` NetworkService.ENABLE_START → validateSubscription(subId) → if invalid: log error → updateDailyNetworkEnabled FAILED ``` --- ### **4. 调试与问题定位** #### **(1) 订阅状态检查** ```bash # 查看当前订阅信息 adb shell dumpsys iphonesubinfo # 强制刷新订阅状态 adb shell service call phone 23 i32 1 ``` #### **(2) 网络服务诊断** ```bash # 检查网络策略服务状态 adb shell dumpsys network_policy | grep "mServiceState" # 触发网络状态更新 adb shell am broadcast -a android.net.conn.CONNECTIVITY_CHANGE ``` #### **(3) 典型修复策略** ```java // 增强的订阅验证逻辑 boolean safeUpdate(int subId) { if (!SubscriptionManager.isValidSubscriptionId(subId)) { Log.w("Network", "Skipping invalid subId: " + subId); return false; } if (!isSubscriptionReady(subId)) { Log.i("Network", "Scheduling retry for subId: " + subId); retryHandler.postDelayed(() -> updateDailyNetworkEnabled(subId), 500); return false; } return true; } ``` --- ### **5. 厂商定制扩展** #### **(1) 小米MIUI网络管理** - **订阅优先级策略**: ```xml <!-- 双卡配置(miui_network_config.xml) --> <subscription_priority> <default_data_sub>1</default_data_sub> <!-- 默认数据卡 --> <fallback_sub>2</fallback_sub> <!-- 备用卡 --> </subscription_priority> ``` #### **(2) 华为智能切换** ```java // 订阅状态自愈逻辑 void handleSubscriptionLoss(int subId) { if (isDualSimDevice() && subId == 1) { switchToSecondarySub(2); // 自动切换到备用卡 } else { triggerSimRecovery(); // SIM卡恢复流程 } } ``` --- ### **6. 开发者注意事项** #### **(1) 状态同步优化** ```java // 防御性编程实践 void updateNetworkState(int subId) { if (!isSystemReady() || !isRadioAvailable()) { Log.d("Network", "Postponing update until radio ready"); return; } // 安全执行网络更新 } ``` #### **(2) 异常处理机制** ```java // 重试策略设计 int retryCount = 0; while (retryCount++ < MAX_RETRIES) { if (updateDailyNetworkEnabled(subId)) { break; } Thread.sleep(RETRY_INTERVAL); } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值