分析DB2活动日志满的原因及解决DB2日志满方法与避免方案

本文简单地介绍了DB2中日志的使用、活动日志以及首个活动日志的概念、日志满的原因、日志满的诊断、临时处理以及避免办法

日志使用

下图显示了并发事务条件下,日志使用的示意

有3个并发的程序Process 1、Process 2、Process 3。每一个程序都有两个事务。蓝块代表SQL语句,红块代表commit操作,绿块代表rollback操作。每一个向下的箭头都代表日志缓冲区的数据被刷新到日志磁盘上(默认是每一次提交操作都会导致日志缓冲被刷新到磁盘上)。

在T1时刻,事务A commit,日志缓冲区被刷新到磁盘上。
在T2时刻,事务B commit,日志缓冲区被刷新到磁盘上,此时日志X使用完,但由于X中的事务C还没有提交,所以X此时还是活动日志。

在上图中,如果事务C一直没有提交操作,那么日志X将永远是首个活动日志(oldest transaction log),后续的日志也是活动日志,其他应用最终会导致日志满。

活动日志

如果一个日志中包含有未提交的事务,那么这个日志就是活动日志(也有其他情况,比如虽然所有事务已经提交,但对应的更改还没有持久化到磁盘上)。

首个活动日志(First Active Log)

第一个活动日志,首个活动日志之后的日志(也就是编号比首个活动日志大的日志)都是活动日志,可以通过数据库的snapshot查看first active log, current active log, 以及 last active log.

 $ db2 get snapshot for db on sample | grep -i "File number" File number of first active log      = 0 File number of last active log       = 2 File number of current active log     = 0 File number of log being archived     = Not applicable

日志满原因

DB2总的可用活动日志的最大空间是有限制的,当达到限制之后,就会发生日志满的问题,限制为(LOGPRIMARY + LOGSECOND) * LOGFILSIZ * 4KB

日志满的原因无非两种:

1.) 一个小事务hold住了首个活动日志,一直没有提交,导致首个活动日志一直是活动状态,不被释放。这个跟堵车类似,一辆车因发动机故障(事务没有提交)堵住路口(占用首个活动日志),即使后面的车都没有问题(后续事务正常提交),也无法通过路口,且会越积越多,最终导致整个路都堵满车(日志满)。

2.) 有个事务非常大,迅速用尽了所有的日志。

日志满的表现:

首先应用会报出SQL0964C错误:

 $ db2 "insert into test select * from test" DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command. During SQL processing it returned: SQL0964C The transaction log for the database is full. SQLSTATE=57011

其次,db2diag.log中会有以下报错

 2017-03-09-17.24.50.315000+480 E3234873F644     LEVEL: Error PID   : 8532         TID : 13028     PROC : db2syscs.exe INSTANCE: DB2INST1       NODE : 000      DB  : SAMPLE APPHDL : 0-453        APPID: *LOCAL.DB2INST1.170309092321 AUTHID : MIAOQINGSONG     HOSTNAME: ADMINIB-PR7US3I EDUID  : 13028        EDUNAME: db2agent (SAMPLE) FUNCTION: DB2 UDB, data protection services, sqlpgResSpace, probe:2860 MESSAGE : ADM1823E The active log is full and is held by application handle "0-441". Terminate this application by COMMIT, ROLLBACK or FORCE APPLICATION.

日志满的临时处理:

1. 可以通过增加LOGSECOND来临时增加可用的日志大小(修改时需要加上immediate选项使之立即生效);增加LOGPRIMARY并没有用,因为需要重启数据库才能生效。

2. force掉hold住首个活动日志的的应用,在force之前,可以抓取snapshot,看一下这个应用的状态:

 $ db2 get snapshot for database on sample | grep -i oldest Appl id holding the oldest transaction   = 441 $ db2 get snapshot for application agentid 441 Application Snapshot Application handle             = 441 Application status             = UOW Waiting         <<--应用状态为UOW Waiting Status change time             = 2017-03-09 17:23:15.068895 Application code page           = 1386 Application country/region code      = 86 DUOW correlation token           = *LOCAL.DB2INST1.170309092244 Application name              = db2bp.exe Application ID               = *LOCAL.DB2INST1.170309092244 .. Connection request start timestamp     = 2017-03-09 17:22:44.963163 <<--应用连库时间 Connect request completion timestamp    = 2017-03-09 17:22:45.961157 Application idle time           = 4 minutes 7 seconds .. UOW log space used (Bytes)         = 664 Previous UOW completion timestamp     = 2017-03-09 17:22:45.961157 Elapsed time of last completed uow (sec.ms)= 0.000000 UOW start timestamp            = 2017-03-09 17:23:02.770477 <<--当前事务开始时间 UOW stop timestamp             =              <<--当前事务结束时间为空,说明还没有commit UOW completion status           = .. Statement type               = Dynamic SQL Statement Statement                 = Close Section number               = 201 Application creator            = NULLID Package name                = SQLC2K26 Consistency Token             = Package Version ID             = Cursor name                = SQLCUR201 Statement member number          = 0 Statement start timestamp         = 2017-03-09 17:23:15.067789 Statement stop timestamp          = 2017-03-09 17:23:15.068893 Elapsed time of last completed stmt(sec.ms)= 0.000024 Total Statement user CPU time       = 0.000000 Total Statement system CPU time      = 0.000000 .. Dynamic SQL statement text: select * from t1 

<<--一个事务中可能有多条SQL,这个只表示当前正在执行或者最后执行过的SQL,并不能表示就是这条SQL导致了日志满,这里抓取到的是一条SELECT语句,SELECT语句不占用日志。

以上就是分析DB2活动日志满的原因及解决DB2日志满方法与避免方案的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » 数据库