ASE
数据库日志的管理
1
.
SYBASE ASE
事务日志
SYBASE ASE
的每一个数据库,无论是系统数据库(
master,model, sybsystemprocs, tempdb
),还是用户数据库,都有自己的
transaction log
,每个库都有
syslogs
表。
Log
记录用户对数据库修改的操作,所以如果不用命令清除,
log
会一直增长直至占满空间。清除
log
可用
dump transaction
命令;或者开放数据库选项
trunc log on chkpt
,数据库会每隔一段间隔自动清除
log
。管理好数据库
log
是用户操作数据库必须考虑的一面。
下面就几个方面谈谈
log
及其管理:
一、
ASE
如何记录及读取日志信息
我们知道,
ASE
是先记
log
的机制。
Server Cache Memory
中日志页总是先写于数据页:
Log pages
在
commit ,checkpoint,space needed
时写入硬盘。
Data pages
在
checkpoint,space needed
时写入硬盘。
系统在
recovery
时读每个
database
的
syslogs
表的信息,回退未完成的事务
(transaction)
(数据改变到事务前状态);完成已提交的事务
(transaction)
(数据改变为事务提交后的状态)。在
Log
中记下
checkpoint
点。这样保证整个数据库系统的一致性和完整性。
二、
Transaction logs
和
checkpoint
进程
checkpoint
命令的功能是强制所有
“
脏
”
页(自上次写入数据库设备后被更新过的页)写入数据库设备。自动的
checkpoint
间隔是由
ASE
根据系统活动和系统表
sysconfigures
中的恢复间隔(
recovery interval
)值计算出的。通过指定系统恢复所需的时间总量,恢复间隔决定了
checkpoint
的频率。
如果数据库开放
trunc log on chkpt
选项,则
ASE
在数据库系统执行
checkpoint
时自动清除
log
。但用户自己写入执行的
checkpoint
命令并不清除
log
,即使
trunc log on chkpt
选项开放。只有在
trunc log on chkpt
选项开放时,
ASE
自动执行
checkpoint
动作,才能自动清除
log
。这个自动的
checkpoint
动作在
ASE
中的进程叫做
checkpoint
进程。当
trunc log on chkpt
选项开放时,
checkpoint
进程每隔
60
秒左右清除
log
,而不考虑
recovery interval
设置时间的间隔。
三、
Transaction log
的大小
没有一个十分严格的和确切的方法来确定一个数据库的
log
应该给多大空间。对一个新建的数据库来说,
log
大小为整个数据库大小的
20%
左右。因为
log
记录对数据库的修改,如果修改的动作频繁,则
log
的增长十分迅速。所以说
log
空间大小依赖于用户是如何使用数据库的。
例如:
update,insert
和
delete
的频率
每个
transaction
中数据的修改量
ASE
系统参数
recovery interval
值
log
是否存到介质上用于数据库恢复
还有其它因素影响
log
大小,我们应该根据操作估计
log
大小,并间隔一个周期就对
log
进行备份和清除。
四、检测
log
的大小
若
log
在自己的设备上,
dbcc checktable (syslogs)
有如下信息:
例
:***NOTICE:space used on the log segment is 12.87Mbytes,64.35%
***NOTICE:space free on the log segment is 7.13Mbytes,35.65%
根据
log
剩余空间比例来决定是否使用
dump transaction
命令来备份和清除
log
。
用快速方法来判断
transaction log
满的程度。
1>use database_name
2>go
1>select data_pgs (8,doampg)
2>from sysindexes where id=8
3>go
Note:this query may be off by as many as 16 pages.
在
syslogs
表用
sp_spaceused
命令。
五、
log
设备
一般来说,应该将一个数据库的
data
和
log
存放在不同的数据库设备上。这样做的好处:
可以单独地备份
(back up)transaction log
防止数据库溢满
可以看到
log
空间的使用情况。
[dbcc checktable (syslogs)]
可以镜像
log
设备
六、
log
的清除
数据库的
log
是不断增长的,必须在它占满空间之前清除。前面已经讨论过,清除
log
可以开放数据库选项
trunc log on chkpt
,使数据库系统每隔一段时间间隔自动清除
log
,还可以执行命令
dump transaction
来清除
log.trunc log on chkpt
选项同
dump transaction with truncate_only
命令一样,只是清除
log
而不保留
log
到备份设备上。所以如果只想清除
log
而不做备份,可以使用
trunc log on chkpt
选项及
dump transaction with truncate_only,dump transaction with no_log
命令。若想备份,应做
dump transaction database_name to dumpdevice
。
七、管理大的
transactions
有些操作是大批量地修改数据,
log
增长速度十分快,如:
大量数据修改
删除一个表的所有记录
基于子查询的数据插入
批量数据拷贝
下面讲述怎样使用这些
transaction
使
log
不至溢满:
大量数据修改
例
:
1>update large_tab set col_1=0
2>go
若这个表很大,则此
update
动作在未完成之前就可能使
log
满,引起
1105
错误(
log full
)而且执行这种大的
transaction
所产生的
exclusive table lock
,阻止其他用户在
update
期间修改这个表,这可能引起死锁。为避免这些情况,我们可以把这个大的
transaction
分成几个小的
transactions
,并执行
dump transaction
动作。
上述例子可以分成两个或多个小
transactions.
例如:
1>update large_tab set col1=0
2>where col2
3>go
1>dump transaction database_name with truncate_only
2>go
1>update large_tab set col1=0
2>where col2>=x
3>go
1>dump transaction database_name with truncate_only
2>go
若这个
transaction
需要备份到介质上,则不用
with truncate_only
选项。若执
行
dump transaction with truncate_only
,应该先做
dump database
命令。
删除一个表的所有记录:
例:
1>delete table large_tab
2>go
同样,把整个
table
的记录都删除,要记很多
log
,我们可以用
truncate table
命 令代替上述语句完成相同功能。
1>truncate table large_tab
2>go
这样,表中记录都删除了,而使用
truncate table
命令,
log
只记录空间回收情况,而不是记录删除表中每一行的操作。
基于子查询的数据插入
例:
1>insert new_tab select col1,col2 from large_tab
2>go
同样的方法,对这个大的
transaction
,我们应该处理为几个小的
transactions
。
1>Insert new_tab
2>select col1,col2 from large_tab where col1<=y
3>go
1>dump transaction database_name with truncate_only
2>go
1>insert new_tab
2>select col1,col2 from large_tab where col1>y
3>go
1>dump database database_name with truncate_only
2>go
同样,若想保存
log
到介质上,则
dump transaction
后不加
with truncate_only
选项。若执行
dump transaction with truncate_only
,应该先做
dump database
动作。
批量数据拷贝
在使用
bcp
把数据拷入数据库时,我们可以把这个大的
transaction
变成几个小的
transactions
处理,避免
log
剧增。
开放
trunc log on chkpt
选项
1>use master
2>go
1>sp_dboption database_name,trunc,true
2>go
1>use database_name
2>go
1>checkpoint
2>go
bcp... -b 100 (on unix)
bcp... /batch_size=100(on vms)
关闭
trunc log on chkpt
选项,并
dump database
。
在这个例子中,一个批执行
100
行拷贝。也可以将
bcp
输入文件分成两或多个分开的文件,在每个文件执行后做
dump transaction
来避免
log
满。
若
bcp
使用快速方式(无索引,无
triggers
),这样操作不记
log
,换句话说,
log
只记载空间分配情况。在这种情况下,要先做
dump database
(为恢复数据库用)。若
log
太小,可置
trunc log on chkpt
选项,这样在每次
checkpoint
后清除
log
。
八、
Threshold
和
transaction log
管理
ASE
提供阈值管理功能,它能帮助用户自动监视数据库
log
设备段的自由空间。这方面的详细讨论见
NO.5
技术支持杂志。
log
的管理是灵活而复杂的,我们应该在实践中摸索经验,针对每个数据库的不同情况,不同操作,做不同处理。
2
.
如何截断数据库的事务日志?
事务日志填满数据库中的日志空间后,可能不能使用转储事务日志的办法备份并且清除原来存在的日志,因为转储日志这个动作本身也需要记录日志。
这时候,可以首先使用
dump transaction database_name with truncate_only
命令,该命令只是截断
/
清除事务日志,并不生成实际的备份。
如果不能奏效,可以使用
dump transaction database_name with no_log
命令。该命令也是仅仅清除既有的事务日志,不生成实际的备份文件,且该命令本身不记日志。
如果该命令还不能奏效,应当使用
alter database
命令为此数据库的日志分配额外的空间,随后执行
dump transaction
。
3
.
使用
dump transaction with no_log
的危险性
在命令参考手册中的
dump transaction with no_log
条目下,有一条警告信息告诉你,你应该把这条命令作为没有其它办法时的最后一招才使用它。但是
“
最后一招
”
究竟是什么意思呢?当你使用这条命令时会怎样呢?那你应使用哪条命令来代替它呢?最后,若这条命令如此有问题,为什么
Sybase
却要提供它呢?
Sybase
技术支持建议你定期的
dump
你的
transaction log
。你必须根据你的数据库中记入日志的活动量的大小以及你的数据库的大小来决定
dump
的方式。有些地方按月
dump transaction
;有些地方每夜
dump transaction
。
若你从未做过
dump transaction
,
transaction log
将最终会满。
SQLServer
使用
log
(日志)是出于恢复目的的。当
log
满时,服务器将停止事物的继续进行,因为服务器将不能将这些事物写进日志,而服务器不能运行大多数的
dump tran
命令,因为
ASE
也需在日志中记录这些命令。
这就是为什么当其它
dump tran
命令不能执行时
no_log
可执行的原因。但是想一下
dump transaction with no_log
被设计执行的环境,将不做并发性检查。
若你在对数据库的修改发生时使用
dump transaction with no_log
,你就会冒整个数据库崩溃的风险。在多数情况下,它们被反映成
813
或
605
错误。为了在数据库被修改时,删除
transaction log
中的不活跃部分可使用
dump transaction with truncate_only
。这条命令写进
transaction log
时,并且它还做必要的并发性检查。这两条命令都有与其相关的警告,在命令参考手册中会看到这些警告。请确保在使用其中任一条命令以前,你已理解这些警告和指示。
Sybase
提供
dump transaction with no_log
来处理某些非常紧迫的情况。为了尽量确保你的数据库的一致性,你应将其作为
“
最后一招
”
。
4
.
为什么数据库事务日志满了,使用
dump tran with no_log
仍不能截断日志?
有两种情况,可能出现这个问题。一是应用系统给
ASE
发送了一个用户自定义事务,一直未提交,这个最早活跃事务阻碍系统截断日志。二是客户端向
ASE
发送了一个修改数量大的事务,清日志时,该事务还正在执行之中,此事务所涉及的日志只能等到事务结束后,才能被截掉。
对于第一种情况,只要督促用户退出应用或者提交事务,系统管理员便可清掉日志。因为给
ASE
发送
Dump transaction with no-log
或者
with truncate-only
,它截掉事务日志的非活跃部分。所谓非活跃部分是指服务器检查点之间的所有已提交或回退的事务。而从最早的未提交的事务到最近的日志记录之间的事务日志记录被称为活跃的。从此可以看明,打开的事务能致使日志上涨,因为在最早活跃事务之后的日志不能被截除。
对于第二种情况,道理也同上。只是在处理它时,需慎重从事。如果这个大事务已运行较长时间,应尽量想法扩大数据库日志空间,保证该事务正常结束。若该事务被强行回滚,
ASE
需要做大量的处理工作,往往是正向执行时间的几倍,系统恢复时间长,可能会影响正常使用的时间。