- 浏览: 112577 次
- 性别:
- 来自: 西安
文章分类
最新评论
-
qb345801622:
根据您的办法,成功解决!
解决项目中页面报错问题 -
Visual___Angle:
能说明一下,这个文件保存后,放在那里??我今天也出现这种情况了 ...
microsoft windows script engine必须工作正常 -
csjxhx:
可以问下,你的最后解决问题的那段代码怎么放?放到哪里去了?
解决项目中页面报错问题 -
qq409982078:
谢谢分享 正好可以用
microsoft windows script engine必须工作正常 -
v韧竹v:
...
用Spring提供的JUnit框架扩展对DAO或Service层进行单元测试
事务日志记录数据库中所有对象和数据的改变,在早前版本中最大可达256G,其大小为( logprimary + logsecond ) * logfilsiz,其中logprimary + logsecond的值小于或等于256,logfilsiz的最大为262144,在9.5版本中,日志最大已经可以达到512G,其中logfilsz的大小更改为524286。
我们就对数据库的日志原理和使用中经常遇到的问题以及其解决方法跟大家分享下。
1、DB2数据库的日志原理
事务日志记录数据库中所有对象和数据的改变,在早前版本中最大可达256G,其大小为( logprimary + logsecond ) * logfilsiz,其中logprimary + logsecond的值小于或等于256,logfilsiz的最大为262144,在9.5版本中,日志最大已经可以达到512G,其中logfilsz的大小更改为524286。
DB2数据库的日志分为主日志和辅助日志,其中主日志在第一个连接到达数据库或者数据库被激活后立即分配,而辅助日志在主日志大小不够的时候动态分配。所以需要注意一点,日志所在的文件系统的大小必须大于主日志文件与辅助日志文件的大小之和。
DB2数据库有2种日志配置方式,循环日志与归档日志。
循环日志:这是数据库默认的日志使用方式,主日志用来记录所有的更改,当事务提交后,日志文件会被重用。当主日志文件达到限制时,辅助日志文件将被使用。这种日志方式可以进行崩溃恢复和版本恢复,不能进行前滚恢复,不支持在线备份。
当活动事务的使用空间超过主日志和辅助日志的限制或者日志空间超过磁盘可使用空间,将会得到日志满的错误。
归档日志:启用logarchmetd1、logarchmetd2或打开logretain参数,注意,在9.5版本中,不推荐使用logretain参数,其所有的设置值将被忽略。在数据库归档日志规划时,建议不再使用logretain的方法。日志文件将不会被删除-保持在线或者离线状态。支持前滚恢复和在线备份。
疑问:归档日志下,日志一直保留,持续生成新日志,为什么还会出现日志满的错误?
归档日志下,其可用的活动日志大小依然受到主日志与辅助日志大小之和的限制,所以,即使在归档日志下,日志满的场景与活动日志下是完全一样的。
2、日志使用中的问题与解决方法
在日常使用中,我们遇到最多的问题就是日志满,现在用几个实际的例子来看如何分析和解决日志满的问题,一般的,日志满可以分以下几个场景:
A、 环境准备,并介绍数据库日志使用大小评估方法:
数据库参数设置如下:
日志文件大小(4KB) (LOGFILSIZ) = 10000
主日志文件的数目 (LOGPRIMARY) = 3
辅助日志文件的数目 (LOGSECOND) = 2
日志总大小为200M.
创建测试用表:
C:\Documents and Settings\administrator>db2 "create table test_log(col int, col2 char(10)
,col3 timestamp,col4 varchar(100),col5 varchar(100),col6 varchar(100),col7 varch
ar(100),col8 varchar(100))"
DB20000I SQL命令成功完成。
创建插入数据的存储过程:
C:\Documents and Settings\administrator>db2 -td@ -vf proc_testlog.sql
create procedure proc_testlog(v1 int)
begin
declare time int default 0;
while (time < v1)
do
insert into test_log values(1,'testlog',current timestamp,'testlogtestlogte
stlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestl
og','testlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestl
ogtestlogtestlogtestlog','testlogtestlogtestlogtestlogtestlogtestlogtestlogtestl
ogtestlogtestlogtestlogtestlogtestlogtestlog','testlogtestlogtestlogtestlogtestl
ogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlog','testlogtestl
ogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogt
estlog');
set time = time + 1;
end while;
end
DB20000I SQL命令成功完成。
我们来评估下插入使用日志的情况,以便构造日志满的场景,使用db2pd来查看事务日志的使用。
分别打开2个db2cmd会话窗口,在窗口1中我们执行:
C:\Documents and Settings\administrator>db2 +c call proc_testlog(1)
返回状态 = 0
会话2中执行:
C:\Documents and Settings\administrator>db2pd -db sample -transactions
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:29:20
Transactions:
Address AppHandl [nod-index] TranHdl Locks State Tflag Tflag2
Firstlsn Lastlsn LogSpace SpaceReserved TID
AxRegCnt GXID
0x7FC21A80 7 [000-00007] 2 7 WRITE 0x00000000 0x00000
000 0x000027718800 0x000027718800 110 700 0x000000004F13
1 0
可以看到这个写操作占用的日志大约为700个字节,在回话1中再重复执行上面的命令,会话2中在看db2pd的输出:
C:\Documents and Settings\administrator>db2pd -db sample -transactions
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:45:55
Transactions:
Address AppHandl [nod-index] TranHdl Locks State Tflag Tflag2
Firstlsn Lastlsn LogSpace SpaceReserved TID
AxRegCnt GXID
0x7FC21A80 7 [000-00007] 2 8 WRITE 0x00000000 0x00000
000 0x000028E385B8 0x000028E38806 154 1334 0x000000004F57
1 0
1334-700=634,我们可以这样评估,单个事务每执行一次表插入,插入一行占用的日志约为700字节,在一个事务中,插入多条记录,插入一行记录占用的日志约为634字节,当然,实际上当插入多行时,日志的大小会比计算值略大。
使用这个方法可以根据业务运行情况来评估需要数据库应该配置的日志大小,也可以评估单个大事务需要的日志空间。
根据估算,200M总日志大小,200*1024*1024/635=330781。因此可以一次插入大约33W记录来构造日志满的场景。
B、 事务日志满场景一:当前未提交的事务太大,超过日志的限制。
在会话1中执行:
C:\Documents and Settings\administrator>db2 commit
DB20000I SQL命令成功完成。
提交前面未提交的事务。
C:\Documents and Settings\administrator>db2 +c call proc_testlog(330000)
SQL0964C 数据库的事务日志已满。 SQLSTATE=57011
这时候我打开另外一个session,执行一个不相关的插入操作。
C:\Documents and Settings\administrator>db2 "insert into test values(1112,1,’sdfsdfsdfsdf’,’sdfsdfsdfsdfsdf’,’sdfsdfsdffsdfsd’)
DB21034E 该命令被当作 SQL 语句来处理,因为它是无效的“命令行处理器”命令。在
SQL 处理期间,它返回:
SQL0964C 数据库的事务日志已满。 SQLSTATE=57011
可以看到,当日志满的时候其他的任何记日志的操作都将不能进行,所以整个系统基本处于不可用的状态,除非等事务回滚结束。
OK,事务日志满的情况出现,现在我们就根据日志满的日志,来逆向分析是哪个操作导致的该问题,分析步骤如下:
首先,确定哪个应用的事务占用了大量的日志空间:
在回话2中执行:
C:\Documents and Settings\administrator>db2pd -db sample -transactions
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:02:27
Transactions:
Address AppHandl [nod-index] TranHdl Locks State Tflag Tflag2
Firstlsn Lastlsn LogSpace SpaceReserved TID
AxRegCnt GXID
…..
0x7FC21A80 7 [000-00007] 2 10 WRITE 0x00000000 0x00000
000 0x00003D86000C 0x000048C4FCD0 14014572 201955470 0x000000004F91
1 0
…..
可以看到上面红色部分, AppHandl为7的应用的一个事务占用了大量的日志。如果有多个应用占用了大量的日志,我们可以按照下面的方法逐个分析,看每个应用是执行了什么sql导致的占用如此大的日志。
然后使用db2pd确定这个日志执行了什么语句导致占用了大量的日志:
C:\Documents and Settings\administrator>db2pd -db sample -applications
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:02:36
Applications:
Address AppHandl [nod-index] NumAgents CoorEDUID Status C-
AnchID C-StmtUID L-AnchID L-StmtUID Appid
WorkloadID WorkloadOccID
…..
0x7AED8080 7 [000-00007] 1 1572 UOW-Waiting 0
0 185 1 *LOCAL.DB2.081111100729
1 1
…..
Application handle为7的应用,对应的L-AnchID为185,L-StmtUID为1。在回话2中继续使用db2pd找到对应的sql语句:
db2pd -db sample -dynamic
…..
Dynamic SQL Statements:
Address AnchID StmtUID NumEnv NumVar NumRef NumExe Text
0x7EA7D540 185 1 1 1 1 1 CALL proc_testlog(?)
…
对应AnchID为185, StmtUID为1的语句,是CALL proc_testlog(?),通过上面的分析,我们可以找到,是调用存储过程proc_testlog导致占用了大量的日志,从而找出导致日志满的罪魁祸首。
解决方案:
首先,尽量规避超大事务的操作,对于必须执行的这种大操作,可以考虑是否可以分解成几个事务进行,如果可以,尽量分解为小事务的方式进行;如果业务上不可以分解,是否可以考虑采用不记日志的方式?比如,load代替insert?表针对这个操作,暂时改为不记日志的方式等等。
注意:当进行不记日志的操作时,必须非常清楚这样的操作的影响,比如,归档日志下数据库前滚的影响,hadr与复制的数据同步影响,操作失败结果如何等等。
其次,总有些我们无法预料的操作发生,可能某个维护人员某天发出一个不适当的命令,删除了大量的数据,导致日志满,整个系统无法运行,如何规避这样的操作带来的系统运行影响呢?可以设置参数:max_log和DB2_FORCE_APP_ON_MAX_LOG注册变量。
max_log此参数指示一个事务可以消耗的主日志空间的百分比。该值是为 logprimary 配置参数指定的值的百分比。如果该值设置为 0,那么对一个事务可以消耗的总的主日志空间的百分比没有限制。我们可以配合设置DB2_FORCE_APP_ON_MAX_LOG注册变量来规定如果应用程序违反了 max_log 配置,我们对该应用如何处理,DB2_FORCE_APP_ON_MAX_LOG设置为true,则超过max_log的应用回被强制与数据库断开连接,事务将被回滚,并且将返回错误 SQL1224N。如果 DB2_FORCE_APP_ON_MAX_LOG 注册表变量设置为 FALSE,则违反了max_log设置的的事务将失败,并返回错误 SQL0964N。该应用程序仍然可以提交在工作单元中由先前语句完成的工作,它也可以回滚已完成的工作以撤销该工作单元。
通过次设置我们可以保证即使有大事务操作,总有(1-max_log/100)*log_primary+log_second的日志可以用来处理日常交易,从而避免系统中断。
注意: 由 max_log 配置参数施加的限制不适用于下列 DB2 命令:ARCHIVE LOG、BACKUP DATABASE、LOAD、REORG TABLE(联机)、RESTORE DATABASE 和 ROLLFORWARD DATABASE。
C、 事务日志满场景二:某个事务一直未提交,占用的日志不能被重用,导致日志满
现在看另外一个场景,我在一个会话中执行了如下命令:
C:\Documents and Settings\administrator>db2 +c call proc_testlog(3)
SQL0964C 数据库的事务日志已满。 SQLSTATE=57011
显然,数据库日志已满,于是,根据上面的方法,我找是哪个事务占用了日志。
C:\Documents and Settings\administrator>db2pd -db sample -transactions
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:10:12
Transactions:
Address AppHandl [nod-index] TranHdl Locks State Tflag Tflag2
Firstlsn Lastlsn LogSpace SpaceReserved TID
AxRegCnt GXID
0x7FC21A80 12 [000-00012] 2 7 READ 0x00000000 0x00000
000 0x000000000000 0x000000000000 0 0 0x0000000053A9
1 0
0x7FC22780 13 [000-00013] 3 0 READ 0x00000000 0x00000
000 0x000000000000 0x000000000000 0 0 0x00000000538F
1 0
0x7FC23480 14 [000-00014] 4 0 READ 0x00000000 0x00000
000 0x000000000000 0x000000000000 0 0 0x0000000053BE
1 0
0x7FC24180 15 [000-00015] 5 0 READ 0x00000000 0x00000
000 0x000000000000 0x000000000000 0 0 0x000000005391
1 0
0x7FC24E80 16 [000-00016] 6 0 READ 0x00000000 0x00000
000 0x000000000000 0x000000000000 0 0 0x000000005394
1 0
0x7FC25B80 17 [000-00017] 7 4 WRITE 0x00000000 0x00000
000 0x0000538A93B7 0x0000538A9455 184 408 0x00000000539A
很奇怪,从结果显示,我没有发现任何一个占用大量日志的应用程序,日志的使用显然都非常的小,那为什么日志还会满呢?我们再注意下占用日志的应用,查看下各自使用的日志文件。
C:\Documents and Settings\administrator>db2pd -db sample -logs
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:12:34
Logs:
Current Log Number 4
Pages Written 9498
Method 1 Archive Status n/a
Method 1 Next Log to Archive n/a
Method 1 First Failure n/a
Method 2 Archive Status n/a
Method 2 Next Log to Archive n/a
Method 2 First Failure n/a
Address StartLSN State Size Pages Filename
0x7FBECBD4 0x0000537F0000 0x00000000 10000 10000 S0000000.LOG
0x7FBECC74 0x000055F00000 0x00000000 10000 10000 S0000001.LOG
0x7FBECD14 0x000058610000 0x00000000 10000 10000 S0000002.LOG
0x7EABB2F4 0x00005AD20000 0x00000000 10000 10000 S0000003.LOG
0x7EABB394 0x00005D430000 0x00000000 10000 10000 S0000004.LOG
分析发现,这个占用日志的应用的日志开始lsn为0x0000538A93B7,结束lsn为0x0000538A9455,正好落在第一日志文件中,因为这个事务一直没有被提交,所以S0000000.LOG一直不能被重用,这样业务在将主日志和辅助日志用完后,无法重新开始使用日志文件,导致出现日志满的错误。同样,使用上面的方法,我们可以查找出这个Applications handle为7的一直没有提交的小事务执行的是什么操作。
上面的情况模拟方法:
在一个回话中执行一个小事物,比如
C:\Documents and Settings\administrator>db2 +c "insert into test values ( 1112,1, ’sdfsdfsdfsdf’ , ’sdfsdfsdfsdfsdf’ , ’sdfsdfsdffsdfsd’ )
在另外一个回话中执行占用事务比较大的操作,比如:db2 call proc_testlog(300000),在这个回话中的操作都及时提交,直到配置的日志文件被使用完,再执行小操作db2 call proc_testlog(3),就可以出现上面的日志满的情况。
解决方案:
可以看出,不是日志满的问题一定是由于应用占用大量的日志导致的,一个被忽略的未提交的操作也可能导致系统的日志无法被重用而导致日志满,在应用中,这是我们应该尽量避免的。但是总是如果无法保证所有的操作都及时的提交,我们可以设置num_log_span参数来规避这个问题,参数指定是否对一个事务可以跨越多少个日志文件具有限制以及该限制是多少,当设置这个参数后,未提交的事务所在的日志与当前日志跨越的个数超过这个值,将被中断,从而避免事务长时间存在导致系统日志满。另外大事务可以跨越的日志也不能超过这个限制,所以当设置max_log和num_log_span后,一个事务所可以使用的事务日志将取2者中比较小的值。
当启用了无限活动日志空间时,max_log和 num_log_span 配置参数非常有用。如果打开了无限记录(即,logsecondary 为 -1),那么事务数不受日志文件数的上限(logprimary + logsecond)限制。当到达 logprimary 的值时,DB2 将开始归档活动日志,而不是使事务失败。这样可能会导致问题,例如,有一个长期运行的事务,但一直未落实它(可能是由于应用程序不正确导致的)。如果出现这种情况,那么活动日志空间会不断增长,从而可能使得崩溃恢复性能很差。为了防止这样,可以为 max_log 和/或 num_log_span 配置参数指定值。
注意:系统临时表的使用,系统临时表的数据操作是不记日志的,但是表的定义是有少量日志记录的,所以,临时表定义了一直没操作,不提交也可能会引起部分小日志的一直被占用。
我们就对数据库的日志原理和使用中经常遇到的问题以及其解决方法跟大家分享下。
1、DB2数据库的日志原理
事务日志记录数据库中所有对象和数据的改变,在早前版本中最大可达256G,其大小为( logprimary + logsecond ) * logfilsiz,其中logprimary + logsecond的值小于或等于256,logfilsiz的最大为262144,在9.5版本中,日志最大已经可以达到512G,其中logfilsz的大小更改为524286。
DB2数据库的日志分为主日志和辅助日志,其中主日志在第一个连接到达数据库或者数据库被激活后立即分配,而辅助日志在主日志大小不够的时候动态分配。所以需要注意一点,日志所在的文件系统的大小必须大于主日志文件与辅助日志文件的大小之和。
DB2数据库有2种日志配置方式,循环日志与归档日志。
循环日志:这是数据库默认的日志使用方式,主日志用来记录所有的更改,当事务提交后,日志文件会被重用。当主日志文件达到限制时,辅助日志文件将被使用。这种日志方式可以进行崩溃恢复和版本恢复,不能进行前滚恢复,不支持在线备份。
当活动事务的使用空间超过主日志和辅助日志的限制或者日志空间超过磁盘可使用空间,将会得到日志满的错误。
归档日志:启用logarchmetd1、logarchmetd2或打开logretain参数,注意,在9.5版本中,不推荐使用logretain参数,其所有的设置值将被忽略。在数据库归档日志规划时,建议不再使用logretain的方法。日志文件将不会被删除-保持在线或者离线状态。支持前滚恢复和在线备份。
疑问:归档日志下,日志一直保留,持续生成新日志,为什么还会出现日志满的错误?
归档日志下,其可用的活动日志大小依然受到主日志与辅助日志大小之和的限制,所以,即使在归档日志下,日志满的场景与活动日志下是完全一样的。
2、日志使用中的问题与解决方法
在日常使用中,我们遇到最多的问题就是日志满,现在用几个实际的例子来看如何分析和解决日志满的问题,一般的,日志满可以分以下几个场景:
A、 环境准备,并介绍数据库日志使用大小评估方法:
数据库参数设置如下:
日志文件大小(4KB) (LOGFILSIZ) = 10000
主日志文件的数目 (LOGPRIMARY) = 3
辅助日志文件的数目 (LOGSECOND) = 2
日志总大小为200M.
创建测试用表:
C:\Documents and Settings\administrator>db2 "create table test_log(col int, col2 char(10)
,col3 timestamp,col4 varchar(100),col5 varchar(100),col6 varchar(100),col7 varch
ar(100),col8 varchar(100))"
DB20000I SQL命令成功完成。
创建插入数据的存储过程:
C:\Documents and Settings\administrator>db2 -td@ -vf proc_testlog.sql
create procedure proc_testlog(v1 int)
begin
declare time int default 0;
while (time < v1)
do
insert into test_log values(1,'testlog',current timestamp,'testlogtestlogte
stlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestl
og','testlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestl
ogtestlogtestlogtestlog','testlogtestlogtestlogtestlogtestlogtestlogtestlogtestl
ogtestlogtestlogtestlogtestlogtestlogtestlog','testlogtestlogtestlogtestlogtestl
ogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlog','testlogtestl
ogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogtestlogt
estlog');
set time = time + 1;
end while;
end
DB20000I SQL命令成功完成。
我们来评估下插入使用日志的情况,以便构造日志满的场景,使用db2pd来查看事务日志的使用。
分别打开2个db2cmd会话窗口,在窗口1中我们执行:
C:\Documents and Settings\administrator>db2 +c call proc_testlog(1)
返回状态 = 0
会话2中执行:
C:\Documents and Settings\administrator>db2pd -db sample -transactions
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:29:20
Transactions:
Address AppHandl [nod-index] TranHdl Locks State Tflag Tflag2
Firstlsn Lastlsn LogSpace SpaceReserved TID
AxRegCnt GXID
0x7FC21A80 7 [000-00007] 2 7 WRITE 0x00000000 0x00000
000 0x000027718800 0x000027718800 110 700 0x000000004F13
1 0
可以看到这个写操作占用的日志大约为700个字节,在回话1中再重复执行上面的命令,会话2中在看db2pd的输出:
C:\Documents and Settings\administrator>db2pd -db sample -transactions
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:45:55
Transactions:
Address AppHandl [nod-index] TranHdl Locks State Tflag Tflag2
Firstlsn Lastlsn LogSpace SpaceReserved TID
AxRegCnt GXID
0x7FC21A80 7 [000-00007] 2 8 WRITE 0x00000000 0x00000
000 0x000028E385B8 0x000028E38806 154 1334 0x000000004F57
1 0
1334-700=634,我们可以这样评估,单个事务每执行一次表插入,插入一行占用的日志约为700字节,在一个事务中,插入多条记录,插入一行记录占用的日志约为634字节,当然,实际上当插入多行时,日志的大小会比计算值略大。
使用这个方法可以根据业务运行情况来评估需要数据库应该配置的日志大小,也可以评估单个大事务需要的日志空间。
根据估算,200M总日志大小,200*1024*1024/635=330781。因此可以一次插入大约33W记录来构造日志满的场景。
B、 事务日志满场景一:当前未提交的事务太大,超过日志的限制。
在会话1中执行:
C:\Documents and Settings\administrator>db2 commit
DB20000I SQL命令成功完成。
提交前面未提交的事务。
C:\Documents and Settings\administrator>db2 +c call proc_testlog(330000)
SQL0964C 数据库的事务日志已满。 SQLSTATE=57011
这时候我打开另外一个session,执行一个不相关的插入操作。
C:\Documents and Settings\administrator>db2 "insert into test values(1112,1,’sdfsdfsdfsdf’,’sdfsdfsdfsdfsdf’,’sdfsdfsdffsdfsd’)
DB21034E 该命令被当作 SQL 语句来处理,因为它是无效的“命令行处理器”命令。在
SQL 处理期间,它返回:
SQL0964C 数据库的事务日志已满。 SQLSTATE=57011
可以看到,当日志满的时候其他的任何记日志的操作都将不能进行,所以整个系统基本处于不可用的状态,除非等事务回滚结束。
OK,事务日志满的情况出现,现在我们就根据日志满的日志,来逆向分析是哪个操作导致的该问题,分析步骤如下:
首先,确定哪个应用的事务占用了大量的日志空间:
在回话2中执行:
C:\Documents and Settings\administrator>db2pd -db sample -transactions
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:02:27
Transactions:
Address AppHandl [nod-index] TranHdl Locks State Tflag Tflag2
Firstlsn Lastlsn LogSpace SpaceReserved TID
AxRegCnt GXID
…..
0x7FC21A80 7 [000-00007] 2 10 WRITE 0x00000000 0x00000
000 0x00003D86000C 0x000048C4FCD0 14014572 201955470 0x000000004F91
1 0
…..
可以看到上面红色部分, AppHandl为7的应用的一个事务占用了大量的日志。如果有多个应用占用了大量的日志,我们可以按照下面的方法逐个分析,看每个应用是执行了什么sql导致的占用如此大的日志。
然后使用db2pd确定这个日志执行了什么语句导致占用了大量的日志:
C:\Documents and Settings\administrator>db2pd -db sample -applications
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:02:36
Applications:
Address AppHandl [nod-index] NumAgents CoorEDUID Status C-
AnchID C-StmtUID L-AnchID L-StmtUID Appid
WorkloadID WorkloadOccID
…..
0x7AED8080 7 [000-00007] 1 1572 UOW-Waiting 0
0 185 1 *LOCAL.DB2.081111100729
1 1
…..
Application handle为7的应用,对应的L-AnchID为185,L-StmtUID为1。在回话2中继续使用db2pd找到对应的sql语句:
db2pd -db sample -dynamic
…..
Dynamic SQL Statements:
Address AnchID StmtUID NumEnv NumVar NumRef NumExe Text
0x7EA7D540 185 1 1 1 1 1 CALL proc_testlog(?)
…
对应AnchID为185, StmtUID为1的语句,是CALL proc_testlog(?),通过上面的分析,我们可以找到,是调用存储过程proc_testlog导致占用了大量的日志,从而找出导致日志满的罪魁祸首。
解决方案:
首先,尽量规避超大事务的操作,对于必须执行的这种大操作,可以考虑是否可以分解成几个事务进行,如果可以,尽量分解为小事务的方式进行;如果业务上不可以分解,是否可以考虑采用不记日志的方式?比如,load代替insert?表针对这个操作,暂时改为不记日志的方式等等。
注意:当进行不记日志的操作时,必须非常清楚这样的操作的影响,比如,归档日志下数据库前滚的影响,hadr与复制的数据同步影响,操作失败结果如何等等。
其次,总有些我们无法预料的操作发生,可能某个维护人员某天发出一个不适当的命令,删除了大量的数据,导致日志满,整个系统无法运行,如何规避这样的操作带来的系统运行影响呢?可以设置参数:max_log和DB2_FORCE_APP_ON_MAX_LOG注册变量。
max_log此参数指示一个事务可以消耗的主日志空间的百分比。该值是为 logprimary 配置参数指定的值的百分比。如果该值设置为 0,那么对一个事务可以消耗的总的主日志空间的百分比没有限制。我们可以配合设置DB2_FORCE_APP_ON_MAX_LOG注册变量来规定如果应用程序违反了 max_log 配置,我们对该应用如何处理,DB2_FORCE_APP_ON_MAX_LOG设置为true,则超过max_log的应用回被强制与数据库断开连接,事务将被回滚,并且将返回错误 SQL1224N。如果 DB2_FORCE_APP_ON_MAX_LOG 注册表变量设置为 FALSE,则违反了max_log设置的的事务将失败,并返回错误 SQL0964N。该应用程序仍然可以提交在工作单元中由先前语句完成的工作,它也可以回滚已完成的工作以撤销该工作单元。
通过次设置我们可以保证即使有大事务操作,总有(1-max_log/100)*log_primary+log_second的日志可以用来处理日常交易,从而避免系统中断。
注意: 由 max_log 配置参数施加的限制不适用于下列 DB2 命令:ARCHIVE LOG、BACKUP DATABASE、LOAD、REORG TABLE(联机)、RESTORE DATABASE 和 ROLLFORWARD DATABASE。
C、 事务日志满场景二:某个事务一直未提交,占用的日志不能被重用,导致日志满
现在看另外一个场景,我在一个会话中执行了如下命令:
C:\Documents and Settings\administrator>db2 +c call proc_testlog(3)
SQL0964C 数据库的事务日志已满。 SQLSTATE=57011
显然,数据库日志已满,于是,根据上面的方法,我找是哪个事务占用了日志。
C:\Documents and Settings\administrator>db2pd -db sample -transactions
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:10:12
Transactions:
Address AppHandl [nod-index] TranHdl Locks State Tflag Tflag2
Firstlsn Lastlsn LogSpace SpaceReserved TID
AxRegCnt GXID
0x7FC21A80 12 [000-00012] 2 7 READ 0x00000000 0x00000
000 0x000000000000 0x000000000000 0 0 0x0000000053A9
1 0
0x7FC22780 13 [000-00013] 3 0 READ 0x00000000 0x00000
000 0x000000000000 0x000000000000 0 0 0x00000000538F
1 0
0x7FC23480 14 [000-00014] 4 0 READ 0x00000000 0x00000
000 0x000000000000 0x000000000000 0 0 0x0000000053BE
1 0
0x7FC24180 15 [000-00015] 5 0 READ 0x00000000 0x00000
000 0x000000000000 0x000000000000 0 0 0x000000005391
1 0
0x7FC24E80 16 [000-00016] 6 0 READ 0x00000000 0x00000
000 0x000000000000 0x000000000000 0 0 0x000000005394
1 0
0x7FC25B80 17 [000-00017] 7 4 WRITE 0x00000000 0x00000
000 0x0000538A93B7 0x0000538A9455 184 408 0x00000000539A
很奇怪,从结果显示,我没有发现任何一个占用大量日志的应用程序,日志的使用显然都非常的小,那为什么日志还会满呢?我们再注意下占用日志的应用,查看下各自使用的日志文件。
C:\Documents and Settings\administrator>db2pd -db sample -logs
Database Partition 0 -- Database SAMPLE -- Active -- Up 0 days 00:12:34
Logs:
Current Log Number 4
Pages Written 9498
Method 1 Archive Status n/a
Method 1 Next Log to Archive n/a
Method 1 First Failure n/a
Method 2 Archive Status n/a
Method 2 Next Log to Archive n/a
Method 2 First Failure n/a
Address StartLSN State Size Pages Filename
0x7FBECBD4 0x0000537F0000 0x00000000 10000 10000 S0000000.LOG
0x7FBECC74 0x000055F00000 0x00000000 10000 10000 S0000001.LOG
0x7FBECD14 0x000058610000 0x00000000 10000 10000 S0000002.LOG
0x7EABB2F4 0x00005AD20000 0x00000000 10000 10000 S0000003.LOG
0x7EABB394 0x00005D430000 0x00000000 10000 10000 S0000004.LOG
分析发现,这个占用日志的应用的日志开始lsn为0x0000538A93B7,结束lsn为0x0000538A9455,正好落在第一日志文件中,因为这个事务一直没有被提交,所以S0000000.LOG一直不能被重用,这样业务在将主日志和辅助日志用完后,无法重新开始使用日志文件,导致出现日志满的错误。同样,使用上面的方法,我们可以查找出这个Applications handle为7的一直没有提交的小事务执行的是什么操作。
上面的情况模拟方法:
在一个回话中执行一个小事物,比如
C:\Documents and Settings\administrator>db2 +c "insert into test values ( 1112,1, ’sdfsdfsdfsdf’ , ’sdfsdfsdfsdfsdf’ , ’sdfsdfsdffsdfsd’ )
在另外一个回话中执行占用事务比较大的操作,比如:db2 call proc_testlog(300000),在这个回话中的操作都及时提交,直到配置的日志文件被使用完,再执行小操作db2 call proc_testlog(3),就可以出现上面的日志满的情况。
解决方案:
可以看出,不是日志满的问题一定是由于应用占用大量的日志导致的,一个被忽略的未提交的操作也可能导致系统的日志无法被重用而导致日志满,在应用中,这是我们应该尽量避免的。但是总是如果无法保证所有的操作都及时的提交,我们可以设置num_log_span参数来规避这个问题,参数指定是否对一个事务可以跨越多少个日志文件具有限制以及该限制是多少,当设置这个参数后,未提交的事务所在的日志与当前日志跨越的个数超过这个值,将被中断,从而避免事务长时间存在导致系统日志满。另外大事务可以跨越的日志也不能超过这个限制,所以当设置max_log和num_log_span后,一个事务所可以使用的事务日志将取2者中比较小的值。
当启用了无限活动日志空间时,max_log和 num_log_span 配置参数非常有用。如果打开了无限记录(即,logsecondary 为 -1),那么事务数不受日志文件数的上限(logprimary + logsecond)限制。当到达 logprimary 的值时,DB2 将开始归档活动日志,而不是使事务失败。这样可能会导致问题,例如,有一个长期运行的事务,但一直未落实它(可能是由于应用程序不正确导致的)。如果出现这种情况,那么活动日志空间会不断增长,从而可能使得崩溃恢复性能很差。为了防止这样,可以为 max_log 和/或 num_log_span 配置参数指定值。
注意:系统临时表的使用,系统临时表的数据操作是不记日志的,但是表的定义是有少量日志记录的,所以,临时表定义了一直没操作,不提交也可能会引起部分小日志的一直被占用。
发表评论
-
db2中获取某个表/索引占用空间的大小
2012-04-17 11:24 11257在数据库运维中, ... -
PowerDesigner反向工程操作步骤 及 SQLSTATE = 37000解决方案
2012-04-10 11:12 1202PowerDesigner反向工程操作步骤 1、打开“Pow ... -
db2查询表的最后使用时间
2011-09-06 15:24 2846在本月出账的过程中,出现表空间不足的情况。虽然在出账之前已清理 ... -
使用merge语句更新数据库中的记录
2011-07-29 15:15 3735在平时更新数据时,经常有这样一种更新,即将表中的数据与 ... -
DataStage 如何解决"job is being accessed by another user"错误
2011-05-25 17:34 1770由于网络连接失败或客户端崩溃造成Job被锁定的解决方法 当某 ... -
查看表空间详细信息
2011-04-25 18:43 1368查看表空间详细信息 list tablespaces ... -
用DataStage进行数据整合: 第 1 部分 (转载)
2011-03-03 17:20 1107数据整合的核心内容是从数据源中抽取数据,然后对这些数据进行转化 ... -
db2树形结构sql问题(转)
2010-10-19 17:24 1775今天在论坛中看到一个很有意思的题目,拿来分享一下: 创建tab ... -
db2死锁问题
2010-09-15 18:00 1249今天解决项目中问卷无法导出答案详细内容的问题。出现问题的原因是 ... -
函数中大杂烩
2010-09-03 16:00 632常用日期函数整理: -- ... -
DB2数据库部分日常实用操作----Load 方法装入数据
2010-08-30 18:05 1370由于最近要频繁的load数据,多多少少会遇到一些问题。而 ... -
解决项目中主键重复无法插入数据的问题
2010-08-19 09:22 6868出现此问题是由于这样:表中之前有一些插入的数据,后期经别人导入 ... -
在 DB2 通用数据库中自动生成数值序列(转载)
2010-08-18 17:37 1444原文地址:http://www.360do ...
相关推荐
在DB2中,日志是用于记录数据库中所有事务活动的重要组件,包括所有的修改操作(如插入、更新和删除)。为了保证数据的一致性和完整性,DB2通过日志机制实现了数据恢复功能。然而,随着时间的推移,日志文件会不断...
在DB2中,事务日志(Log Files)是系统的重要组成部分,它记录了所有对数据库的修改操作。如果日志文件大小不合适,可能会导致磁盘空间不足、性能下降甚至数据丢失等问题。因此,合理调整日志文件的大小是必要的。 ...
### DB2数据库事务日志详解及处理方法 #### 一、引言 在数据库管理领域,尤其是对于IBM DB2这样的大型关系型数据库管理系统而言,事务日志管理是至关重要的环节之一。事务日志用于记录数据库中的所有事务操作,确保...
要查看当前的事务日志配置,可以使用db2getdbcfg命令,查看返回结果中的LOGFILSIZ、LOGPRIMARY和LOGSECOND的值,这些值决定了总的事务日志容量。例如,如果当前配置的LOGFILSIZ为1024(表示每个日志文件为4KB),...
DB2 数据库归档日志管理方案 DB2 数据库中的日志文件管理是非常重要的,因为日志文件中包含了数据库的所有操作记录。如果日志文件没有被正确地管理,可能会导致数据库的崩溃和数据丢失。为了解决这个问题,需要对...
事务日志记录是关系数据库系统用来保证数据完整性的关键工具,它记录了所有事务的详细信息,包括事务的开始、修改和结束。本文将深入探讨DB2的日志系统,包括日志的分类、相关参数以及其设置方法。 1. **日志概述**...
Db2 11.5 引入了一个名为高级事务日志空间管理的新特性,这是针对“数据库事务日志已满”这一常见问题的解决方案。在传统的数据库管理中,当事务日志达到其最大容量时,可能导致数据库操作失败,严重影响系统的正常...
这份"db2使用经验积累.rar"压缩包文件显然包含了作者在实际工作中对DB2操作和管理的总结,对于学习和理解DB2的功能、性能优化以及问题解决等方面具有较高的参考价值。 文档中的知识点可能涵盖以下几个方面: 1. **...
DB2是IBM开发的一款关系型数据库管理系统,广泛应用于企业级数据...提供的文档"DB2数据库性能优化的几个小技巧.docx"和"DB2使用经验总结.docx"可能会提供更具体的操作步骤和实战经验,建议详细阅读以获取更全面的知识。
### DB2使用经验积累及心得 #### 前言 本文档主要总结了在首都国际机场、海口梅兰国际机场系统的开发过程中积累的DB2使用经验和心得。这些经验来源于实际项目实践,涉及DB2数据库的多种应用场景和技术细节。所处的...
### DB2使用经验积累 #### 一、DB2专有名词解释 - **Instance(实例)**:DB2实例是DB2数据库系统的核心组件之一,它指的是运行DB2数据库引擎的一个独立进程组。每个实例都有其自己的配置文件和一组运行参数,可以...
### DB2 使用经验积累知识点概览 #### 一、DB2专有名词解释 - **INSTANCE(实例)**:DB2中的实例是指运行DB2数据库管理系统的环境,它为多个数据库提供了一个共享的服务环境。每个实例都有一个独立的进程空间,可以...
在使用DB2的过程中,开发者可能会遇到各种问题,以下是一些关键的知识点和经验分享,旨在帮助你理解和解决DB2使用中可能遇到的困惑。 1. **实例(INSTANCE)**:DB2实例是一个运行中的DB2软件实体,它包含一组共享的...
- 日志管理对于事务处理至关重要,DB2提供了多种日志模式,如正常日志、归档日志等,以满足不同的事务恢复需求。 总之,DB2作为一款强大的数据库管理系统,提供了丰富的功能和灵活的配置选项,适用于各种规模的...
这篇文章将深入探讨DB2的使用经验和一些实用案例,帮助你更好地理解和掌握这个强大的数据库系统。 一、DB2安装与配置 在开始使用DB2之前,我们需要进行安装和配置。DB2提供多种版本,包括个人版、企业版和云版本。...
这份名为“DB2使用经验积累.rar”的压缩包文件显然是一个关于DB2管理与开发的经验分享集合,对于想要深入学习DB2或者正在使用DB2的IT从业者来说,具有很高的参考价值。下面,我们将详细探讨DB2的一些关键知识点。 ...
DB2使用事务日志记录所有对数据库的更改,确保在系统崩溃或异常情况下的数据一致性。日志文件通常位于DB2实例的指定日志路径下。当数据库发生故障时,通过重播日志中的事务,可以进行故障恢复。DB2支持两种日志模式...
4. **滚动前向恢复**:用于将数据库恢复到某个时间点后,并继续处理事务日志中的所有更改。 ```sql db2rollforward <dbname> to <timestamp> on all nodes and stop ``` ### db2move的使用 `db2move`是一个强大...
### DB2数据库使用经验积累 #### 一、前言与背景 本文档总结了一系列关于IBM DB2数据库的使用经验和技巧,这些经验主要来源于在首都国际机场和海口梅兰国际机场系统开发项目中的实践经验。项目的运行环境包括IBM ...