暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【干货攻略】达梦SQL阻塞分析

达梦E学 2023-02-10
1513



前言

我们进行日常巡检或是用户反馈执行SQL语句死或是应用运行缓慢时,首先会想到,在数据库中有没有阻塞的发生然后找到它,记录它,杀掉它让应用恢复正常,分析SQL的合理性并去优化




分析篇



用户报告

执行某条DML语句,发现卡住,很长时间都没有执行完成,比如如下SQL:

    update test set c1=3; --会话1

    猜测可能是某个事务未提交导致相关表锁住,阻塞了本事务的执行,导致等待。



    查询阻塞事务

    一般运维人员都是从这步开始的,查询v$trxwait视图,发现事务69666被事务69667阻塞了,已经阻塞了312秒。




    查询阻塞会话

    根据WAIT_FOR_ID,事务号69667查询哪个会话导致的阻塞问题。


    通过查询可以看到对应会话的SQL_TEXT显示是一条select语句(会话2),并且该会话的状态还是空闲状态(STATE=‘IDLE’),是不是比较疑惑,update为什么会被一个select语句阻塞呢?带着疑问我们可以查询下相关事务锁的信息。



    查询阻塞事务的锁信息
      select * from v$lock where trx_id=69667;


      可以看到该事务存在表id为1100的IX锁和TID的X锁,表明table_id=1100的表进行了数据修改。查询对应ID号的表信息。

        select * from sysobjects where id=1100 ;



        可以看到被上锁的表为TEST。分析到这里我们可以确认trx_id=69667的事务应该是一个混合操作事务,该事务做了数据修改后没有提交,然后又执行了其他的操作(一个事务中可以执行多条SQL),这也就解释了为什么update(会话1)会被select(会话2)SQL语句阻塞,真正阻塞的罪魁祸首应该是与这个select语句在同一事务中的其他修改数据操作。



        查询真正的阻塞SQL
          cat dmsql_DMSERVER_20230110_145721.log | grep “trxid:69667


          注:根据会话2对应的last_recv_time时间,查询事务69667在此时间前执行了哪些SQL。使用日志查询需要开启日志记录。如果日志刷新很快,有很多日志都包含这个事务,

            cat dmsql_DMSERVER_20230110_14*.log | grep “trxid:69667” > tmp/sql.log



            Kill掉问题会话
              sp_close_session(139926142266440); --sid

              在2.2步查询会话时获得
              注:杀掉会话前记得记录问题SQL以及会话的相关信息。



              开启SQL日志记录

              开启SVR_LOG:vi dm.ini --修改如下SVR_LOG=1,执行

                SP_REFRESH_SVR_LOG_CONFIG();

                --刷新生效

                或者执行

                  SP_SET_PARA_VALUE(1,‘SVR_LOG’,1);

                  通过修改SVR_LOG的参数为1,

                  来开启SQL日志功能。



                  修改日志存储配置

                  开启svr_log后,默认会在dm.ini的存放目录下生成一个sqllog.ini文件
                  vi  sqllog.ini --具体配置请参考官方文档,包含日志文件存放目录、大小、个数等。




                  总结篇


                  当用户发生执行某条DML语句长时间异常等待时,可以查询是否发生阻塞。类似场景如下,当进行UPDATE或DELETE时,相关对象如果已经被其他的事务修改过,将会发生阻塞直到其他的事务提交或回滚。


                  经过上述分析,我们可以怀疑与这个select语句在同一事务中还有一个update或delete等操作没有提交。如何查找这个问题SQL,v$sessions中可能看不出来,我们可以通过sql日志去查看(需要开启日志记录功能),根据会话2对应的last_recv_time,我们在sql日志这个时间往前搜索trx_id=69667的事务包含了哪些操作。从而可以告知客户发生问题的根本原因。


                  最后,查出问题SQL语句并记录相关会话信息后,需要杀掉问题会话,即可解除阻塞。如果是DSC集群,杀会话时需要在相应的问题SQL执行的节点执行sp_close_session(sid)语句。


                  ZONG JIE

                  SQL阻塞排查步骤


                  单机和集群都适用)


                  查询阻塞的事务ID
                    select * from v$trxwait order by wait_time desc;

                    --单机

                      select * from v$dsc_trxwait order by wait_time desc;

                      –DSC集群



                      查询阻塞事务的会话信息
                        select sf_get_session_sql(sess_id),* from v$sessions where trx_id=69667;

                        --单机

                          select sf_get_session_sql(sess_id),* from gv$sessions where trx_id=69667;

                          --DSC集群



                          查询问题SQL
                            cat dmsql_xxxxxx.log | grep “trxid:69967

                            –查找问题DML SQL,保留

                            注:需要开启SVR_LOG参数



                            杀掉会话
                              sp_close_session(139926142266440);

                               注:对于DSC,需要在相应的节点执行。

                              其他SQL:

                                select * from v$lock where trx_id=69667;

                                –--可用于查询阻塞事务的相关锁信息





                                普及篇





                                阻塞和死锁的区别?

                                阻塞和死锁是会与并发事务一起发生的两个事件,它们都与锁相关。当一个事务正在占 用某个资源的锁,此时另一个事务正在请求这个资源上与第一个锁相冲突的锁类型时,就会 发生阻塞。被阻塞的事务将一直挂起,直到持有锁的事务放弃锁定的资源为止。死锁与阻塞 的不同之处在于死锁包括两个或者多个已阻塞事务,它们之间形成了等待环,每个都等待其他事务释放锁。



                                阻塞和死锁发生的情形?

                                在DM数据库中,INSERT、UPDATE、DELETE 是最常见的会产生阻塞和死锁的语句: 

                                (1) INSERT 发生阻塞的唯一情况是,当多个事务同时试图向有主键或 UNIQUE 约束的表中 插入相同的数据时,其中的一个事务将被阻塞,直到另外一个事务提交或回滚。一个事务提交时,另一个事务将收到唯一性冲突的错误;一个事务回滚时,被阻塞的事务可以继续执行。 

                                (2) 当 UPDATE 和 DELETE 修改的记录,已经被另外的事务修改过,还未commit时,将会发生阻塞,直到另一个事务提交或回滚。


                                总结

                                新的一年,干货栏目会一如继往的给大家分享达梦数据库的相关知识。如果大家在工作中有好的想法也可以整理成文章发给我们,我们将在公众号分享给大家。新年伊始,让我们一起来学习达梦吧。



                                END


                                达梦知识普及

                                扫码关注我们
                                学习共享
                                知识普及


                                原文:引用自达梦在线体验平台,具体请点击“阅读原文”

                                编辑:crossrainbow

                                排版:哈哈


                                文章转载自达梦E学,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                评论