我爱电脑技术论坛's Archiver

黑侠 发表于 2008-6-30 09:11

讲解Sybase开发和维护必须熟知的日志知识

我们知道,SYBASE SQL Server用事务(Transaction)来跟踪所有数据库的变化。事务是SQL Server的工作单元。一个事务包含一条或多条作为整体执行的T-SQL语句。每个数据库都有自己的事务日志(Transaction Log),即系统表(Syslogs)。事务日志自动记录每个用户发出的每个事务。日志对于数据库的数据安全性、完整性至关重要,我们进行数据库开发和维护必须熟知日志的相关知识。 8P:FF'Z3Sb)P

'pl/Tq;E Z he ,Y/J,T-Im
一、SYBASE SQL Server 如何记录和读取日志信息
}zWG1^/~ ~?3f|T1s1e
n-wcVu.L?N WV7|
SYBASE SQL Server是先记Log的机制。每当用户执行将修改数据库的语句时,SQL Server就会自动地把变化写入日志。一条语句所产生的所有变化都被记录到日志后,它们就被写到数据页在缓冲区的拷贝里。该数据页保存在缓冲区中,直到别的数据页需要该内存时,该数据页才被写到磁盘上。若事务中的某条语句没能完成,SQL Server将回滚事务产生的所有变化。这样就保证了整个数据库系统的一致性和完整性。
r0M,C'b i1Xt!{
%mM8z)c)P `
c|9RS]$w 二、日志设备 ce1b }7ZJ}B
(jE2N q0D

9Xh/e7U6V X[ Log和数据库的Data一样,需要存放在数据库设备上,可以将Log和Data存放在同一设备上,也可以分开存放。一般来说,应该将一个数据库的Data和Log存放在不同的数据库设备上。这样做有如下好处:一是可以单独地备份Backup事务日志;二是防止数据库溢满;三是可以看到Log的空间使用情况。 jR"V2`W x!p6A
{2qc @-r(G q9DE
qZ{\Y$H2o
所建Log设备的大小,没有十分精确的方法来确定。一般来说,对于新建的数据库,Log的大小应为数据库大小的30%左右。Log的大小还取决于数据库修改的频繁程度。如果数据库修改频繁,则Log的增长十分迅速。所以说Log空间大小依赖于用户是如何使用数据库的。此外,还有其它因素影响Log大小,我们应该根据实际操作情况估计Log大小,并间隔一段时间就对Log进行备份和清除。
I z$R-gF"q
!E$a;S&L![&F in*BbZ AFP{s
三、日志的清除 ;Ue2N!Ntt3Y0rxa
DnY8k,Ea%k9?%F2]
'\J+YH"KRz`uXDm
随着数据库的使用,数据库的Log是不断增长的,必须在它占满空间之前将它们清除掉。清除Log有两种方法:
|sS.Z4J9P
K3{Du;|D3jQG,M;p
+V/a;_9F.^ZP [ 1.自动清除法 i#Q4N*wP
5R/o/F Me)LS'A _
oC M;z0eprJC+k
开放数据库选项 Trunc Log on Chkpt,使数据库系统每隔一段时间自动清除Log。此方法的优点是无须人工干预,由SQL Server自动执行,并且一般不会出现Log溢满的情况;缺点是只清除Log而不做备份。
E$r H)WM9R
;F l zUKc m[;tX L*m!s7wD
2.手动清除法 x r*A)]C_
Gy["D{C
6}SY8J7IhO]~
执行命令"dump transaction"来清除Log。以下两条命令都可以清除日志: t GnF'|sC
+H&@:OOi?

-[Z,qt;@-Qe/R+g dump transaction with truncate_only
#s2U)d.U'k O:E/L Xd"b6F.k"eV
dump transaction with no_log 6~Gr'` l/]+iiT+yD
.p6Jlqdl

)[GO }?eI 通常删除事务日志中不活跃的部分可使用"dump transaction with trancate_only"命令,这条命令写进事务日志时,还要做必要的并发性检查。SYBASE提供"dump transaction with no_log"来处理某些非常紧迫的情况,使用这条命令有很大的危险性,SQL Server会弹出一条警告信息。为了尽量确保数据库的一致性,你应将它作为"最后一招"。 na6_;]*Bf
R!_ jv c3Sj,}?2s

Jc%iz&f*VL 以上两种方法只是清除日志,而不做日志备份,若想备份日志,应执行"dump transaction database_name to dumpdevice"命令。
Z8DSM#E2b6t&V
e*DU UHB1e0V$h
%]&cn|C myYi5^$n 四、管理庞大的事务 "](g T*p h!P

7S1Qa|T1D _;ZnC4} c(G.M
有些操作会大批量地修改数据,如大量数据的修改(Update)、删除一个表的所有数据(Delete)、大量数据的插入(Insert),这样会使Log增长速度很快,有溢满的危险。下面笔者给大家介绍一下如何拆分大事务,以避免日志的溢满。 B} VHAtZ

]']H y4Nhrv
qW*x1J+y 例如执行"update tab_a set col_a=0"命令时,若表tab_a很大,则此Update动作在未完成之前就可能使Log溢满,引起1105错误(Log Full),而且执行这种大的事务所产生的独占锁(Exclusive Table Lock),会阻止其他用户在执行Update操作期间修改这个表,这就有可能引起死锁。为避免这些情况发生,我们可以把这个大的事务分成几个小的事务,并执行"dump transaction"动作。 :{l.e;Vgu2B)}

5JS-L0Zu"f/d \*BD;~ Z"h2gt C@$_
上例中的情况就可以分成两个或多个小的事务: qF$?scM2?
'K A*b2~&O7{5^ yU

?2VsXZ.| eR update tab_a set col_a=0 where col_b>x
'{0Y'b\`:P #j8G;D:ph
go ?if5Z5\
7D9tgq;Xfr
dump transaction database_name with truncate_only QU^R\2B

/@f9Eol:Q{ go 5L;vu3]9\~0Vi
eFw-t Y`I+{I7I }
update tab_a set col_a=0 where col_b <=x
9Blw^-J U,a!?q3Z~^R
go /fWzyxJ

-{7s)Eq@)jF0i dump transaction database_name with truncate_only P]6xbQXzL e
:~o+F$x6h4cD5R8B*l!K$sp|;Y
go 5@R,}|5G'PHZ
*E`[D7wI7H&E
p r)Ymks2q
这样,一个大的事务就被分成两个较小的事务。 0N2jY-z,rod

b;c:yTA$q8lGZg ?3x3P d F {.g
按照上述方法可以根据需要任意拆分大的事务。若这个事务需要备份到介质上,则不用"with truncate_only"选项。若执行"dump transaction with truncate_only"命令,应该先执行"dump database"。以此类推,我们可以对表删除、表插入等大事务做相应的拆分。

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.