アーカイブ

‘sqlserver’ カテゴリーのアーカイブ

SQL Server 2000 (2005, 2008でも多分可)でインデックスの再構築

2009 年 10 月 27 日 tdtsh コメントはありません

SQL Server 2000時代に、インデックスの再構築といえば

dbcc dbreindex

でしたが、このコマンドは将来なくなる様ですね。
かわりに、alter index rebuild を使えとの事。
rebuild句が、dbreindexと同じ機能です。
all on を指定しないと、非クラスタ化インデックスは再構築されないそうな。

alter index all on テーブル名 rebuild

参考サイトを元に、新たなストアドを作った。

USE MASTER
GO

create procedure sp_reindex as

DECLARE @tablename varchar(30)

DECLARE tables CURSOR FOR
SELECT name FROM sysobjects WHERE type = 'U'
OPEN tables

FETCH NEXT FROM tables INTO @tablename
WHILE (@@fetch_status <> -1)
BEGIN
	Execute ('ALTER INDEX ALL ON' + @tablename + ' REBUILD')
	FETCH NEXT FROM tables INTO @tablename
END
DEALLOCATE tables
GO

USE YOUR_DATABASE
exec SP_REINDEX
カテゴリー: sqlserver タグ:

MS SQL Server 2000について、 2002年頃に書いたメモ

2009 年 8 月 6 日 tdtsh コメントはありません

ロックアーキティクチャ

ロックの自動エスカレーション

SQL Server 2000のロックは、動的にロック方法を自動判断して行われる。

行ロック・ページロック・DBロック

上記のチューニングとしてMS SQLでは”分離レベル”の設定 が4つある。
下に行くほどデータの整合性が上がるが、デッドロックが起こりやすくなる。
OLTPの場合、余程大勢でInsert、Updateをしない限り、デフォルトでいいんじゃないかと思う。
トランザクションを使用する場合は、明示的に 3) を選択 (後述) する場合もあるかも知れない。
但し、トランザクションは短めに。

1) READ UNCOMMIITTED
ユルユル。ダーティリード可能

2) READ COMMITTED
コミット済み読み取り (SQL Server の既定の分離レベル)

3) REPEATABLE READ

4) SERIALIZABLE
直列化 (各トランザクションが完全に分離される最高の分離レベル)

明示的なロック

ロックは明示的にもできる。ロックヒントと呼ばれるモノをSQLステートメントに挿入ればいい。

   SELECT * FROM TABLE_NAME  WITH (ROWLOCK) WHERE FIELD_NAME = 'hoge'

WITHのとこのロック種類はこんなにある。

  • FASTFIRSTROW
  • HOLDLOCK
  • NOLOCK
  • PAGLOCK
  • READCOMMITTED
  • READPAST
  • READUNCOMMITTED
  • REPEATABLEREAD
  • ROWLOCKSERIALIZABLE
  • TABLOCK
  • TABLOCKX
  • UPDLOCK

ロック競合

ロックが競合した時のタイムアウト設定があるらしい。

    SET LOCK_TIMEOUT [timeout_period(ミリ秒単位)]デフォルト0ミリ秒

と言う事は、トランザクションが失敗した時の処理をキチンと実装しなければ(ロールバック->コネクトクローズ)、タイムアウトまで待ちっぱなしになると言う事になると言う事だろうか。

ロックの状況は、エンタープライズマネージャで確認できる。ストアドプロシージャ(sp_lock)、master.syslockinfoテーブルでも確認できる。

参考サイト
ZDNet SQL Serverのデットロックを防ぎ同時実行性を向上させよう

トランザクション分離レベルの選択とデッドロックの問題~ SQL Server 2000 における Web アプリケーション開発 ~

テーブル増時のパフォーマンスは?インデックス vs DB分割

RDBMSをスケールさせる為に、データを垂直分割したいときがある。
それに備えて、DB設計時から垂直分割するのは是か非か。
SQL Serverは1つのインスタンスに複数のデータベースが作れる。
貧乏なウチは、1つの物理サーバかつインスタンスで、複数のデータベースを作って、データを垂直分割し、アプリケーション側で何の工夫もせずに、SQLだけで検索できなくもない。
例えば、2億レコードの単一DB と、 10万レコードの200個のデータベースとで、どれ位のパフォーマンスの差がでるだろう。
一般的に、テーブルが分かれると発行するSQL文が増える為、パフォーマンスが低下するのだけど、設計とSQLの作りにもよるし、実際に検証しなければわからない。
時間があれば一度検証してみたい。

物理ディスク構成

最低でも、データベースファイルとトランザクションログファイルは物理的に分けたい。
SANにデータベースファイル、ローカルHDDにトランザクションログファイルとか。

APIはあるの

ある。BOL参照。インストール時にカスタムを選択し、開発ツールを選択すると、スクリプトのサンプルもインストールされる。

phpからデータベースサーバへの接続方法(ミドルウェア)

MS SQL Serverの接続方法には色々あるが、PHPでの使用となると、ODBC関数の使用もしくはMS SQL関数の使用の2つが用意されている。

下記2つのパフォーマンスの善し悪しは、比較検証して見ないと分からない。

1)MS SQL関数
MS SQL関数は、MS SQLクライアントツール”ntwdblib.dll”を必要とする。
このモジュールは、DB-Libraryと呼ばれる呼び出しインターフェースで、MS SQL Server6.5の頃の古いAPIである。下位互換の為に用意されているようで、MS SQL Server2000で用意された新機能を使う事が出来ないらしい。Unicodeにも非対応である(非対応の意味が良く分からないが)。

2)ODBC関数
ODBC3.7以上では、Unicodeをサポートするようだ。(要検証)
正確には、MDAC 2.1以上 または SQL Server ODBC ドライバ (バージョン 3.70.0623 以降) または OLEDB プロバイダ (バージョン 7.01.0623 以降(MS KB JP234748)。
MS SQL Serverをインストールすると、MDAC2.6がインストールされるようだ。

カテゴリー: DBA, sqlserver タグ:

SQL Server 2000 の ハードウェア障害の際の予備機への復旧手順

2009 年 6 月 10 日 tdtsh コメントはありません

前提条件

本番機でオンラインバックアップを取得しており、そのバックアップファイルがある
本番機の *.ldf を取得できる
予備機に SQL Server2000 がインストールされており、サービスパック、HotFixが本番機と同様に適用されている
*.ldfのPATHは C:\SQL_DATA
*.mdfのPATHは F:\SQL_DATA
オンライン・フルバックアップがC:\SQL_BK\FULL にある
オンライン・トランザクションログバックアップがC:\SQL_BK\TRAN にある

工程1 クラッシュした本番機から、トランザクションログファイル(*.ldf)の取得

クラッシュした本番機のHDDを他サーバに接続する等して、本番機の*.ldfファイルを取得する。

※本番機の*.ldf ファイルの有無で、リカバリポイントが決まる。

*.ldfが有る -> 障害発生時点までリカバリ可能。

*.ldfが無い -> 障害発生時点までのリカバリ不可、巻き戻りが発生する。

工程2 オンラインバックアップファイルの確認

オンラインバックアップファイルが存在する事、およびファイルシステム上の更新日時を確認する
userdb1.BAK
userdb2.BAK
userdb3.BAK
master_full.BAK
model.BAK▲
msdb.BAK▲

▲印はシステムデータベースに付き、復旧出来なくても影響が軽微(ジョブが消えてしまう程度)なので無くても構わない

トランザクションログのオンラインバックアップファイルが存在する事、およびファイルシステム上の更新日時を確認する
userdb1_transaction.BAK
userdb2_transaction.BAK
userdb3_transaction.BAK

工程3 既存のデータベースファイルの移動

MSSQLSERVERサービスを停止し、データベースファイル達を、任意のディレクトリに移動する。

mkdir "C:\SQL_DATA\old"
mkdir F:\SQL_DATA\old
move C:\SQL_DATA\*.ldf "C:\SQL_DATA\old"
move F:\SQL_DATA\*.mdf F:\SQL_DATA\old

工程4 masterの再構築

シングルユーザモードで起動する
"C:\Program Files\Microsoft SQL Server\MSSQL\Binn\sqlservr.exe" -m -c
masterを再構築する
restore database master from disk= 'C:\SQL_BK\FULL\master_full.BAK'
go

工程5 クラッシュ時点までのトランザクションログのバックアップを取得する

本番機の最新の*.ldfを、本番機と同一パス(C:\SQL_DATA\)にコピー※する

※リストアに失敗したらデータが消えてしまうので、必ず移動ではなくコピーにする

予備機のMSSQLSERVERサービスを起動する
Enterprize Managerにて’sa’ユーザで接続し、各データベースの灰色のアイコン(未確認)があるか確認する
最新トランザクションログをバックアップ

※2回やっちゃ駄目。やったら工程4からやりなおし

backup log [userdb1] to disk='C:\SQL_BK\TRAN\userdb1_last_tran.bak' with no_truncate
go
backup log [userdb2] to disk='C:\SQL_BK\TRAN\userdb2_last_tran.bak' with no_truncate
go
backup log [userdb3] to disk='C:\SQL_BK\TRAN\userdb3_last_tran.bak' with no_truncate
go

工程6 システムデータベース(modelとmsdb)のりストア

restore database [model] from disk='C:\SQL_BK\FULL\model.BAK' with file = 1, recovery, replace
go
restore database [msdb] from disk='C:\SQL_BK\FULL\msdb.BAK' with file = 1, recovery, replace
go

工程7 フルバックアップをリストア

restore database [userdb1] from disk='C:\SQL_BK\FULL\userdb1.BAK' with file = 1, norecovery, replace
go
restore database [userdb2] from disk='C:\SQL_BK\FULL\userdb2.BAK' with file = 1, norecovery, replace
go
restore database [userdb3] from disk='C:\SQL_BK\FULL\userdb3.BAK' with file = 1, norecovery, replace
go

工程8 トランザクションログの復旧

前回のフルバックアップ取得時点から、1度でもトランザクションログバックアップを行っていた場合に必要
declare @i int
set @i = 1
while @i <= 3
begin
restore log [userdb1] from disk='C:\SQL_BK\TRAN\userdb1_transaction.BAK'
with file = @i, norecovery, replace
restore log [userdb2] from disk='C:\SQL_BK\TRAN\userdb2_transaction.BAK'
with file = @i, norecovery, replace
restore log [userdb3] from disk='C:\SQL_BK\TRAN\userdb3_transaction.BAK'
with file = @i, norecovery, replace
set @i = @i + 1
end

以下のようなエラーが表示されても無視する
デバイス 'C:\SQL_BK\TRAN\userdb1_transaction.BAK' にファイル ID 7 が見つかりません。
サーバー : メッセージ 3013、レベル 16、状態 1、行 21
RESTORE LOG が異常終了しました。

工程9 最後のトランザクション(工程5で取得)を復旧

restore log [userdb1] from disk='C:\SQL_BK\TRAN\userdb1_last_tran.bak' with norecovery
restore log [userdb2] from disk='C:\SQL_BK\TRAN\userdb2_last_tran.bak' with norecovery
restore log [userdb3] from disk='C:\SQL_BK\TRAN\userdb3_last_tran.bak' with norecovery, stopat='2009-06-10 10:00:00'
go

工程10 データベースを有効化

restore database [userdb1] with recovery
restore database [userdb2] with recovery
restore database [userdb3] with recovery
go

工程11 復旧後処理

SQL認証のGIDを確認する

use [userdb1]

go

select m.sid as master_sid ,a.sid as account_sid ,m.name as master_name ,a.name as accouunt_name

from master.dbo.sysusers as m

right outer join sysusers as a on a.name = m.name

where m.sid is not null

GO

本番機のNT認証を削除する

exec sp_revokelogin ‘本番機\Administrator’

GO

各データベース認証を削除する

use [userdb1]

exec sp_revokedbaccess ‘user_a’

exec sp_revokedbaccess ‘user_b’

exec sp_revokedbaccess ‘Administrator’

use [userdb2]

exec sp_revokedbaccess ‘user_a’

exec sp_revokedbaccess ‘user_b’

exec sp_revokedbaccess ‘Administrator’

use [userdb3]

exec sp_revokedbaccess ‘user_a’

exec sp_revokedbaccess ‘user_b’

exec sp_revokedbaccess ‘Administrator’

use [master]

exec sp_revokedbaccess ‘user_a’

exec sp_revokedbaccess ‘user_b’

exec sp_revokedbaccess ‘Administrator’

use [model]

exec sp_revokedbaccess ‘user_a’

exec sp_revokedbaccess ‘user_b’

exec sp_revokedbaccess ‘Administrator’

use [msdb]

exec sp_revokedbaccess ‘user_a’

exec sp_revokedbaccess ‘user_b’

exec sp_revokedbaccess ‘Administrator’

予備機のNT認証を登録する
カテゴリー: DBA, sqlserver タグ:

SQL Server 2000で、2つあるldfを1つにする

2009 年 5 月 17 日 tdtsh コメントはありません

SQL Server 2000で、2つあるldfを1つにする

use [database_name]

go

checkpoint

exec sp_dboption ‘table_name’, ‘trunc. log on chkpt.’, ‘TRUE’

dbcc shrinkfile( ‘table_name_log_d’ , emptyfile )

alter database [table_name] remove file ‘table_name_log_d’

go

アーキテクチャ徹底解説Microsoft SQL Server 2000 (マイクロソフト公式解説書)
カレン デレーニ
日経BPソフトプレス
売り上げランキング: 328654
カテゴリー: DBA, sqlserver タグ: