美文网首页
Processlist的Host字段为%

Processlist的Host字段为%

作者: 左轮Lee | 来源:发表于2023-03-28 16:42 被阅读0次
    DB version: 8.0.25 - 阿里RDS

    监控收到一条告警信息,于是连上DB查看Processlist processlist.png

    发现一条慢查询,USER字段为root账号,HOST字段是%,觉得很诡异:
    1.root账号密码只有本人持有,应用连接是另外一个单独账号
    2.HOST字段来源IP是%,正常情况下应该是IP地址才对
    3.此SQL执行为何这么久?

    针对以上第3个问题,排查到为SQL中调用了一个函数,如果函数的入参为NULL则会导致执行死循环,也正是调用了函数,才会出现USER=‘yd_root’和HOST=‘%’的情况。

    后面在阿里云 RDS 文档找到一篇关于%的说明,在最下面常见问题,链接:https://help.aliyun.com/document_detail/94842.html?spm=5176.2020520104.0.0.1155709akPIYwv 文章中提到调用存储过程可能会出现,经测试,发现调用存过,函数,Event的时候都会出现类似情况,其他场景暂没想到。

    测试前先创建一个临时账号:

    create user test_user@'%' identified by "test_user";
    grant all on *.* to test_user@'%' ;
    

    1.测试调用存过

    -- session1: 登录root账号
    # 创建存储过程,其中 DEFINER=`root`@`%`
    USE test;
    DELIMITER $$
    DROP PROCEDURE IF EXISTS `das` $$
    CREATE DEFINER=`root`@`%` PROCEDURE `das`()
    BEGIN
    SELECT * FROM information_schema.processlist WHERE Id = CONNECTION_ID();
    END $$
    DELIMITER;
    
    # session2: 登录test_user账号执行存储过程,得到预期结果的USER和HOST
    USE test;
    CALL das();
    ID    USER    HOST    DB    COMMAND    TIME    STATE    INFO
    178616    root    %:52958    test    Query    0    executing    SELECT * FROM information_schema.processlist WHERE Id = CONNECTION_ID()
    
    # session3: 用root账号执行存过会得到正确的HOST
    结果略
    

    2.测试调用函数

    -- session1: 登录root账号
    # 创建函数,其中 DEFINER=`root`@`%`
    USE test;
    DELIMITER $$
    DROP FUNCTION IF EXISTS `das` $$
    CREATE DEFINER=`root`@`%` FUNCTION `das`(cid int) RETURNS VARCHAR(100)
    BEGIN
    declare v_user VARCHAR(50) ;
    declare v_host VARCHAR(50) ;
     SELECT user,host into  v_user,v_host FROM information_schema.processlist WHERE Id = cid;
    return concat('USER:',v_user,'       ','HOST:',v_host);
    END $$
    DELIMITER;
    
    # session2: 登录test_user账号执行函数,得到预期结果的USER和HOST
    USE test;
    select das(CONNECTION_ID()) as res ;
    res
    USER:root       HOST:%:52958
    
    # session3: 用root账号执行函数会得到正确的HOST
    结果略
    

    3.测试调用event
    event不涉及 存过 或者 函数 的时候是不会出现HOST字段%的情况的

    #模拟下event调用存过出现`%`的场景:
    
    # 登录root账号,创建表及存储过程
     use test ;
     create table t_event(id int auto_increment PRIMARY key ,  name VARCHAR(10)) ;
    
    # 创建存储过程,其中 DEFINER=`root`@`%`
    use test;
    DELIMITER $$
    DROP PROCEDURE IF EXISTS `das` $$
    CREATE DEFINER=`root`@`%` PROCEDURE `das`()
    BEGIN
    insert into t_event (name) select concat(sleep(2),'ccc');
    END $$
    DELIMITER;
    
    # 创建event
    use test;
    CREATE  DEFINER=`root`@`%` EVENT IF NOT EXISTS `test`.`t_event`
    ON SCHEDULE
    EVERY '2' SECOND
    DO call test.das();
    
    # 查看processlist
    SELECT *from information_schema.`PROCESSLIST` where id <>CONNECTION_ID() and info <> '' ;
    ID    USER    HOST    DB    COMMAND    TIME    STATE    INFO
    1487    root    %    test    Connect    1    User sleep    insert into t_event (name) select concat(sleep(2),'ccc')
    
    模拟下event调用函数出现%的场景:
    略
    

    相关文章

      网友评论

          本文标题:Processlist的Host字段为%

          本文链接:https://www.haomeiwen.com/subject/hjgtddtx.html