SYBASE 12.5 維護手冊 3. 技術專刊

3.1 關於Backup Server

 什麼是Backup Server?
Backup Server是一個基於Open Server的工具。它可以處理SQLServer10。0以及更高版本的數據Dump/Load。因爲它是獨立於ASE的處理過程,完成它的工作不依賴於ASE。因此,在聯機數據庫Dump/Load時,不會降低ASE的性能。
 
網絡環境下的Backup Server
Backup Server必須與ASE放在同一臺機器上(如果在Open VMS上,可以在同一簇內)。你也可以如下圖所示的環境,使用分佈在網絡上的兩個Backup Server來完成Dump/Load。這兩個Backup Server一個與ASE放在同一臺機器上另一個可在遠程某一節點上。
 
上圖的配置,可以將本地(Local)的數據庫Dump到遠程(Remote)節點的外部設備上,或者從Remote節點讀取Dump,將數據庫Load到本地的ASE。

當將本地數據庫Dump到遠程機器的設備時,由Local Backup Server讀取數據庫數據,再送到網絡另一端的Remote Backup Server,經它將數據寫到外部設備上。同樣,從遠程設備Load時,load Backup Server發出命令給Remote Backup Server,Remote Backup Server讀取Dump設備內容並傳送到Local Backup Server,由Load Backup Server將讀到的數據寫到數據庫設備。網絡上的Dump性能僅受網絡傳輸能力的影響。

Backup Server新的特性,提高了系統Dump/Load的能力
? 能自動測出設備類型和密度;
? 支持多個SYBASE Dump到同一設備卷;
? 支持一個SYBASE Dump到多個設備卷。

Backup Server支持並行Dump設備
Backup Server支持最大32個Backup設備並行地Dump/Load。亦即可以將一個數據庫分成碎片Dump到多個設備上。ASE並行Dump/Load的設備數受操作系統能打開的最大文件數和共享內存資源的限制。因此,各種不同硬件平臺,不同的操作系統下,並行Dump/Load設備數不同。
多文件(Multi-file),多卷(Multi-volumn)Dump
? 操作系統文件和Raw Partifion是Single_volumn,Single-file的介質,這就是說這兩種設備只能含有一個SYBASE Dump。
? QIC磁帶和可移動硬盤是Single-file,,Multi-Volumn介質,意味着一個Dump可以跨越多個卷。這些設備不允許疊加,如果你想在同一個設備捲上追加存放多個Dump,系統將提示是否覆蓋已有的內容。
? DAT,8mm,9-Track磁帶是Multi-file,multi-volumn設備。以上三種設備可以包含一個或多個數據庫Dump。設備捲上的最後一個Dump可以跨過磁帶,繼續存放在另一設備帶上。
Backup Server在網絡上的Server名稱
  網絡環境中的所有Server必須在Interfaces文件中有一個註冊信息項,包括Server的名字,在網絡中的網絡節點地址及SYBASE Server用的網絡端口號Backup Server也必須將它的信息放在Interfaces文件中。可以用Sybinit來完成這個工作。並且Backup Server的名字也必須加在master數據庫的Sysservers表中。如果你還有一個Remote Backup Server,也需將它的信息放在本地的Interfaces文件中。
  Backup Server項在Interfaces文件和Sysservers表中必須有準確的名字。如果在啓動Backup Server時用-s選項指定了Backup Server的名字,那麼在整個網絡中都要用這個名字來標識這個Backup Server。換言之,在Interfaces文件中,不能使用別名來標識某一個Backup Server。
Backup Server使用的設備
  Backup Server必須使用不回捲(No Rewind)設備,以便Backup Server能夠控制磁帶設備的位置。
  下表列出了某些硬件平臺上的Dump設備名稱。其中N代表了設備號。
Platform Type Device Name
HP9000 4mm(SCSI and /HPIB) /dev/rmt/Num
 9 track (/SCSI and /HPIB) /dev/rmt/Nmn
NCR 8mm /SCSI (5 GB and 2.2 GB) dev/nrmtN
 4mm/SCSI dev/nrmtN
RS6000 9 track /SCSI /dev/rmtN.1
 8mm DAT /SCSI (5 GB and 2.2 GB) /dev/rmtN.1
 QIC /SCSI (1/4?cartridge /dev/rmtN.1
Sun4 9 track /SCSI / dev /nrmtN
 QIC /SCSI (1/4?cartridge) / dev / nrarN
 8mm /SCSI (5 GB and 2.2 GB) / dev / nrstN
Sun4 SVR4
(Solaris) 9 track See un4 SVR4?on page
4-10
 1/4 cartridge
 8mm /SCSI (5 GB and 2..2 GB
VAX VMS 9 track (HSC and /DSSI) See pen VMS?on page
4-10
 8mm (/HSC 5 GB and 2 GB and /DSSI)
 TK50 (HSC and /DSSI)
AXP VMS 8mm / SCSI See pen VMS?on page
4-10
 9 track
 4mm DAT /SCSI
AXP OSF/1 4mm DAT /SCSI See XP OSF/1?on page
4-10
 TZ851
  Table 4-1:Device names for database dumps to tape
3.2 Backup Server的名字
當使用Backup Server做Dump/Load時,系統會自動地尋找SYB_BACKUP這樣的Backup Server名字。這就要求在master庫的sysservers表中必須有一條記錄來描述這個Server,其srvname爲SYB_BACKUP。在安裝Backup Server時,如果使用缺省值,那麼安裝過程將自動生成一個名字爲SYB_BACKUP的Backup Server,同時完成這些操作。
1.master庫的sysservers表中增加一條記錄如下
srvid srvstatus srvname srvnetname
n 0 SYB_BACKUP SYB_BACKUP
2.$SYBASE/interfaces文件中增加一項,servername爲SYB_BACKUP,有它自己的網絡地址和網絡端口號。
3.在$SYBASE/install目錄下,創建啓動Backup Server名爲RUN_SYB_BACKUP的文件。
文件中啓動Backup Server命令的-S選項指明BackupServer在網上的名字爲SYB_BACKUP。

在做Dump/Load時,系統自動地找SYB_BACKUP作爲BackupServer。再根據(1)中指出的srvnetname到interfaces文件中找到server。但是,如果在安裝時未使用SYB_BACKUP作爲Backup Server名字。那麼安裝僅完成以上(2),(3)的操作。例如,你使用MY_BACKUP作爲Backup Server名,則$SYBASE/interfaces中Server名爲MY_BACKUP,啓動Backup Server命令的-S選項參數爲MY_BACKUP。完成(1)的操作,則必須依靠手工完成,在ISQL中,用sa帳號登錄。
1>sp_addserver SYB_BACKUP, null, MY_BACKUP
2>go 
  其中SYB_BACKUP爲固定參數,MY_BACKUP是你指定的網絡上Backup Server的名字。
3.3 Sybase的數據庫設備
數據庫設備是指用於存取數據庫的存儲介質。它既可以是磁盤的一個分區,也可以是文件系統中的一個文件。但無論用哪種作數據庫設備,它們在能被用來存取數據庫對象之前必須初始化。一旦數據庫設備被初始化,該設備就能:
? 爲某個用戶數據庫分配一塊可用空間
? 在爲某用戶數據庫分配的空間內指定並存儲某個特定的數據庫對象
? 用於存儲某數據庫的事務日誌
選擇磁盤分區還是unix文件來作數據庫設備應視具體情況而定。一般來說,如果是最終用戶的數據庫,建議您用磁盤化區而非文件。因爲對磁盤文件,ASE不能確切地知道數據是否真正被寫到文件中去。如果是開發人員的數據庫,那麼用磁盤文件要稍好些,因爲它使得建在其上的數據庫恢復起來要容易一些。但對於master device來講,無論是最終用戶還是開發人員的數據庫,磁盤文件無疑更爲合適。因爲相對而言,對master device的修改更少些而且鏡像更爲方便簡單些。

如果在磁盤分區作數據庫設備,應避免使用柱面0,C,swap分區以及其它已被OS佔用的分區。如果選擇磁盤文件作數據庫設備,要保證SYBASE用戶在相關的目錄下有寫權限。

命令diskinit命令對數據庫設備進行初始化,使得物理上的硬盤分區或文件可以被ASE使用,同時把邏輯設備映射到物理設備上,而每一次disk init執行後,都會在sysdevices系統表中增加一行。其映射關係如圖:
 
disk init的語法:
disk init
name = "device-name",
phyname = "physical-name",
vdevno = virtual - device - number ,
size = number - of - pages
其中:
name: 邏輯設備名
physname: 硬盤分區或磁盤文件名
vdevno: 虛擬設備號。它們取值可以是從1到max configured -1未被使用的任何值。可以用sp_helpdevice或從errorlog文件中查看device。用sp_configure來看max configured的值。最大取值爲255。一般來說,the master device的vdevno 總爲0,如果系統缺省設置最大設備數爲10,而您希望使用更多的邏輯設備,可以重新設置備數限制。
在OS下打入:
這是sql 11.0.X 以下版本的配置
isql -Uxx -Pxx
1) sp_configure " device", 20
2) reconfigure with override
3) go

這個新的配置值必須在Server重新啓動後才生效。若一個數據庫設備被刪除掉後,其vdevno只有在重新啓動Server後才能被新的設備所用。
3.4 數據庫選項(dboptions)的使用與管理
一、概述
ASE能管理多個數據庫,每個數據庫有自己的選項。ASE允許用戶通過設置數據庫選項,來更好地管理和使用數據庫。當大批數據需要加載到數據庫的表時,如果把該庫的Select into/bulkcopy選項設置爲true,同時暫時刪掉表上的索引和觸發器,再使用系統提供的實用程序bcp,數據將以驚人的高速度被裝載到用戶表裏。也曾有用戶抱怨,調用dbwritetext函數不能成功地把一幅bmp圖寫入數據庫的image字段中。原因是用戶數據庫的select into/bulkcopy選項沒有設置成true。還有正在開發數據庫應用的用戶希望日常工作不受數據庫日誌滿的不斷打擾。這也可以通過設置數據庫選項辦到。因此,我們這裏將數據庫選項的設置和用法詳細介紹給讀者,希望它有助於你有效地使用和管理用戶數據庫。

二、數據庫選項的設置
使用系統存貯過程sp_dboption來設置數據庫選項,它的語法規則如下:
sp_dboption [dbname,optname,{true┃false}] 
其中:
? dbname爲用戶所需設置選項的數據庫名稱。如果執行帶參數的sp_dboption,則當前使用的庫必須是master。不帶參數便顯示數據庫選項清單。但是,用戶不能設置master庫的數據庫選項。
? optname爲用戶所要設置或關閉的選項名稱。ASE能識別選項名的任何唯一的字符串。當其名稱爲關鍵字或含嵌入空格或標點符號時,用引號括起來。
? {true┃false}——設置該選項時爲true,關閉該選項時爲false。

使用sp_dboption,能設置以下數據庫選項:
? abort tran on log is full 
? allow null by default 
? dbo use only
? ddl in tran
? disable free space acctg 
? no chkpt on recovery 
? read only 
? select into/bulkcopy 
? single user 
? trunc log on chkpt
查看數據庫的選項設置情況,使用sp_helpdb存貯過程。
三、數據庫選項的用途

(1)Selectinto/bulkcopy
使用bcp或批拷貝程序接口將數據高速拷貝到一張沒有索引和觸發器的表,Writetext或者Select into生成永久表,則此選項必須設置爲true。因此,當你使用bcp實用程序往用戶數據庫加載數據時,或者調用dbwretetext函數把一幅圖片插入到某張表的image字段,或者通過Select into命令形成結果表時,別忘了把該選項置爲true。ASE爲了快速執行上述操作,減少記錄修改操作的日誌。但是,這種不記日誌的操作會使事務日誌與數據庫中數據不同步。這種事務日誌對於系統失敗後的恢復就沒有用處。系統禁止在這種情況下,dump transation到轉儲設備。因此,這些不記日誌記錄的操作完成後,將Select into/bulkcopy選項關閉後,執行dump database。

由Select into或批拷貝對數據庫產生未被日誌記錄的修改後,執行dump transaction命令時,顯示錯誤信息,並指導用戶改用dump database(而Wrrietext命令沒有這種保護)。

由於臨時庫tempdb從不恢復,所以使用Select into產生臨時表時不必將Selectinto/bulkcopy選項打開。對於有索引的表進行bcp時,一般進行慢速批拷貝並且記入日誌,所以此時也不必將Select into/bulkcopy設置爲true。

(2)trunc log on chkpt
該選項表示每當checkpoint檢查進程執行時(通常每分鐘12次以上),事務日誌被載截,即將已提交的事務日誌刪除。但是,該選項設置成true以後,人工執行checkpoint操作時都不載截事務日誌。在開發數據庫應用時,防止日誌增長太快.可以將該選項設置成true,所以它很有用。

(3)abort tran on log full 
該選項決定當指定數據庫日誌段最後機會閥值被超越時,正在運行的事務的處理辦法。缺省值爲false,也就是說事務被暫停掛起,直到空間空餘出來再恢復。本選項設置爲true時,在日誌存儲空間空餘出來之前,所有用戶的需要寫事務日誌的查詢將被去掉。

(4)allow nulls by default
該選項置爲true,將列的缺省狀態從not null改爲null,這與ANSI標準一致。T-SQL中列的缺省狀態爲not null,即不允許列爲空值。但用戶可在列定義時指定該列爲null狀態。allow nulls by default true與缺省狀態相反。

(5)dbo use only 
該選項設置爲true時,只有數據庫擁有者才能使用該數據庫。

(6)ddl in tran
該選項設置爲true時,用戶在事務中可以使用某些數據庫定義語言的命令,例如:Create table,grant和alter table命令。?只有ddl in tran選項設置爲true時,下述命令纔可在用戶自定義事務內部使用:
alter table create table drop rule create default create trgger drop table create index create view drop trigger create procedure ceate default drop view create rule drop index grant create Schera drop procedure revoke 
下述命令在任何情形下都不能在用戶自定義事務內部使用。
alter database load database truncate table create database load transation update statistics disk init recorfigure drop database select into
另外,系統過程sp_helpdb,sp_helpdevice,sp_helpindex,sp_helpjoins,sp_helpserver和sp_spaceused,由於在執行時產生臨時表,也不能在用戶自定義事務中使用。再者,用戶自定義事務中不能使用修改master數據庫的系統過程。
 
(7)no free space acctg
該選項抑制剩餘空間計帳及非日誌段閥值活動的執行,由於不再計算這些字段的剩餘空間,所以將加速恢復時間。關於該選項,在閥值管理部分,已有詳細介紹。

(8)no chkpt on recovery
當保持最新的數據庫備份時,此項設置爲true。此時,存在一個基本庫和一個輔助庫。首先,基本庫轉儲到輔助庫中。然後,基本庫的事務日誌間斷地轉儲並裝載到輔助庫中

若此選項設置爲缺省值false,重新啓動ASE時,恢復數據庫後將向數據庫增加一條檢查點記錄。檢查點記錄確保機制不會不必要地重新運行,改變順序號,並導致隨後從基本庫裝載事務日誌的失敗。

將輔助庫的此項設置打開,恢復過程將不產生檢查點,這樣從基本庫轉儲的事務日誌可以被裝載至輔助庫。
 
(9)read only
該選項使得用戶可以從數據庫中檢索數據,但不能修改數據。

(10)single user
該選項設置爲true時,每次只能有一個用戶訪問該數據庫。
3.5 Index & Performance
在應用系統中,尤其在聯機事務處理系統中,對數據檢索及處理速度已成爲衡量應用系統成敗標準。而採用索引來加快數據處理速度也成爲廣大數據庫用戶所接受的優化方法。
索引的使用效果不僅僅依賴於ASE的優化策略,在相當程度上也依賴於應用程序的設。怎樣正確地使用索引,不能一概而論,究竟是讓索引滿足程序設計的需要,或是程序設計遵循已建立的索引,這兩者是相符相承的。只有正確地使索引與程序結合起來,才能產生最佳的優化方案。
建立索引的目地是爲了優化檢索速度,如果檢索所需要的時間過長,便有理由懷疑是否索引不存在或者優化器沒有使用索引。尚若是索引不存在,那麼就要取決於用戶是否願意用空間來換取時間,使用索引來解決檢索速度慢的問題。如果優化器未使用表上已有的索引,那麼要分析爲什麼,關於這一點將在後一點篇幅來說明如果update的效率很低,很可能是由於表上有太多的索引需要維護,從而浪費了時間。

優化器怎樣使用索引
 
Table scan
如果表上沒有任何索引,那麼檢索將採用Table Scan方式進行,其所用時間主要依賴於表的大小。
例如:
- dbcc checktable 測出表佔76923頁
-系統每秒讀取50頁
-76923頁/50頁/秒=1538秒 (大約25分鐘)
如果系統有比較大的cache,某些數據可能由於以前已被讀到內存,那麼讀取數據時間可能會低於估計的時間。一般情況下,Tablescan檢索是由於表上沒有ClusteredIndex或者優化器認爲,表中將有20%的數據做爲結果追回。

   使用索引(條件爲指定值)
索引中包含指定記錄的值及地址,ASE不必做全表掃描。
例: select * from title where title_id="mc3021" 
 

當優化器認爲讀取索引頁I/O加讀取數據頁I/O比做Table Scan效果更好時,檢索將使用索引。

   使用索引(條件爲某範圍內值) 例:
select * from titles
where title_id >"BU1032"
and title-id <"mc3032" 
 
如果數據是排序的(有Clustered索引),索引將被用來限制數據的掃描範圍。
 使用索引避免檢索排序所需要的時間。
例:
select * from titles
order by title_id 
 
對Clustered索引來說,如果索引順序與Server順序一致,那麼上面的查詢不需要重新排列返回結果。但是,若數據存儲本身是升序排列,而查詢要求降序排列,那麼索引對加快查詢沒有任何作用。

對於Non-Clustered索引,優化器將判斷查詢Non_Clustered索引頁,找到滿足條件的數據進行排序是否比Table Scan更快,優化器將找出最佳結果。從以上幾例可以看出,並非在表上建立了Clustered或on-Clustered索引之後,就一定會被使用,優化器是否使用索引取決於數據的查詢命令,ASE將從幾個檢索方案中選擇最佳的一個。

在什麼樣的條件下才選擇Clustered索引呢?
選擇什麼樣的索引基於用戶對數據的檢索條件,這些條件體現於where從句和join表達式。如果你的應用與以下情況相符,你可以考慮選擇Clustered索引。
? 主鍵時常作爲where子句的條件
? 某一列經常以這樣的格式出現在where表達式中(x<=column <="y)" 
? 某一列非常頻繁地被訪問
? 某列被用作order by或group by
? 某列很少被改寫
? 某列常出現在join中。

Non-Clustered常被用在以下情況:
? 某列常用於Aggregate函數(如Sum,....)
? 某列常用於join,order by,group by。
? 查詢檢索出的數據不超過表中數據量的20%

索引覆蓋
索引覆蓋是指Non_Clustered索引項中包含查詢所需要的全部信息。這種索引之所以比較快也正是因爲索引頁中包含了查詢所必須的數據,不需去訪問數據頁。如果Non-Clustered索引中包含結果數據,那麼它的檢索速度將快於Clustered索引。覆蓋索引的缺點:由於索引項比較多,要佔用比較大的空間。而且update操作會引起索引值改變。

ASE對索引的限制
? 每個表上最多僅能有一個Clustered索引。
? 如果表上有一個Clustered索引,最多還能有249 Non-Clustered索引。
? 當沒有Clustered索引時,則可有250個Non-Clustered索引。
? 索引最多建立在256個列上。
? 當索引被創建時,ASE需要120%的附加空間。

索引維護
隨着應用系統的運行,數據不斷地發生變化,當數據變化達到某一個程度時將會影響到索引的使用。上面講到,某些不合適的索引影響到ASE的性能,這時需要用戶自己來維護索引。一種方法是刪除老的索引,重新建新的索引。另外一種方法是保持索引統計有效(使用命令update statistics),在以下情況下需要重新索引。
? 使用數據模式發生了較大變化。
? 某段時間內有極大量的數據插入。
? ASE排序改變。
? dbcc發現索引錯誤。

當重建Clustered索引時,這張表的所有Non-Clustered索引將被重建。

維護索引統計表:
數據庫擁有者必須用命令維護統計表。 update statistics table_name [index_name] 

索引優化調整
用這條命令可以改善創建索引的性能,減少建索引所用的時間。 在ASE中可以調整如下參數: sp_configure "extent i/o buffers",nnnn帶來的影響是增加了extent i/o buffers大小,在ASE使用內存不變情況下,減少了procedure和data cache,而且同一時刻僅有一個用戶能用到extent buffer。
3.6 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進程每隔0秒左右清除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,doa mpg)
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<x
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的管理是靈活而複雜的,我們應該在實踐中摸索經驗,針對每個數據庫的不同情況,不同操作,做不同處理。
3.7 閥值管理(Threshold Management)
在使用Sybase數據庫管理系統(ASE)開發企業應用系統時,或者開發好的數據庫應用系統投入實際運行後,由於用戶不斷地增加或者修改數據庫中的數據,用戶數據庫的自由存儲空間會日益減少。特別是數據庫日誌,增長速度很快。一旦自由空間用盡,ASE在缺省情況下掛起所有數據操縱事務,客戶端應用程序停止執行。這樣有可能會影響企業日常業務處理流程。Sybase ASE提供自動監視數據庫自由存貯空間的機制——閾值管理,當數據庫使用剩餘空間低於一定值時,通過執行一個自定義的存儲過程,來控制自由空間。在空間用完之前,採取相應措施,這樣有利於業務處理順利進行。如果能充分利用ASE的閾值管理功能,用戶能使一些數據庫管理工作自動化,規程化。所以,在此我們將ASE這一重要功能介紹給讀者。

ASE的閾值管理允許用戶爲數據庫的某個段上的自由空間設置閾值和定義相應的存儲過程。當該段上的自由空間低於所置閾值時,ASE自動運行相應存儲過程。與閾值相對應的存儲過程由用戶定義,ASE不提供。一般來說,數據庫管理員可通過這些存儲過程來完成一些日常管理事務,例如:
備份數據庫,清理日誌和刪除舊數據
備份數據庫日誌
擴展數據庫空間
拷貝出表中的內容,清理日誌,等等。

(一)段(Segment)
ASE的閾值管理是基於段(Segment)的,因此,讓我們先回顧一下段的概念。每個數據庫創建時,它有三個缺值段:(1)System段;(2)default段;(3) logsegment段。以後,還可以爲該數據庫增加用戶自定義段。將來所有的數據庫對象都建立在這些段上,要麼是系統定義的段,要麼是用戶定義的段。數據庫的系統表存放在System段上。在沒有指明段時,建立的對象存放在default段上。數據庫的事務日誌放在logsegment段上,該段是通過使用建立數據庫( Create database )命令的log on 選項來定義的。


(二)最後機會閾值(Last_chance Threshold)
缺省情況下,SQLServer監測日誌段的自由空間,當自由空間量低於事務日誌能成功轉儲的需要時,ASE運行sp_ thresholdaction過程。此自由空間量稱爲最後機會閾值( Last_chance threshold ),它由ASE計算得來,並且用戶不能改變。
 
sp_thresholdaction必須由用戶編寫,ASE不提供。另外,如果最後機會閾值越出,那麼在日誌空間釋放前,ASE一直掛起所有事務。但可以使用sp_dboption對某一數據庫來改變這一行爲。設置abort tran on log full選項爲true,可使得最後機會越出時,ASE撤回所有還未被註冊的事務。

(三)閾值管理
系統缺省建立最後機會閾值,由用戶編寫缺省閾值處理存儲過程( sp_thresholdaction ),來控制自由空間。除此之外,還可以使用以下存儲過程管理閾值:
? sp_addthreshold 建立一個閾值
? sp_dropthreshold 刪除一個閾值
? sp_helpthreshold 顯示閾值有關的信息
? sp_dboption 改變閾值的“掛起或取消”行爲和取消閾值管理
? sp_helpsegment 顯示某個段上空間大小和自由空間大小的信息
(四)增加閾值(sp_addthreshold)
它用於創建閾值( threshold )來監測數據庫段中空間的使用。如果段中自由空間低於指定值,ASE運行有關的存儲過程。增加閾值的命令語法爲:
sp_addthreshold database, segment, free_pages, procedure 
其中:
? database——要添加閾值的數據庫名。必須是當前數據庫名稱。
? segment——其自由空間被監測的段。當指定“default“ 段時要用引號。
? free_pages——閾值所指的自由空間頁數。當段中自由空間低於該標準時,ASE運行有關存儲過程。
? procedure——當segment中的自由空間低於free_pages時,ASE 執行該存儲過程。該過程可以放置在當前ASE或Open server的任意數據庫中。但是,超出閾值時,不能執行遠程ASE上的存儲過程。
例如:sp_addthreshold pubs2, logsegment, 200, dump_transaction
其中,存儲過程定義爲:
create procedure dump_transaction
@ dbname varchar (30),
@ segmentname varchar (30),
@ space_left int,
@ status int
as
dump transaction @dbname to "/dev/rmtx"

那麼,當日志段上可用空間小於200頁時,ASE運行存儲過程dump_transaction,將pubs2 數據庫的日誌轉儲到另一臺設置上。

sp_addthreshold不檢查存儲過程存在已否。但當閾值越出時,如果存儲過程不存在,ASE把錯誤信息送到錯誤日誌( errorlog )中。系統允許每個數據庫有256個閾值,而同一段上二個閾值之間的最小空間爲128頁。其存儲過程可以是系統存儲過程,也可是在其它數據庫裏的存儲過程,或者Open Server遠過程調用。

(五)刪除閾值(sp_dropthreshold)
它刪除某個段的自由空間閾值,但是不能刪除日誌段的最後機會閾植。刪除閾值的命令語法爲:
sp_dropthreshold database_name,segment_name,free_pages 
其中三個參數分別爲:閾值所屬數據庫名,閾值所監測的自由空間的段名,和自由空間頁。例如:
sp_dropthreshold pubs2, logsegment, 200
刪除pubs2庫中logsegment段的閾值200。
(六)顯示閾值(sp_helpthreshold)
它報告當前數據庫上與所有閾值有關的段,自由空間值,狀態以及存儲過程或報告某一特定段的所有閾值。顯示閾值的語法爲:
sp_helpthreshold [segment_name] 
其中segment_name是當前數據庫上一個段的名字。
  例如:
? sp_helpthreshold logsegment 顯示在日誌段上的所有閾值
? sp_helpthreshold 顯示當前數據庫上所有段上的全部閾值
(七)sp_dboption的新選擇

abort tran when log is full 
當日志段的最後機會閾值被超越時,試圖往該日誌段上記日誌的用戶進程將被掛起還是被撤回?缺省情況下系統掛起所有進程。但是可以使用sp_aboption改變它。執行sp_dboption salesdb,"abort tran when log is full",true 命令後,一旦日誌滿了,則數據庫修改事務將會被回滾。

disable free space acctg
這個選擇取消數據庫中的閾值管理,但不影響最後機會閾值。執行:sp_dboption saledb, "disable free space acctg",true 它取消對非日誌段上自由空間的統計。取消後,對系統有以下影響:
? ASE僅計算日誌段上的自由空間
? 日誌段上的閾值繼續處於活動狀態
? 在數據段上,系統表不改變,並且sp_spaceused得到的值是該選擇被取消時刻的值
? 數據庫段上的閾值失效
? 恢復加快

(八)閾值的觸發過程
頻繁的插入和刪除可能會使數據庫段中的空間波動,閾值可能被多次超越,ASE使用系統變量@@thresh_hysteresis,避免連續觸發閾值存儲過程。它的值由ASE設定。在system 10.0中,@@thresh_hysteresis是64頁。

如圖所示:
 
因此,增加一個閾值,它必須與下一個最近的閾值相距至少
2*@@thresh_hysteresis頁。

一個閾值被觸發,需要以下幾個條件成立:
? 必須到達閾值
? 閾值處於活動狀態(即它被建立後或者自由空間達到閾值減於@@thresh_hysteresis)
? 只有自由空間減少閾值才觸發,如果自由空間增加,它永遠不觸發
3.8 日常後備數據庫
SYBASE 數據庫的備份主要是通過 dump 命令來實現的, 分爲數據庫備份和日誌備份。 簡單語法格式如下:
dump database database_name to device_name
dump transaction database_name to device_name
如果使用磁帶設備做備份, 還要使用capacity、init選項。

應該多長時間備份一次數據庫呢? 這決定於發生系統故障時( 例如磁盤故障 ) 應用系統允許丟失多長時間的數據。 如果允許丟失一個小時的數據, 那麼可以考慮每天至少備份一次數據庫, 並每個小時至少備份一次日誌。

備份數據庫之前, 應對數據庫做 dbcc 檢查, 確保備份的數據庫是完好的數據庫。如果數據庫有損壞, 備份時可能不會報錯, 但將來可能無法裝載(load)。

通常情況下, 只有發生嚴重故障需要恢復時才進行裝載數據庫, 但是 SYBASE 建議偶爾對備份的數據庫裝載到一個測試環境上, 以保證備份工作過程正常並熟悉備份和裝載工作過程。

Master 數據庫的備份也不能忽略。每次master 數據庫的內容有變動時, 應及時備份 master 數據庫, 例如增加 login, 增加設備, 增加用戶數據庫等。

用戶可根據自己的應用制定可行的備份方案。 詳細的命令語法及備份方案的詳細建議均可在 SYBASE 手冊中查到。

舉例:Unix平臺後備pubs2數據庫
? 啓動ASE和BACKUP SERVER
? isql -Usa -Pxxxxxx -SSYBASE
dump database pubs2 to "/sybase/dump/pubs2_db.990705"
go
dump transaction pubs2 to "/dev/nrct0" capacity=1500000,file="pubs2_log.990705" with init(capacity取值爲磁帶容量的70%左右,以K爲單位)
go
3.9 使用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時,並且它還做必要的併發性檢查。這兩條命令都有與其相關的警告,在命令參考手冊中會看到這些警告。請確保在使用其中任一條命令以前,你已理解這些警告和指示。 Syase提供dump transaction with no_log來處理某些非常緊迫的情況。爲了儘量確保你的數據庫的一致性,你應將其作爲“最後一招”。
3.10 在ASE 11.9.2版中採用了行級加鎖機制以提高性能
Sybase公司關係型數據庫管理系統產品的最新版本----Adaptive Server? Enterprise 11.9.2通過對行級加鎖機制的創新以滿足日益增長的可伸縮性的需求,並使得產品的性能和可伸縮性得到了明顯的提高;特別是在商業應用中,使得這個產品能夠滿足儘量少佔用硬件和操作系統資源的用戶需求。本白皮書對這種新加鎖機制的實現方法進行了詳細的介紹,並且針對特定的採用頁面級加鎖機制的應用系統和以前所推薦的提高性能的典型優化方法,就新的行加鎖機制所帶來的效益進行了量化的分析。

隨着Adaptive Server Enterprise (ASE) 11.9.2的發佈,Sybase公司已經使得其數據庫管理系統產品ASE在11.9版本中所申明增加的功能都得到了實現。這次發佈ASE11.9.2表明了對於那些採用較早地使用了Sybase ASE產品的應用系統,它們所遇到的一系列與併發處理有關的課題得到了解決。

從高層的觀點看來,有人可能會說新功能不過只是實現了行加鎖功能。然而實際上卻不止如此,Sybase公司已經抓住了這次機遇,在新產品中實現了包括新型存貯和索引等在內的範圍廣泛的新技術,以擴大其產品的功能並改善產品的性能。這種方法不僅是提供了更小尺度的加鎖機制,而且還比其它一些方法諸如傳統地對索引、分配、OAM,和GAM頁面加鎖進行限制明顯地提高了性能。

在本技術報告文件中,通過一些特定的實例對新的加鎖機制進行了闡述,而這些實例都是使其併發性及其性能得到了很大的提高。應該注意到,爲了使本文件內容更加集中,所提供的材料都是在很高層次上的。有關更詳細的信息,請參看如下的文件:
? New Functionality in Sybase Adaptive Server Enterprise 11.9.2[1],本文件是ASE 11.9.2 文檔系列之一,該資料詳盡介紹了本版本中所包含的全部新功能。
? When (and When not to) Use Data-Only Locking [2]( by Ian Smart),在這本由筆者撰寫的資料中包含了本文獻中所引用實例的詳細分析、測試數據和硬件/軟件配置。
     3.10.1 所支持的加鎖機制

1) 全頁加鎖
全頁加鎖既是一個新術語,它又是由ASE(Adaptive Server Enterprise)在過去所支持的一種加鎖類型。這種類型有下列特性:
? 對所有可被訪問的頁面在頁面級加鎖
? 當各種類型的頁面以任何方式發生改變時,對這些排它性的頁面進行加鎖;而且這種加鎖機制一直保持到該事務終止;
? 當下一個所需的頁面已經成功地獲得,對那些已經釋放的的當前訪問頁進行共享頁面加鎖(如果採用了第三層ANSI隔離,則把這種加鎖機制保持到該事務終止爲止)
? 採用頁級時間印記(timestamp)以確定是否發生改變,詳細信息記錄在事務日誌中,以便在系統恢復時以向前或向後方式使用。
這種加鎖方式常常提供性能最高的解決方案,特別是當應用設計時已經考慮了這些特性時更是如此。但是,有一些應用系統,當發生某些活動時,這種對整個頁面進行加鎖的方式就可能會對系統性能產生有重大意義的影響。對於那些面對諸如文件系統或其它已經支持更細小尺度加鎖機制的數據庫廠家產品的一般環境而設計的應用系統而言,這種情況尤其如此。

此外,還存在一系列問題,它們要圍繞着更加困難的條件進行工作。它們通常要採用更加具有Sybase特性的解決方案。對於商用的應用軟件製造廠商而言,對他們是一個挑戰,因爲這將要求他們必須跨越他們所支持的數據庫平臺,去完成維護其原代碼的工作,而這個工作有相當工作量。在這個領域的基本問題如下:
? 對已經按照升序值創建的非羣聚性索引的最末端葉型頁面存在着爭議
? 對非羣聚性索引的表進行插入和查詢時可能發生死鎖;
? 在按照羣聚性的索引值進行更新和對非羣聚性索引的表進行查詢訪問之間可能發生死鎖;
? 在沒有作索引的表的最後一行可能發生衝突(儘管對最後的特定地址可以使用分區) ;
? 有可能使行數很少的表之間發生潛在的衝突(儘管對特定的地址可以使用填充因子[ fillfactors]和每頁最大行數[ max_rows_per_page]這兩個參數)
? 對每個頁面兩邊進行加鎖的需要常常被分割開來;
? 如果一個表特別小,以致在一個單一頁面中進行駐留,那麼對單一行的訪問實際上將破壞對整個表的加鎖機制。
2) 僅對數據加鎖

僅對數據加鎖機制試圖去解決本文前一節所關注的主要問題(其他的議題將在其它功能領域中加以解決)。這種加鎖方式支持兩類不同的工作方式: 數據行加鎖和數據頁加鎖。在這兩種情況中,對於它們所支持的加鎖方式,都與以前的加鎖機制有所不同。僅對數據加鎖具有下列特性:
? 在索引頁面中不會破壞事務加鎖。相反,而是採用了一種稱之爲鎖存的機制。鎖存是一種類似於旋轉鎖(spinlocks)的同步方法,它們與事務無關並且只保留很短的週期(一般而言,當一個任務在數據庫中物理上改變一小片數據時,這個週期相當於在共享存貯區中在一個2K的頁面改變某些字節數據的時間)一旦完成之後,這個任務將直接打開這個鎖存。當這種情況還可能臨時同其它組塊時 ,因爲這種鎖存不能對服務器任務進行有上下文的切換,也不能涉及死鎖,並且只能保持主要的一小段時間,所以它們不能產生有顯著意義的爭用。
? 採用一個RID對單一行進行數據行加鎖(行標識[RID----Row ID]是邏輯頁號與所在頁面上該行號的組合);
? 支持固定的行標識 RIDs, 它可以是向前的,允許不進行其RID的改變,就完成數據行的移動。當一行變大超過了它的可用空間時,採用上述結果對非羣聚索引不需要進行任何改變。
? 不需要進行任何爭用就可以在表的尾部進行插入操作,這一功能已經增加進來。.
? 支持採用範圍加鎖、下一個關鍵字加鎖和無限大加鎖等方式對邏輯範圍值進行加鎖
? 支持由最頂層操作所導致的頁面分割。這些情況直接加以提交,"系統"事務可以導致在更短一點的時間週期裏保持分裂的頁面處於鎖定狀態。
爲了支持這些變化,需要對採用的存貯表結構進行一系列改善。這些改進的主要效果如下:
? 羣聚索引現在被存貯爲象許多人所熟悉的IBM DB2產品所採用的“放置索引”("placement indexes.”)方式。這種結構類似於非羣聚性的索引,需要類似的空間總量。這種修正的結構導致了在數據初始存貯時可以按照順序跨數據頁進行存儲,但是當發生插入時,它們就要儘可能緊密存放以便在正確的邏輯頁面中不存在頁面分割。此外,在數據頁中的數據順序在新行增加時是不進行維護整理的。這種索引的應用使每個羣聚化的索引周遊增加了一次I/O操作。
? 行位移表已經增加到索引頁和數據頁中。這種增加和新的行索引行存貯格式具有使每個索引頁面所存貯的索引條目個數減少的潛在能力。
? 固定行標識(RIDS)。當一行移動時,對於分配新行位置的向前地址被放在用於駐留該行的位置上。當這種移動需要改變非羣聚性索引時,對該行的訪問需要增加一次I/O操作以得到‘向前’的位置。
? 一般而言,索引將更小和更短,這是因爲如下原因:
? 從每個葉級頁面中採用雙重鍵限制機制來限制雙重鍵(Duplicate key)例如,如果值“綠”("GREEN”)在下列行標識(RIDs)值等於123-1,234-2,和345-3的行中, 就分別存貯值“綠”("GREEN”),123-1,234-2,345-3,而不是存貯值“綠”("GREEN,”)三次。在每個索引頁中每個值只存貯一次。
? 在非羣聚性索引樹的非葉型結點中將後綴實行壓縮(例如,如果鍵值是"GREEN”和"HAMILTON”,而在這兩個值之間發生分裂,那麼就在非頁級索引頁面中存儲"G”和"H”)。
3) 數據頁和數據行加鎖

只對數據加鎖機制支持兩種方式:數據頁加鎖和數據行加鎖。這些與它們的工作方式和所提供的功能相類似。這兩種方式僅在對數據訪問產生阻礙作用時,在加鎖的尺度上有所區別。在數據頁加鎖方式下再採用數據行加鎖方式具有兩種作用(一種起正向作用,另一種起反向作用)。首先,較小尺度加鎖機制的使用可能導致減少爭用與衝突,然而當大量數據發生變化時,就有可能對加鎖產生大量阻礙的情況發生。

4) 特定使用的加鎖類型
除非對配置參數加以特定,對所有的表都予置了隱含的全頁面加鎖機制。
sp_configure ‘lock scheme’,0, [allpages | datapages | datarows]

當數據庫從原先版本的服務器中轉儲出來重新加載時,所有的表都被定義爲全頁面加鎖的表。當建立一個新表時,可以不使用這個缺省值,可採用如下的句法格式:
create table <tablename>… lock [allpages | datapages | datarows]

爲了在使用的一個表中改變加鎖類型,可以採用如下的句法格式:
alter table <tablename> lock [allpages | datapages | datarows]

在一個現存的表中改變加鎖方式,將引起下列三種行動後果發生:
? 首先,如果一張表從全頁加鎖轉變爲僅對數據加鎖,或者從僅對數據加鎖轉變爲全頁加鎖,在這兩種類型之間就要對錶進行選擇以允許進行存貯格式改變。如果這是一個分區表,就要同時假定必要的並行級別和工作線程已經配置好的情況下,才能執行。
? 其次, 對錶中的羣聚性索引必須重新創建。因爲我們能保證數據,所以如果從全頁加鎖方式轉換爲只對數據加鎖時,這種重新創建可以通過"with sorted_data"來完成。然而,當從僅對數據加鎖機制轉換爲全頁加鎖方式時,就要進行並行的索引創建操作。(請注意:如果這是一個分區表時,那麼並行等級和工作線程的數目必須加以配置才能允許進行這種改變,否則這種遷移將會失敗)
? 最後,非羣聚性的索引將被重建,如果服務器已經爲並行處理所加以配置,當進行本步驟時將加以採用。
由於這些活動同潛在的工作量有關,從全頁加鎖機制改變爲僅對數據加鎖或從僅對數據加鎖改變爲全頁加鎖機制都可能是耗費時間的活動。爲了標註這一點,有以下一些選擇:
? 如果可能的話,應該配置使用並行方式。這至少對執行非羣聚性索引的哈斯(雜湊,即hashed)創建方法是必須的,但是如果可能的話,採用分區表和分區掃描將使系統得到更大的改進。
? 在選擇進入和創建羣聚性的索引之後,該任務將被設置檢查點(checkpointed )所以,如果有充分的硬件資源,通過允許在任何一個時間點上,檢查點任務可以具有多於10個(系統缺省值)的異步I/O請求,利用dbcc進行調諧將能夠帶來有益的效果。(‘maxwritedes’, number)
? 進一步作爲降低使用檢查點成本的一種方法,在相關的高速緩衝池(cache pool)、大數據量的I/O操作中,採用對高淘汰程度進行標記的方法,並允許清潔程序(好象家庭主婦一樣)保持特別活躍的狀態,將爲那些檢查點需要從高速緩衝池中刷新較“髒”的頁面的而增加的I/O操作次數,並因此花費了在檢查點上的時間,都能夠大大減少作出貢獻。
? 如果預先進行了配置,則可以對並行的選擇進入可以使用預先分配的盤區。所以,通過將sp_configure number of pre-allocated extents設置爲16也將對系統性能有明顯的積極的效果。
備註:在僅對數據加鎖類型之間進行改變不需要對數據進行備份, 而且執行起來只需很短的一段時間。

     3.10.2 對小量數據的多次併發訪問

1) 在小型表中採用不同加鎖方式之間的比較
對於那些被訪問的數據同時(或者)僅有一張或很少數量的頁面發生改變的情況,在頁面級進行加鎖極有可能導致表中很大比例的頁面都實施了加鎖機制。使用按數據行進行加鎖將因爲降低了加鎖的尺度而明顯增加了系統的吞吐量。

爲了對使用按數據行進行加鎖改變了原先發生的組塊移動,已經設計了一系列基於TPC/B基準的測試實驗。在這些實驗中,使用了各種TPC/B的變量以創建略有不同的條件和可能發生的情況。在下面這些結果中,前三個執行的是直接更新。在實驗4與5中,採用了選擇、刪除以及插入的組合(請注意,這些實驗比其它的實驗作了更多的工作)在實驗6與7中, 由於補償索引直至補償列引起了數據更新的拖延。

利用已經執行的全部工作,在更新三張表的實驗中,最小的表總是最後一個被更新。然後事務在歷史記錄表中插入一個條目。

備註:下列測試是在具有12個處理器的HP9000/891 T500的設備誰進行的。Adaptive Server Enterprise 配置爲具有10個驅動核心( engines)和 1GB的內存。
  測試結果如下圖所示:
 
從這些數據可以看出,利用數據頁加鎖方式與全頁加鎖方式相比較而言,對於吞吐量來說幾乎沒有什麼差別。這是由於兩者之間在加鎖尺度方面沒有什麼差別。然而,一旦使用了數據按行加鎖方式,100行的數據可以單獨訪問時,此時在性能上的明顯改進就能夠達到了。

2) 在小型表中採用填充因子(Fillfactor)與僅對數據加鎖方式之間的比較

在上文中所提及的小型表中,對錶傳統的工作方式是採用了諸如在每頁的某一行,在羣聚性索引上有效地放置了數目爲1 的填充因子。我們採用100行的表重複進行了同樣的一組實驗,此處表都已經具有采用這類填充因子創建的羣聚性索引。

下圖顯示了實驗結果,它們分別是較早時間進行的按數據頁和數據行加鎖的結果,以及與之形成對照的採用1%的填充因子的全頁加鎖實驗結果:
 
正如所看到的,在直接更新的情況,對吞吐量來說有一點微小的提高;而在刪除/插入的測試情況中,對吞吐量卻有明顯的提高;而對延遲的更新實驗,吞吐量則要有一些降低。

這些實驗說明對這些課題來說,Sybase公司傳統的響應在大多數情況下還是有效的,而且對那些已經用這種方法實現的用戶來說並沒有明顯的缺陷。然而,對於填充因子方法來說還是有一些缺點,因而就限制了它們的用途。

3) 何時採用只對數據加鎖或填充因子

隨着引入僅對數據加鎖方式,現在數據庫設計者對使用更新的表中,如何解決爭用衝突課題方面,有了選擇。在表比較小或保持較小時,採用填充因子對於不使用延遲更新的情況將對吞吐量的提高有輕微的改善作用。

如果表比“少數”頁大,那麼填充因子的使用,特別是該因子爲1時,就成爲應該禁止和代價昂貴的一種方式了。這是由精確度所決定的,填充因子在每個頁面裏都留下了一些沒有使用的空間。這樣一來明顯增加了磁盤空間需求,對大表尤其如此,這將導致更大的數據庫和對更多硬件的需要。

其次,因爲填充因子不是永久的,客戶必須安排重構索引的程序段以對性能進行調整和維護。這樣一來使爭用和衝突發生在特定的區域,使之變得更加令人煩惱。事實上在過去,當用戶激活邏輯分區的數據,靜態數據放在另外的表裏時,就把靜態數據緊緊地包裝在一起,在利用填充因子使之激活,這種情況對於用戶並不是罕見的情況。使用這種技術已經引用了把數據放回到一個單一的結果集合中來的組合操作,這使得編寫SQL程序變得格外複雜。

採用僅對數據加鎖的方法可以使用戶不一定需要使用填充因子來解決更好地利用可用空間的問題。這種選擇使得用戶可以在“兩個世界之間的最佳者”選項中作出決定,以爲其環境選擇最優的方案。

     3.10.3 堆棧表和熱點

1) 在堆棧表中增加行

應用系統更新行時,如果同時使用了填充因子(fillfactor)或每頁最大行數(max_rows_per_page),在這一話題是插入一行時,特別是在特定的位置(即熱點--"hot spot”)插入時,這些方法就變得幾乎沒有價值。無論何時在一個沒有羣聚性索引的表(即所謂“堆”表--"heap”)中進行插入時,這種插入總是插到表的最後一頁中去。在Sybase ASE 11.0之中,Sybase公司提供了允許用戶在分區表中把這種插入蔓延分散到跨分區裏去。然而,在採用這種方式解決問題的同時,這種方法不能處理由於空間開銷而不能使用堆的情況,也不能解決那些因爲查詢原因要把數據按着添加的順序存放的表的問題。

隨着在Adaptive Server Enterprise 11.9.2版本中增加了“追加行”的邏輯,僅對數據加鎖和鎖存技術的採用,使得索引訪問與空間分配得以協調,從而明顯提高了性能。現在通過執行這樣的任務,就能夠不需要再採用依靠數據庫加鎖的一系列複雜的傳統事務就能進行表的追加。

在下列的實驗中,基於TPC/B的歷史記錄表被用於確定對堆表追加行時可能提高性能的級別。在每個事務的末尾插入歷史記錄表,作爲工作性能的一條審計記錄。運行TPC/B 的正常過程要採用多張已經分區化的歷史記錄表。(例如,在第三節中所顯示的小表實驗中,採用了具有100張分區化的60張歷史記錄表)。
  這種實驗的結果如下圖所示:
 
備註:此處運行號分別對應於在所有直接更新和放置適當位置的小表測試中的運行號。
如果分析加鎖爭用與衝突,可以觀察到排他性的組塊加鎖大大減少,這是由於對於“下一行加鎖”的技術已經被增加到按數據行加鎖機制的一部分。但是這種功能還沒有充分擴展爲包括僅對數據加鎖的方式,這就是在這些案例中爲什麼還會發生某些組塊現象的原因。

從這些結果,可以看到需要羣聚或分區的堆表不止是一個選擇,當採用僅對數據加鎖方式時將給用戶在明顯提高其吞吐量的方面一個很實際的替換方式,特別是在數據行加鎖方式的情況下,更是如此。

2) 追加到非羣聚性索引的葉級末端
正如在4.1節中所描述的,對於堆表頁鏈末端的熱點(hot spots)可以通過使用羣聚性的索引或分區來加以解決。但是當非羣聚性索引最末級(即葉級)的最後一個頁面發生爭用衝突時,或者在到達一個特定的點的中途,利用上述技術中的任一種方法都不能使上述問題按傳統的方式加以解決。既然按照升序值建立索引是非常普通的(例如序列號、日期/時間列等),這就成爲迄今爲止難於克服的一個問題.

在採用僅對數據加鎖的情況下,索引頁不再按照傳統方式進行加鎖,而寧可使用鎖存技術。因爲鎖存僅僅是一個短時期的同步技術,所以使用傳統的頁加鎖方式時,不會加大開銷或可能發生當主要的組塊現象。

採用4.1節中的歷史記錄表,設計了一個實驗,其中按照日期時間列建立了非羣聚性的索引,這個日期時間列的值是在該列插入的時刻使用getdate() 所得到的。這個按常數升序所建立的索引引起了索引葉級的最後頁面的爭用衝突。這個表自身被劃分爲1000個分區,以試着避免在任何一個數據頁發生衝突。

實驗結果如下圖所示:
 
因爲在這種情況下前面所提及的議題還是有爭論的,也沒有考慮加鎖的尺度,所以選擇僅按數據行加鎖或數據頁加鎖是沒有什麼實質意義的。正如所看到的,一旦完全通過鎖存技術避免對索引加鎖的話,那麼明顯可以使性能得到提高和改善。

     3.10.4 死鎖

1) 發生死鎖的原因
以前,由於採用通過服務器訪問或變更數據的技術,就存在可能發生死鎖的情況。對於常常是更多地由ASE的處理特性所引起的死鎖, 而不是由不恰當的事務設計所引起的死鎖,就給數據庫管理員(DBA)帶來了特別的麻煩。通過幾種增強方式,ASE 11.9.2將這些系統所引起的死鎖問題得到了解決。

隨着鎖存技術的引入,對於其它用戶而言,索引頁只是在很短的週期內不能被使用,永遠不會延續到數據庫事務中。所以鎖存技術的特性將那些在索引頁中發生死鎖的情形都排除掉了。這一點對在使用僅僅是數據表時,可以使用併發技術的情況具有巨大的效果。

此外,爲了進一步處理針對數據可能發生的死鎖,已經認識到可以對釋放共享鎖的時間點加以改變,這樣一來,就能夠使對以前發生死鎖的數據行的併發訪問保持一致。在處理一個連接(join)時,以前的處理方式是將在外部表中加鎖的行一直保持到檢索到內部行時爲止。然而在大多數情況下,一旦檢索到數據就不再需要對進行訪問的行繼續加鎖。隨着引入固定的行標識(RIDs),這就意味着,外部表的掃描從這一行掃描到下一行,一旦所需要的信息已經被檢索到之後,在所連接的外部表中,對行的加鎖就可以釋放了。這個功能被稱之爲“帶有加鎖方式的讀提交”("read committed with lock”),並可用如下的命令加以配置:
sp_configure ‘read committed with lock’,0|1
2) 客戶情形
爲了證實上述情形,建立了一個實際的客戶環境,以便按照一系列它們所提供的測試進行,用於驗證他們所認爲的最壞的併發情況下以確保不發生死鎖。

在這類“最壞情況”測試中的應用負載如下:
? 在一臺應用服務器上執行項分開的流式任務,它們包括如下任務:
? 大量的插入
? 在一個單一邏輯事務中進行5000條SQL語句的更新操
? SQR報告
? 用戶執行OLTP工作(插入、更新和聯機查詢)
? 使用複雜查詢的報告。向下鑽取的報告:
? 訪問一定數量的表(典型爲6或7)
? 引用至少包含兩個子查詢的SQL語句;
? 在光標定義中採用截然不同的光標(cursors),以引起工作表的使用。
3) 可能發生的死鎖
採用較早版本的服務器產品,進行上述的應用實驗,可能發生死鎖,其主要原因如下:

插入與非羣聚性的索引訪問
如果插入一行,服務器就會採用羣聚性的索引以訪問存貯該行所在的頁面,並在一種排它性的頁面加鎖方式下執行插入操作。接着服務器就對錶的每個非羣聚性索引進行訪問,在一種排它性的頁面級加鎖方式下,在其末端(葉級)結構中插入相應的條目。如果第二個用戶也通過非羣聚性的索引訪問該表,他們可以按照非羣聚性索引保持對該葉級頁面實施共享加鎖,與此同時,這些非羣聚性的索引也由這個排它性的頁面加鎖所阻礙並用在插入操作中。這種對由第二個用戶對非羣聚性索引的葉級結構所進行的加鎖方式,可能阻礙插入嘗試併爲第一個用戶增加一個條目,從而可能引起死鎖。

更新的範圍
在這個商業應用的設計中,開始首先在一張表中採用零值與一個標識符兩部分組成的鍵值插入所有的新行。在一個單一的邏輯事務中對所有的行使用相同的標識符來進行併發更新。這些更新採用唯一鍵值去代替零值,就引發了索引行移動到索引的葉級結構的最後。當多個用戶併發執行這個任務時,第一個用戶就鎖定進行處理的頁面和索引所在的葉級結構的末端。這將阻礙用戶試圖對第二個按行範圍所進行的工作。當第一個用戶到達所確定的頁面邊緣,即該範圍即將終止,下一批所組塊並妨礙的頁面範圍即將開始之時,就可能發生死鎖。

按照不同順序訪問表
即使訪問行是不同的,對錶按照任何不一致的順序進行訪問,也會意味着可能發生死鎖。這是因爲一個用戶所訪問的行可能在另一個用戶訪問的同一個以不同順序排列的頁面中。對於應用系統而言,當然這種設計明顯是很差的,但是卻還令人驚奇地普遍存在。

連接與更新
正如在 5.1節所敘述的有關“採用加鎖機制的讀提交”段的內容,當處理連接,同時對外部表的加鎖方式會一直保持到內部行被檢索到爲止,這種情況就會發生。如果第二個用戶在訪問所連接的外部表中的行之前,先訪問了所連接的內部表的行,這種操作可能受阻,因爲加鎖的順序被連接所破壞,從而也會引起死鎖。

4) 問題的解決方案
採用Adaptive Server Enterprise 11.9.2的產品, 應用對索引頁的鎖存技術以代替傳統的加鎖方式,以及更小尺度的按行加鎖方式,導致了前三種死鎖類型不再發生。採用“按照加鎖進行讀提交”可以處理第四種死鎖情況。

作爲進一步的測試,在前面所述及的最壞情況實驗中,同時還進行了增加額外負載的運行實驗。這類實驗包括一個擁有7000條SQL語句的單一事務,和從Microsoft Excel電子數據表中卸載數據(加入ASE服務器)。這兩個版本的測試已經進行了多次,從未發生過死鎖。

5) 一類新的死鎖以及如何解決
就在Adaptive Server Enterprise產品的設計中進行修正以防止死鎖和增加併發性的同時,也發生了一種情形,可能發生死鎖,而這種情況在過去是不可能發生的。

當一次更新操作必須訪問整個表時(例如此時不支持索引),可能會發生一種改變。在它們已經被確認爲符合要求之後,將只對個別行加鎖(以前是對一張表加鎖)。當訪問小表的時候,對於因爲性能的原因而建立的任何索引,一般而言都不會很多。如果一個用戶掃描這些小表之一,並對一行加以限定,這將隨之帶來一個排他性的行加鎖。如果第二個用戶也訪問同一張表,這種掃描就會因爲第一個用戶的排他性行加鎖所阻礙。如果第一個用戶試圖更新同一張表中的另一行,這種掃描也會被第二個用戶所阻礙,所以引起死鎖。

爲了解決這一問題,已經採用了一種稱之爲“併發優化”的優化程序。這個方法指明瞭如果在一張表中需要進行存取行的頁面數小於某個固定的數字(其缺省值爲16),那麼將不再考慮使用任何一個索引,而寧可對錶進行直接掃描。這就意味着對於很小的表,利用索引而不是用全表掃描方式直接訪問某些可能會產生直接影響的行,存在引起死鎖的可能性。在考慮掃描一張表之前,需要確定在一張表中能有多少頁,可採用如下的命令在頁級結構中加以配置:
sp_chgattribute <tablename>, “concurrency_opt_threshold”, <value>

爲了提高性能,也需要僅僅對錶中的少數行添加索引的建立。與以前一般都忽略了索引不同,現在利用索引是爲了提供最大的併發性並避免死鎖的發生。

      3.10.5 何時使用不同類型的加鎖方法

爲了在儘量降低資源消耗的前提下實現性能和併發性的平衡, Sybase 已經建立了集中加鎖方式,它們分別具有略有不同的特性。在什麼時候採用那一種加鎖方式,對這一問題。可以利用下列的“大拇指原則”,基於環境和應用程序的基本情況就應該採用的適當的加鎖框架,提出原則性的指導意見。

1) 全頁加鎖方式
? 除非有特別的理由,應儘量使用全頁加鎖方式,因爲它消耗諸如內存和CPU之類的資源最少。
? 如果發生爭用衝突,並不是空間的問題,而且也可以排除正在執行的工作負載是由於在特定點(例如熱點(hot spot))進行插入或延遲更新所引起的,在全頁加鎖方式下采用填充因子(Fillfactor)或max_rows_per_page 將能夠在不增加維護問題(重組)的條件下對行級加鎖提供類似的性能改善。
? 如果一張堆(棧)表中發生了大量的插入操作,而且空間不成爲問題的話,採用較大數目分區的全頁加鎖方式將使性能提高到一定的水平。
? 如果工作負載已經是同CPU緊密相關的,那麼附加的僅對數據加鎖方式所需要的CPU實用程序,可能也是使用與CPU較少關聯的全頁加鎖方式的一個主要原因。這一點對於已經使用了填充因子來解決爭用衝突問題的情況尤其如此。
2) 數據行加鎖方式
? 對於那些發生爭用衝突而且工作負載基本上是由於延遲更新所引起的情況,應該使用數據行加鎖方式,而不要再考慮空間問題。
? 一張表佔據數據庫空間的總量是一個問題,如果表較小而且有爭用和衝突的話,應該採用按行加鎖方式。
? 在一列需要非羣聚性索引而且該列上所有的插入操作都在這個索引的一個確定點上發生時,按行加鎖方式提供了既可以不發生索引加鎖爭用衝突的情況,又具有所需要的索引的能力。
? 對於那些正在使用堆(棧)表,但空間成爲問題的情況,僅對數據加鎖方法提供了較高的性能。
? 對於死鎖的發生,利用僅對數據行加鎖是一個可選的解決方案,其原因是或者由於較低的加鎖爭用衝突,或者由於採用了加鎖方式下的讀提交。
3) 數據頁加鎖方式
? 對於那些需要僅對數據加鎖但加鎖機制的數目是一個問題時(例如由於內存),那麼採用僅對數據頁加鎖可能就是一種最優的選擇。
? 當由於某個特定的或罕見的原因需要對一張表實現僅對數據加鎖時,那麼採用數據頁加鎖比數據行加鎖方式佔用的資源較少,而且當加鎖爭用衝突只是限制在索引時,會有相同或更好的性能。
      3.10.6 結論

在推出Adaptive Server Enterprise 11.9.2產品之前,在Sybase公司提供了最高性能的關係性數據庫服務器產品的同時,也存在着一組特定的加鎖問題限制了用戶可能獲得的性能。這些問題主要對那些不是針對該產品所專門設計的應用系統有所影響,可能需要在工作中逐步靠近Sybase產品,或者進行代價昂貴的性能改善以使應用系統更符合Sybase的技術特性。

隨着Adaptive Server Enterprise 11.9.2新版產品的普遍上市,Sybase公司正在向廣大用戶提供已被證明能夠解決加鎖爭用衝突問題的解決方案。他們既能使用戶在現存的應用系統中同樣達到以前所達到的非常高超的性能水平,同時又向用戶提供了一系列可以解決所可能遇到的加鎖爭用衝突問題的解決方案。

在本技術白皮書中所包含的測試結果,和通過論述這些結果的文獻已經論證了新型的加鎖和鎖存技術,可以使用戶在不需要任何應用系統作任何改變的條件下,大幅度地提高性能與可伸縮性。

Sybase已經作出了改變,對於先前或者是在有限的方式,或者是具有相當重要影響作用的方式下,使用Sybase產品的問題,都提供了採用範圍廣泛的組合方法以利用Sybase Adaptive Server Enterprise 11.9.2版本產品,清除以前所遇到的各種障礙。這樣一來,就可以使所有服務器的用戶,都能達到以前那些專門爲Sybase環境所特意設計的系統中所能體驗到的性能水平。
3.11 DBCC

我們知道,在數據庫系統的開發和應用中,必須保證數據庫的完整性和一致性。當數據庫出現了嚴重錯誤;當我們懷疑數據庫受到破壞(如無法用drop命令刪除數據庫或對象,使用某個表時出現“不可靠數據”的信息等);當用戶改變了Server的缺省排序的順序或改變了字符集而需要檢查;當SA對系統做定期檢查;這些時候,我們都需要使用數據庫一致性檢查工具(Database Consistenecy Checker,簡稱DBCC)。DBCC是一個實用命令集,用來檢查一個數據庫的邏輯一致性及物理一致性。在開發和應用中,DBCC是我們經常要使用的命令。

DBCC命令的格式如下 
dbcc
(checktable ((表名|表標識( [, skip_ncindex] ) |
checkdb [(數據庫名[, skip_ncindex] )] |
checkalloc [ (數據庫名[, fix | nofix] )] |
tablealloc( {表名|表標識}
[,{full |optimized |fast |null}
[, fix |nofix] ]]) |
indexalloc ( {表名|表標識},索引標識
[,{full |optimezed | fast | null}
[, fix |nofix ]] ) |
checkcatalog [ (數據庫名)] |
dbrepair(數據庫名,dropdb ) |
reindex({表名|表標識} ) |
fix_text({表名|表標識} ) 
dbcc的權限,對於checktable,fix_text和reindex是缺省賦給表的屬主,對於checkdb,checkalloc,checkcatalog,dbrepair,indexalloc和tablealloc,是缺省賦給數據庫屬主的。DBO自動獲得DBCC命令和全部選項的權限。該權限不可轉授。此外,dbcc在數據庫是活動時運行,除了dbrepair選項和帶有fix選項的dbcc checkalloc以外。

checktable選項
checktable是用來對一個指定的表做檢查,確保索引和數據頁正確地連接,索引按正確的順序存儲,所有指針的一致性,每頁上數據信息的合理性,頁偏移的合理性。如果日誌段在它自己的(日誌)設備上,對syslogs表使用dbcc checktable命令可以報告已使用的和剩餘的日誌空間,使用skip_ncindex選項使得dbcc checktable跳過對用戶表上非聚簇索引(nonclustered index)的檢查。缺省是檢查所有的索引。

例1.檢查日誌使用的空間量和未用的空間量:
dbcc checktable (syslogs) 

若日誌段在日誌設備上,則會返回如下信息:
checking syslogs
The total number of data page in the table is 1.
NOTICE:Space used on the log segment is 0.20 Mbytes, 0.13%.
NOTICE:Space free on the log segment is 153.4Mbytes,99.87%.
DBCC execution Completed.If dbcc printed error messages,
Contact a user with SA role. 
若日誌不在它自己的設備上,則會顯示下列信息:
NOTICE:Notification of log space used/free.
Can not be reported because the log segment is not on its own device.
例2. dbcc checktable (titles)
The total number of data page in this table is 3.
Table has 18 data rows.
DBCC execution Completed. If DBCC printed error messages. contact a user with SA role. 
checkdb選項
運行checkdb選項同checktable檢查的內容一樣,但它是對一指定數據庫中的每張表都做這樣的檢查。若未指定數據庫名,checkdb檢查當前的數據庫。checkdb返回的信息,也同於checktable。

checkalloc選項
checkalloc是檢查指定數據庫,看其所有正確分配的頁和尚未分配的頁的情況。若未指定數據庫名,則checkalloc檢查當前數據庫。checkalloc會返回已分配的和使用的空間數量。checkalloc的缺省模式爲nofix,要使用fix選項,必須把數據庫置於單用戶模式。  例:
dbcc checkalloc (pubs2)
.
.
.
alloc page 0 (#of extent=32 used pages=68 ref pages=68)
alloc page 256 (# of extent=32 used pages=154 ref pages=154)
alloc page 512 (# of extent=28 used pages=184 ref pages=184)
alloc page 768 (# of extent=1 used pages=1 ref pages=1)
total (# of extent=93 used pages=407 ref pages=407) in this database.
DBCC execution completed.If dbcc printed error message,
Contact a user with System Adminstrator (SA) role. 
tablealloc選項
tablealloc檢查指定的表以確保所有頁都被正確地分配。它是checkalloc的縮小版本。對單張表進行相同的完整性檢查。使用tablealloc可以生成三種類型的報表:full,optimized和fast。full選項相當於表一級的checkalloc;它報告各種類型的分配錯誤。optimized選項基於表的對象分配映像(OAM)頁裏列出的分配頁生成報告。它並不報告,也不能整理OAM頁裏沒有列出的在分配頁上沒有引用的擴展(extent)。如果沒有指明類型,或使用了null,則optimized選項是缺省的設置。fast選項,並不生成分配報告,但生成一個被引用但並沒有在擴展裏分配的頁的額外的報告。fix|nofix選項決定tablealloc 是否整理表中發現的分配錯誤。對於所有的表,缺省爲fix,但系統表除外,它們的缺省爲nofix。要對系統表使用fix選項,必須首先將數據庫置成單用戶模式。  例:
dbcc tablealloc(titles)
顯示信息如下:
The default report option of OPTIMIZED is used for this run. The default fix option of FIX.is used for this run.
.
.
.
Total #of extent=3
Alloc page 256 (# of extent=1 used pages=2 ref pages=2).
Alloc page 256(# of extent=1 used pages=2 ref pages=2)
Alloc page 256 (# of extent=1 used pages=2 ref pages=2)
Total (# of extent=3 used pages=8 ref pages=8) in this database. 
indexalloc 選項
indexalloc檢查指定的索引,確保所有的頁都被正確地分配,它是checkalloc的縮小版本,對單獨一條索引指定同樣的完整性檢查。其中各選項與tablealloc相同。
 
checkcatalog選項
checkcatalog選項用於檢查系統表內,系統表之間的一致性。例如:它確保在syscolumns表中的每一(數據)類型在systypes表中都有一個相匹配的記錄;對於sysobjects中的每個表和視圖在syscolumns表中應有關於它們每一列的描述記錄;確保在syslogs中的最後一個檢查點是有效的。checkcatalog也報告任何已定義的段。若不指定數據庫名,則檢查當前數據庫。

dbrepair選項
dbrepair(數據庫名,dropdb)選項是刪除一個受破壞的數據庫。受破壞的數據庫是不能用drop database命令刪除的,drop database只能刪除正常的數據庫,當執行dbrepair命令時,任何用戶(包括執行此命令的用戶)都不得使用正被刪除的數據庫。該選項要在master庫中運行。
 
reindex選項
reindex選項通過運行dbcc checktable的“fast”執行方式檢查用戶表上索引的完整性。如果它檢測出索引有問題則會刪除並重建索引。在ASE的排列順序改變之後,SA或表屬主應該執行這一選項。此選項不能在用戶定義的事務中運行。 例:
dbcc reindex (titles)
返回信息:One or more indexes corrupt.They will be rebuilt. 
fix_text選項
ASE的字符集由單字節轉變爲多字節後,fix_text選項用於升級文本值。ASE的字符集由單字節轉變爲多字節字符集會使文本數據的管理更加複雜。由於文本值可能較大足以覆蓋若干頁,ASE必須能處理(通過頁約束)可能橫跨頁的字符。爲做到這點,服務器需要在每一文本頁上添加一些信息。SA或表屬主必須在文本數據的每一個表上運行dbcc fix_text,以計算所需要的新頁數。

總之,DBCC命令所返回的信息能準確地反映數據庫及它的各個對象的狀態,是我們檢測數據庫的好幫手。
3.12 Sybase ASE的字符集

     3.12.1 概念

一、什麼是字符集?

字符集是字符(包含字母,數字,符號和非打印字符等)以及所指定的內碼所組成的特定的集合。通常一個字符集包含一個字母表中的字符,例如拉丁字母表被使用在英語語言中,那麼如果要使用拉丁字符,就要配置使用英語語言集中的特定的字符集合――拉丁語言字符集。這裏爲什麼特指了是英語語言集呢?因爲字符集是基於某種操作系統平臺和某種語言集支持的。語言集的集合被稱爲語言組,它可能包含一種或多種語言。本地字符集是基於特定語言組中所包含的一種或多種語言支持的,在特定操作系統平臺上編碼的集合。
在Client/Server系統中,支持多語言的數據處理,但是所有的語言必須屬於同一個語言組。例如,從下表可以看出,如果服務器中的數據用組1中的字符集,則同一數據庫中可以有法語,德語,英語以及該組中的其它語言。而在這個數據庫中就不能同時存儲日語,法語了。
這裏請注意一個非常特別的字符集—Unicode—它支持世界上超過650種語言的國際字符集。Unicode允許在同一服務器上混合使用不同語言組的不同語言。

                  表1-1  Adaptive Server支持的語言和字符集
 
 
注意:表中所顯示的所有字符集,因爲任何字符集的前128(十進制)個字符都包含拉丁字母表,所以所有字符集都支持英語。各字符集中前128個字符之外的字符各不相同,用於支持不同的本地語言字符。

二、什麼是排序順序?

每種字符集都有一種或多種排序順序,Adaptive Server使用它們存儲數據。排序順序與特定的語言或語言組及特定的字符集聯繫密切,不同的語言對同樣字符的排序是不同的,因此,需要特定語言的排序順序,以便正確地對字符進行排序。另外,排序順序與特定地字符集也密切相關,對於特定字符集可使用的排序順序位於字符集目錄的排序順序定義的文件中(.srt文件)。
有關字符集及其可用排序順序的列表,如下所示:
                 
                          表1-2可用的排序順序
 
 

排序順序用於
――創建索引
――將數據存入按索引排序的表
――指定order by子句

對於不同類型排序順序的解釋
二進制排序順序:
對於所有字符集都至少提供一個二進制排序順序,這一排序順序基於字符集中分配給代表每個字符的代碼(“二進制”代碼)的算數值,適用於每個字符集的前128個字符和亞洲語言。當字符集支持一種以上的語言時,二進制排序順序將會得出不正確的結果,這時就應該選擇其它排序順序了。

字典排序,區分大小寫,區分重音:
分別對大寫和小寫字母進行排序。字典排序順序識別字母的各種重音形式,並將它們排在相關聯的非重音字母之後。

字典排序,不區分大小寫,區分重音:
按字典順序排序,大寫字母與小寫字母等同,在排序結果中大小寫字母混合使用。對於避免表中名稱的重複條目很有用。

字典排序,不區分大小寫,區分重音,具有優先級:
在排序時不區分大小寫,在所有其它條件相同時,大寫字母具有高的優先級(即大寫字母先出現)。
當order by子句中指定的列與表的聚簇索引鍵值相匹配時,使用這種排序順序可能導致大表性能降低,因此,不建議使用這種排序順序,除非特意要求大寫字母排在小寫字母之前。

字典排序,不區分大小寫,不區分重音:
將加重音格的字母與未加重音格的相關聯字母同等對待,它在排序中混合了重音字符。

三、什麼是字符集轉換?

爲保持客戶端與服務器之間的數據完整性,數據必須在字符集之間進行轉換,目的是跨機器和字符集使用時,確保“a”還是“a”,此過程就是字符集轉換。

字符集轉換的方式
本地字符集的轉換:
Adaptive Server支持屬於同一語言組的本地字符集之間的轉換。如果服務器把一種本地字符集作爲它的缺省值,則客戶端字符集必須屬於同一個語言組,此時可以在服務器上瀏覽所有客戶端提交的數據。如下圖:

               圖1-3 服務器端和客戶端字符集屬於同一語言組
 

本圖中,服務器端與客戶端使用的語言集與字符集都同屬於組1(見表1-1),那麼他們之間實現的就是本地字符集轉換方式。

Unicode系統中的轉換方式:
在Unicode系統中,由於服務器的缺省字符集爲UTF-8,所以客戶端字符集可以是任何語言組中的一種本地字符集。如下圖:

圖1-4Unicode系統中的字符集轉換
 
上圖中來自每一個客戶端的數據經過服務器和每個客戶端時,都會被正確轉換,而無論每一個客戶端選擇的時哪個語言組的字符集,原因是ASE服務器端選擇了缺省字符集UTF-8.

字符集轉換類型
直接轉換:
支持同一語言組內兩種本地字符集之間的轉換。例如,Adaptive Server支持CP437與CP850之間的轉換,因爲他們同屬於第1語言組。

Unicode轉換:
Unicode轉換可應用於所有本地字符集,在兩種本地字符集之間進行轉換時,Unicode轉換方式把Unicode作爲中間字符集。例如,在服務器缺省字符集CP437和客戶端字符集CP860之間進行轉換時,CP437先被轉換成Unicode,Unicode再轉換成CP860。
Unicode轉換方式既可以用於服務器缺省字符集UTF-8,還可用於本地字符集。除非使用服務器缺省字符集UTF-8,否則您必須專門配置您的服務器才能使用Unicode轉換方式(配置方法請參看配置篇之如何配置字符集的轉換類型)。

如何選擇字符集的轉換方式
這將取決於系統的類型。
在非Unicode系統中,服務器和客戶端的字符集爲本地字符集,因此可以使用Adaptive Server直接轉換,但是有些字符集沒有直接轉換,這種情況就必須使用Unicode轉換了。
如下表所示:
 
             表1-5 字符集轉換方式
 
 
――如果系統中使用的所有字符集都在表1-5的列1中,則使用直接轉換。前提是所有字符集同屬於一個語言組。
――如果系統中使用的所有字符集都在表1-5的列2中,或者有些在列1中,有些在列2中,那麼必須配置服務器使用Unicode轉換方式。前提是所有字符集同屬於一個語言組。

在Unicode系統中,如果服務器缺省字符集爲Unicode UTF-8,那麼所有的轉換將在UTF-8與客戶端使用的本地字符集之間進行,因此,在Unicode系統中,只能使用Unicode轉換。

     3.12.2 配置

一、 如何配置字符集的轉換類型

禁用字符集轉換的配置方法
在isql環境中執行:
1> sp_configure “disable character set conversion”,1
2> go
 “disable character set conversion”參數默認配置值爲0,即啓用字符集轉換。

如何配置字符集的轉換類型
把”enable unicode conversions”參數設置爲1或者2。當配置爲1時,此設置使用直接轉換或Unicode轉換;當配置爲2時,此設置使用Unicode轉換;默認配置值爲0,使用直接轉換。
在isql環境中執行:
1> sp_configure ”enable unicode conversions”,1
2> go

二、如何配置服務器端缺省字符集

直接轉換法
直接轉換法是指直接使用Sybase提供的實用程序,如UNIX平臺上使用sqlloc命令或者編輯sqlloc.rs腳本文件;Windows平臺使用“服務器配置”圖形化管理工具直接配置服務器端字符集。

使用直接轉換法的條件是:
――服務器中沒有用戶數據
――對服務器中用戶數據的損壞是可以接受的
――絕對確定服務器中的數據只使用ASCII-7字符集

間接轉換法
間接轉換法相對於直接轉換法而言,需要通過一下三步來完成配置工作:
1. 先將服務器端的數據使用bcp命令導出
2. 再選擇直接轉換法之中的一種方式配置服務器端字符集
3. 再使用帶有-J 參數的bcp命令把數據導回服務器端

配置服務器端字符集的方法
sqlloc—適用於UNIX平臺的命令
在$SYBASE_OCS/bin目錄下執行:sqlloc,將出現一個圖形化界面,在這個界面中您可以直接選擇語言集,字符集,排序順序,便很容易地就完成了配置工作。

編輯sqlloc.rs腳本文件
將$SYBASE-ASE/init/sample_resource_files/sqlloc.rs拷貝到$SYBASE_OCS/bin目錄下,按以下黑體字提示編輯該文件:
sybinit.release_directory: /home/sybase―――輸入Sybase產品的安裝路徑
sqlsrv.server_name: SYB125―――輸入數據庫服務器的名稱
sqlsrv.sa_login: sa
sqlsrv.sa_password: ―――輸入sa的口令,若爲空,則什麼也不填
sqlsrv.default_language: us_english―――輸入想要配置的語言集
sqlsrv.language_install_list: USE_DEFAULT
sqlsrv.language_remove_list: USE_DEFAULT
sqlsrv.default_characterset: cp850―――輸入想要配置的字符集
sqlsrv.characterset_install_list: USE_DEFAULT
sqlsrv.characterset_remove_list: USE_DEFAULT
sqlsrv.sort_order: binary―――輸入想要配置的排序順序

# An example sqlloc resource file...
# sybinit.release_directory: USE_DEFAULT
# sqlsrv.server_name: PUT_YOUR_SERVER_NAME_HERE
# sqlsrv.sa_login: sa
# sqlsrv.sa_password:
# sqlsrv.default_language: french
# sqlsrv.language_install_list: spanish,german
# sqlsrv.language_remove_list: USE_DEFAULT
# sqlsrv.default_characterset: cp437
# sqlsrv.characterset_install_list: mac,cp850
# sqlsrv.characterset_remove_list: USE_DEFAULT
# sqlsrv.sort_order: dictionary

保存已經修改好的sqlloc.rs腳本文件,執行以下命令:

sqllocres -r sqlloc.rs

注意屏幕上出現的提示信息,如無異常,則完成配置工作。

“服務器配置”圖形化管理工具――適用於Windows平臺
“服務器配置”管理工具提供了一個易於操作的圖形化管理平臺,根據工具中提示的信息,很容易就完成了字符集的配置工作,這裏就不多講了,請參看相關文檔說明。

三、如何配置客戶端缺省字符集

配置客戶端缺省字符集實際上就是對“$SYBASE\locales”目錄下locales.dat文件的修改。
在Windows平臺用寫字板方式打開該文件,在UNIX平臺可以直接使用“vi”命令打開該文件,我們會看到,該文將中所有字符集的配置都是以服務器端操作系統平臺名稱分組的:
.
.
[aix]
 locale = C, us_english, iso_1
 locale = En_US, us_english, iso_1
 locale = en_US, us_english, iso_1
 locale = default, us_english, iso_1
 locale = En_US.IBM-850, us_english, cp850
 locale = en_JP, us_english, eucjis
 locale = Fr_FR, french, cp850
.
 .
[axposf]
 locale = C, us_english, iso_1
 ; Use Posix Locales, straight from the Posix Guidelines
 locale = en_US.88591, us_english, iso_1
 locale = fr_FR, french, iso_1
 locale = zh_CN, chinese, eucgb
 locale = zh_TW, tchinese, euccns
 locale = ko_KR, korean, eucksc
 locale = us_english.utf8, us_english, utf8
 locale = default, us_english, iso_1
.
.
其中,操作系統名稱放在每一組最開始的“[]”中,而且請注意上面黑體字,每一組中都會存在一行“locale = default,…”。我們要修改客戶端的默認字符集,就是對這一行進行修改。
例如,某系統服務器端是SUN平臺,服務器端語言集爲english,字符集爲cp850。我們要修改客戶端字符集與服務器端一致,怎麼做?
首先找到[SUN]操作系統分組,然後修改“locale = default,…”爲“locale = default,us_English,cp850”。

修改前:
[sun]
 ; from JLE, KLE, CLE, OS/4.1.1, man setlocale()
 ; and Sun Software Internationalization Guide (p/n 800-5972-08)
 ; use setenv LC_CTYPE, LC_MESSAGES, LANG
 locale = C, us_english, iso_1
 locale = fr, french, iso_1
 locale = de, german, iso_1
 locale = tr, us_english, iso88599
 locale = zh, chinese, eucgb
 locale = zh_CN, chinese, eucgb
 locale = zh_TW, tchinese, euccns
 locale = ko, korean, eucksc
 locale = us_english.utf8, us_english, utf8
 locale = default, us_english, iso_1

修改後:
[sun]
 ; from JLE, KLE, CLE, OS/4.1.1, man setlocale()
 ; and Sun Software Internationalization Guide (p/n 800-5972-08)
 ; use setenv LC_CTYPE, LC_MESSAGES, LANG
 locale = C, us_english, iso_1
 locale = fr, french, iso_1
 locale = de, german, iso_1
 locale = tr, us_english, iso88599
 locale = zh, chinese, eucgb
 locale = zh_CN, chinese, eucgb
 locale = zh_TW, tchinese, euccns
 locale = ko, korean, eucksc
 locale = us_english.utf8, us_english, utf8
 locale = default, us_english, cp850
保存該文件,就完成對客戶端字符集的修改了。

這裏,還要說明一種特殊情況:
爲了滿足服務器端某些應用的特殊需求,在服務器端設置了一個環境變量:LANG,此時客戶端字符集該如何設置呢?
例如,某系統服務器端是Windows平臺,使用語言集english,字符集iso_1,並設置環境變量LANG=C。我們要修改客戶端字符集與服務器端一致,怎麼做?
首先找到[NT]操作系統分組,然後在該組中加入一行
“locale = C,us_English,iso_1”

修改前:
[NT]
 locale = enu, us_english, iso_1
 locale = fra, french, iso_1
 locale = deu, german, iso_1
 locale = japanese, japanese, sjis
 locale = chs, chinese, eucgb
 locale = cht, tchinese, big5
 ; locale = kor, korean, eucksc
 locale = us_english.utf8, us_english, utf8
 locale = default, us_english, iso_1
修改後:
[NT]
 locale = enu, us_english, iso_1
 locale = fra, french, iso_1
 locale = deu, german, iso_1
 locale = japanese, japanese, sjis
 locale = chs, chinese, eucgb
 locale = cht, tchinese, big5
 ; locale = kor, korean, eucksc
 locale = us_english.utf8, us_english, utf8
 locale = default, us_english, iso_1
locale = C,us_english,iso_1

因此在修改客戶端字符集之前,請先查看服務器端是否設置了環境變量“LANG“,再決定如何修改。

四、如何選擇ASE字符集使之支持中文字符

目前在ASE 12.5中支持中文字符的字符集有四種:CP936,EUCGB,UTF-8和GB18030。
其中EUCGB字符集是基於GB2312-80編碼規範的,它的EUC (Extended Unix Code)編碼範圍是第一字節0xA1~0xFE(實際只用到0xF7),第二字節0xA1~0xFE。
CP936字符集是基於GBK編碼規範(實際上的國家標準是GB13000-90),是對GB2312進行的擴展,第一字節爲0x81~0xFE,第二字節分兩部分,一是0x40~0x7E,二是0x80~0xFE。其中和GB2312相 同的區域,字完全相同。
GB18030字符集(國家標準號是GB18030-2000)是2000年3月17日發佈的新的中文編碼標準。它是GB2312的擴充,採用單/雙/四字節編碼體系結構,收錄了27000多個漢字以及臧文、蒙文、維吾爾文等主要的少數民族文字。Sybase 從ASE 12.5.0.3之後開始支持GB18030字符集。
UTF-8字符集是現有ASCII系統向Unicode轉換的一個過渡方案。它使用1-3字節表示一個字符。簡體中文的每個字符在utf8中的長度基本上都是3個字節。它的最主要的優點是可以同時支持超過650種語言的字符。缺點是針對中文字符來說,需要增加50%的空間用來存儲。
一般來說,由於EUCGB不支持國標一、二級字庫以外的漢字,所以我們推薦用戶在服務器端和客戶端都使用CP936字符集,或者在ASE 12.5.0.3之後還可以使用GB18030字符集,它可以支持一些比較生僻的漢字。它的不足是隻有一種排序方式,即區分大小寫的Binary方式。所以,如果需要使用支持中文字符集且不區分大小寫的數據庫時,就只能使用UTF-8作爲服務器端字符集,而客戶端使用CP936或GB18030字符集。
另外,還有一種選擇是,服務器端和客戶端都使用iso_1字符集,雖然iso_1字符集並不直接支持中文字符,但我們將服務器端和客戶端都設置成iso_1字符集後,系統也不會在客戶端和服務器端進行字符轉換,它只不過將一個漢字的兩個字節當做兩個單獨字符來處理,一般情況下沒有問題。但當執行like匹配查詢的時候,它有可能返回不正確的結果,原因是服務器端是根據單字節去匹配查詢條件的,很可能會有前一個漢字的第二字節與後一個漢字的第一字節的內碼組合符合查詢條件,被服務器端作爲查詢結果返回來。
如果客戶端是通過JDBC訪問數據庫的,那麼,爲了支持中文字符,服務器端最好採用CP936/GB18030或UTF-8作爲字符集。如果應用是多層結構的,那麼應用服務器的字符集也最好採用與數據庫服務器端相同的字符集。

五、如何查看服務器端、客戶端字符集

查看服務器端字符集:
在isql環境中執行:
1> sp_helpsort
2> go

查看客戶端字符集:
在isql環境中執行:
1> select @@client_csname
2> go

3.12.3 錯誤處理

爲什麼會出現字符集轉換失敗?

1. 當字符存在於客戶端字符集中但在服務器字符集中不存在時,Adaptive Server的字符集轉換將報告轉換錯誤,反之亦然。
用戶會碰到下面的錯誤消息:
Msg 2402,Severity 16 (EX_USER):
Error converting client characters into server's character set. Some character(s) could not be converted.
轉換錯誤會阻止插入與更新語句的執行。如果發生此情況,請檢查數據中有問題的字符並替換它們。

2. 當客戶端發送數據時Adaptive Server遇到轉換錯誤,它用ASCII碼的問號(?)代替可疑字符所佔字節,但查詢批處理繼續進行直到完成爲止。
語句完成後,Adaptive Server將發送一下消息:
Msg 2403,Severity 16 (EX_USER):
WARNING!  Some character(s) could not be converted into client's character set.  Unconverted bytes were changed to question marks (`?')。

3. 當在客戶端查詢服務器端存儲的數據時,當碰到中文漢字,在客戶端顯示亂碼的現象,且沒有任何提示信息。
這是我們在應用中經常會碰到的現象,產生的原因是:客戶端與服務器端字符集不符。怎麼解釋呢?假設我們先期設置服務器端字符集爲iso_1,客戶端字符集也爲iso_1,然後我們從客戶端向服務器端錄入了所有的數據;之後當我們需要查詢時,使用的客戶端,它的字符集爲cp850,那麼勢必在該客戶端上顯示的字符集爲亂碼。
當出現這種情況時,最好配置客戶端字符集爲先期客戶端使用的字符集或者配置客戶端字符集與服務器端字符集一致,使得客戶端字符集與服務器端字符集匹配。這裏我們不建議用戶修改服務器端字符集,因爲服務器中此時已經存在大量的數據,在使用直接轉換方式時,由於源字符集與目的字符集中可能存在無法轉換的字符而導致Adaptive Server無法啓動;如果使用間接的轉換方式,會增加工作量。

      3.12.4 附:如何安裝cp936字符集

以在Windows平臺安裝cp936字符集爲例,說明如何安裝使用服務器中沒有被默認安裝的字符集。(在ASE 12.5.0.3版本中安裝GB18030字符集的方法類似)

(這裏SYBASE的安裝路徑爲c:\sybase)

1.c:\>cd \sybase\charsets\cp936
2.c:\sybase\charsets\cp936> charset -Usa -Psa_pass -Sserver_name binary.srt cp936
3.在SQL環境中
1>select name,id from syscharsets
2>go
找到name爲cp936對應的id(假設爲171)
4.1>sp_configure "default character set id",171
2>go
5.重啓server兩次
(注:第一次啓動後,server會自動宕掉,需要第二次重啓後才能使用)

發佈了15 篇原創文章 · 獲贊 32 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章