維護目的:
監測數據庫的當前運行狀況,保證數據庫穩定運行。
做好數據庫的日常的備份工作,減輕問題發生時的風險和責任
檢測數據庫的整體運行狀況,對數據庫的性能進行調整,保證數據庫高效的運行。
可以減少緊急故障發生頻率,減少對系統的影響。
盡早發現系統存在的潛在問題,使可能的故障消除在萌芽狀態。
數據庫日常維護的主要內容
監測數據庫運行情況
監控CPU和I/O的使用情況
監控空間的使用情況
監控數據庫的錯誤日志errorlog
制定一個合理的備份計劃
檢查數據庫的一致性
數據庫的排錯
數據庫性能調整
數據庫日常維護的方法
數據庫服務和備份服務的啟動和關閉方法
數據庫和備份服務的啟動
$cd $SYBASE/ASE-12_*/install
$startserver –f RUN_Servername(Servername為你的數據庫服務名)
$startserver –f RUN_Servername_back
數據庫和備份服務的關閉
isql –Usa –Pxxx –Sservername
>shutdown SYB_BACKUP (關閉備份服務)
>go
>use dbname (用戶庫)
>go
>checkpoint
>go
>shutdown
>go
查看sybase用戶的運行環境是否正常
$env
查看SYBASE,SYBASE_ASE,SYBASE_OCS等環境是否正常
查看數據庫服務和備份服務進程是否運行正常
$ps –ef | grep dataserver
$ps –ef | grep backupserver
查看數據庫的版本和補丁信息
$dataserver –v
或是
isql –Usa –Pxxx –Sservername
>select @@version
檢查數據庫的配置是否合理.
檢查數據庫內存分配、鎖個數、存儲過程緩沖、多CPU配置、用戶連接配置、網絡包尺寸等重要參數的設置。
命令:
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”
查看數據庫的用戶,數據庫的鎖狀況
sp_who(用戶)
sp_lock(鎖)
select spid,blocked from sysprocesses where blocked>0(檢查阻塞進程)
查看最早進程,發現不完整事務
select * from master..syslogshold
其中對應的spid為最早的進程,如果最早的進程開始時間距離當前時間已經非常長(如2、3天),則可能該進程有問題,確認后,應該將其kill,下面有一個存儲過程來檢測不完整的事務,可以將該存儲過程放在操作系統的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%,則要看系統使用是否正常還是系統資源配置不夠,具體細節可參考下面數據庫的優化部分。
定期檢查數據庫日志使用的情況,定期清除數據庫的日志
如果數據庫日志滿,則業務無法進行。
sp_helpdb dbname(用戶庫名)
發現數據庫的日志空間不足,應立刻清除已經完成的事務,或是根據需要擴大日志空間。
定期清除日志:
dump tran dbname with truncate_only
可以將上述的命令放在crontab中。
定期檢查磁盤空間的使用。 如果發現操作系統有磁盤分區使用達到100%,應盡快處理。
#df -k
定期檢查數據庫的錯誤日志(errorlog),如果錯誤日志中發現有數據庫的嚴重錯誤,應立即處理。
有計劃的截斷數據庫的錯誤日志。
數據庫運行一定時間后,可以在數據庫沒有業務時,(下班或周末),將數據庫stop后,將錯誤日志更名,然后重新啟動數據庫,產生一個新的數據庫錯誤日志。
在錯誤日志中,以下的錯誤級別為不嚴重錯誤,通常是用戶錯誤,如語法,讀寫權限空間不足等。
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
在錯誤級別17中,要注意錯誤號1105,1105表示空間不足(數據庫數據或是日志)。
在錯誤級別18中,最多的是1608,1608表示一個客戶連接不是正常方式退出的,
這類錯誤不用關注。
以下錯誤級別為嚴重錯誤,通常是系統(數據庫、磁盤損壞、操作系統)錯誤
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
在錯誤日志中,可以按照"Sybase Technical Support"來搜索,
找到的錯誤通常是嚴重錯誤。
檢查數據庫的一致性
檢測系統數據庫、用戶數據庫的數據分配頁物理可用性,檢查數據庫系統表和用戶表的數據完整性,查看是否有表損壞(可能是邏輯也可能是物理的損壞,如磁盤錯誤可能導致數據庫的表損壞)
做數據庫的一致性通常需要單用戶狀態,并且都是一些耗時操作(如果數據庫大的話),因此,這些檢查可以考慮在系統檢修時運行。
dbcc checkalloc(dbname)檢查數據庫的空間分配,必須在單用戶下執行
checkcatalog(dbname) 檢查系統表的一致性
dbcc checkdb(dbname) 檢查用戶數據庫的數據庫一致性(包括系統表和用戶表)
dbcc checktable(tablename) 檢查一張表的數據一致性。
數據庫的備份
數據庫的備份對于日常的維護來說十分重要,系統管理員一定要注意數據庫每天都有成功備份。需要檢查備份的介質(磁盤或是磁帶)是否正常。
備份命令:
dump database to ‘/xx/xxx’ (設備名或是磁盤上的文件名)
用戶可以規劃一個備份的計劃,然后將備份的命令放在crontab 中,讓系統自動定時做數據庫的備份。
數據庫的排錯
數據庫通常的錯誤主要是以下幾種
數據庫服務無法啟動
解決:查看數據庫的錯誤日志,根據錯誤日志找到無法啟動的原因,原因通常是ip地址,端口不對或是被占用,內存配置過大,或是數據庫設備的屬性不對,sybase用戶沒有訪問權限。
數據庫不能恢復(recovery)
解決:查看數據庫的錯誤日志,找到數據庫不能恢復的原因,然后做相應的處理。通常是由于系統突然斷電或是系統非正常關機。
用戶表不能訪問
解決:查看數據庫的錯誤日志,找到不能訪問的原因。通常是由于訪問權限或是表損壞,
最常見的數據庫重大故障分析
根據我們的經驗,除去硬件故障外,造成重大數據庫故障都是因為日志滿,重啟動時異常刪除日志導致,
而日志滿主要是一下幾個原因造成:
1)數據庫配置不合理
主要是內存、鎖的配置不合理。
2)存在不完整的事務或是進程
出現這種情況是由于不完整的事務引起的。引起不完整的事務主要有兩個方面的原因:第一是網絡質量不佳,如果在客戶端向ASE服務端進行事務時,如果網絡突然中斷,會導致事務的不完整。第二是應用程序存在問題,而在這種情況下,重新啟動數據庫服務后,數據庫的恢復可能是非常緩慢的,主要是看日志的大小和事務的類型,(有時用戶為了快速啟動,通常會異常清除數據庫的日志,就有可能會造成數據庫表損壞)所以,在這種情況下千萬不要急于重新啟動數據庫服務。
如果存在不完整的事務,在該事務之后的所有事務都不能被清除,導致數據庫日志滿。
不完整的事務可以從master..syslogshold表中發現,如果其中starttime(最早的事務開始時間)距離當前時間很長,比如一天,一月,則該事務應該是一個不完整的事務,可以將該事務對應的數據庫進程kill。
3)出現過大的事務
這類問題完全是應用或是人為造成的問題。例如一次刪除一個5000萬條記錄的表,導致日志滿。這種情況下重啟動服務,數據庫的恢復也將是十分緩慢的,防止出現這類問題,是將大事務轉換成許多小事務來執行。在事務之間來刪除數據庫的日志。例如手工刪除日志或是將數據庫設置成自動清日志。
數據庫的性能優化
查看數據庫的配置,看能否有不合理的數據庫配置。
查看方法參考上一節查看數據庫的配置。
更新數據庫的統計信息(頁鎖)
update statistics tablename
對行鎖表回收空間(表鎖)
reorg rebuild tablename
做空間回收時需要在系統維護時做
監測數據庫的運行,查看是否阻塞縮
sp_lock
sp_who
select spid,bloced from master..sysprocesses where blocked>0
對數據庫系統運行進行監測,發現可能引起性能差的因素
在系統運行忙或是性能不佳時運行
sp_sysmon “00:10:00”
分析的一些常用工具:
在應用開發或是執行之前,對可能引起問題的語句檢查命令:
set showplan on
set noexec on
這樣,可以看到該語句的執行過程,而該語句并不執行。
set showplan off
set noexec off
off 以上的選項
set statistics io on /off
set statistics time on/off
在語句執行時可以看到I/O的實際情況(包括物理I/O,邏輯I/O)
以上語句基于session
在運行過程中查找可能有問題的語句的命令:
運行幾次 sp_lock
查找其中對表意向鎖 (sh_intent,ex_intent)較長時間的進程,記錄下spid
( 比如,update 一張100萬條記錄中的一條,如果表不使用索引,最終會有一個Ex_row鎖,但在表掃描期間,一直會有一個
Ex_intent意向鎖)
通過spid,可以看到執行命令和執行過程:
dbcc traceon(3604)
go
dbcc sqltext(spid)
go
sp_showplan spid,null,null,null
go
查找阻塞進程:
select spid,blocked from master..sysprocesses where blocked>0
其中blocked 對應阻塞別人的進行,spid對應被阻塞經常,
查看blocked對應進程執行的命令和執行過程
方法同上
查找最耗資源的進程:下面有兩個存儲過程,可以分析在數據庫繁忙時最消耗cpu和i/o資源的數據庫進程,并顯示該進程所執行的語句以及執行的過程,根據執行過程來判斷問題的原因。
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
數據庫版本在 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