日志使用 下图显示了并发事务条件下,日志使用的示意 有3个并发的程序Process 1、Process 2、Process 3。每一个程序都有两个事务。蓝块代表SQL语句,红块代表commit操作,绿块代表rollback操作。每一个向下的箭头都代表日志缓冲区的数据被刷新到日志磁盘上(
日志使用 下图显示了并发事务条件下,日志使用的示意
有3个并发的程序Process 1、Process 2、Process 3。每一个程序都有两个事务。蓝块代表SQL语句,红块代表commit操作,绿块代表rollback操作。每一个向下的箭头都代表日志缓冲区的数据被刷新到日志磁盘上(默认是每一次提交操作都会导致日志缓冲被刷新到磁盘上)。
在T1时刻,事务A commit,日志缓冲区被刷新到磁盘上。 在上图中,如果事务C一直没有提交操作,那么日志X将永远是首个活动日志(oldest transaction log),后续的日志也是活动日志,其他应用最终会导致日志满。 活动日志 如果一个日志中包含有未提交的事务,那么这个日志就是活动日志(也有其他情况,比如虽然所有事务已经提交,但对应的更改还没有持久化到磁盘上)。 首个活动日志(First Active Log) 第一个活动日志,首个活动日志之后的日志(也就是编号比首个活动日志大的日志)都是活动日志,可以通过数据库的snapshot查看first active log, current active log, 以及 last active log.
日志满原因 DB2总的可用活动日志的最大空间是有限制的,当达到限制之后,就会发生日志满的问题,限制为(LOGPRIMARY + LOGSECOND) * LOGFILSIZ * 4KB 日志满的原因无非两种: 1.) 一个小事务hold住了首个活动日志,一直没有提交,导致首个活动日志一直是活动状态,不被释放。这个跟堵车类似,一辆车因发动机故障(事务没有提交)堵住路口(占用首个活动日志),即使后面的车都没有问题(后续事务正常提交),也无法通过路口,且会越积越多,最终导致整个路都堵满车(日志满)。 2.) 有个事务非常大,迅速用尽了所有的日志。 日志满的表现: 首先应用会报出SQL0964C错误:
其次,db2diag.log中会有以下报错
日志满的临时处理: 1. 可以通过增加LOGSECOND来临时增加可用的日志大小(修改时需要加上immediate选项使之立即生效);增加LOGPRIMARY并没有用,因为需要重启数据库才能生效。 2. force掉hold住首个活动日志的的应用,在force之前,可以抓取snapshot,看一下这个应用的状态:
<<--一个事务中可能有多条SQL,这个只表示当前正在执行或者最后执行过的SQL,并不能表示就是这条SQL导致了日志满,这里抓取到的是一条SELECT语句,SELECT语句不占用日志。
日志满的避免:
1.)根据抓取到的应用的snapshot,找应用开发人员查看为何不肯提交,这才是避免问题再次出现的根本办法。 补充说明: 查看每个应用使用的日志大小:
也可以通过db2pd -db <dbname> -transactions 查看每个正在使用的日志的情况 重点关注的参数有:
ApplHandl 通过对DB2活动日志满原因的分析我们就可以找到解决此问题的方法同时避免此问题的再次出现 |
2021-07-26
2022-08-12
2022-08-12