* nix上のDB2の自動バックアップ

少し前まで、職場で、AIX上のDB2の自動オフラインバックアップを構成する必要がありました。 標準の方法は機能しなかったため、クラウンを使用して起動されるスクリプトを使用してすべてを構成しようとすることにしました。 簡単な突く方法を使用して、数ギガバイトを占めるデータベースの完全なオフラインバックアップが7zを使用して非常にうまくアーカイブできることを発見しました。 最終結果は、サイズが2〜3ギガバイトのデータベースで約20〜50 mbかかります。 したがって、日付ごとにパッケージ化された完全バックアップを保存できます。 このすべてを自動化することは残っています。 これを行うために、データベースへの接続を自動的に強制終了し、スキームとデータベース自体のバックアップを作成するスクリプトをいくつか作成することにしました。



たとえば、Centos 5.5にインストールされたDB2 9.7.4 Express Editionを検討します。 このシステム全体が機能するためには、perlと7zaがインストールされている必要があります。 ベースは、デフォルトでディレクトリ/ home / db2inst1にインストールされます。 スクリプト用とバックアップ用の2つのディレクトリを作成しましょう。

mkdir bin mkdir backups
      
      





最初に必要なスクリプトは、forcedbデータベースへの接続を強制終了するスクリプトです

 #!/usr/bin/perl sub getDBApplicationHandles { my $dbname = $_[0]; my @appHandles = (); open (DB2, "db2 list application for database ".$dbname." |"); $f = 0; while (<DB2>){ $l = $_; if($l =~ /^\-\-\-/){ $f = 1; } if($f == 1 && !($l =~ /^\-\-\-/)){ for($i=0;$i<1000;$i++){ $l =~ s/ / /g; } my @val = split(' ', $l); push(@appHandles, @val[2]); } } close DB2; return @appHandles; } sub forceDBApplication { my $dbname = $_[0]; my $forceS = "( "; my $found = 0; my @appHandles = getDBApplicationHandles($dbname); foreach my $val (@appHandles) { $val =~ s/^\s+//; if(length($val) > 0){ $found = 1; $forceS = $forceS . $val . ", "; } } if($found == 1){ $forceS = substr($forceS, 0, length($forceS)-2) . " )"; print "db2 \"force application ".$forceS."\"\n"; system("db2 \"force application ".$forceS."\""); } } if(length($ARGV[0]) == 0){ print "Please specify database name to force connections\n"; exit 1; } forceDBApplication($ARGV[0]);
      
      





ご覧のとおり、getDBApplicationHandles関数は特定のデータベースからのみアプリケーションハンドルを取得し、forceDBApplicationはそれらを閉じます。 このスクリプトはバックアップ中には使用されませんが、将来的には役立つ可能性があります。 2番目のスクリプトにその機能を埋め込みます。 関数を埋め込み、このスクリプトを呼び出さない理由を尋ねますか? スピードがすべてです。 db2に接続する一部のシステムは、バックアップスクリプトがデータベースのバックアップを開始する前に、新しい接続を作成します。



このスクリプトを機能させるには、次のエントリを.profileに追加します。

 export PATH=~/bin:$PATH export DB2_BACKUP_DIR=~/backups export DB2_BACKUP_PARALLELISM=4
      
      



ご覧のとおり、2つのグローバル変数を発表しました。 2番目のスクリプトでそれらを使用します。 parallelismパラメーターはdb2バックアップ中に使用され、マルチプロセッサーシステムでのバックアップ時間を短縮します。



2番目のスクリプトはbackupdbです

 #!/usr/bin/perl use Time::localtime; $globBackupDirectoryPath = $ENV{'DB2_BACKUP_DIR'}; $globBackupParallelism = $ENV{'DB2_BACKUP_PARALLELISM'}; sub getTimeStamp { $tm = localtime; ($DAY, $MONTH, $YEAR, $HOUR, $MINUTE) = ($tm->mday, $tm->mon, $tm->year, $tm->hour, $tm->min); return $HOUR ."-". $MINUTE . "." . $DAY . "." . ($MONTH+1) . "." . ($YEAR+1900); } sub getPathPrefix { $tm = localtime; return ($tm->year+1900). "/" . ($tm->mon+1); } sub archiveDirectory { $dirPath = $_[0]; $dbname = $_[1]; $tm = localtime; ($DAY, $MONTH, $YEAR, $HOUR, $MINUTE) = ($tm->mday, $tm->mon, $tm->year, $tm->hour, $tm->min); $dirPathArch = $dirPath."/tmp/". $dbname .".". getTimeStamp() . ".7z"; if (-e $dirPathArch){ system("rm",$dirPathArch); } system("7za","a","-r","-mx=9","-mfb=64","-md=64m","-ms=on",$dirPathArch,$dirPath."/tmp/"); system("mv",$dirPathArch,$dirPath . "/db/" . getPathPrefix()); system("rm","-Rf",$dirPath."/tmp/"); print $dirPathArch . " archived\n"; } sub backupDB { my $dbname = $_[0]; my $dbschema = $_[1]; my $dbparallelism = "".$globBackupParallelism; my $backupDir = $globBackupDirectoryPath."/".$dbname; # Schema backup if(length($dbschema) > 0){ system("mkdir","-p",$backupDir . "/schema/" . getPathPrefix()); my $schemapath = $backupDir . "/schema/" . getPathPrefix() ."/". $dbname . "." . getTimeStamp().".sql"; system("db2look","-d",$dbname,"-z",$dbschema,"-e","-o",$schemapath,"-nofed"); print "db2 ".$dbname." schema ".$dbschema." backup completed\n"; } # Database backup system("mkdir","-p",$backupDir . "/db/" . getPathPrefix()); system("rm","-Rf",$backupDir."/tmp/"); system("mkdir","-p",$backupDir."/tmp/"); forceDBApplication($dbname); system("db2","backup","database",$dbname,"to",$backupDir."/tmp/","parallelism",$dbparallelism); archiveDirectory($backupDir,$dbname); } sub getDBApplicationHandles { my $dbname = $_[0]; my @appHandles = (); open (DB2, "db2 list application for database ".$dbname." |"); $f = 0; while (<DB2>){ $l = $_; if($l =~ /^\-\-\-/){ $f = 1; } if($f == 1 && !($l =~ /^\-\-\-/)){ for($i=0;$i<1000;$i++){ $l =~ s/ / /g; } my @val = split(' ', $l); push(@appHandles, @val[2]); } } close DB2; return @appHandles; } sub forceDBApplication { my $dbname = $_[0]; my $forceS = "( "; my $found = 0; my @appHandles = getDBApplicationHandles($dbname); foreach my $val (@appHandles) { $val =~ s/^\s+//; if(length($val) > 0){ $found = 1; $forceS = $forceS . $val . ", "; } } if($found == 1){ $forceS = substr($forceS, 0, length($forceS)-2) . " )"; print "db2 \"force application ".$forceS."\"\n"; system("db2 \"force application ".$forceS."\""); } } if(length($ARGV[0]) == 0){ print "Please specify database name and schema to backup\n"; exit 1; } backupDB($ARGV[0],$ARGV[1]);
      
      





getTimeStamp関数は、バックアップファイルの名前に使用される日付を提供します。 getPathPrefix関数は、バックアップがパッケージ化されるパスを提供します。 これらの機能は独自の方法で変更できます。 archiveDirectory関数の7zaアーカイブオプションを試すこともできます。 データベーススキーマのバックアップで問題が発生した場合は、backupDB関数のdb2lookパラメーターを参照してください。



別のbackup.shスクリプトをビンに追加して、クラウンと呼びます。

 #!/usr/bin/env bash # Loading Enviroment variables . /home/db2inst1/.profile # Backing up database backupdb DBNAME SCHEMANAME echo "Backup Completed"
      
      



バックアップするデータベースごとに、バックアップするデータベースの名前と.sqlファイルに保存するバックアップスキームの名前を指定してbackupdbを呼び出す必要があります。 スキームを指定しない場合、データベースのバックアップのみが実行されます。



すべてのスクリプトを確認し、たとえば毎日毎日午前3時に、backup.sh呼び出しをクラウンに追加します。

 # DB2 backups 0 3 * * * /home/db2inst1/bin/backup.sh
      
      





ご清聴ありがとうございました。



All Articles