You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GridDB执行用户权限授予时出现TXN_ERROR_NOT_EXIST ERROR 10086求助

GridDB TXN_ERROR_NOT_EXIST (10086) 错误排查与用户权限管理

错误信息

10086 TXN_ERROR_NOT_EXIST ERROR
User/DB administration operation failed. User may not exist. Check the user name.

环境信息

  • 操作系统:Ubuntu 20.04
  • Python版本:3.8
  • GridDB版本:4.5
  • 集群规模:5节点
  • 数据库:集群内单个默认数据库

问题场景

执行以下Python脚本创建用户并授予权限时,create_user提示创建成功,但后续grant_privileges抛出上述10086错误,提示用户不存在:

from griddb_python import StoreFactory, GSException

def create_user(username, password):
    try:
        factory = StoreFactory.get_default()
        gridstore = factory.get_store({
            "host": "239.0.0.1",
            "port": 41999,
            "cluster_name": "defaultCluster",
            "username": "admin",
            "password": "admin"
        })

        # 创建新用户
        user_management = gridstore.get_user_management()
        user_management.create_user(username, password)
        print(f"User '{username}' created successfully.")

    except GSException as e:
        print(f"Operation failed: {e.what()}")
        raise

def grant_privileges(username):
    try:
        factory = StoreFactory.get_default()
        gridstore = factory.get_store({
            "host": "239.0.0.1",
            "port": 41999,
            "cluster_name": "defaultCluster",
            "username": "admin",
            "password": "admin"
        })

        # 为用户授予权限
        user_management = gridstore.get_user_management()
        user_management.grant_role(username, "dbOwner")
        print(f"Privileges granted to user '{username}'.")

    except GSException as e:
        print(f"Operation failed: {e.what()}")
        raise

if __name__ == "__main__":
    create_user("testUser", "password123")
    grant_privileges("testUser")

1. 同脚本创建用户后仍报错的可能原因

  • 集群元数据同步延迟:GridDB分布式集群中,用户创建操作需要同步到所有节点。如果授权操作在同步完成前执行,当前连接的节点可能还未收到用户数据,导致判定用户不存在。
  • 用户创建未实际落地:create_user打印成功但可能因集群内部异常(如节点失联、元数据存储故障)未完成创建,需查看日志确认操作是否真的成功。
  • 独立连接的节点差异:两个函数分别创建独立的gridstore连接,多播地址可能连接到不同节点,第二个连接的节点可能未同步到用户数据。
  • 用户名大小写敏感:GridDB的用户名区分大小写,若创建与授权时用户名大小写不一致(代码中虽一致,但需确认实际执行是否有隐性转换),会导致找不到用户。

2. GridDB用户与权限管理最佳实践

  • 复用连接会话:在同一脚本中执行多个管理操作时,复用同一个gridstore连接,避免因连接不同节点导致的数据不一致。
  • 等待集群同步:执行用户创建/修改后,根据集群规模等待3-5秒再执行依赖操作,确保元数据同步到所有节点。
  • 最小权限原则:避免给普通用户授予dbOwner等高权限角色,根据业务需求分配reader/writer等细分权限。
  • 原子化操作:将用户创建与权限授予放在同一个连接会话中执行,保证操作的连贯性。
  • 定期审计:使用user_management.get_users()和user_management.get_roles(username)定期检查用户权限配置,清理冗余权限。

3. 确保用户存在后执行操作的步骤

添加用户存在性校验

在授权前先查询用户列表,确认目标用户存在:

def grant_privileges(username):
    try:
        factory = StoreFactory.get_default()
        gridstore = factory.get_store({
            "host": "239.0.0.1",
            "port": 41999,
            "cluster_name": "defaultCluster",
            "username": "admin",
            "password": "admin"
        })

        user_management = gridstore.get_user_management()
        # 检查用户是否存在
        users = user_management.get_users()
        if username not in users:
            raise ValueError(f"User '{username}' does not exist.")
        
        user_management.grant_role(username, "dbOwner")
        print(f"Privileges granted to user '{username}'.")

    except (GSException, ValueError) as e:
        print(f"Operation failed: {e}")
        raise

增加重试机制

针对集群同步延迟,添加重试逻辑:

import time

def grant_privileges(username, max_retries=3, retry_delay=1):
    try:
        factory = StoreFactory.get_default()
        gridstore = factory.get_store({
            "host": "239.0.0.1",
            "port": 41999,
            "cluster_name": "defaultCluster",
            "username": "admin",
            "password": "admin"
        })

        user_management = gridstore.get_user_management()
        # 带重试的用户存在性检查
        for attempt in range(max_retries):
            users = user_management.get_users()
            if username in users:
                break
            if attempt < max_retries - 1:
                time.sleep(retry_delay)
        else:
            raise ValueError(f"User '{username}' does not exist after {max_retries} retries.")
        
        user_management.grant_role(username, "dbOwner")
        print(f"Privileges granted to user '{username}'.")

    except (GSException, ValueError) as e:
        print(f"Operation failed: {e}")
        raise

复用连接会话

修改脚本,在主函数中创建一次连接并传递给两个函数:

def create_user_with_conn(gridstore, username, password):
    try:
        user_management = gridstore.get_user_management()
        user_management.create_user(username, password)
        print(f"User '{username}' created successfully.")
    except GSException as e:
        print(f"Operation failed: {e.what()}")
        raise

def grant_privileges_with_conn(gridstore, username):
    try:
        user_management = gridstore.get_user_management()
        users = user_management.get_users()
        if username not in users:
            raise ValueError(f"User '{username}' does not exist.")
        user_management.grant_role(username, "dbOwner")
        print(f"Privileges granted to user '{username}'.")
    except (GSException, ValueError) as e:
        print(f"Operation failed: {e}")
        raise

if __name__ == "__main__":
    factory = StoreFactory.get_default()
    gridstore = factory.get_store({
        "host": "239.0.0.1",
        "port": 41999,
        "cluster_name": "defaultCluster",
        "username": "admin",
        "password": "admin"
    })
    create_user_with_conn(gridstore, "testUser", "password123")
    # 可添加短暂等待应对同步延迟
    time.sleep(2)
    grant_privileges_with_conn(gridstore, "testUser")

4. 排查思路与经验分享

  • 检查集群状态:使用gs_stat命令查看所有节点是否正常运行,确认无离线或故障节点。
  • 查看日志:检查GridDB日志(默认路径/var/lib/griddb/log/下的gs_node.log和gs_cluster.log),查找用户创建操作的隐性错误。
  • 手动验证用户:通过gs_sh工具登录集群,执行list users;命令确认用户是否存在:
    gs_sh -u admin/admin
    > list users;
    
  • 单节点测试:先在单节点GridDB环境中测试脚本,排除分布式同步问题。
  • 指定单个节点连接:将连接地址从多播239.0.0.1改为单个节点的IP,确认是否是特定节点未同步数据。

内容的提问来源于stack exchange,提问作者Samar Mohamed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:59:51