DB2问题分类以及解决思路

来源:互联网 发布:mac air 装单win详细 编辑:程序博客网 时间:2024/06/05 09:16

     在我们日常使用和维护数据库的过程中,肯定会遇到各种不同类型,千奇百怪的问题,现在我就将常见的问题进行分类汇总。


一、DB2实例不能正常启动。

      问题描述:当我们运行db2start时,有时侯会碰到system error 或者一直hang在那里不返回启动成功信息。

       解决问题思路:  1)是不是数据库刚刚升级没有运行db2iupdate 或者db2iupgrade来升级实例

                                           Solution: 在做DB2升级时,正确按照安装文档对实例进行升级

                                   2)是不是上次DB2 实例被非正常终止

                                            Solution:  运行ipclean ,清除db2占用的共享内存和信号量,然后再重启。

                                   3) 是不是安装了HADR +TSA,但是没有安装成功

                                            Solution: 使用db2haicu -delete 先删除TSA,之后进行重新配置

                                    4) 是不是最近更改了实例的一些参数

                                             Solution:主要看是不是设置了实例内存参数,设置过大,调整为Automatic或者合适的值。

                                    5)其他原因

                                            Solution: 查看db2diag, 然后根据错误信息,去db2 support, knowledge center, google上查询具体原因。 IBM内部员工查询内部知识库psDB.

二、实例能正常启动,但是连接不上数据库。

       问题描述:当我们运行db2 connect to DB时,要么碰到错误信息,要么hang在那里

       解决问题思路:  1)是不是活动日志丢失?数据库的活动日志有可能被某些脚本或者人不小心删除。一般来说DB2会在交互界面或者db2diag会有明确的错误信息。

                                        Solution: 活动日志丢失了,真的没有办法。只能用以前的版本进行恢复。 如果没有最近可用的备份,那么需要打800电话开PMR, 将日志控制文件发给

                                          db2实验室, db2实验室会修改日志控制文件后返回来。 将返回的日志控制文件替换原来的文件,数据库就可以正常启动了。 但是这种操作可能会带来数

                                          据不一致或者数据丢失。

                                  2) 数据库主日志(primary log ) ,数据库内存, bufferpool设置过大?

                                          设置太多的主日志个数,会导致在连接数据库的时候需要创建所有这些日志,需要一定的时间,如果空间没有计划好,可能日志文件能占满文件系统。

                                           与内存相关的一些设置,比如database_memory 和bufferpool设置太大都有可能造成DB不能正常连接。 (一般来说bufferpool设置过大,这个bufferpool

                                            自己不能启动,数据库会启动缺省的size比较小的bufferpool)

                                 3) 如果是hang在那里,一定要有些耐心等会。 因为非常有可能是在做前滚和后滚恢复。可以使用db2pd -util来进行监控。 我曾经看到前滚和后滚花了30分

                                      钟,然后正常启动的。

 三、事务日志满

        问题描述: 所有对数据的增删改都不能正常完成, 都会遇到如下信息 “SQL0964C Thetransaction log for the database isfull."

        解决问题思路:  出现此问题的原因:  活动日志已经把LOGPRIMARY + LOGSECOND全部用完, 所以应该按照如下思路解决:

                                 1)此问题经常出现吗,真的是transaction 日志不够吗? 如果以前的确设置的LOGPRIMARY + LOGSECOND很小,可以根据需要进行增加。

                                 2) 更多情况是临时运行了大的事务,而这个的事务做了大量的Insert/update/delete而没有提交,比如一下子更新几千万纪录。 如果是这种情况,

                                        应该更改运行此事务的程序, 将大的事务分解成小的事务,比如要删除1000万条数据,那么我们进行循环删除,每删除10万行,提交一次。

                                        比如以前的SQL是   delete from tab where update_timesamp < current timestamp - 360 days,  如果此表有个主键字段 id 可以改为:

                                                ==>    delete from tab where id in ( select id from tab where update_timesamp < current timestamp - 360 days fetch first 100000 rows only)

                                       注: 可以通过如下方法定位正在运行的大的事务:

                                                 a. 问业务人员,开发人员

                                                 b. db2top  => l (sessions)  找到正在运行的SQL

                                                 c. db2pd -db xxxx -apinfo  > ssapinfo.txt , 通过apinfo查看正在运行的SQL

                                                 d.  $ db2 get snapshot for applications on DBNAME > ssapp.txt

              

                                 3) 虽然没有运行大的事务,但是运行了某个小事务,而此小事务迟迟不提交,导致此小事务之后提交的事务日志也无法变成归档日志,占用活动日志空间。

                                         $ db2 get snapshot for database on saleconn | grep -i oldest

                                            Appl id holding the oldest transaction     =441

                                        $ db2 get snapshot for application agentid 441

                                             Application Snapshot

                                              Application handle                         =441

                                                ....    
                                              Dynamic SQL statement text:      

                                               delete from t1 where xxxx

                                         所以此种情况就需要将此事务force掉  db2 "force application (441)" , 迫使此事务回滚后,才会释放后面的活动日志。

四、 锁的问题

问题描述: 一个运行的job突然间卡住了。日志里发现SQL0911N的错误

        解决问题思路:  出现此问题的原因,要么是发生了锁超时(reason code 68),要么发生了死锁(reason code 2)。所以要弄清楚谁把谁锁住了。

                                  需要重现此问题,在事务被卡住期间,运行:

                                  1) db2pd -db xxx -wlocks,   此命令能看到哪个applicaiton 锁住了哪个application , 然后我们可以找出持有锁的apphandle, 使用

                                           db2 get snapshot for application agentid xxxx  > ssapp.txt 来查看此app的信息(什么时候connect的,当前状态,做了多少insert/update/delete, 执行的

                                             是啥SQL,从哪台机器,什么ID连接到数据库的) ,之后决定是否可以force掉持有锁的appliction.

                                  2)  很多情况下,当我们运行一个job失败后,后台数据库继续执行,甚至hang在那里,持有锁,永远不释放。 这样当我们重新运行此job时,因为获取不到需

                                          要更新数据的锁(被以前的僵死job占用),导致了锁超时。 所以我们需要从数据库端将以前的僵尸 application给force掉。

                                  3) 如果是死锁, 那么这个就得更加小心了,肯定是代码逻辑出了问题, 通过db2pd -db xxx -apinfo > apinfo.txt ,可以比较容易的看出死锁的具体信息。

                                         一般来说都是同类型的job锁住同类型的job,  一般来说都是job内部更改多条数据,而对于更新顺序没有制定,job运行时更新顺序比较随机。造成了死

                                         锁。对于死锁,DBA找出原因后,一定要告诉开发team更改代码。 数据库会有死锁检测器,每10s检测一下,发现死锁,检测器会决定谁胜出。而让另

                                        外一方回滚。

                                 $ db2 get db cfg for saleconn | grep -i deadlock
                                     Interval for checking deadlock (ms)         (DLCHKTIME) = 10000

                                     4)db2 get snapshot for locks on DBNAME会给出详细的锁的信息    


五、 内存问题

      1. 排序堆问题, 运行比较大的查询时,有时候会出SQL0955C的问题, 除非经过很专业的观察和调整,否则建议将排序相关的参数设置为如下值

        DBM 参数

              Sort heap threshold (4KB)                  (SHEAPTHRES) = 0

        DB参数

              Sort heap thres for shared sorts (4KB) (SHEAPTHRES_SHR) = AUTOMATIC
              Sort list heap (4KB)                         (SORTHEAP) = AUTOMATIC

        2. 锁升级问题,如果数据库nofity文件中出现很多lock escalation的消息, 那么需要调整

              DB参数:

               Max storage for lock list (4KB)              (LOCKLIST) = AUTOMATIC(1930272)
               Percent. of lock lists per application       (MAXLOCKS) = AUTOMATIC(97)

        3. Bufferpool的命中率问题:

             如果通过db2pd -db DBNAME -buf , 命中率很低,可能需要调整bufferpool的大小,对于bufferpool,一般建议设置为固定的值,在允许范围内越大越好。而不是让数据库 

               自动分配         

 六、 空间的问题:

            经常遇到表空间不能分配新的页面问题,或者file system full的问题。 就需要对表空间进行详细的设计规划和监控:

             1. 建议使用自动存储,并且尽量使用storage group,增强灵活性。

             2. 对于表空间,设置autosize yes,这样表空间不够就能自动扩充

             3.  当表空间能自动扩从,表空间能存储的数据基本上就决定于 1)表空间存储数据的极限  2)表空间container所在文件系统的大小。

             4. 需要对表的数据条数,表空间大小进行监控和并根据情况设置alert.

  七、性能问题:

          这是一个大大的topic,各方面的问题最终都有可能导致性能问题。下面粗略的说一下:

          1.  性能中最重要的事, runstats + reorg,至少一周做一次。

          2.  如果IO是瓶颈(top /topas/nmon中显示磁盘diskbusy很高,30%以上),要么是应用问题,要么可以使用比较好的存储设备或者SSD盘

          3.  尽量将instance_memory(系统的80%)和database_memory(instance的80%)设置大一些。

          4.  对于数据库表空间的页面设计,尽量要么4K (OLTP),  要么32K (OLAP),这样我们就可以将4K或者32K的bufferpool设置得很大,提高buffer pool 的hit ratio.

          5.  SELECT中能使用with ur的尽量使用,这样减少锁等待。

          6.  数据库的LOGFILSIZ的大小有可能严重影响ETL的性能(对于仓库性能)

          7.  定期运行“PRUNE HISTORY”可能会比较显著的提高整体性能

          8.  通过nmon检查数据库系统的CPU, 内存和存储是不是被其他程序和应用过量占用,从而影响本系统。

          9 .  SQL性能,最最最重要,一条没有经过优化的SQL可以毁掉整个Server, SQL调优可以从如下几方面入手:

                  1)从业务逻辑上优化SQL, 这是最简单的,最有成效的方式。 比如三个表的连接查询,如果从业务逻辑上简化成两个表的连接查询。

                       把没有必要的left outer join 变为inner join. 

                   2)  索引,索引是最重要的SQL优化手段。 可以通过分析Access Plan来查看是否使用了合适的索引。 然后通过db2advis或者自己的经验来创建合适的索引。

                   3)runstats  with distribution, 对于数据仓库系统,数据分布倾斜严重的数据, distribution会带来重要的变化。

                   4) 一定不要让数据库做隐式转换。比如 select xxx from yyy where aa=1 , 而aa是char类型。

                           隐式转换经常让SQL不能使用索引。

                   5) 表与表的连接字段的数据类型最好一致,不一致的时候可能选择的连接方式不正确,nestloop join编程merge join. 从而影响效率。

                   6) in 和 exist , 当 in 里面的value值很多的时候,试试exist,可能会极大的提高性能。

                   7) 尽量减少不必要的排序,比如减少不必要的distinct, order by。 (通过改写SQL或者创建索引)

                   8)   是否适用stmt_con, 如果应用类型是OLTP, 建议enable, 如果是OLAP,不要使用,并且不要使用position parameter.

                   9)

 

         


                                         


               


原创粉丝点击