📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

为什么这个错误发生 #

retention_lease_invalid_retaining_sequence_number_exception 表示尝试更新保留租约时,新的保留序列号小于现有租约的序列号。保留租约用于确保软删除的文档不会被过早清理。

这个错误可能由以下原因引起:

  1. 序列号递减:尝试用更小的序列号更新租约
  2. 旧副本请求:来自旧副本的恢复请求
  3. 时序混乱:操作的时序混乱导致序列号不正确
  4. 并发操作冲突:并发操作导致序列号冲突
  5. 节点重启后:节点重启后使用旧的序列号
  6. 跨集群复制:跨集群复制时序列号不同步
  7. 分片恢复:分片恢复时序列号不匹配

如何修复这个错误 #

1. 查看现有租约 #

# 查看索引的保留租约信息
GET /<index>/_stats?filter_path=**.retention_leases

# 查看特定分片的租约
GET /<index>/_stats?level=shards&filter_path=**.retention_leases

2. 使用更大的序列号 #

// 确保使用大于当前序列号的值
// 在更新租约前先检查当前序列号
long currentSeqNo = getCurrentRetainingSequenceNumber(leaseId);
long newSeqNo = Math.max(currentSeqNo, proposedSeqNo);
renewRetentionLease(leaseId, newSeqNo, ...);

3. 检查操作顺序 #

# 确保操作的时序正确
# 检查操作日志
grep -i "retention.*lease\|sequence.*number" /path/to/easysearch/logs/easysearch.log | tail -100

4. 同步集群状态 #

# 确保集群状态同步
GET /_cluster/state?filter_path=**.retention_leases

# 等待集群稳定
GET /_cluster/health?wait_for_status=green&timeout=50s

5. 删除并重建租约 #

# 如果租约状态混乱,可能需要删除并重建
# 注意:这可能导致数据丢失

6. 重启节点 #

# 如果节点状态异常,重启可能清理状态
sudo systemctl restart easysearch

# 等待节点启动
GET /_cat/nodes?v

7. 检查跨集群复制 #

# 对于跨集群复制,确保序列号同步
# 查看复制统计
GET /_ccr/stats

8. 使用正确的序列号 #

// 获取当前最大的序列号
long maxSeqNo = getMaxSeqNo();
long newRetainingSeqNo = maxSeqNo + 1;

// 使用新序列号更新租约
retentionLeases.renew(leaseId, newRetainingSeqNo, ...);

9. 实现序列号检查 #

// 在更新租约前检查序列号
long existingSeqNo = getExistingRetainingSequenceNumber(leaseId);
if (proposedSeqNo < existingSeqNo) {
    // 使用现有序列号而非提议的序列号
    proposedSeqNo = existingSeqNo;
}

10. 查看错误日志 #

# 查看租约相关错误日志
grep -i "invalid.*retaining\|sequence.*number" /path/to/easysearch/logs/easysearch.log | tail -100

11. 等待分片恢复完成 #

# 如果分片正在恢复,等待恢复完成
GET /_cat/recovery?v&active_only=true

# 等待恢复完成后再更新租约

12. 验证分片状态 #

# 确保分片状态正常
GET /_cat/shards?v&h=index,shard,prirep,state

# 查看分片统计信息
GET /<index>/_stats?level=shards

13. 处理并发更新 #

// 使用乐观锁处理并发更新
// 或使用同步机制确保更新的原子性
synchronized (leaseLock) {
    long currentSeqNo = getCurrentRetainingSequenceNumber(leaseId);
    if (proposedSeqNo >= currentSeqNo) {
        retentionLeases.renew(leaseId, proposedSeqNo, ...);
    }
}

14. 增加序列号 #

// 如果序列号必须递增,使用增量的方式
long increment = 1000; // 或根据实际需求
long newSeqNo = ((currentSeqNo / increment) + 1) * increment;

15. 联系支持 #

# 如果问题持续存在,可能需要检查:
# - 集群配置
# - 节点版本兼容性
# - 数据完整性

预防措施 #

  • 确保序列号单调递增
  • 检查现有序列号再更新
  • 处理并发更新冲突
  • 监控租约状态
  • 同步集群状态
  • 使用正确的序列号生成策略
  • 实现序列号验证
  • 避免使用旧副本请求
  • 监控跨集群复制状态
  • 测试租约更新逻辑