2011年7月10日

「我回不去了」之 Microsoft SQL Server 資料庫版本問題

台視於 2010 年 11 月播出的《犀利人妻》(英文劇名為:The Fierce Wife、日文劇名為:結婚って、幸せですか)偶像劇,在完結篇那集,有一句經典台詞:「我回不去了」,引發不少迴響。

八卦一下,該劇在 2011 年 6 月 9 日起,每週四晚上 11:00 ~ 11:54 也在 BS 日本電視台播放,我們也有偶像劇可以進軍日本。

圖片來源:BS 日本電視台:結婚って、幸せですか

在 0 與 1 的資訊界中,Microsoft SQL Server 也有「我回不去了」的情況發生。這是怎麼一回事呢?

當您把較新版本 SQL Server 上的資料庫附加或還原到較舊版的 SQL Server 時,就會發生「我回不去了」的事情。

Microsoft SQL Server 有版本Edition:通常是指產品的分類,例如:標準版、企業版;Version:產品的版號,例如:2005、2008)、Service Packs相容性層級、與內部的資料庫版本,相信很多人都知道前面幾種,卻可能不知道還有相容性層級以及內部資料庫版本這 2 個與版本相關的名詞。

以下就分別介紹相容性層級以及內部資料庫版本。

相容性層級

當新版 SQL Server 發行時,除了新增功能之外,也可能會改變一些行為(例如:從 SQL Server 7.0 開始,在執行 ALTER TABLE 的同時,可以使用 ALTER COLUMN 子句來改變欄位的設定)。為了不讓原本於舊版 SQL Server 可使用的程式,於升級 SQL Server 之後,發生不能執行或是執行的結果與舊版 SQL Server 不同,遂有相容性層級這樣的設定。

在 SQL Server 2000 的 Enterprise Manager 管理工具可以查看並設定相容性層級,如下所示的相容性層級設定為 80
在 Enterprise Manager 查看相容性層級

在 SQL Server 2005 / 2008 / 2008 R2 的 Management Studio 管理工具可以查看並設定相容性層級,如下所示的相容性層級設定為 90
在 Enterprise Manager 查看相容性層級

使用下面的 T-SQL 可查詢相容性層級:
USE master;
go
SELECT name 資料庫名稱, cmptlevel 相容性層級 FROM sysdatabases;
查詢相容性層級

使用預存程序也行:
EXEC sp_helpdb;

SQL Server 2005 開始提供「資料庫和檔案目錄檢視」的新功能,所以亦可在 SQL Server 2005 之後的版本,使用如下的 T-SQL 指令來查詢相容性層級:
-- SQL 2005 以上的版本,可由檢視表(View)查詢
SELECT name 資料庫名稱, compatibility_level 相容性層級 FROM sys.databases;

相容性層級與資料庫版本的對應關係如下所示:
資料庫版本 相容性層級
SQL Server 6.060
SQL Server 6.565
SQL Server 7.070
SQL Server 200080
SQL Server 200590
SQL Server 2008100

由上面的查詢結果或設定畫面,可以看出相容性層級是針對單一資料庫,而非整個執行個體。

欲調整相容性層級,除了使用 GUI 介面的 Enterprise Manager、Management Studio 管理工具之外,也可透過 T-SQL 指令。唯在執行時,需特別注意,避免在使用者仍連線到資料庫時,變更相容性層級,此舉可能會讓使用中的查詢,產生不正確的結果。因此建議依照下列步驟變更相容性層級:
  1. 將資料庫設定為單一使用者存取模式。
  2. 變更資料庫的相容性層級。
  3. 將資料庫設定成多使用者存取模式。
上述步驟用 T-SQL 指令來表達即為:
EXEC sp_dboption '<資料庫名稱>', 'single user', 'true';
go

EXEC sp_dbcmptlevel '<資料庫名稱>', '<相容性層級>';
go

EXEC sp_dboption '<資料庫名稱>', 'single user', 'false';
go
如果是 SQL Server 2005 以上的版本,可以改用新的 T-SQL 語法:
-- SQL Server 2000 亦可用此指令
ALTER DATABASE <資料庫名稱> SET SINGLE_USER;
go

ALTER DATABASE <資料庫名稱> SET COMPATIBILITY_LEVEL = <相容性層級>;
go 

-- SQL Server 2000 亦可用此指令
ALTER DATABASE <資料庫名稱> SET MULTI_USER;
go

於建立新資料庫時,SQL Server 如何去決定相容性層級的版本呢?當 SQL Server 收到 CREATE DATABASE 陳述式時,會複製 model 資料庫的內容,來建立資料庫的第一個部份,剩餘的部份則填入空白頁。

在預設狀態下,系統資料庫 model 的相容性層級會跟前面所列的那張表一樣,除非有去調整系統資料庫 model 的相容性層級,這麼一來,爾後建立的所有資料庫自然都會繼承相容性層級的變更。

內部資料庫版本

當我們使用附加或是還原的方式,將舊版 SQL Server 的資料庫附加或還原到新版 SQL Server 時,SQL Server 會自動升級內部資料庫版本。一般來說,版本升級的過程是看不到的,藉由特定的方式,即可看到此升級過程。

如下所示,即為附加 SQL Server 2000 所建立的 NorthWind 資料庫時,升級過程中,所顯示的訊息:
將資料庫 'NorthWind' 從版本 539 轉換為目前版本 661。
資料庫 'NorthWind' 正在執行從版本 539 升級到版本 551 的步驟。
資料庫 'NorthWind' 正在執行從版本 551 升級到版本 552 的步驟。
資料庫 'NorthWind' 正在執行從版本 552 升級到版本 611 的步驟。
...
...
資料庫 'NorthWind' 正在執行從版本 660 升級到版本 661 的步驟。

▼ 資料庫 NorthWind 從版本 539 升級到 661
資料庫 NorthWind 從版本 539 升級到 661

下面的訊息是將 SQL Server 2000 所備份出來的 Pubs 資料庫,在 SQL Server 2008 R2 還原時,所顯示的升級訊息:
已處理資料庫 'Pubs' 的 208 頁,檔案 1 上的檔案 'pubs'。
已處理資料庫 'Pubs' 的 1 頁,檔案 1 上的檔案 'pubs_log'。
將資料庫 'Pubs' 從版本 539 轉換為目前版本 661。
資料庫 'Pubs' 正在執行從版本 539 升級到版本 551 的步驟。
資料庫 'Pubs' 正在執行從版本 551 升級到版本 552 的步驟。
資料庫 'Pubs' 正在執行從版本 552 升級到版本 611 的步驟。
...
...
資料庫 'Pubs' 正在執行從版本 660 升級到版本 661 的步驟。
RESTORE DATABASE 已於 0.361 秒內成功處理了 209 頁 (4.506 MB/sec)。

▼ 資料庫 Pubs 從版本 539 升級到 661


使用下面的 T-SQL 可以知道資料庫現在的內部版本為何:
--查詢資料庫的內部版本
USE <資料庫名稱>;
go

SELECT DATABASEPROPERTY('<資料庫名稱>', 'Version') 資料庫內部版本;

-- 適用 SQL Server 2005 以上的版本
SELECT DATABASEPROPERTYEX('<資料庫名稱>', 'Version') 資料庫內部版本
如果要知道當初建立資料庫的內部版本,請使用下面的 T-SQL:
USE <資料庫名稱>;
go

DBCC TRACEON (3604);  
DBCC DBINFO;
DBCC TRACEOFF (3604);
— 或  —
DBCC TRACEON (3604);
DBCC PAGE ('<資料庫名稱>', 1 ,9 ,3);
DBCC TRACEOFF (3604);

執行的部分結果如下:
DBCC 的執行已經完成。如果 DBCC 印出錯誤訊息,請連絡您的系統管理員。

...
...

DBINFO @0x000000000BAAA060

dbi_dbid = 6                         dbi_status = 29                      dbi_nextid = 1221579390
dbi_dbname = NorthWind               dbi_maxDbTimestamp = 1100            dbi_version = 661
dbi_createVersion = 539              dbi_ESVersion = 0                    
dbi_nextseqnum = 1900-01-01 00:00:00.000                                  dbi_crdate = 2004-12-13 16:11:08.590
dbi_filegeneration = 0               
dbi_checkptLSN

...
...

DBCC 的執行已經完成。如果 DBCC 印出錯誤訊息,請連絡您的系統管理員。
DBCC 的執行已經完成。如果 DBCC 印出錯誤訊息,請連絡您的系統管理員。


內部資料庫版本與資料庫版本的對應關係如下所示:
資料庫版本 內部資料庫版本
SQL Server 7.0515
SQL Server 2000539
SQL Server 2005611/612
SQL Server 2008655
SQL Server 2008 R2661

沒有留言:

張貼留言