ガルーン バージョン 5.x 向け
今回の記事では、パッケージ版ガルーン(Windows)にて、データをバックアップするスクリプトのサンプルを紹介します。
尚、当スクリプトはVBScriptを使用します。
そのため、Windows Server上で稼働するガルーンであれば、Windowsのバージョンに関わらず動作します。
※LinuxではVBScriptは動作しないため使用できません。
また、退避したガルーンのファイル群を圧縮する処理も実装していますが、その処理は「7-Zip」を使用しています。
よって、当サンプルプログラムのまま利用する場合は、7-Zipをダウンロードしてください。※インストールは不要です。
ガルーンのバックアップ処理について
パッケージ版ガルーンのバックアップ方法については、サイボウズ社の公式な手順が公開されています。
大きく分けて以下の二通りあります。
- OSのコマンドを使用したバックアップ
- mysqldumpコマンドを使用したバックアップ
「OSのコマンドを使用したバックアップ」では、ガルーンを停止したうえで、ガルーンの構成ファイルとデータベースファイルをまるっとコピーして退避します。
「mysqldumpコマンドを使用したバックアップ」では、ガルーンのデータベース(MySQL)のデータはMySQLのdumpコマンドで出力し、非データベースデータについては、特定のフォルダ配下をまるっとコピーして退避します。
今回紹介するバックアップスクリプトでは、「OSのコマンドを使用したバックアップ」の手順をスクリプト化しています。
バックアップ手順の流れ
サイボウズ社が公開しているWindow版ガルーンのバックアップ手順は以下のリンク先で紹介されています。
詳しい手順はリンク先をご確認ください。
当記事では大まかな手順を紹介しておきます。
- Webサーバーサービスの停止
- スケジューリングサービスの停止
- MySQLサービスの停止
- ガルーンのサービスが停止しているか確認
- dataディレクトリーとfilesディレクトリーをコピーして退避
- MySQLサービスの起動
- スケジューリングサービスの起動
- Webサーバーサービスの起動
当手順は「OSのコマンドを使用したバックアップ」の手順ですが、紹介したように一度サービスを停止する必要があり、ガルーンのバックアップ処理中はガルーンにアクセスできなくなります。
よって、利用環境によっては導入が難しいかもしれません。
そのかわり、「リストア」をする場合は、バックアップ処理で退避した「data」フォルダと「files」フォルダを、ガルーンがインストールされた環境の同フォルダ配下のファイル群と置き換えるのみです。
手順も容易であり、初心者向けのバックアップ方式だと言えます。
サンプルプログラムの処理概要
今回紹介するサンプルのスクリプトではVBScriptを使用しているため、Windows Serverであれば、どのバージョンでも動作します。
また、Windows10やWindows11といった非サーバーOSでも動作します。
尚、前述したサイボウズ社が案内している手順にある「Webサーバーサービスの停止」は省略しております。
後、MySQLはガルーンのインストールと併せてインストールされた環境を前提としておりますが、前項で紹介したサイボウズ社の公式手順に記載されている通り、MySQLのサービス名を現環境に合わせた内容でスクリプトを書き換えていただければ同じように動作します。
当スクリプトでは、ガルーンの「data」フォルダと「file」フォルダをコピーしてきた後に、「7-Zip」を利用して圧縮します。
よって、当記事の冒頭でも記載した通り、7-Zipの実行ファイルが必要になります。
尚、7-Zipは当スクリプトを配置したカレントディレクトリ内に7-Zip用のフォルダを配置し、そのなかに7-Zipの実行ファイルを置く想定です。
7-Zipのコマンドラインでの使い方は当ブログの過去の記事で解説しております。
良ければ以下のリンク先を参考にしてください。
また、圧縮したZIPファイルを世代管理する機能も実装しております。
以下で当スクリプトの処理の流れを提示します。
- スケジューリングサービスとMySQLのサービスの状態を取得→起動していたら停止。
- スケジューリングサービスとMySQLのサービスが確実に停止しているか確認。
- スクリプト冒頭の定数で指定したフォルダパスに今日の日時付きフォルダを作成して「data」フォルダと「file」フォルダをそこにコピー。
- スケジューリングサービスとMySQLのサービスを起動。
- スケジューリングサービスとMySQLのサービスが確実に起動しているか確認。
- 前処理で「data」フォルダと「file」フォルダをコピーしてきた日付付きフォルダを「7Zip」を利用して圧縮。
- 圧縮後、元のフォルダは削除。
- 過去に作成した圧縮ファイルの更新日を元に並び替えて定数で指定した世代以前のファイルを削除。
- 処理結果をメールで送信。
バックアップ処理サンプルスクリプト
Option Explicit 'ガルーンのファイル系データ及びデータベースをバックアップします。 CONST CYBOZU_SERVICE_SCHE = "Cybozu_Scheduling_Service_cbgrn" CONST CYBOZU_SERVICE_DB = "Cybozu_Database_Engine_5_0" CONST BACKUP_TEMP = "D:\Backup" CONST DB_PATH = "D:\Program Files\Cybozu\mysql-5.0\data" CONST FILE_PATH = "D:\Program Files\Cybozu\mysql-5.0\files" CONST SEVENZIP_FOLDER = "7z1900-extra" '当ファイルのカレントディレクトリに配置すること CONST FILE_GEN = 5 'バックアップを取得する世代数を指定 Call Main() Sub Main() Dim objWshShell Dim FailureFlag Dim Message Dim MailMessage Dim wkNow Dim objFS Dim BackupDateFolder Dim ServiceStatus Dim objFolder Dim objRS Dim CountDiff Dim objFile Dim i FailureFlag = False Message = "処理1:ガルーンのサービスを停止します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) Set objWshShell = CreateObject("WScript.Shell") '処理1:ガルーンのサービスを停止状態を確認して、停止されていなければ停止します。 'スケジューリングサービス ServiceStatus = Get_ServiceStatus(CYBOZU_SERVICE_SCHE) If ServiceStatus = "" Then 'サービスの状態取得失敗 Message = "スケジューリングサービスの状態取得に失敗したため、処理を終了します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) FailureFlag = True ElseIf ServiceStatus = "Running" Then 'サービスが稼働中 'スケジューリングサービスを停止します。 Message = CYBOZU_SERVICE_SCHE & " を停止します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) objWshShell.Run "sc stop " & CYBOZU_SERVICE_SCHE,1,True End If 'エラーの場合は処理を終了します。 If FailureFlag Then MailSend(MailMessage) Set objWshShell = Nothing Exit Sub End If '5秒待機します。 WScript.Sleep 5000 '確実に停止しているかを確認します。 ServiceStatus = Get_ServiceStatus(CYBOZU_SERVICE_SCHE) If ServiceStatus = "" Then 'サービスの状態取得失敗 Message = "スケジューリングサービスの状態取得に失敗したため、処理を終了します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) FailureFlag = True ElseIf ServiceStatus = "Running" Then 'サービスが稼働中 Message = CYBOZU_SERVICE_SCHE & " の停止に失敗したため処理を停止します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) FailureFlag = True End If 'エラーの場合は処理を終了します。 If FailureFlag Then MailSend(MailMessage) Set objWshShell = Nothing Exit Sub End If 'DBサービス ServiceStatus = Get_ServiceStatus(CYBOZU_SERVICE_DB) If ServiceStatus = "" Then 'サービスの状態取得失敗 Message = "DBサービスの状態取得に失敗したため、処理を終了します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) FailureFlag = True ElseIf ServiceStatus = "Running" Then 'サービスが稼働中 'DBサービスを停止します。 Message = CYBOZU_SERVICE_DB & " を停止します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) objWshShell.Run "sc stop " & CYBOZU_SERVICE_DB,1,True End If 'エラーの場合は処理を終了します。 If FailureFlag Then MailSend(MailMessage) Set objWshShell = Nothing Exit Sub End If '10秒待機します。 WScript.Sleep 10000 '確実に停止しているかを確認します。 ServiceStatus = Get_ServiceStatus(CYBOZU_SERVICE_DB) If ServiceStatus = "" Then 'サービスの状態取得失敗 Message = "DBサービスの状態取得に失敗したため、処理を終了します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) FailureFlag = True ElseIf ServiceStatus = "Running" Then 'サービスが稼働中 Message = CYBOZU_SERVICE_DB & " の停止に失敗したため処理を停止します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) FailureFlag = True End If 'エラーの場合は処理を終了します。 If FailureFlag Then MailSend(MailMessage) Set objWshShell = Nothing Exit Sub End If '処理2:ローカルディレクトリに対象のファイル群をコピーします。 Message = "処理2:ローカルディレクトリに対象のファイル群をコピーします。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) Set objFS = CreateObject("Scripting.FileSystemObject") 'システム日時を元に、wwwwmmddの文字列を作成します。 wkNow = Year(Now()) wkNow = wkNow & Right("0" & Month(Now()) , 2) wkNow = wkNow & Right("0" & Day(Now()) , 2) wkNow = wkNow & Right("0" & Hour(Now()) , 2) wkNow = wkNow & Right("0" & Minute(Now()) , 2) wkNow = wkNow & Right("0" & Second(Now()) , 2) '日時付きのフォルダ名を生成します。 BackupDateFolder = "GaroonBackup_" & wkNow '今日の日時のフォルダ名を作成します。 SysWriter(BACKUP_TEMP & "\" & BackupDateFolder) objFS.CreateFolder(BACKUP_TEMP & "\" & BackupDateFolder) 'dataフォルダをコピーします。 Message = "dataフォルダをコピーします。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) SysWriter("xcopy """ & DB_PATH & """ " & BACKUP_TEMP & "\" & BackupDateFolder & "\data /e /i") objWshShell.Run "xcopy """ & DB_PATH & """ " & BACKUP_TEMP & "\" & BackupDateFolder & "\data /e /i",1,True 'fileフォルダをコピーします。 Message = "fileフォルダをコピーします。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) SysWriter("xcopy """ & FILE_PATH & """ " & BACKUP_TEMP & "\" & BackupDateFolder & "\file /e /i") objWshShell.Run "xcopy """ & FILE_PATH & """ " & BACKUP_TEMP & "\" & BackupDateFolder & "\file /e /i",1,True '処理3:ガルーンのサービスを再開します。 Message = "処理3:ガルーンのサービスを再開します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) 'DBサービスを開始します。 Message = "DBサービスを開始します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) objWshShell.Run "sc start " & CYBOZU_SERVICE_DB,1,True 'DBサービスの状態を確認します。 '10秒待機します。 WScript.Sleep 10000 ServiceStatus = Get_ServiceStatus(CYBOZU_SERVICE_DB) If ServiceStatus = "" Then 'サービスの状態取得失敗 Message = "DBサービスの状態取得に失敗したため、処理を終了します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) FailureFlag = True ElseIf ServiceStatus <> "Running" Then 'サービスが稼働中 Message = CYBOZU_SERVICE_DB & " の起動に失敗したため処理を停止します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) FailureFlag = True End If 'エラーの場合は処理を終了します。 If FailureFlag Then MailSend(MailMessage) Set objWshShell = Nothing Exit Sub End If 'スケジューリングサービスを開始します。 Message = "スケジューリングサービスを開始します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) objWshShell.Run "sc start " & CYBOZU_SERVICE_SCHE,1,True 'スケジューリングサービスの状態を確認します。 '10秒待機します。 WScript.Sleep 10000 ServiceStatus = Get_ServiceStatus(CYBOZU_SERVICE_SCHE) If ServiceStatus = "" Then 'サービスの状態取得失敗 Message = "スケジューリングサービスの状態取得に失敗したため、処理を終了します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) FailureFlag = True ElseIf ServiceStatus <> "Running" Then 'サービスが稼働中 Message = CYBOZU_SERVICE_SCHE & " の起動に失敗したため処理を停止します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) FailureFlag = True End If 'エラーの場合は処理を終了します。 If FailureFlag Then MailSend(MailMessage) Set objWshShell = Nothing Exit Sub End If '処理4:コピーしてきたフォルダを圧縮します。 Message = "処理4:コピーしてきたフォルダを圧縮します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) '7ZIPでフォルダを圧縮します。 objWshShell.Run objWshShell.CurrentDirectory & "\" & SEVENZIP_FOLDER & "\7za.exe a " & BACKUP_TEMP & "\" & BackupDateFolder & ".7zip " & BACKUP_TEMP & "\" & BackupDateFolder,1,True Message = "フォルダの圧縮が完了しました。ファイル名:" & BackupDateFolder & ".7zip " MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) '処理5:不要なコピーを削除して世代管理処理を実行します。 Message = "処理5:不要なコピーを削除して世代管理処理を実行します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) '今回コピーしたフォルダを削除します。 objFS.DeleteFolder BACKUP_TEMP & "\" & BackupDateFolder,True Set objRS = CreateObject("ADODB.Recordset") 'レコードセットの列を定義します。 objRS.Fields.Append "ファイル名",200,255 '200:VarChar(255) objRS.Fields.Append "更新日時",200,50 '200:VarChar(50) objRS.Open '出力先フォルダのファイルリストを取得します。 Set objFolder = objFS.GetFolder(BACKUP_TEMP) For Each objFile In objFolder.Files Set objRS = AddRecordsetRow(objRS,objFile.Name,objFile.DateLastModified) Next '存在するファイル数が世代管理対象数より大きい場合のみ世代管理処理を実行します。 If FILE_GEN < objFolder.Files.Count Then '実ファイル数から世代管理数を引き、差を算出します。 CountDiff = objFolder.Files.Count - FILE_GEN 'ファイルリストのレコードセット昇順でソートします。 objRS.Sort = "更新日時 ASC" '古い順から世代と実ファイル数の差分の個数分のみファイルを削除します。 For i = 1 To CountDiff Step 1 objFS.DeleteFile BACKUP_TEMP & "\" & objRS("ファイル名").Value,True objRS.MoveNext Next End If Set objRS = Nothing '処理を終了します。 Message = "処理を終了します。" MailMessage = MailMessage & vbCrlf & now() & ":" & Message SysWriter(Message) MailSend(MailMessage) Set objFS = Nothing Set objWshShell = Nothing End Sub Function AddRecordsetRow(Rs,Column1Value,Column2Value) '新規行を作成します。 Rs.AddNew '作成した新規行に値をセットします。 Rs("ファイル名").Value = Column1Value Rs("更新日時").Value = Column2Value 'レコードセットへの反映を確定します。 Rs.Update '関数の戻り値にレコードセットをセットします。 Set AddRecordsetRow = Rs End Function '引数で渡されたサービス名の状態を返します。 '引数1:サービス名 '戻り値:ステータス状態文字列※取れなければ空文字列 Function Get_ServiceStatus(ServiceName) Dim objWMIService, colRunningServices, objService Get_ServiceStatus = "" Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Set colRunningServices = objWMIService.ExecQuery("Select * from Win32_Service where displayname = '" & ServiceName & "'") For Each objService In colRunningServices Get_ServiceStatus = objService.State Exit For Next Set colRunningServices = Nothing Set objWMIService = Nothing End Function 'ログファイルを書き込みます。 Public Sub SysWriter(str) Dim objWshShell Dim fso, fi Dim LogFileName Dim wkNow 'ファイル名に設定する日付をyyyymmdd形式で取得します。' wkNow = Year(Now()) wkNow = wkNow & Right("0" & Month(Now()) , 2) wkNow = wkNow & Right("0" & Day(Now()) , 2) 'カレントディレクトリを取得して、カレントディレクトリのlogsフォルダ内にlogファイルを作成します。' Set objWshShell = WScript.CreateObject("WScript.Shell") Set fso = CreateObject("Scripting.FileSystemObject") LogFileName = objWshShell.CurrentDirectory & "\logs\" & wkNow & ".log" 'ファイルを開く 'もしも存在しない場合には作成する Set fi = fso.OpenTextFile(LogFileName, 8, true) fi.WriteLine (Date() & " " & Time() & ": " & str) 'ログを書き込む Set fi = Nothing Set objWshShell = Nothing End Sub 'メールを送信します。 Sub MailSend(strMessage) Dim objMail Set objMail = CreateObject("CDO.Message") objMail.From = "from_user@example.com" objMail.To = "to_user@example.com" objMail.Subject = "メール件名" objMail.TextBody = strMessage objMail.TextBodyPart.Charset = "ISO-2022-JP" objMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 objMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "メールサーバーのIP又はホスト名" objMail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25 objMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = "to_user" objMail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "パスワード" objMail.Configuration.Fields.Update objMail.Send Set objMail = Nothing End Sub
- 4行目から10行目の定数の値はご利用環境に合わせて書き換えてください。
- メール送信が不要な場合は、Subプロシージャ「MailSend」の呼び出し箇所をコメントアウトしてください。
- 実行結果をlogファイルに出力しますが、ログも不要であれば、Subプロシージャ「SysWriter」の呼び出し箇所をコメントアウトしてください。
最後に
今回の記事では、パッケージ版ガルーンのバックアップ処理を実行するスクリプトを紹介させていただきました。
実行環境さえ合わせてもらえれば、このスクリプトのままで動作すると思います。
また、今回紹介したスクリプトは、ほぼ同じ内容の実装で私の環境でも使用しておりますが、御社の環境で当スクリプトを使用する場合は必ず検証環境で動作検証を実施したうえで、十分に安全性を確認のうえ導入してください。
今回も長々と読んでいただきましてありがとうございました。
それでは皆さまご機嫌よう!