維護(hù)目的:
監(jiān)測數(shù)據(jù)庫的當(dāng)前運(yùn)行狀況,保證數(shù)據(jù)庫穩(wěn)定運(yùn)行。
做好數(shù)據(jù)庫的日常的備份工作,減輕問題發(fā)生時(shí)的風(fēng)險(xiǎn)和責(zé)任
檢測數(shù)據(jù)庫的整體運(yùn)行狀況,對(duì)數(shù)據(jù)庫的性能進(jìn)行調(diào)整,保證數(shù)據(jù)庫高效的運(yùn)行。
可以減少緊急故障發(fā)生頻率,減少對(duì)系統(tǒng)的影響。
盡早發(fā)現(xiàn)系統(tǒng)存在的潛在問題,使可能的故障消除在萌芽狀態(tài)。
數(shù)據(jù)庫日常維護(hù)的主要內(nèi)容
監(jiān)測數(shù)據(jù)庫運(yùn)行情況
監(jiān)控CPU和I/O的使用情況
監(jiān)控空間的使用情況
監(jiān)控?cái)?shù)據(jù)庫的錯(cuò)誤日志errorlog
制定一個(gè)合理的備份計(jì)劃
檢查數(shù)據(jù)庫的一致性
數(shù)據(jù)庫的排錯(cuò)
數(shù)據(jù)庫性能調(diào)整
數(shù)據(jù)庫日常維護(hù)的方法
數(shù)據(jù)庫服務(wù)和備份服務(wù)的啟動(dòng)和關(guān)閉方法
數(shù)據(jù)庫和備份服務(wù)的啟動(dòng)
$cd $SYBASE/ASE-12_*/install
$startserver –f RUN_Servername(Servername為你的數(shù)據(jù)庫服務(wù)名)
$startserver –f RUN_Servername_back
數(shù)據(jù)庫和備份服務(wù)的關(guān)閉
isql –Usa –Pxxx –Sservername
>shutdown SYB_BACKUP (關(guān)閉備份服務(wù))
>go
>use dbname (用戶庫)
>go
>checkpoint
>go
>shutdown
>go
查看sybase用戶的運(yùn)行環(huán)境是否正常
$env
查看SYBASE,SYBASE_ASE,SYBASE_OCS等環(huán)境是否正常
查看數(shù)據(jù)庫服務(wù)和備份服務(wù)進(jìn)程是否運(yùn)行正常
$ps –ef | grep dataserver
$ps –ef | grep backupserver
查看數(shù)據(jù)庫的版本和補(bǔ)丁信息
$dataserver –v
或是
isql –Usa –Pxxx –Sservername
>select @@version
檢查數(shù)據(jù)庫的配置是否合理.
檢查數(shù)據(jù)庫內(nèi)存分配、鎖個(gè)數(shù)、存儲(chǔ)過程緩沖、多CPU配置、用戶連接配置、網(wǎng)絡(luò)包尺寸等重要參數(shù)的設(shè)置。
命令:
sp_configure ‘allocate max shared memory’
sp_configure ‘max memory‘
sp_configure ‘procedure cache size‘
sp_configure ‘user log cache size’
sp_configure ‘default network packet size’
sp_cacheconfig
sp_configure ‘number of user connections‘
sp_configure ‘number of locks‘
sp_configure ‘number of engines at startup’
sp_configure ‘max online engines’
sp_configure “number of open index”
sp_configure “number of open objects”
sp_configure “number of open partitions”
查看數(shù)據(jù)庫的用戶,數(shù)據(jù)庫的鎖狀況
sp_who(用戶)
sp_lock(鎖)
select spid,blocked from sysprocesses where blocked>0(檢查阻塞進(jìn)程)
查看最早進(jìn)程,發(fā)現(xiàn)不完整事務(wù)
select * from master..syslogshold
其中對(duì)應(yīng)的spid為最早的進(jìn)程,如果最早的進(jìn)程開始時(shí)間距離當(dāng)前時(shí)間已經(jīng)非常長(如2、3天),則可能該進(jìn)程有問題,確認(rèn)后,應(yīng)該將其kill,下面有一個(gè)存儲(chǔ)過程來檢測不完整的事務(wù),可以將該存儲(chǔ)過程放在操作系統(tǒng)的crontab中。
create proc proc_kill
@last_min int=720
AS
/*
** kill the processes that didn’t commit for a impossible time
** the parameter's time unit is minute,default is 12 hours
** the procedure is just for user transactions ,not for xa transaction
** you can add this procedure to your opration system crontab
*/
declare @spid int
declare @cspid char(20)
select spid into #killtab from master..syslogshold where datediff(mi,starttime,getdate()) >@last_min and spid>0
declare t1_cur cursor for select * from #killtab
open t1_cur
fetch t1_cur into @spid
while @@sqlstatus!=2
begin
select @cspid=convert(char(20),@spid)
select "kill "+@cspid
exec("kill "+@cspid)
fetch t1_cur into @spid
end
查看CPU和I/O的使用
#sar #iostat
#vmstat
查看Sybase的資源使用
sp_sysmon “00:10:00”
如果CPU或是I/O的使用率長期高于80%,則要看系統(tǒng)使用是否正常還是系統(tǒng)資源配置不夠,具體細(xì)節(jié)可參考下面數(shù)據(jù)庫的優(yōu)化部分。
定期檢查數(shù)據(jù)庫日志使用的情況,定期清除數(shù)據(jù)庫的日志
如果數(shù)據(jù)庫日志滿,則業(yè)務(wù)無法進(jìn)行。
sp_helpdb dbname(用戶庫名)
發(fā)現(xiàn)數(shù)據(jù)庫的日志空間不足,應(yīng)立刻清除已經(jīng)完成的事務(wù),或是根據(jù)需要擴(kuò)大日志空間。
定期清除日志:
dump tran dbname with truncate_only
可以將上述的命令放在crontab中。
定期檢查磁盤空間的使用。 如果發(fā)現(xiàn)操作系統(tǒng)有磁盤分區(qū)使用達(dá)到100%,應(yīng)盡快處理。
#df -k
定期檢查數(shù)據(jù)庫的錯(cuò)誤日志(errorlog),如果錯(cuò)誤日志中發(fā)現(xiàn)有數(shù)據(jù)庫的嚴(yán)重錯(cuò)誤,應(yīng)立即處理。
有計(jì)劃的截?cái)鄶?shù)據(jù)庫的錯(cuò)誤日志。
數(shù)據(jù)庫運(yùn)行一定時(shí)間后,可以在數(shù)據(jù)庫沒有業(yè)務(wù)時(shí),(下班或周末),將數(shù)據(jù)庫stop后,將錯(cuò)誤日志更名,然后重新啟動(dòng)數(shù)據(jù)庫,產(chǎn)生一個(gè)新的數(shù)據(jù)庫錯(cuò)誤日志。
在錯(cuò)誤日志中,以下的錯(cuò)誤級(jí)別為不嚴(yán)重錯(cuò)誤,通常是用戶錯(cuò)誤,如語法,讀寫權(quán)限空間不足等。
10 Status information
11 Specified database object not found
12 Wrong datatype encountered
13 User transaction syntax error
14 Insufficient permissions to execute commands
15 Syntax error in SQL statement
16 Miscellaneous user error
Hardware/software errors
17 Insufficient resources
18 Non-fatal internal error
在錯(cuò)誤級(jí)別17中,要注意錯(cuò)誤號(hào)1105,1105表示空間不足(數(shù)據(jù)庫數(shù)據(jù)或是日志)。
在錯(cuò)誤級(jí)別18中,最多的是1608,1608表示一個(gè)客戶連接不是正常方式退出的,
這類錯(cuò)誤不用關(guān)注。
以下錯(cuò)誤級(jí)別為嚴(yán)重錯(cuò)誤,通常是系統(tǒng)(數(shù)據(jù)庫、磁盤損壞、操作系統(tǒng))錯(cuò)誤
19 Fatal error in resource
20 Fatal error in current process
21 Fatal error in database process
22 Fatal error: table integrity suspect
23 Fatal error: database integrity suspect
24 Hardware error or system table corruption
在錯(cuò)誤日志中,可以按照"Sybase Technical Support"來搜索,
找到的錯(cuò)誤通常是嚴(yán)重錯(cuò)誤。
檢查數(shù)據(jù)庫的一致性
檢測系統(tǒng)數(shù)據(jù)庫、用戶數(shù)據(jù)庫的數(shù)據(jù)分配頁物理可用性,檢查數(shù)據(jù)庫系統(tǒng)表和用戶表的數(shù)據(jù)完整性,查看是否有表損壞(可能是邏輯也可能是物理的損壞,如磁盤錯(cuò)誤可能導(dǎo)致數(shù)據(jù)庫的表損壞)
做數(shù)據(jù)庫的一致性通常需要單用戶狀態(tài),并且都是一些耗時(shí)操作(如果數(shù)據(jù)庫大的話),因此,這些檢查可以考慮在系統(tǒng)檢修時(shí)運(yùn)行。
dbcc checkalloc(dbname)檢查數(shù)據(jù)庫的空間分配,必須在單用戶下執(zhí)行
checkcatalog(dbname) 檢查系統(tǒng)表的一致性
dbcc checkdb(dbname) 檢查用戶數(shù)據(jù)庫的數(shù)據(jù)庫一致性(包括系統(tǒng)表和用戶表)
dbcc checktable(tablename) 檢查一張表的數(shù)據(jù)一致性。
數(shù)據(jù)庫的備份
數(shù)據(jù)庫的備份對(duì)于日常的維護(hù)來說十分重要,系統(tǒng)管理員一定要注意數(shù)據(jù)庫每天都有成功備份。需要檢查備份的介質(zhì)(磁盤或是磁帶)是否正常。
備份命令:
dump database to ‘/xx/xxx’ (設(shè)備名或是磁盤上的文件名)
用戶可以規(guī)劃一個(gè)備份的計(jì)劃,然后將備份的命令放在crontab 中,讓系統(tǒng)自動(dòng)定時(shí)做數(shù)據(jù)庫的備份。
數(shù)據(jù)庫的排錯(cuò)
數(shù)據(jù)庫通常的錯(cuò)誤主要是以下幾種
數(shù)據(jù)庫服務(wù)無法啟動(dòng)
解決:查看數(shù)據(jù)庫的錯(cuò)誤日志,根據(jù)錯(cuò)誤日志找到無法啟動(dòng)的原因,原因通常是ip地址,端口不對(duì)或是被占用,內(nèi)存配置過大,或是數(shù)據(jù)庫設(shè)備的屬性不對(duì),sybase用戶沒有訪問權(quán)限。
數(shù)據(jù)庫不能恢復(fù)(recovery)
解決:查看數(shù)據(jù)庫的錯(cuò)誤日志,找到數(shù)據(jù)庫不能恢復(fù)的原因,然后做相應(yīng)的處理。通常是由于系統(tǒng)突然斷電或是系統(tǒng)非正常關(guān)機(jī)。
用戶表不能訪問
解決:查看數(shù)據(jù)庫的錯(cuò)誤日志,找到不能訪問的原因。通常是由于訪問權(quán)限或是表損壞,
最常見的數(shù)據(jù)庫重大故障分析
根據(jù)我們的經(jīng)驗(yàn),除去硬件故障外,造成重大數(shù)據(jù)庫故障都是因?yàn)槿罩緷M,重啟動(dòng)時(shí)異常刪除日志導(dǎo)致,
而日志滿主要是一下幾個(gè)原因造成:
1)數(shù)據(jù)庫配置不合理
主要是內(nèi)存、鎖的配置不合理。
2)存在不完整的事務(wù)或是進(jìn)程
出現(xiàn)這種情況是由于不完整的事務(wù)引起的。引起不完整的事務(wù)主要有兩個(gè)方面的原因:第一是網(wǎng)絡(luò)質(zhì)量不佳,如果在客戶端向ASE服務(wù)端進(jìn)行事務(wù)時(shí),如果網(wǎng)絡(luò)突然中斷,會(huì)導(dǎo)致事務(wù)的不完整。第二是應(yīng)用程序存在問題,而在這種情況下,重新啟動(dòng)數(shù)據(jù)庫服務(wù)后,數(shù)據(jù)庫的恢復(fù)可能是非常緩慢的,主要是看日志的大小和事務(wù)的類型,(有時(shí)用戶為了快速啟動(dòng),通常會(huì)異常清除數(shù)據(jù)庫的日志,就有可能會(huì)造成數(shù)據(jù)庫表損壞)所以,在這種情況下千萬不要急于重新啟動(dòng)數(shù)據(jù)庫服務(wù)。
如果存在不完整的事務(wù),在該事務(wù)之后的所有事務(wù)都不能被清除,導(dǎo)致數(shù)據(jù)庫日志滿。
不完整的事務(wù)可以從master..syslogshold表中發(fā)現(xiàn),如果其中starttime(最早的事務(wù)開始時(shí)間)距離當(dāng)前時(shí)間很長,比如一天,一月,則該事務(wù)應(yīng)該是一個(gè)不完整的事務(wù),可以將該事務(wù)對(duì)應(yīng)的數(shù)據(jù)庫進(jìn)程kill。
3)出現(xiàn)過大的事務(wù)
這類問題完全是應(yīng)用或是人為造成的問題。例如一次刪除一個(gè)5000萬條記錄的表,導(dǎo)致日志滿。這種情況下重啟動(dòng)服務(wù),數(shù)據(jù)庫的恢復(fù)也將是十分緩慢的,防止出現(xiàn)這類問題,是將大事務(wù)轉(zhuǎn)換成許多小事務(wù)來執(zhí)行。在事務(wù)之間來刪除數(shù)據(jù)庫的日志。例如手工刪除日志或是將數(shù)據(jù)庫設(shè)置成自動(dòng)清日志。
數(shù)據(jù)庫的性能優(yōu)化
查看數(shù)據(jù)庫的配置,看能否有不合理的數(shù)據(jù)庫配置。
查看方法參考上一節(jié)查看數(shù)據(jù)庫的配置。
更新數(shù)據(jù)庫的統(tǒng)計(jì)信息(頁鎖)
update statistics tablename
對(duì)行鎖表回收空間(表鎖)
reorg rebuild tablename
做空間回收時(shí)需要在系統(tǒng)維護(hù)時(shí)做
監(jiān)測數(shù)據(jù)庫的運(yùn)行,查看是否阻塞縮
sp_lock
sp_who
select spid,bloced from master..sysprocesses where blocked>0
對(duì)數(shù)據(jù)庫系統(tǒng)運(yùn)行進(jìn)行監(jiān)測,發(fā)現(xiàn)可能引起性能差的因素
在系統(tǒng)運(yùn)行忙或是性能不佳時(shí)運(yùn)行
sp_sysmon “00:10:00”
分析的一些常用工具:
在應(yīng)用開發(fā)或是執(zhí)行之前,對(duì)可能引起問題的語句檢查命令:
set showplan on
set noexec on
這樣,可以看到該語句的執(zhí)行過程,而該語句并不執(zhí)行。
set showplan off
set noexec off
off 以上的選項(xiàng)
set statistics io on /off
set statistics time on/off
在語句執(zhí)行時(shí)可以看到I/O的實(shí)際情況(包括物理I/O,邏輯I/O)
以上語句基于session
在運(yùn)行過程中查找可能有問題的語句的命令:
運(yùn)行幾次 sp_lock
查找其中對(duì)表意向鎖 (sh_intent,ex_intent)較長時(shí)間的進(jìn)程,記錄下spid
( 比如,update 一張100萬條記錄中的一條,如果表不使用索引,最終會(huì)有一個(gè)Ex_row鎖,但在表掃描期間,一直會(huì)有一個(gè)
Ex_intent意向鎖)
通過spid,可以看到執(zhí)行命令和執(zhí)行過程:
dbcc traceon(3604)
go
dbcc sqltext(spid)
go
sp_showplan spid,null,null,null
go
查找阻塞進(jìn)程:
select spid,blocked from master..sysprocesses where blocked>0
其中blocked 對(duì)應(yīng)阻塞別人的進(jìn)行,spid對(duì)應(yīng)被阻塞經(jīng)常,
查看blocked對(duì)應(yīng)進(jìn)程執(zhí)行的命令和執(zhí)行過程
方法同上
查找最耗資源的進(jìn)程:下面有兩個(gè)存儲(chǔ)過程,可以分析在數(shù)據(jù)庫繁忙時(shí)最消耗cpu和i/o資源的數(shù)據(jù)庫進(jìn)程,并顯示該進(jìn)程所執(zhí)行的語句以及執(zhí)行的過程,根據(jù)執(zhí)行過程來判斷問題的原因。
if exists( select name from sysobjects where type='P' and name='proc_who_do_io')
drop proc proc_who_do_io
go
/* print top n (of physical_io usages) applications 's execute plan and sql */
/* example useage : proc_who_do_io */
create proc proc_who_do_io
@inter_time char(8)='00:00:05',
@topn int=3
as
declare @spid int
select @spid=11
dbcc traceon(3604)
select spid,cmd,physical_io,hostname,program_name into #t1 from master..sysprocesses order
by spid
waitfor delay @inter_time
select spid,cmd,physical_io ,hostname,program_name into #t2 from master..sysprocesses order
by spid
select #t1.spid,#t1.cmd,#t1.program_name,#t1.physical_io as phy_io,#t1.hostname,#t2.physical_io - #t1.physical_io as
phy_io_add into #t3 from #t1,#t2
where #t1.spid=#t2.spid and abs(#t2.physical_io - #t1.physical_io) >2 order by #t2.physical_io - #t1.physical_io desc
select * from #t3
select * into #t4 from #t3 where 1=2
set rowcount 1
while @topn >0
begin
insert #t4 select * from #t3
delete #t3
select @spid=spid from #t4
select "execute plan :"+ str(@spid)
exec sp_showplan @spid,null,null,null
dbcc sqltext(@spid)
delete #t4
select @topn = @topn-1
end
set rowcount 0
go
if exists( select name from sysobjects where type='P' and name='proc_who_use_cpu')
drop proc proc_who_use_cpu
go
/* print top n (of cpu usages) applications 's execute plan and sql */
/* example useage : proc_who_use_cpu */
create proc proc_who_use_cpu
@inter_time char(8)='00:00:05',
@topn int=3
as
declare @spid int
select @spid=11
dbcc traceon(3604)
select spid,cmd,cpu,hostname,program_name into #t1 from master..sysprocesses order
by spid
waitfor delay @inter_time
select spid,cmd,cpu ,hostname,program_name into #t2 from master..sysprocesses order
by spid
select #t1.spid,#t1.cmd,#t1.program_name,#t1.cpu ,#t1.hostname,#t2.cpu - #t1.cpu as
cpu_add into #t3 from #t1,#t2
where #t1.spid=#t2.spid and abs(#t2.cpu - #t1.cpu) >2 order by #t2.cpu - #t1.cpu desc
select * from #t3
select * into #t4 from #t3 where 1=2
set rowcount 1
while @topn >0
begin
insert #t4 select * from #t3
delete #t3
select @spid=spid from #t4
select "execute plan :"+ str(@spid)
exec sp_showplan @spid,null,null,null
dbcc sqltext(@spid)
delete #t4
select @topn = @topn-1
end
set rowcount 0
go
數(shù)據(jù)庫版本在 ASE12.5.0.3以上, 尋找索引使用情況
select s.SPID,s.CpuTime,t.LineNumber,t.SQLText
from monProcessStatement s,monProcessSQLText t
where s.SPID=t.SPID
order by s.CpuTime,s.SPID,t.LineNumber desc