Date: Sat, 21 Feb 2004 18:35:50 +0900
From: "Akira Horikawa" <who@example.ne.jp>
堀川です、今晩は
-----Original Message-----
From: Akira Horikawa [mailto:who@example.ne.jp]
Sent: Thursday, January 29, 2004 12:51 AM
To: who@example.ne.jp
Subject: [ml-msde-beg:01031] 一括ログ記録モードの危険性について
昨日のPASSJ カンファレンスセミナーでは、
>このような話の内容を、PASSJカンファレンスではデモする予定なのですが、
>話すことが多いのでデモは割愛するかもしれません。
デモする予定でしたが、時間が無くてできませんでした。
デモで使う予定だったプログラムを掲載しますので、ぜひ1度、MSDE2000や
SQLServer2000で実行して頂き、その意味をご理解下さい。
------------------------
(1)データベースの新規作成
------------------------
CREATE DATABASE TEST
ON PRIMARY
(
NAME = TEST_DAT , -- 論理ファイル名
FILENAME = 'D:\WORK\TEST.MDF' -- 物理ファイル名
)
LOG ON
(
NAME = TEST_LOG , -- 論理ファイル名
FILENAME = 'D:\WORK\TEST.LDF' -- 物理ファイル名
)
ドライブ名やサブディレクトリ名などを書き換えて、実行します。
--------------------------------------------------
(2)データベースの復旧モデルを「一括ログ記録」に変更する
--------------------------------------------------
ALTER DATABASE TEST SET RECOVERY BULK_LOGGED
SELECT DATABASEPROPERTYEX( 'TEST' , 'RECOVERY' )
DATABASEPROPERTYEX関数は、データベースのオプション状態などを
調べることができます。
-----------------------------------
(3)テーブルを作成し、レコードを挿入する
-----------------------------------
USE TEST
GO
CREATE TABLE TBL(
ID INT PRIMARY KEY ,
DT VARCHAR(10)
)
GO
INSERT INTO TBL(ID,DT) VALUES(1,'A')
INSERT INTO TBL(ID,DT) VALUES(2,'B')
INSERT INTO TBL(ID,DT) VALUES(3,'C')
INSERT INTO TBL(ID,DT) VALUES(4,'D')
INSERT INTO TBL(ID,DT) VALUES(5,'E')
GO
-----------------------------------------
(4)データベースの完全バックアップを実行する
-----------------------------------------
BACKUP DATABASE TEST
TO DISK='D:\WORK\TEST.BAK'
ドライブ名などを書き換えて下さい
このバックアップファイルの中には、(3)のレコード挿入の結果が含まれています。
-------------------------------
(5)SELECT INTO 命令を実行します
-------------------------------
USE TEST
GO
SELECT * INTO TBL_COPY FROM TBL
GO
INSERT INTO TBL(ID,DT) VALUES(10,'X')
INSERT INTO TBL(ID,DT) VALUES(11,'Y')
INSERT INTO TBL(ID,DT) VALUES(12,'Z')
GO
従来のSQLServer7.0/MSDEでは、SELECT INTO命令はログに記録されない
命令と呼ばれており、原則的には実行できませんでした。
それが、SQLServer2000/MSDE2000では、いつでも実行できます。
ただし、「一括ログ記録」モードの運用では、注意が必要です。
その注意点を体験します。
-----------------------------------------------------------
(6)ここでデータベースのサービスを止めて、TEST.MDFファイル名の変更
-----------------------------------------------------------
(5)を実行した後に、データベースが壊れたことを想定します。
データベースを壊す方法で一番簡単な方法は、サービスを止めて、プライマリ
データファイル(MDFファイル)を削除することです。
ここでは、ファイル拡張子を変更しました。
----------------------------------------------------
(7)サービス再開後、TESTデータベースが壊れていることを確認
----------------------------------------------------
SELECT DATABASEPROPERTYEX( 'TEST' , 'Status') AS 現在状態
DATABASEPROPERTYEX関数を使って、データベースが壊れていることを
確認します。
SUSPECT と表示されるはずです。
データベースサービスを再開させたときに、各データベースの状態を
トランザクションログによって復旧させます。
このSUSPECTとは、その復旧ができなかったことを意味します。
午前中のメールにも書きましたが、データのキャッシュ情報が、データファイルに
書き込まれずにサービスが停止されることがあります。
このようなデータベースの状態は許されません。
トランザクションが、コミットしたのか、ロールバックしたのか、その結果が
データファイルには反映されておりません。
そこで、トランザクションログファイルの内容を参照し、データベースのデータ
ファイルの内容を正しい状態に修復する操作が、データベースサービス開始時の
復旧処理と呼ばれます
データファイルは、OSによって、その内容がメモリにキャッシュされます。
トランザクションログファイルは、キャッシュされず、DISKに即座に書き込み
されるとお考え下さい。
----------------------------------------------------
(8)トランザクションログファイルのバックアップの実行
WITH NO_TRUNCATEオプション付きで実行
----------------------------------------------------
BACKUP LOG TEST
TO DISK='D:\WORK\TESTLOG.BAK'
WITH NO_TRUNCATE
データベースが壊れたら、まず最初に、トランザクションログファイルの
バックアップを実行します(WITH NO_TRUNCATEオプションが必要)
ここで正常にログのバックアップが取れたら、そのログの中には、(5)の
レコード操作記録が含まれます。
そこで、(4)の完全バックアップのファイルと、このログのバックアップファイル
によって、データベースが壊れた直前まで、復元できることになります。
ところが、「一括ログ記録」モードでは、このログのバックアップは失敗します。
このエラーを確認することが、重要です。
「一括ログ記録」のログのバックアップ操作では、データファイルの内容を
参照します。
データファイルの内容が参照できなければ、ログのバックアップはできません。
厳密には、SELECT INTOなどの命令を実行していたら、データファイルの
参照が必要となるという意味です。
データベースをフルモードにすれば、エラーは出ません。
ですからSQLServer2000では、フルモードが初期値になっています。
なお、MSDE2000は、シンプルモードが初期値です。
ご注意下さい
------------------------------------
(株)日本技術ソフト開発
堀川 明 (Akira Horikawa)
02月21日(土曜日) 18時35分記
mailto:who@example.ne.jp
http://www.horikawa.ne.jp/msde/
[MSDE/SQLServerに関して、今、どんなことにお困りですか?] |
よろしければお困りの内容を、電子メールで教えて下さい。 |
質問を電子メールで作成する
|
[ウィンドを閉じる][MSDE/SQLServer FAQ ][MSDE / MSDE2000 技術サポート情報一覧]
|