SQLCMD(SQLServerでコマンドプロンプト/CUIからSQL実行)

SQLServerでSQLを実行する際、わかりやすい方法としては

SQL Server Management Studio(SSMS)にて新しいクエリを作成する事ですが、

連続作業の場合にはコマンドラインからの実行が便利です。

 

そのためのツールがSQLCMDです。

sqlcmd ユーティリティを使用すると、Transact-SQL ステートメントやシステム プロシージャ、スクリプト ファイルを使用可能なさまざまなモードで入力できます。

  • コマンド プロンプト。
  • クエリ エディターでの SQLCMD モード。
  • Windows スクリプト ファイル。
  • SQL Server エージェント ジョブのオペレーティング システム (Cmd.exe) ジョブ ステップ。

このユーティリティでは、ODBC を使用して、Transact-SQL バッチを実行します。

 

利用前提環境

Windows インストーラー 4.5 と Microsoft ODBC Driver for SQL Server 17 の両方が必要です。

 

■利用法

コマンドプロンプトを起動から”SQLCMD”です。

管理者モードで起動する必要もなく、特に設定しなくてもパスが通っています。

 

オプションには以下のようなものがあります。

 

クエリ実行オプションを指定しない場合は対話モードになります。

この場合、クエリ実行の際にはSQL文の次に「GO」を指定します。

use msdb

go

のイメージですね。

 

 

-q または -Q で、コマンドオプションとしてSQL文を指定できます。

2つの違いはSQL文実行後の振る舞いです。

連続実行したいような場合は-Qを指定(コマンド1行ごとにSQLCMDの接続を終了する)がよいでしょう。

 

複数のインスタンスで同じSQL文を実行するような(例:新しいユーザを全DB環境に登録する)場合は、

実行するSQL文をファイルとして用意しておき、-i オプションで読み込ませるのが良さそうです。

 

 

 

 

※本投稿は過去に掲載したものを整理して再掲したものです。

 

SQLServerのサービスアカウントにドメインユーザが指定出来ない

環境構築中にハマりました。

業務運用の為のドメインユーザが設定されていて、

SQLServerのサービスアカウントも同じユーザが指定されている、

そういう現行環境設定を元にSQLServerをインストールしていたのですが。

 

SQLServerのインストール時に、SQLServerサービスのアカウントを聞かれます。

デフォルト設定の場合なら特に問題ないのですが、ドメインユーザを指定する場合。

色々試した結論から、下記の条件を満たす必要があるようでした。

 

インストールする際のログインユーザは、ドメイン管理者または設定するドメインユーザである事

 

指定するドメインユーザが、インストール先となるサーバの管理者権限を持っている事

 

 

サーバにソフトウェアを導入する場合、特に何も条件がついてなければ

ローカルAdministratorのアカウントでログインするかと思います。

この状況で、SQLServerサービスのアカウントにドメインユーザを指定すると

「指定されたユーザが無効です」と延々怒られます。

 

直接文字入力ではなくGUIからの選択が必要なのか、パスワードが間違ってるのか、

あれこれ悩んでみたのですが、全然ダメでした。

 

軽くググってみると、ローカルAdminではドメインユーザ情報を参照する動作に問題がある、

みたいな記事を見かけたので、ドメイン管理者でログインしてみたのですが、結果は変わらず。

 

 

そこでもう一度現行環境に何かヒントがないかと調べていて気付いたのが②でした。

コンパネからユーザーアカウント。

アカウントの管理一覧の中にドメインユーザが定義されていて、管理者権限が付与されていました。

対象がドメインユーザなので、ローカルユーザの一覧には表示されません。

一応移行前にローカルユーザは調べていたのですが、こちらのUIはあまり触った事がなく。。。

 

ユーザーアカウントのUIから、サービスアカウントに指定したいドメインユーザに管理者権限を付与。

その後、ドメイン管理者でログインしてインストール、サービスアカウントを指定、

と進めていくと、無事希望のユーザを指定してのインストールが出来ました。

 

 

ユーザーアカウントの設定については特にややこしい手順はなかったのですが、

具体的な手順は手元になく、ドメイン環境でないと試しにくいので、

再度確認してから追記しようと思います。

 

SQLServer SSISパッケージとジョブの移行

SSISパッケージの移行方法メモです。

オペレーションは環境によって異なると思うので、とある1パターンと思って頂ければと。

 

■環境/条件

・SSISをバッチ代わりに使用

・実際に処理対象となるDBは別サーバ上に存在

・SSISパッケージはSQLserverに保存

・SSISパッケージの起動は、SQLServerジョブまたはDOSバッチファイル

・移行先サーバはNW未接続の為、外部媒体でデータを移行する必要あり

・SQLServerのバージョンは、移行元が2008、移行先も2008

 

 

■エクスポート

SSISパッケージ

1.SSMSで移行対象サーバに接続します。接続先は[Integration Service]。

権限を持つユーザでのWindows認証接続になります。権限がないとパッケージが見えなかったり。

 

2.左ペインのツリーを展開して格納先を開きます。当方環境では[格納済パッケージ]>[MSDB]。

 

3.パッケージを右クリックして[パッケージのエクスポート]を選択。

 

4.パッケージの場所は[ファイルシステム]を選択。

ファイル出力パスを指定する。暗号化は、すぐ移行するなら気にしなくてもいいと思います。

わかるなら、パッケージ作成時のルールに従うべきでしょう。

 

 

SSIS起動ジョブ

1.SSMSで[データベースエンジン]に接続します。ユーザは①と同じか、saで。

 

2.SQLServerエージェントが起動していない場合は起動。

 

3.左ペインのツリーから[SQLServerエージェント]>[ジョブ]を選択。

 

4.F7キー押下。右ペインにジョブのリストが表示されます。

ツリーからジョブを右クリックでも構わないのですが、ここだと複数選択が可能です。

対象ジョブを選択して、右クリックメニューからエクスポートします。

出力形式を選べますが、移行を目的とするならスクリプトファイル一択かと思います。

 

 

 

■インポート

SSISパッケージ

1.SSMSで移行対象サーバに接続します。接続先は[Integration Service]。

権限を持つユーザでのWindows認証接続になります。権限がないとパッケージが見えなかったり。

 

2.左ペインのツリーを展開して格納先を開きます。当方環境では[格納済パッケージ]>[MSDB]。

 

3.パッケージを右クリックして[パッケージのエクスポート]を選択。

 

4.パッケージの場所は[ファイルシステム]を選択。

ファイル出力パスを指定する。暗号化は、すぐ移行するなら気にしなくてもいいと思います。

わかるなら、パッケージ作成時のルールに従うべきでしょう。

 

 

SSIS起動ジョブ

1.SSMSで[データベースエンジン]に接続します。ユーザは①と同じか、saで。

 

2.出力したスクリプトファイルを実行します。

ファイルを開く、新しいクエリに中身を貼り付ける、など幾つか手段はあると思います。

 

注意点としては、ジョブに定義されたオブジェクトを事前に作成しておく事

・ユーザ

・オペレータ

パッケージは事前にインポートしていたので分かりませんが、パッケージが無い場合もエラーになる気がします。

 

 

 

記憶を頼りに書いたので抜け漏れがあるかも知れませんが、適宜補完願います…

 

無料で出来る!SQL文のテスト環境~SQL Server編~

なんであれIT系の言語の学習に実行環境は必須ですが、SQLの学習を始めたばかり、という方にとって

「実行環境の作り方/使い方」は分からない事だらけではないでしょうか。

 

という事で、お金をかけずにSQL文(クエリ)を実行して結果を得る、

その為の環境構築から実際にSQLを実行出来る所まで、

について書いてみたいと思います。

 

対象環境はWindows10です。

無償エディションである「SQL Server Express」を使用します。

※Developerも製品無料のエディションですが、ユーザーライセンスが必要です。

 

1.ダウンロード

こちらのサイト、画面中段辺りからダウンロードします。

https://www.microsoft.com/ja-jp/sql-server/sql-server-downloads

 

2.ダブルクリックでインストール開始

最初は「基本」で良いと思います。

ライセンスに同意、インストールパスを指定して、インストールボタンをクリック。

コンポーネントのダウンロード(260MB程度)とインストールが実行されます。

 

インストール完了画面で「今すぐ接続」をクリックすると、SQL Serverのコマンドラインクライアント(SQLCMD)が起動します。

 

このままこんな感じでSQLを実行する事も可能です。

 

本記事が前提とする読者の方は多分SQL Serverの構造を理解する前の段階だと思いますので、

見た目でわかりやすいGUIツールをインストールしましょう。

 

3.SQL Server Management Studio(SSMS)のインストール

インストール完了画面の「SSMSのインストール」をクリックするとブラウザが開きます。

「SSMSのダウンロード」のリンクをクリック・・・してはいけません。英語版setupがダウンロードされます。

画面中段の「使用できる言語」の箇所で、「日本語」をクリックすると、日本語版setupがDLされます。

 

4.SSMSインストーラを起動

「Install」ボタンをクリックします。エラーが無い限り、特に操作は不要のまま完了します。

 

5.スタートメニューからSSMSを起動します。

 

6.ログインする

SSMS起動時にはデフォルトで「サーバーへの接続」ダイアログが表示されます。

取り敢えず今回は、認証の部分はそのままで。

サーバー名が空欄の場合は、コンボボックスを開いて「参照」。

データベースエンジンのツリーを展開し、「コンピュータ名\SQLEXPRESS」を選択してOKボタンをクリック。

 

ログイン後の画面はこんな感じになります。

データベース、サーバー(インスタンス)、等の基本的な知識はこちらのサイトが参考になると思います。

https://www.nobtak.com/archive/category/SQL%20Server

 

 

7.データベースを作る

SQL文はデータベースに対して実行するものです。データベースとは、データを入れる器のようなもの。

まずは、テストしたいSQLを実行する為の器を用意します。

ツリーの「データベース」を右クリックして、「新しいデータベース」を選択。

 

こんなウインドウが表示されます。

データベース名を入れると、データベースファイルの論理名にも同じ名前が入ります。

 

TESTデータベースが作成されます。

 

 

8.テーブルを作る

SQLはデータベースに対して実行するものだと言いましたが、

通常使用するデータ操作言語(select,insertなどのDML)は、

具体的にはテーブルに対して実行するものです。

TESTデータベースにはテーブルがありませんので、テーブルを作ります。

 

TESTデータベースのツリーにある「テーブル」の右クリックメニューからテーブルを選択

 

テーブル構造を定義します。

取り敢えずサンプルとしてこんな感じで。

テーブル名 parts ・・・部品情報の表

partsID char(8) NULL非許容(主キー) ・・・部品を示すID

partsName varchar(64) NULL許容  ・・・部品の名前

partsPrice integer NULL非許容  ・・・部品の単価

データ型を選択する際、コンボボックスでは「char(10)」など、

予め列のサイズが決まっているかのような表現になっています。

画面下部の「長さ」で変更出来ますので、列サイズは気にせずデータ型だけ見て選べばOKです。

 

主キーの設定は、対象列を右クリックして「主キーの設定」を選択。

列の先頭に鍵アイコンが付きます。

 

ウインドウを閉じる時は、タブのように表示された部分の×をクリックします。わかりにくい。

 

確認ダイアログが表示されます。ここで「はい」をクリックすると、

ようやくテーブル名を付けさせてくれます。

 

partsテーブルが出来ました。

 

 

9.SQLを試す

ようやくSQLを試せる環境が整いました。

SQL入力ウインドウを表示するには、左ツリーのデータベース名を右クリックして「新しいクエリ」を選択します。

 

まずは先程作ったテーブルに、INSERT文でデータを入れてみましょう。

あとはselectやupdate、deleteなどをお好みに応じて!

 

入力したSQLを実行するには、F5キーかツールバーの「▷実行」をクリックします。

上記例のように複数のSQLを記述した場合、通常は全て上から順に実行されますが、

一部選択状態で実行した場合は、選択したSQLだけが実行されます。

 

 

それでは皆様、よいSQLライフを!!

 

 

 

自分がSQLを学んだ時の事を思い返すと、以前のブログ記事でも書いたのですが

・就業先から分厚いマニュアルを渡され「一週間で覚えてね」

・どうやって勉強すればいいかネットで知り合った先輩PGに泣きつき

・その方からデータベースのインストーラをゴニョゴニョしていただき

さあやるぞ!とインストールしたのですが、そこから何をすればいいのか分からない!

となって、そもそもSQLってデータベースって何やねんと本を買い漁って何とか間に合わせた感じでした。

あの時はリミットがすぐだった事もあり、受験勉強さながらに机に向かってました。

 

そんな初心者でも、2年も経つ頃にはチューニングとか出来るようになり、

15分位掛かってた500行のSQLを実行時間1分前後まで縮めた事もありました。

 

やる気さえあれば、大抵の事は出来るようになると思います。

やりたいけどとっかかりがつかめない、そんな方の一助になればと願ってやみません。

 

SQLserverで高コストクエリ調査 ~上位20件では足りない!全部見たい!~

DBサーバのCPU負荷が高騰する事が多く、よく調査を依頼されます。

 

いつもはパフォーマンスダッシュボードを見ています。

インスタンスの右クリックメニューから[レポート]>[標準レポート] です。

※SSMSのバージョン17.2以上、が要件です

https://docs.microsoft.com/ja-jp/sql/relational-databases/performance/performance-dashboard?view=sql-server-ver15

表示はバケるのですが、Excelにエクスポートすると解消されます。

右中段の「CPU」をクリックすると、高コストクエリの一覧が表示されます。

 

こちらも同じく文字バケております。

 

そして、こちらが先程のレポートをExcelにエクスポートしたものになります。

 

 

累積CPU時間でソートされているので、「1SQLがめっちゃくちゃ時間が掛かる」だけでなく

「一回の処理は短いけど超絶連続実行されている」ようなケースも挙がるみたいです。

 

いつもこのレポートをExcelで渡していたのですが、

「全体の状況を把握したい。レポートの各クエリが、全CPU時間に対して何%だったか調査できないか」

というリクエストを受けました。

レポートは上位20件の為、この累積時間が全体の1%なのか10%なのかもっとなのか、

対策によって全体のコストが何%削減されたのか、が知りたいという事でした。

 

で、色々調べてちょっと手を加えたのが下記。

SELECT query_stats.query_hash AS “Query Hash”,   
    SUM(query_stats.total_worker_time) AS “累積 CPU 時間”,  
    MIN(query_stats.statement_text) AS “クエリ”  
FROM   
    (SELECT QS.*,   
    SUBSTRING(ST.text, (QS.statement_start_offset/2) + 1,  
    ((CASE statement_end_offset   
        WHEN -1 THEN DATALENGTH(ST.text)  
        ELSE QS.statement_end_offset END   
            – QS.statement_start_offset)/2) + 1) AS statement_text  
     FROM sys.dm_exec_query_stats AS QS  
     CROSS APPLY sys.dm_exec_sql_text(QS.sql_handle) as ST) as query_stats  
GROUP BY query_stats.query_hash  
ORDER BY 2 DESC;

 

これで、このSQL実行時点での全累積CPU時間が取れるようです。

参考にしたのは下記ページ
sys.dm_exec_query_stats (Transact-SQL)    
    A. TOP N クエリを確認する
https://docs.microsoft.com/ja-jp/sql/relational-databases/system-dynamic-management-views/sys-dm-exec-query-stats-transact-sql?view=sql-server-ver15#a-finding-the-top-n-queries  ;  

 

 

対策した後はDBサーバのCPU使用率が激減しました。(平均使用率で30%程度)

その割合と、上記SQLで比較した減少率がほぼ同じだったので、大きく間違ってはいないと思います。

 

SQLserver設計メモ

DBサーバを一台新設する事になりました。

 

要件をヒアリングしたところ”基本的な設定は既存DBと同じで”との事。

フムフムそれじゃ簡単かな?と思ってドキュメントを探してみたら・・・・・・ない。

インストール時の選択内容しか残されていない。

 

「え、もしかして全部デフォで動いてるの??まさか(笑)(笑)」

と実機を確認した所、どうやらファイルサイズ以外はホントにデフォみたいで・・・

 

そういう訳で、一般的にはどういうポイントがあるのだろう?と調べて見ることにしました。

 

■メモリ

まずは既存DBで逼迫しているメモリについて。

サーバー メモリの構成オプション

min server memory の既定の設定は 0 MB で、max server memory の既定の設定は 2,147,483,647 MB (中略) 詳細については、「動的メモリ管理」を参照してください。

 

いやいや最大2ペタて。無制限に確保する感じかな…詳細についてはこっちか。

動的メモリ管理

メモリを動的に使用する場合、 SQL Server はシステムに定期的にクエリして、メモリの空き容量を確認します(中略)空きメモリが少ない場合、 SQL Server は OS に対してメモリを解放します。 

今回は、構築時にSQLServer入れる直前のメモリ使用状況を確認して、

安全率だけちょっと見込んで設定する方向で進めようと思います。

 

 

もうひとつ、これは各所で「絶対やるべき」とオススメされていました

Lock Pages in Memory (LPIM)

プロセスを使用して物理メモリにデータを保持できるアカウントを指定し、ディスク上の仮想メモリへのデータのページングを防止します。 メモリ内のページをロックすると、ディスクへのメモリのページングが発生した際に、サーバーの応答性を維持できます。

 

が、

という事みたいです。下手に設定するとマズイという事でしょうか。

 

SQLserverのプロセスが使用するメモリを物理メモリにロックするという事は、

別のプロセスが使える物理メモリは当然減少する訳で、

そしてSQLserverが使用するメモリはデフォルトで2ペタである訳で。

動的メモリ管理でちゃんと増減してくれるようですが、こういう言う風にも書いてある訳で。

Lock Pages in Memory ユーザー権利を使用するとき、上記のように max server memory の上限を設定することが推奨されます。

LPIMだけ有効にするのは危ないようですね。

 

 

■ファイル

データファイルの配置はそれぞれ環境毎の要件があるかと思うので割愛。

それ以外で、知らなかったけど有効そうなものを見つけました。

tempdb データファイル数を CPU 数に一致させる

一般的には、tempdb データファイルの数は、SQL Server が使用可能な CPU の数に一致させた方が高負荷時のパフォーマンス劣化を防ぐことができるとされています。

tempdb 負荷が高いのか低いのか分からないのであれば、やっておいた方が無難でしょう。

はい。やってみます。スケジューラ(=CPUコア数)に合わせましょう、という事らしいです。

ちなみにtempdbがどういう時に使われるのかというと。

SQL Serverインスタンスが内部で利用する一時領域「TEMPDB」とはhttps://www.atmarkit.co.jp/ait/articles/1610/06/news013.html

 

サブクエリとかインラインビュー、ORDERBYの結果とかが含まれるのでしょうか。

 

そのほか、実効性は状況次第と思われるが試してみたい手法がいくつかありました。

  1. データとインデックスのデータファイルを分ける
  2. ログファイルは分割しない
  3. ファイルの自動拡張は基本ナシ。するならサイズベースで、同時拡張。

1は、物理レコード削除が頻繁に発生するなら効果がありそうに思います。

2と3はお作法のようです。ファイルI/Oの効率向上が見込めるようです。

 

 

■MaxDOP

並列処理可能な実行プランの最大値、だそうです。これだけ読んでもよく解りませんでした。

max degree of parallelism サーバー構成オプションの構成

並列プラン実行で使用するプロセッサの数を制限できます。 SQL Server では、クエリ、インデックス データ定義言語 (DDL) の操作、並列挿入、オンライン列変更、並行統計コレクション、静的およびキーセット ドリブン カーソルの作成の場合に並列実行プランが検討されます。

 

ますますわからん…ですが、注意事項の記載内容を見ると

セットアップで実施するようになったという事は、重要なオプションという事なのでしょうね。

このオプションは詳細設定オプションであるため、熟練したデータベース管理者または認定された SQL Server プロフェッショナルだけが変更するようにしてください。

あまりほいほいと弄るものでもないようです。

とあるサイトではCPUコアの1/4が推奨とされていたのですが、弊社環境だと1になってしまいます。

並列処理しない、というのはとてもとてもマズイ事に思えるので、今回は見送り。

2019の試用版インストーラを起動してみて推奨値だけ確認してみる、というのもアリでしょうか。

 

 

これらを元に、来週(忙しかったら再来週)に環境構築予定です。

 

 

■今回拝見させて頂いたサイト様

いつも勉強させて頂いてます。ありがとうございます。

 

 

■読み飛ばしてもいい感想文

メモリ制限は、一応OSの邪魔はしないように、っていう方針ではある様子。

とはいえ、ギリギリまで確保しては「ごめんなさい!お返しします!」っていうのも、

却ってオーバーヘッドになりそうな感じがします。

世の皆様も明示を推奨されている項目でした。

 

 

ディスクに関していうと、昔は特に物理ディスクを意識したI/O性能検討

(内周と外周、アクセスヘッドの移動)がなされてました。

今でも構成によっては有効だと思います(テスト用の単体物理サーバとか)が、

昨今のエンタープライズ用DBサーバはだいたいFCでストレージと繋がっていると思います。

その場合はいきなりディスクに書くのではなく、入り口の大きなキャッシュメモリとやり取りしますし、

実際のディスク書き込みでもRAID構成、それらを束ねて論理的に見せる仮想ボリュームなど、

物理ディスクの事はほぼ気にしなくていいのが現状かと思います。

 

インストール先とかデータファイルパスをCドライブにしない、とかは当たり前と言われてますが。

今やシステムソフトウェアインストール用のドライブ分けに意味を持たせるには、

個別でリストア可能という利点を活かせる運用が前提です。

OSやミドルの設定をいじってもバックアップしないのであれば、(そしてそういう会社は多い)

最初から全部Cドライブでいいんじゃない?と思います。

前述のように昔はI/O分散の意味もあったでしょうが、SANブート環境では無意味ですし。

 

 

どれをとってみても感じるのは、内部動作を深く掘り下げないと効果的なチューニングは難しい、

という事ですね。まだまだ学びの道は続きます。

 

SQLserverでコマンドプロンプトからSQLを実行する

今週は弊課に新人がいらっしゃいました。

その為、システム利用に関するユーザー追加依頼がチラホラとありまして。

 

中でもちょっと面倒だなと思ったのが、SQLserverのユーザ追加。

管理中のシステムにおいて、DB(全部SQLserver)接続ユーザは個人別になっており、

ユーザの立場によって割り当てる権限(ロール)が決まっています。

私はそれを付与する立場です。

何が出来るか出来ないか、私の指先一つです。ふひひ。

 

 

大きく3つ(本番環境、結合環境、単体環境)に区分される環境に、

それぞれ数台ずつのDBサーバ(1サーバ1インスタンス)、

各インスタンスにはいくつかのデータベース。

ユーザの立場によって使うデータベースはバラバラ。

 

今回は急かされたのもあっていつもどおりにSSMSで接続して作業してたのですが、

コマンドラインでパパパっと出来るんじゃないのかー、と思って調べてみました。

 

 

■SQLCMD

そういう訳でSQLCMDです。

sqlcmd ユーティリティを使用すると、Transact-SQL ステートメントやシステム プロシージャ、スクリプト ファイルを使用可能なさまざまなモードで入力できます。

  • コマンド プロンプト。
  • クエリ エディターでの SQLCMD モード。
  • Windows スクリプト ファイル。
  • SQL Server エージェント ジョブのオペレーティング システム (Cmd.exe) ジョブ ステップ。

このユーティリティでは、ODBC を使用して、Transact-SQL バッチを実行します。

利用前提環境

Windows インストーラー 4.5 と Microsoft ODBC Driver for SQL Server 17 の両方が必要です。

私のPCにはSQLserverを入れてるのですが、ODBCドライバは入って無い状態でした。

インストールで躓く事は特にないと思います。

 

■使ってみる

コマンドプロンプトを起動して SQLCMD と叩くだけ。

管理者モードで起動する必要もなく、パスも通してくれてます。

 

じゃあなんか適当にSQLを実行してみようかと

あれ。

どうやったら実行出来るんだろ?まだDBに繋がっていないとかかな?DB変えてみよ。

あっ

 

なるほど。goで実行、そういえばそうでしたね。

 

うんうん。

 

 

抜けるときはgo不要です。

 

さて、別サーバに接続するには…

-H -U -P あたりでしょうか。

 

 

来週出社したら試してみたいと思います。

 

余談ですが、SQLserverでサーバとかインスタンスとか言うとややこしいですね。

発言者のバックボーンによって、何を指してるのかが違ったりして…

 

SQLServer2012のバックアップファイル圧縮

弊社の基幹システムDBは、数段のバックアップ手法で信頼性を確保しています。

 

①毎日夜中にストレージ内でD2Dのコピー

 NEC製ストレージの仕組みです。よくわかってません。

②①のコピー先ディスクをLTOにバックアップ

 コピー先ディスクをバックアップサーバにマウントしてARCserve

③①、②の導入前からSQLServerのメンテナンスプランで稼働しているバックアップ

 週次でフル、平日の朝バッチ後と昼休みに差分でバックアップ

 

ただ、現場の古株に聞いたところ③の作業は誰もやった事がないそうで。

DB自体のロールフォワード回復は一般的な手順で当然出来ますが、

業務の回復手段が確立されていません。

というか、システム処理が個別処理単位でコミットされてしまうので、

トランザクション全体の整合性が取れない(そういう思想の)作りになってます。

 

なので、③のバックアップは意味をなしていないのだし不要ではないか、

と何度も進言しているのですが、直近まで回復したい病の上司には通じず。

あろうことか、使いみちのなさそうなバックアップの処理が容量不足でコケて、

対策までさせられる事になりました。

 

 

 

というのが、タイトルに書いたバックアップファイル圧縮の前置きになります。

やってみたらめっちゃくちゃ簡単で影響も少ない作業でした。

 

■バックアップ圧縮について

docs.microsoft.comにて詳細が解説されています。

  1. デバイスI/O削減により高速化
  2. 1つのバックアップセット内に圧縮・非圧縮のデータ共存不可
  3. 設定の有効範囲には「バックアップ処理単位」と「サーバー全体」の二種類
  4. 規定ではサーバー全体の設定無効(構成オプション:backup compression default)
  5. バックアップ処理単位の設定はサーバー全体設定より優先

といった特徴があるとの事でした。

 

■テスト

まずは普通にバックアップ

1.適当にメンテナンスプラン(全DBフル)を作成

3枚めにある「バックアップの圧縮の設定」、ここではデフォルトのままです。

 

2.「規定のサーバー設定」の内容確認

「バックアップを圧縮する」のチェックは外れています。

 

3.バックアップ実行

作成したメンテナンスプランを右クリックして「実行」

 

4.結果確認

ファイルサイズと実行時間ですが、時間短縮は見えそうにないですね。。。

 

■バックアップ圧縮の設定手順

パターンA:メンテナンスプランの個別設定

 1.メンテナンスプランのオプションタブから下記を設定

これだけです。

 

2.結果確認

 

ファイルサイズが約1/6、実行時間は半分(4秒減)でした。

ちなみに実行時間は、メンテナンスプランの履歴を参照しています。

 

 

パターンB:サーバーレベル構成オプションでの設定

1.メンテナンスプランのバックアップ設定を「サーバーの規定」に戻しておきます

2.サーバーのプロパティから圧縮にチェックしてOKをクリック


 

※以後サーバープロパティの全般タブに以下のメッセージが表示されるようになります。

 SQLServerのサービス再起動後も消えませんでした。

 

3.結果確認

時間、サイズともパターンAと同様です。

 

 

 

■結論

設定一つ触るだけで簡単にバックアップファイルが圧縮出来ました。

バックアップ容量に悩んでいるなら活用しない手はないと思います。

 

弊社の本番サーバーには既に反映済なのですが、

バックアップファイル240GBが140GBまで減りました。

バックアップ領域が溢れて処理がコケるので、

この240GBを退避する作業を、毎週人手でやってました。。。

 

SQLserver2012のログファイル物理サイズ縮小

今勤めているのは出戻り現場。5年前から2年間お世話になってました。

 

当時、まともにドキュメントもなく管理されていないシステムを前に、

サーバーの一覧(すらなかった!)を初めに、管理資料や手順書群を作り、

後続要員に半年かけて引き継いだのですが。

全く運用されてないしドキュメントも修正されてない有様で…

5年前と同じく、調査とドキュメント作成に勤しむ毎日です。

 

そんな愚痴から始まる今回の記事は、

昨日からトライ&エラーでやってた事を書いてみようかと。

SQLserverの基本的な事は知ってる前提になりますが、

それがそもそも何なのかは私もわかりません。。。

 

■発端

テスト用DBサーバのDBバックアップが失敗してました。

調べてみると、容量不足。

 

■原因調査

で、SSMSからDBのプロパティを眺めていると、

初期サイズ50GBも取ってる癖に使用可能が49GBという、

なかなかの乱暴者を発見。

主に利用するチームのリーダーに確認した所、

当初要件でサイズ見積したが、要件ドロップした為

DBのサイズは小さくしても構わない。

但し今テストで使ってるので、中身は壊すな、との事。

 

■愚痴

要件落ちた時点で再見積もりしてくれよ…

ディスク領域には限りがある事を意識したまえ。

サポート問い合わせしようとしたら、契約切れてました。。。

取り敢えず自宅PCにSQLserverをインストールして、

あれこれ試してみることに。

 

■手順確認

まずGUIでSSMSからの容量削減を試す。

①初期サイズとしてデータ1000MB、ログ10MBのDBを作成。

②適当にテーブルを作ってデータを投入

③SSMSのプロパティで初期サイズを小さくしてみる。

 

あっさり縮小可能。物理ファイル(.mdf)も小さくなっているし、

中身も問題なくselect出来る。

 

次に、

④初期サイズを超えるくらいデータを作成する

⑤データを一旦truncate後、再度データを少しだけ入れてみる

⑥ここで③同様の操作で初期サイズまで削減

 

これも問題なく動作。

じゃあ、もっとガツンと小さくしたらどうなるのか?

という興味が湧いて、サイズを1MBに指定してみました。

すると、初期サイズの指定値が”3”に変化しました。

 

 

つまり、指定値が小さすぎたからと言ってDBが破損する訳ではなく、

可能な限りで頑張って小さくしてくれる、という事みたいです。

 

 

■疑問が増える

あれこれ試したせいか、トランザクションログが大きくなってしまいました。

これをDBと同じようにちいさく…できませんでした。そうですよね。

DBを作成する時に完全復旧モデルにしていたので、

正しいお作法で縮小しないといけないようです。

 

1,初期状態

 

まずはDB圧縮を試してみました。

 

2.DB圧縮後

お、ちょっと縮んだ。

 

そういえばトランザクションログはバックアップで切り捨てられるんだっけ、

という何となくの記憶に従って、次はバックアップを実行。

 

結果。あれ?小さくならない…

 

再圧縮してみる。

 

おおー、小さくなった!

 

つまり、トランザクションログのバックアップを実行して、

中身が切り捨て可能な状態になってから圧縮するのだな!

よし、もう一回確認しておこう。

 

同じSQLを流してログを増やしてから、

 

ログをバックアップしてサイズ確認。この時点ではこのくらい。

 

今度はファイル指定の圧縮を試す。

 

・・・あれ?バックアップ後と一緒??

 

この後、DBの完全バックアップ→DB単位の圧縮→ファイル単位のログ圧縮、

と繰り返してみましたが、ログの容量が小さくならない。

困ってしまったので、DBを削除して1からやり直しました。

 

■結局正しい手順は・・・

MSの正規の手順というものがあるのだとは思いますが。

見つけられませんでしたので、あくまで個人的な実験の結果として。

 

1.まず圧縮(どっちのやり方でもOKみたいです)

2.次にトランザクションログのバックアップ

3.最後にもう一度圧縮(こちらはファイル単位圧縮しか試してません)

 

この方法で3度くらい試して、毎回ログは縮小されました。

 

 

無事に来週を迎えられそうで、ホッとしています。