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))"
,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
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
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
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记录来构造日志满的场景。