[Syniti(DBMoto)][スクリプト] 特定カラムの値が変更となった場合、ターゲットのレコードを削除するサンプルスクリプト

Syniti Data Replication (DBMoto)では、レプリケーションジョブにスクリプトを組み込むことによって、ある程度レコードに操作を加えて、ターゲットデータベースにレプリケーションができます。

例えば、以下のスクリプトを組み込むことで、ソーステーブルに削除フラグを格納するカラムが存在し、そのカラムに対して削除フラグがたった場合、ターゲットテーブルのレコードを削除することが可能です。

“DFLUG” というカラムに格納されている値が1とUpdateされた場合、ターゲットレコードを削除するためのサンプルスクリプトです。

Imports System
Imports System.Data
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript

Namespace DBRS
    Public Class ReplicationScript : Inherits IReplicationScript
		Public Overrides Sub Record_onAfterMapping( recSource As DBMotoPublic.IRecord,  recTarget As DBMotoPublic.IRecord, ByRef AbortRecord As Boolean, ByRef DisableReplication As Boolean)
	' ソーステーブルカラム名の変数
        Dim strField As String
        ' ソース側へUpdateクエリが実行された時
        If (recSource.OperationType = enmOperationType.Update) Then
        ' "DFLUG"というカラム名を指定し、値を取得
        strField = CType(recSource.GetValueAfter("DFLUG").ToString(), Integer)
        End If
        ' "DFLUG"の値が"1"だった場合、ターゲットのレコードにDeleteクエリを発行
        If (strField = "1") Then
            recTarget.OperationType = enmOperationType.Delete
        End If
		End Sub

    End Class
End Namespace

コメントする -->

ステートレスとステートフルの違い

アプリケーションは「ステートレス アプリケーション(Stateless Application)」と「ステートフル アプリケーション(Stateful Application)」の2種類に分類できるそうです。しかし、このステートレスとステートフルの意味は一見簡単なようでわかりにくいです。いろいろな資料を読めば読むほど頭が混乱してきます。たとえば、アプリケーション設計はシンプルがベストであり、マイクロサービスにおいて、ステートレス アプリケーションは何より重要だと説く声がある一方、この世にステートレス アプリケーションなんてものは存在しないという声もあります。

混乱の理由は視点の違いです。アプリケーション設計にも経済学のようにミクロとマクロの視点があるとすれば、マクロ設計はシステム全体を大局的に捉え、アプリケーションにはステート(状態)が付きものだから、それがないのは初心者プログラマーが最初に作るHello Worldプログラムぐらいだとか。一方、ミクロの視点では、システムを構成する個々の要素を見て、ある部分はステートレスで、ある部分はステートフルであると言います。その場合、ステートフル アプリケーションとは即ちデータベースのことであり、その他のステートレス アプリケーション群をまとめてアプリケーション レイヤーと呼んだりします。

この2つの異なる視点を混ぜ合わせて、ステートレス アプリケーションとステートフル アプリケーションの違いを論じる記事(主に英語)がネットに溢れています。書いている人は当然、私はミクロ視点です、とか、マクロです、とか断って書くわけではないので、読み手が「ははーん、さてはこの筆者はマクロだな」と斟酌して読まなければなりません。

さらに状況を複雑にしているのは、この議論が「コンテナ」と切っても切れない関係にある点です。「コンテナとは本質的にステートレスだ」という言説と、「ステートフル コンテナこそが重要だ」という言説が入り混じっています。

マイクロサービス アーキテクチャにおいて、各要素をステートレスなコンテナに隔離し、個々に独立させて互換性や整合性の問題から切り離し、可搬性を確立することこそがコンテナの真価であり、その意味では「コンテナ=ステートレス」の原理には納得するしかありません。Kubernetesをはじめとするオーケストレーション ツールは、コンテナをシステム リソースに応じて適切なノードに臨機応変に再起動するものであり、可搬性はコンテナがコンテナである所以です。

しかし、マクロ視点に立ち返ると、本来ステートフルなアプリケーションをコンテナ化したら、最低でも1つのコンテナはステートフルでなければアプリケーションが機能しません。それに対して、ミクロ論者は、コンテナ アーキテクチャの外にデータベースを接続すべきだと言います。実際、データベースはコンテナ化も、コンテナ アーキテクチャ内の永続ボリューム(Persistent Volume)に置くことも、コンテナ ストレージ インターフェース(CSI)を通じて、外部ストレージに置くことも可能です。つまり、データベースの配置次第でコンテナは完全にステートレスにも、ステートフルにもなります。ステートレスとステートフルの違いとデータベースの配置を一緒に論じたら、混乱が深まるばかりです。

そもそも「ステートレス」は「ステートがない」ことではありません。正確には、ステートはあるけれど、それは一時的で、そのアプリケーションが終了して、再起動したときにはもうそのステートが消えている、という意味です。つまり「この世にステートレス アプリケーションなんてものは存在しない」は的を射ており、もっと言うと、ステートレス コンテナさえ存在しないのです。

どうです、これですべてクリアになったでしょう?それとも、もうどっちでもよくなりましたか?それが正しいと思います。ステートレスの重要性を説く人も、ステートレスなんてないと言う人も、言葉の定義の違いだけで、実は同じことを言っており、設計上、互い矛盾することはないのですから。

コメントする -->

[Syniti(旧DBMoto)]レコード競合(コンフリクト)発生時のレコード内容を出力する方法

データベースレプリケーションツールSyniti(旧DBMoto)では、双方向のデータベース差分連携(シンクロナイゼーション)を行うことも可能です。これにより、双方のデータベースで更新が発生する連携システムなどの運用要件にも対応できます。

また、双方向連携を行う場合は、双方のデータベースで同一レコードに対しての更新が同タイミングで行われることにより、レプリケーション対象レコードの競合(コンフリクト)が発生する可能性があります。

Synitiではこの競合が発生した場合に、どちらのデータベースのレコードを優先するかや、更新タイムスタンプの早い/遅いで決定するなどのオプション機能が標準で搭載されていますので、これにより競合が発生しても、データの不整合が発生しないような仕様動作となっています。
※これらの競合回避オプションはGUI上で設定可能です。

さらに、スクリプトを使用することで競合が発生したレコードをログに出力させることやメール通知を行うことも可能です。今回の記事ではその手法について紹介します。

SynitiではVBとC#のスクリプトに対応しておりますが、今回はVBを用いるので、まずは、Syniti管理画面左上にあるグローバルスクリプトボタンをクリックし、ポップアップされたSynitiグローバルスクリプト画面でスクリプト言語をVBに設定します。

競合判定でスクリプトを使用するため、双方向レプリケーションのプロパティ画面を開き、優先 >ミラーリングオプション > 競合回避項目をUseScriptに変更します。

その後、レプリケーションスクリプトに下記スクリプトをコピーします。

Imports System
Imports System.Data
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript

Namespace DBRS
    Public Class ReplicationScript : Inherits IReplicationScript
        Public Overrides Function Replication_onConflict(recSource As IRecord, recTarget As IRecord) As IRecord
            AddLog("コンフリクトが発生しました", 1, recSource, 4)
            SendMail("DBMoto通知メール", "コンフリクトが発生しました")
            Return recSource
        End Function
    End Class
End Namespace

Replication_onConflict
コンフリクト発生時に呼び出されるイベント処理です。
コンフリクトオプションが UseScript に設定されている場合にのみ有効となります。

AddLog
ログファイルに任意のメッセージを出力します。
第1引数はログメッセージ
第2引数はエラーレベル(0情報1警告2エラー)
第3引数はソース(recSource)かターゲット(recTarget)のどちらか
第4引数は第3引数の情報として、何を出力するかを指定します。
4の場合は、競合が発生したレコード内容を出力します。

SendMail
メール通知を行います。第1引数は件名、第2引数が本文です。
メールサーバの設定はレプリケーションオプション画面の
メールタブにて設定可能です。

Return~
競合発生時の判定の指定で recSource はソース優先、recTarget はターゲット優先となります。更新の先勝・後勝を実施したい場合はタイムスタンプの比較で条件分岐とします。

例 :後勝としたい場合

Imports System
Imports System.Data
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript

Namespace DBRS
    Public Class ReplicationScript : Inherits IReplicationScript
        Public Overrides Function Replication_onConflict(recSource As IRecord, recTarget As IRecord) As IRecord
            AddLog("コンフリクトが発生しました", 1, recSource, 4)
            SendMail("DBMoto通知メール", "コンフリクトが発生しました")
            If recSource.GetLogValue(enmLogFields.TransactionTS).ToString() > recTarget.GetLogValue(enmLogFields.TransactionTS).ToString() Then
                Return recSource
            Else
                Return recTarget
            End If
        End Function
    End Class
End Namespace

スクリプト設定後、実際に競合を発生させてみると、下記のようにDBMoto画面の履歴ビューワ上でもコンフリクトしたレコードが出力されていることが確認できます。

タグ: , , , ,

保護中: Database Performance Analyzerの評価版インストール方法

このコンテンツはパスワードで保護されています。閲覧するには以下にパスワードを入力してください。

タグ: , ,

スケールアップ とスケールアウト [データベース]

日本語で「スケール」と言えば、規模のことで、それが向上するならスケールアップ。スケールアウトはちょっと言葉としておかしい、と一般の人は感じるはずです。ここで言う「一般の人」とはIT関係ではない人という意味です。そもそも英語でも、scale outは不自然です。規模が拡大して、枠外にはみ出すこと(つまりout)を表したくて、枠があることが前提になってしまっています。でも、この言葉が使われ出した背景を考えれば、なぜスケールアウトなのか、合点が行きます。

IT用語の解説によると、サーバーの台数を増やして処理能力を高めること、と定義されています。台数を増やさずに元々のハードディスクを増強したりして、処理能力を高めたらスケールアップなのだとか。どちらも、規模の拡大なので、従来の日本語なら、両方ともスケールアップと言わなければなりません。

Vertical Scaling vs. Horizontal Scaling

サーバーというハードウェアで考えず、その中身、つまりデータベースで考えたほうがわかりやすいです。汎用システムではほとんどの場合、まだリレーショナル データベースが使われていると思いますが、すごく単純化して言ってしまえば表計算みたいなものです。レコード数が増えれば増えるほど表がどんどん縦に伸びていきます。レコードが膨大になり過ぎたら、そのデータベースが置かれたサーバー自体の処理能力を増強するしかありません。それを英語でvertical scaling(縦方向の拡張)と言い、それを達成するのがscale upです。

しかし、スケールアップには限度があります。レコード数が天文学的に膨大になったら、サーバーの処理能力を増強してもきりがありません。そこで、リレーショナル データベースのように表の仕様が細かく規定されてレコードが縦に増えていくのではなく、規定をゆるくして、複数サーバーに分散できるデータベースが考え出されました。それをNoSQLデータベースと呼び、リレーショナル データベースのSQLデータベースと対比されます。NoSQLの例としては、MongoDBのようなドキュメント型や、以前の記事に書いたグラフデータベースなどが挙げられます。

SQL vs. NoSQL

NoSQLデータベースのように複数サーバーに分散して拡張できるなら、リレーショナル データベース(表)のように縦に拡張する必要がないので、horizontal scaling(横方向に拡張)と言い、それこそがscale upに対するscale outです。

拡張性の点では、horizontalのほうがverticalよりずっと可能性があるので、システムはスケールアップせずに、断然スケールアウトすべき、ということになりますが、そう簡単でもないようです。

リレーショナル データベースは、システム処理におけるトランザクションのACIDを達成するために考え抜かれたシステムであり、そう簡単に置き換えることはできません。ACIDとは、A(atomicity=原子性/不可分性)C(consistency=一貫性/整合性)I(isolation=独立性/隔離性)D(durability=耐久性/永続性)のことです。お金のやり取りをするようなシステムなどは、この原理を捨てたら成り立ちません。

NoSQL vs. NewSQL

そこで、SQLデータベースではスケールアウトできないが、NoSQLでも困る場合、つまりリレーショナル データベースを何とか頑張ってスケールアウトしたい場合の秘策として、最近はNewSQLデータベースの活用が少しずつ広がっているようです。リレーショナル データベースの表をパーティションによって複数のサブセットに分割し、さらにレプリケーションと二次インデックスの活用で、複数サーバーに分散してもACIDが保てるようにしたデータベースです。

要するに、スケールアップの限界がスケールアウトの必要性を生み、データベースがSQL→NoSQL→NewSQLと、進化を遂げているという話です。NewSQLデータベースの今後に期待が膨らみます。

コメントする -->

Syniti Data Replication (旧DBMoto)でのスクリプトの書き方③:グローバルスクリプト用の関数とイベント

前回はグローバルスクリプトの基本的な記述の仕方をご紹介しました。今回はそのグローバルスクリプトで使用できる関数とイベントをご紹介します。

関数

グローバルスクリプトで使用するグローバル関数を解説します。 これらの関数をグローバルスクリプトイベントから使用する場合は、IGlobalScriptクラス(IGlobalScript.AddLogなど)を使用して呼び出します。

AddLog (String, enmLogMessageType)

パラメータと解説

注意:この関数はAddLog(str As String, eType As Integer)の代替です。
DBMoto.logファイルに対してログメッセージを記録します。

– str = ログメッセージ

– eType = エミュレータenmLogMessageTypeを指定、Information = 0, Warning = 1, Error = 2を使用できます。

VB .NET

Public Shared Sub AddLog (str As String, eType As enmLogMessageType) 
例: AddLog ("The current record has been inserted", 0)

C#

public static void AddLog(string str, enmLogMessageType eType) 
例: AddLog("The current record has been inserted", 0)

AddLog (String, enmLogMessageType, Record, enmRecordImage)

パラメータと解説

注意:この関数はAddLog(String, Int, Record, enmRecordImage)の代替です。
特定のレコード情報を含むログメッセージをDBMoto.logに記録します。

– str = メッセージログ

– eType = エミュレータenmLogMessageTypeを指定、Information = 0, Warning = 1, Error = 2を使用できます。

– record = メッセージとともに記録されるIRecordオブジェクト

– eRecordImage = 記録するレコード情報の種類をエミュレータenmRecordImageで指定、レコードの情報としてInsert操作に関してはValues Afterが、それ以外はValues Beforeが使用されます。パラメータ値としては1,2,4が使用できます。
1 = 主キー値 – 主キーとなるカラムの値のみ
2 = イメージ – レコードの全ての情報
4 = ログ情報 – トランザクションID、トランザクションタイムスタンプ

VB.NET

Public Shared Sub AddLog (str As String, eType As enmLogMessageType,
record As DBMotoPublic.IRecord, eRecordImage As enmRecordImage)

例:
Public Overrides Sub Record_onAfterMapping(recSource As IRecord, recTarget As IRecord,
ByRef AbortRecord As Boolean)
Dim S as String
AddLog("The current record has been inserted", 0, recSource, 4)
End Sub

C#

public static void AddLog(string str, enmLogMessageType eType, DBMotoPublic.IRecord record, enmRecordImage eRecordImage)

SendMail (subject, body, to)

パラメータと解説

[レプリケーションエージェントオプション]ダイアログの[メール]タブで定義されたSMTP設定を使用して電子メールを送信します。

– sSubject = メール件名

– sMessageBody = メール本文

VB.NET

Public Shared Sub SendMail (sSubject As String, sMessageBody As String, sRcptTo As String)

例:
SendMail ("Message from Syniti DR",
          "An error occurred that requires intervention by the system administrator.",
          "somebody@company.com")

C#

public static void SendMail(string sSubject, string sMessageBody, string sRcptTo)

例:
SendMail("Message from Syniti DR",
         "An error occurred that requires intervention by the system administrator.",
         "somebody@company.com")

SendMail (sSubject, sMessageBody, sSMTPServer, sSMTPPort, sRcptFrom, sRcptTo, bAuthentication, sUser, sPassword, bUseSSL)

パラメータと解説

[レプリケーションエージェントオプション]ダイアログの[メール]タブで定義されたSMTP設指定されたSMTPサーバ等を使用し、メールを送信します。指定されていない場合にはレプリケーションエージェントオプションダイアログで指定されている設定が変わりに使用されます。

– sMessageBody = メール本文

– sSMTPServer = メール送信に使用するSMTPサーバ

– sSMTPPort = メール送信に使用するSMTPサーバのポート

– sRcptFrom = 送信者として使用するメールアドレス

– sRcptTo = 受信者のメールアドレス

– bAuthentication = 認証情報が必要な場合はTrue、不要な場合はFalseを指定

– sUser = bAuthenticationがTrueの場合、ユーザIDを指定

– sPassword = bAuthenticationがTrueの場合、パスワードを指定

– bUseSSL = Trueの場合、SSLを使用、それ以外はFalse

VB.NET

Public Shared Sub SendMail (sSubject As String, sMessageBody As String,
sSMTPServer As String, sRcptFrom As String, sRcptTo As String)

例:
SendMail ("Message from Syniti DR",
"An error occurred that requires intervention by the system administrator.",
"www.smtp.com", "DBMoto Notification Agent", "somebody@company.com")

C#

public static void SendMail(string sSubject, string sMessageBody, string sSMTPServer,
string sRcptFrom, string sRcptTo)

例:
SendMail("Message from Syniti DR",
"An error occurred that requires intervention by the system administrator.",
"www.smtp.com", "Syniti DR Notification Agent", "somebody@company.com")

GetRecordInfo(Record, enmRecordImage)

パラメータと解説

レコードに関する情報を含む文字列を返します。

– record = メッセージとして記録されるIRecordオブジェクト

– eRecordImage = 記録するレコード情報の種類をエミュレータenmRecordImageで指定、レコードの情報としてInsert操作に関してはValues Afterが、それ以外はValues Beforeが使用されます。パラメータ値としては1,2,4が使用できます。
1 = 主キー値 – 主キーとなるカラムの値のみ
2 = イメージ – レコードの全ての情報
4 = ログ情報 – トランザクションID、トランザクションタイムスタンプ

VB.NET

Public Shared Function GetRecordInfo (record As DBMotoPublic.IRecord, eRecordImage As enmRecordImage) As String

例:
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript
Namespace DBRS
Public Class ReplicationScript : Inherits IReplicationScript
Public Overrides Sub Record_onAfterMapping(recSource As IRecord, recTarget As IRecord,
ByRef AbortRecord As Boolean)
Dim S as String = GetRecordInfo(recSource, enmRecordImage.KeyValues)
AddLog("The current record has been inserted: " + S, 0)
End Sub
End Class
End Namespace

C#

public static string GetRecordInfo(DBMotoPublic.IRecord record, enmRecordImage eRecordImage)

例:
using System;
using System.Data;
using DBMotoPublic;
using DBMotoScript;
namespace DBRS
{
public class ReplicationScript : IReplicationScript
{
public override void Record_onAfterMapping(DBMotoPublic.IRecord recSource,
DBMotoPublic.IRecord recTarget, ref bool AbortRecord)
{
string = GlobalScript.GetRecordInfo(recSource, enmRecordImage.KeyValues);
GlobalScript.AddLog("The current record has been inserted: " + s, 0);
}
}
}

GetJSONRecordInfo

パラメータと解説

この関数の4つのバリアントはすべて、汎用の構造化データまたは非構造化データをJSON列タイプにマッピングするときに役立つヘルパー関数です。

GetJSONRecordInfo(record,eRecordImage)
下記のようなJSONフォーマットの文字列をenmRecordImage のパラメータにしたがい、IRecord オブジェクトから返します。

{
"FIELD1" = "Value1",
"FIELD2" = "Value2",
"FIELD3" = "Value3"
}

GetJSONRecordInfo(args)
JSON形式の文字列を返します。オブジェクトの名前と値は、一般的なのリストから選択されます。

GetJSONRecordInfo(T value)
タイプTの特定のオブジェクトのJSON形式を返します。この関数は、渡された値が文字列値ではない場合(DateTime、GUIDなど)に使用できます。

GetJSONRecordInfo T(jsonString)
上記の関数の逆。JSON文字列形式の特定の値が与えられると、文字列を解析し、生成元の(T型の)オブジェクトを返します。

VB.NET

Public Shared Function GetJSONRecordInfo(Of T)(ByVal jsonString As String) As T

Public Shared Function GetJSONRecordInfo(ParamArray ByVal args() As Object) As String

Public Shared Function GetJSONRecordInfo(Of T)(ByVal value As T) As String

Public Shared Function GetJSONRecordInfo(Of T)(ByVal jsonString As String) As T

C#

public static string GetJSONRecordInfo(DBMotoPublic.IRecord record, enmRecordImage eRecordImage)

public static string GetJSONRecordInfo(params object[] args)

public static string GetJSONRecordInfo(T value)

public static T GetJSONRecordInfo(string jsonString)

GetReceiversInUse

パラメータと解説

Syniti DRの接続でレプリケーションがReceiversInfoオブジェクトとして使用しているレシーバーのリストを返します。

– ConnectionName = 使用中のレシーバーを取得するIBM Db2 for i接続の名前

– IsSource = ConnectionNameがソース接続を参照する場合はTrue、そうでない場合はFalse

– OnlyActiveReplications = Trueの場合、アクティブな(有効な)レプリケーションで使用されるレシーバーのみを取得し、無効なレプリケーションをスキップします。

この関数は、ReceiverInfo型の値を返します。クラスの定義は次のとおりです。
Public Class ReceiverInfo
Public JournalLibrary As String
Public JournalName As String
Public ReceiverLibrary As String
Public ReceiverName As String
End Class

VB.NET

Public Shared Function GetReceiversInUse (ConnectionName As String, IsSource As Boolean, OnlyActiveReplications As Boolean) As ReceiverInfo()

例:
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript
Imports System.Data
Namespace DBRS
Public Class ReplicationScript : Inherits IReplicationScript
Public Overrides Sub LogReader_onBeforeMirroring(bSource as Boolean)
Dim arrReceivers As ReceiverInfo() = GetReceiversInUse ("AS400", True, True)
Dim recInfo As ReceiverInfo
For Each recInfo in arrReceivers
AddLog("Receiver in use: " + recInfo.JournalLibrary + "." + recInfo.JournalName +
"/" + recInfo.ReceiverLibrary + "." + recInfo.ReceiverName, 0)
Next
End Sub
End Class
End Namespace

C#

public static ReceiverInfo[] GetReceiversInUse(string ConnectionName, bool IsSource, bool OnlyActiveReplications)

例:
using System;
using System.Data;
using DBMotoPublic;
using DBMotoScript;
namespace DBRS
{
public class ReplicationScript : IReplicationScript
{
public override void LogReader_onBeforeMirroring(bool bSource)
{
ReceiverInfo[] arrReceivers = GlobalScript.GetReceiversInUse("AS400", true, true);
foreach (ReceiverInfo recInfo in arrReceivers)
{
GlobalScript.AddLog("Receiver in use: " + recInfo.JournalLibrary + "." + recInfo.JournalName
+ "/" + recInfo.ReceiverLibrary + "." + recInfo.ReceiverName, 0);
}
}
}
}

イベント

グローバルスクリプトのGlobalEventsクラスでグローバルイベントハンドラを定義します。各グローバルイベントには、関数が処理する内部イベントを指定する「GlobalEventsAttribute」という属性セクションが必要です。

GlobalEventsAttribute

イベント名とヘルプ文字列の2つのパラメーターを持つ属性。Record_OnExecuteErrorおよびReplication_OnErrorイベントのエラーハンドラーを定義するときは、この属性を常に宣言する必要があります。

パラメーター1:必須。イベント名を含む文字列。値は、処理されるイベントの名前と一致する必要があります。

パラメーター2:必須。イベントハンドラの説明またはヘルプメッセージを含む文字列。この文字列は現在Syniti DRで使用されていませんが、パラメーターが必要なので、少なくとも空の文字列 “”を提供する必要があります。

Record_OnExecuteError

解説

このイベントは、単一レコードの実行時にエラーが発生するたびに発生します。Writerのイベントとして、INSERT、DELETE、UPDATEなどのターゲット操作で発生します。操作が最初に失敗したときに、bRetryExecuteオプションを使用して、レコードで実行操作を再実行しようとします。たとえば、単一レコードの挿入がタイムアウトエラーで失敗した場合、bRetryExecuteをtrueに設定し、iSleepおよびiIterationパラメーターの値を設定すると、数ミリ秒後に操作が成功する可能性があります。レプリケーションイベントRecord_OnBeforeExecute は、このパラメーターを使用してレコード操作が何回再試行されても、一度だけ生成されることに注意してください。また、レプリケーションイベントRecord_OnAfterExecute レコード操作が成功した場合にのみ1回生成され、レコード操作が失敗した場合は生成されません。

GlobalEventsAttribute最初のパラメータは、イベント名「Record_OnExecuteError」を示す必要があります。

パラメータ

名前タイプ説明
sReplOrGroupNameString読み取り専用。イベントを生成したレプリケーションまたはグループ名
recTargetIRecord読み取り専用。エラーが生成された対象レコードを表すオブジェクト。IRecordインターフェイスで使用可能なメソッドを使用して、レコード内の特定の情報にアクセスできます。
e例外読み取り専用。このエラーのVB .NET例外オブジェクト。
bRecoverReplicationBooleanデフォルトはFalseです。Trueに設定すると、レプリケーションは回復モードに設定されます。
bDisableReplicationBooleanデフォルトはFalseです。Trueに設定されている場合、RetryExecuteの値に関係なく、レプリケーションはログ内のエラーメッセージの通知を終了し、レプリケーションを無効にします。
bRetryExecuteBooleanデフォルト値はFalseです。Syniti DRログにエラーを記録する前にターゲットレコード操作を再試行する場合は、このパラメーターをTrueに設定します。たとえば、単一レコードの挿入がタイムアウトエラーで失敗した場合、bRetryExecuteをTrueに設定し、iSleepパラメーターの値を設定すると、数ミリ秒後に操作が成功する場合があります。例は、このパラメーターの使用方法を示しています。レプリケーションイベントRecord_OnBeforeExecute は、このパラメーターを使用してレコード操作が何回再試行されても、一度だけ生成されることに注意してください。また、レプリケーションイベントRecord_OnAfterExecute レコード操作が成功した場合にのみ1回生成され、レコード操作が失敗した場合は生成されません。
iSleepIntegerbRetryExecuteがTrueに設定されている場合、操作を再試行する前にこのパラメーターを使用して遅延値を示します。値はミリ秒単位である必要があります。デフォルト値は0です。例では、このパラメーターの使用方法を示しています。
iIterationInteger読み取り専用。bRetryExecuteパラメーターと組み合わせて使用​​します。iIterationは、ターゲットレコード操作が試行された回数を追跡します。開始値は0です。ターゲットレコード操作が初めて試行されると、この値は1に設定されます。イベントハンドラーは、bRetryExecuteがfalseに設定されるまで操作の再試行を続けます。例では、エラー時の無限ループを回避する方法を示しています。  
 

VB.NET


Public Shared Sub MyErrorHandler (ByVal sReplOrGroupName As String,
ByVal recTarget As DBMotoPublic.IRecord,
ByVal e As Exception,
ByRef bRecoverReplication As Boolean,
ByRef bDisableReplication As Boolean,
ByRef bRetryExecute As Boolean,
ByRef iSleep As Integer,
ByVal iIteration As Integer)
※関数名MyErrorHandlerは変更可能です。

例:

Public Shared Sub MyErrorHandler (ByVal sReplOrGroupName As String,
ByVal recTarget As DBMotoPublic.IRecord,
ByVal e As Exception,
ByRef bRecoverReplication As Boolean,
ByRef bAbortRecord As Boolean,
ByRef bDisableReplication As Boolean,
ByRef bRetryExecute As Boolean,
ByRef iSleep As Integer,
ByVal iIteration As Integer)
Dim s As String
s = s + "-- Called MyErrorHandler to catch the error in replication or group '"
+ sReplOrGroupName + "'" + Environment.NewLine
s = s + "-- Exception: " + e.ToString() + Environment.NewLine
s = s + "-- Iteration: " + iIteration.ToString()
bRetryExecute = Falsehttps://www.climb.co.jp/blog_dbmoto/wp-admin/post-new.php?post_type=rtbs_tabs#
' Disable replication if the error is a SQL Server timeout error
If e.Message.IndexOf("System.Data.SqlClient.SqlException: Timeout expired.") = 0 Then
bAbortRecord = True
bDisableReplication = True
s = s + " - Replication disabled"
Else ' retry
If iIteration = 3 Then
bRetryExecute = False
s = s + " - No Retry"
Else
bRetryExecute = True
iSleep = 3000
s = s + " - Try Again after " + (iSleep/1000).ToString() + " seconds."
End If
End If
IGlobalScript.AddLog (s, 1)
End Sub

C#

[GlobalEventsAttribute("Record_OnExecuteError", "Define a general event for the event OnExecuteError")]
public static void MyErrorHandler(string sReplOrGroupName,
DBMotoPublic.IRecord recTarget,
Exception e,
ref bool bRecoverReplication,
ref bool bDisableReplication,
ref bool bRetryExecute,
ref int iSleep,
int iIteration)

例:
public class GlobalEvents : IGlobalEvents
{
[GlobalEventsAttribute("Record_OnExecuteError", "Define a general event for the event EventName")]
public static void MyErrorHandler(String sReplOrGroupName, DBMotoPublic.IRecord recTarget, Exception e,
ref bool bRecoverReplication, ref bool bAbortRecord, ref bool bDisableReplication,
sref Boolean bRetryExecute, ref int iSleep, int iIteration)
{
String s = null;
s = s + "-- Called MyErrorHandler to catch the error in replication or group '" + sReplOrGroupName + "'"
+ Environment.NewLine;
s = s + "-- Exception: " + e.ToString() + Environment.NewLine;
s = s + "-- Iteration: " + iIteration.ToString();
bRetryExecute = false;
// Disable replication if the error is a SQL Server timeout error
if (e.Message.IndexOf("System.Data.SqlClient.SqlException: Timeout expired.") = 0) {
bAbortRecord = true;
bDisableReplication = true;
s = s + " - Replication disabled";
}
else { // retry
if (iIteration >= 3) {
bRetryExecute = false;
s = s + " - No Retry";
}
else {
bRetryExecute = true;
iSleep = 3000;
s = s + " - Try Again after " + (iSleep / 1000).ToString() + "seconds.";
}
}
IGlobalScript.AddLog(s, 1);
}

Record_OnMappingError

解説

このイベントは、単一レコードのマッピングでエラーが発生するたびに発生します。Readerイベントとして、INSERT、DELETE、UPDATEなどのマッピング操作時にソースで発生します。 操作が最初に失敗したときに、bRetryExecuteオプションを使用して、レコードのマッピング操作を再実行できます。たとえば、単一のフィールドマップが構文エラーで失敗した場合、bRetryExecuteをtrueに設定すると、ユーザーがフィールドの値を変更して操作を繰り返すように構成することもできます。 レプリケーションイベントRecord_OnBeforeMappingは、このパラメーターを使用してレコード操作が何回再試行されても、一度だけ生成されることに注意してください。 また、レプリケーションイベントRecord_OnAfterMappingは、レコード操作が成功した場合にのみ1回生成され、レコード操作が失敗した場合はまったく生成されません。

GlobalEventsAttributeの一つめのパラメーターにイベント名「Record_OnMappingError」を示す必要があります。

パラメータ

名前タイプ説明
sReplOrGroupNameString読み取り専用。イベントを生成したレプリケーションまたはグループ名
recSourceIRecord読み取り専用。エラーが生成された対象のソースレコードを表すオブジェクト。IRecordインターフェイスで使用可能なメソッドを使用して、レコード内の特定の情報にアクセスできます
recTargetIRecord読み取り専用。エラーが生成された対象のターゲットレコードを表すオブジェクト。IRecordインターフェイスで使用可能なメソッドを使用して、レコード内の特定の情報にアクセスできます。
eException読み取り専用。このエラーのVB .NET例外オブジェクト。
bAbortBooleanデフォルトはFalaseです。Trueに設定すると、現在のレコードはスキップされ、レプリケーションされません。 ログにエラーは出力されません。
bRecoverReplicationBooleanデフォルトはFalseです。Trueに設定すると、レプリケーションはリカバリモードに設定されます。
bDisableReplicationBooleanデフォルトはFalseです。Trueに設定されている場合、RetryExecuteの値に関係なく、レプリケーションはログ内のエラーメッセージの通知を終了し、レプリケーションを無効にします。
bRetryExecuteBooleanデフォルト値はFalseです。Syniti DRログにエラーを記録する前にターゲットレコード操作を再試行する場合は、このパラメーターをTrueに設定します。たとえば、単一レコードの挿入がタイムアウトエラーで失敗した場合、bRetryExecuteをTrueに設定し、iSleepパラメーターの値を設定すると、数ミリ秒後に操作が成功する場合があります。例は、このパラメーターの使用方法を示しています。レプリケーションイベントRecord_OnBeforeExecute は、このパラメーターを使用してレコード操作が何回再試行されても、一度だけ生成されることに注意してください。また、レプリケーションイベントRecord_OnAfterExecute レコード操作が成功した場合にのみ1回生成され、レコード操作が失敗した場合は生成されません。
iSleepIntegerbRetryExecuteがTrueに設定されている場合、操作を再試行する前にこのパラメーターを使用して遅延値を示します。値はミリ秒単位である必要があります。デフォルト値は0です。例では、このパラメーターの使用方法を示しています。
iIterationInteger読み取り専用。bRetryExecuteパラメーターと組み合わせて使用​​します。iIterationは、ターゲットレコード操作が試行された回数を追跡します。開始値は0です。ターゲットレコード操作が初めて試行されると、この値は1に設定されます。イベントハンドラーは、bRetryExecuteがfalseに設定されるまで操作の再試行を続けます。例では、エラー時の無限ループを回避する方法を示しています。  
 

VB.NET


Public Shared Sub MyErrorHandler (ByVal sReplOrGroupName As String,
ByVal recSource As DBMotoPublic.IRecord,
ByVal recTarget As DBMotoPublic.IRecord,
ByVal e As Exception,
ByRef bAbort As Boolean,
ByRef bRecoverReplication As Boolean,
ByRef bDisableReplication As Boolean,
ByRef bRetryExecute As Boolean,
ByRef iSleep As Integer,
ByVal iIteration As Integer
※関数名MyErrorHandlerは変更可能です。

例:

Public Shared Sub MyErrorHandler (ByVal sReplOrGroupName As String,
ByVal recSource As DBMotoPublic.IRecord,
ByVal recTarget As DBMotoPublic.IRecord,
ByVal e As Exception,
ByRef bAbort As Boolean,
ByRef bRecoverReplication As Boolean,
ByRef bAbortRecord As Boolean,
ByRef bDisableReplication As Boolean,
ByRef bRetryExecute As Boolean,
ByRef iSleep As Integer,
ByVal iIteration As Integer)
Dim s As String
s = s + "-- Called MyErrorHandler to catch the error in replication or group '"
+ sReplOrGroupName + "'" + Environment.NewLine
s = s + "-- Exception: " + e.ToString() + Environment.NewLine
s = s + "-- Iteration: " + iIteration.ToString()
bRetryExecute = False
' Disable replication if the error is a syntax error
If e.Message.Contains("Error applying the mapping for the target field") Then
bAbortRecord = True
bDisableReplication = True
s = s + " - Replication disabled"
Else ' retry
If iIteration = 3 Then
bRetryExecute = False
s = s + " - No Retry"
Else
bRetryExecute = True
iSleep = 3000
s = s + " - Try Again after " + (iSleep/1000).ToString() + " seconds."
End If
End If
IGlobalScript.AddLog (s, 1)
End Sub

C#

[GlobalEventsAttribute("Record_OnMappingError", "Define a general event for the event OnMappingError")]
public static void MyErrorHandler(string sReplOrGroupName,
DBMotoPublic.IRecord recSource,
DBMotoPublic.IRecord recTarget,
Exception e,
ref bool bAbort,
ref bool bRecoverReplication,
ref bool bDisableReplication,
ref bool bRetryExecute,
ref int iSleep,
int iIteration)

例:
public class GlobalEvents : IGlobalEvents
{
[GlobalEventsAttribute("Record_MappingError", "Define a general event for the event EventName")]
public static void MyErrorHandler(String sReplOrGroupName, DBMotoPublic.IRecord recSource, DBMotoPublic.IRecord recTarget, Exception e,
ref bool bAbort, ref bool bRecoverReplication, ref bool bAbortRecord, ref bool bDisableReplication,
sref Boolean bRetryExecute, ref int iSleep, int iIteration)
{
String s = null;
s = s + "-- Called MyErrorHandler to catch the error in replication or group '" + sReplOrGroupName + "'"
+ Environment.NewLine;
s = s + "-- Exception: " + e.ToString() + Environment.NewLine;
s = s + "-- Iteration: " + iIteration.ToString();
bRetryExecute = false;
// Disable replication if the error is a syntax error
if (e.Message.Contains("Error applying the mapping for the target field")) {
bAbortRecord = true;
bDisableReplication = true;
s = s + " - Replication disabled";
}
else { // retry
if (iIteration >= 3) {
bRetryExecute = false;
s = s + " - No Retry";
}
else {
bRetryExecute = true;
iSleep = 3000;
s = s + " - Try Again after " + (iSleep / 1000).ToString() + "seconds.";
}
}
IGlobalScript.AddLog(s, 1);
}

Replication_OnError

解説

このイベントは、レプリケーションでエラーが発生するたびに発生します。 レプリケーション操作の最後にエラーまたは警告アイコンとしてレプリケーションモニターに表示されるすべてのタイプのエラーは、このイベントを生成します。 このイベントは、エラーの発生時ではなく、リフレッシュの終了時またはミラーリング間隔の終了時に呼び出されます。

GlobalEventsAttributeの一つめのパラメーターは、イベント名「Replication_OnError」を示す必要があります。

パラメータ

名前タイプ説明
sReplOrGroupNameString読み取り専用。イベントを生成したレプリケーションまたはグループ名
sMessageString読み取り専用。エラーメッセージ/例外のスタック
bWillDisableBoolean読み取り専用。エラー発生時にレプリケーションを無効にする場合はTrue 
eReplStatusenmReplStatus読み取り専用。エミュレータ enmReplStatusを使用してイベントが呼び出されたときのレプリケーションステータスを指定します。エミュレータに指定できる値は次のとおりです。ErrorAndContinue
レプリケーション中にエラーが発生(リフレッシュまたはミラーリング間隔)した場合にもレプリケーションは続行されます。例は、ターゲットテーブルでレコードが見つからなかったためにトランザクションがターゲットレコードの削除に失敗した場合、「Syniti DR」はログにエラーを報告し、次のレコードに進みます。Error
エラーが生成され、レプリケーションの実行が停止します。 次の間隔でレプリケーションは再開されます。 このタイプのエラーの例は、ソースまたはターゲットデータベースへの接続が切断された場合に該当し、「Syniti DR」はレプリケーションを続行できず、リカバリモードになります。Success
このイベントでは使用されません。 Replication_OnErrorが呼び出されると、レプリケーションは常にエラー状態になります。

VB.NET


Public Shared Sub MyErrorHandler (ByVal sReplOrGroupName As String, ByVal sMessage As String,
ByVal bWillDisable As Boolean, ByVal eReplStatus As enmReplStatus)
※関数名MyErrorHandlerは変更可能です。

例:
_
Public Shared Sub MyGlobalEvent (ByVal sReplicationName As String, ByVal sMessage As String,
ByVal bWillBeDisabled As Boolean, ByVal eReplStatus As enmReplStatus)
Dim s As String
s = DateTime.Now.ToString() + Environment.NewLine + Environment.NewLine
s = s + "Error in replication '" + sReplicationName + "'"
+ Environment.NewLine + Environment.NewLine
s = s + "Replication Status: " + eReplStatus.ToString() + Environment.NewLine
+ Environment.NewLine
s = s + sMessage + Environment.NewLine + Environment.NewLine
If bWillBeDisabled Then
s = s + "The replication will be disabled." + Environment.NewLine + Environment.NewLine
End If
s = s + "-----------------------------------------------------------------" + Environment.NewLine
s = s + " This is an automatic message generated by the Syniti DR script" + Environment.NewLine
s = s + "-----------------------------------------------------------------" + Environment.NewLine
IGlobalScript.SendMail ("Syniti DR Error", s)
End Sub

C#

[GlobalEventsAttribute("Replication_OnError", "Define a general event for the event Replication_OnError")]
public static void MyErrorHandler(string sReplOrGroupName, string sMessage,
bool bWillDisable, enmReplStatus eReplStatus)

例:
[GlobalEventsAttribute("Replication_OnError", "General event for the event OnError")]
public static void MyGlobalEvent(String sReplicationName, String sMessage, Boolean bWillBeDisabled,
enmReplStatus eReplStatus)
{
String s = null;
s = DateTime.Now.ToString() + Environment.NewLine + Environment.NewLine;
s = s + "Error in replication '" + sReplicationName + "'"
+ Environment.NewLine + Environment.NewLine;
s = s + "Replication Status: " + eReplStatus.ToString() + Environment.NewLine
+ Environment.NewLine;
s = s + sMessage + Environment.NewLine + Environment.NewLine;
if (bWillBeDisabled)
{
s = s + "The replication will be disabled." + Environment.NewLine + Environment.NewLine;
}
s = s + "---------------------------------------------" + Environment.NewLine;
s = s + " This automatic message is generated by the Syniti DR script" + Environment.NewLine;
s = s + "---------------------------------------------" + Environment.NewLine;
IGlobalScript.SendMail("Syniti DR Error", s);
}

ReplicationManager_onStart

パラメータと解説

このイベントは、レプリケーションエージェントの起動時に発生します。 Syniti DRログに通知メッセージを追加したり、管理者に電子メールを送信したりするために使用できます。 イベントのハンドラーを作成するには、クラスヘッダー「Public Class GlobalEvents:Inherits IGlobalEvents」内にカーソルを置き、例をガイドラインとして使用してハンドラーを定義します。

GlobalEventsAttributeの一つ目のパラメーターは、イベント名「ReplicationManager_OnStart」を示す必要があります。

このイベントにパラメータはありません。

VB.NET

_
Public Shared Sub OnStart ()

例:
_
Public Shared Sub OnStart ()
Dim s As String
s = s + "-- Message from Syniti DR - START"
s = s + "-----------------------------------------------------------------"
+ Environment.NewLine
s = s + "- This is an automatic message generated by the Syniti DR
script -" + Environment.NewLine
s = s + "-----------------------------------------------------------------"
+ Environment.NewLine IGlobalScript.SendMail
("Replication Manager Message", s)
End Sub

C#

[GlobalEventsAttribute("ReplicationManager_OnStart", "Standard event for the event OnStart")]
public static void OnStart()

例:
[GlobalEventsAttribute("ReplicationManager_OnStart", "Standard event for the event OnStart")]
public static void OnStart()
{
String s = null;
s = s + "-- Message from Syniti DR - START";
s = s + "-------------------------------------------------------" + Environment.NewLine;
s = s + "- This is an automatic message generated by the Syniti DR script -" + Environment.NewLine;
s = s + "-------------------------------------------------------" + Environment.NewLine;
IGlobalScript.SendMail("Replication Manager Message", s);
}

ReplicationManager_onStop

パラメータと解説

このイベントは、レプリケーションエージェントが停止したときに発生します。 Syniti DRログに通知メッセージを追加したり、管理者に電子メールを送信したりするために使用できます。 イベントのハンドラーを作成するには、クラスヘッダー「Public Class GlobalEvents:Inherits IGlobalEvents」内にカーソルを置き、以下の例をガイドラインとして使用してハンドラーを定義します。

GlobalEventsAttributeの最初のパラメーターは、イベント名「ReplicationManager_OnStop」を示す必要があります。

パラメータはありません。

VB.NET

_
Public Shared Sub OnStop ()

例:

Public Shared Sub OnStop ()
Dim s As String
s = s + "-- Message from Syniti DR - STOP"
s = s + "---------------------------------------------------------" + Environment.NewLine
s = s + "This is an automatic message generated by the Syniti DR script -" + Environment.NewLine
s = s + "--------------------------------------------------------"
+ Environment.NewLine
IGlobalScript.SendMail ("Replication Manager Message", s)
End Sub

C#

[GlobalEventsAttribute("ReplicationManager_OnStop", "Standard event for the event OnStop")]
public static void OnStop()

例:
[GlobalEventsAttribute("ReplicationManager_OnStop", "Standard event for the event OnStop")]
public static void OnStop()
{
String s = null;
s = s + "-- Message from Syniti DR - STOP";
s = s + "--------------------------------------------------------" + Environment.NewLine;
s = s + "- This is an automatic message generated by the Syniti DR script -" + Environment.NewLine;
s = s + "---------------------------------------------------------" + Environment.NewLine;
IGlobalScript.SendMail("Replication Manager Message", s);
}
コメントする -->

レプリケーション対象テーブル構成変更後のSyniti Data Replication (旧DBMoto) マッピング対応について

Syniti Data Replication (旧DBMoto)は異種データベース間のレプリケーションツールです。
レプリケーション対象テーブルに実行されたDML文(Insert、Update、Delete)をSynitiが検知し、ターゲットテーブルに対して更新を実行します。
※DDL文(Alter、Drop、Truncate、Create)は対応しておりません。

そのため、例えばAlterクエリを実行し、テーブルにカラムを追加した場合、
Synitiはテーブル構成の変更を検知することができないため、
追加したカラム内のレコードについてはターゲットテーブルに連携されません。

Synitiでレプリケーション対象としているテーブル構成を変更した場合は、
Syniti側でテーブル構成の再読み込みとマッピング設定が必要となります。

以下が手順となります。

※稀なケースですが、メタデータに対する変更が反映されていない場合があります。Ctrl+Shift+Mを同時押しすることで、メタデータに対するコミット操作が可能ですので、メタデータに対する変更を完了する際には、この操作の実施をお願いいたします。

●環境情報
ソースデータベース:SQL Server
ターゲットデータベース:Oracle

現在、Synitiのコンソールでは、SQL Server、Oracle双方ともに以下のようにカラムが3つ確認できます。

Synitiのコンソールからは、既にレプリケーションジョブが定義されている状態となります。

●カラムが追加された場合の手順
ソーステーブルに対してカラムが追加された場合、
まずはSynitiのコンソールに対して追加されたカラムの読み込みが必要となります。

1. 対象レプリケーションジョブを右クリックし、レプリケーションジョブを無効化
2. カラムが追加されたテーブルを右クリックし、スキーマ情報更新をクリック

3. テーブル構成が変更されているため、以下のメッセージが表示されますが、はいをクリック

※トリガー方式でトランザクションセットアップを実施している場合、下記のようにログテーブル、トリガーの再構成を促すダイアログが表示されます。これを実施しないと追加されたカラムに関するトランザクションログは記録されません。「はい」または「すべてはい」をクリックすると自動的に再構成が実施されます。

本ダイアログが表示されないような場合、対象レプリケーションを右クリック、「レプリケーションを検証する」から手動での再ビルドをお願いいたします。

4. テーブルプロパティを確認すると、追加したtestというカラムがSynitiコンソールに反映されます。

5. ターゲットテーブル側にカラムを追加し、再度上記2~4の手順を実施してSynitiコンソールへカラム情報を反映

※Oracle側のtestカラムが反映されます。

6. レプリケーションジョブを右クリックし、プロパティをクリック

7. マッピングをクリック

8. 追加したカラム(test)がまだ紐づいていないことを確認

9. testカラムを右クリックし、フィールドへのマッピングへ進み、マッピングを設定

10. 追加したカラム(test)同士をマッピング

11. マッピングが設定されたことを確認し、OKをクリック

※シンクロナイゼーションモードを設定している場合には、追加で以下のように逆向きのマッピング設定が必要です。

11-1. フィールドマッピングの画面より、マッピング方向ボタンをクリック

11-2. ターゲットテーブルからソーステーブル向きのマッピングが設定されていないことを確認

11-3. マッピングを追加

11-4. ターゲットテーブルからソーステーブル向きのマッピングが設定されていることを確認し、OKをクリック

このように、レプリケーションジョブ定義後にテーブル構成が変更となった場合でも、テーブル構成情報を読み込み直し、マッピングすることで追加されたカラムに対してレプリケーションを実施できます。

また、削除されたカラムについても、スキーマ情報更新を実行することでコンソールから削除可能です。

 

タグ:

Syniti Data ReplicationにおけるDb2 LUWへのバルクミラーリングについて

Syniti Data Replication 9.6では、Db2 LUWへのバルクミラーリング機能が追加されました。
これにより、Db2 LUWに対して変更データを指定したブロックサイズ単位で一括反映でき、
大量の更新データを高速に反映することができます。

既にDBMotoをご利用の場合、こちらの記事よりSyniti Data Replicationへアップグレードでき、
レプリケーションジョブの設定を一部変更することで、バルクミラーリングを設定できます。

まず、Syniti Sata Replicationのコンソールより、Db2 LUWをターゲットとして指定している
レプリケーションジョブを右クリックし、プロパティをクリックします。


レプリケーションプロパティより、ミラーリングオプション – ソースの項目へ遷移し、
ミラーリングInsertモードを BulkInsertへ変更し、適用をクリックします。

上記の手順にて、バルクミラーリングモードでDb2 LUWに対して変更レコードがレプリケーションされます。

タグ:

Syniti Data Replication (旧DBMoto)でのスクリプトの書き方②:グローバルスクリプト

前回に引き続き、 Syniti Data Replication (旧DBMoto) でのスクリプトの書き方をご紹介させていただきます。今回はその中でも特にグローバルスクリプトの基本的な使用方法をご紹介します。

グローバルスクリプトは関数やグローバルイベントに対する制御の定義を行うグローバルクラスを定義する共通モジュールです。レプリケーションスクリプトまたは関数スクリプト内で呼び出す必要があるユーザー関数を定義するためにも使用できます。

グローバルスクリプトでは以下の関数セットを使用または定義できます。

  • Microsoft C#ライブラリ:グローバルスクリプトエディタで選択したスクリプト言語に基づいて、C#またはVB.NETを使用し、スクリプトおよびスクリプトで使用する関数を定義
  • Microsoft Visual Basic名前空間関数: [Strings] Left, Mid, Right, Instr; [Math] Cos, Arc, PowerなどのVisual Basic 6関数を利用可能にする.NET Frameworkクラスライブラリ
  • グローバル関数:DBMotoの一部として関数を実装
  • グローバルスクリプトイベント:全てのレプリケーションに適用するイベント
  • ユーザー関数:レプリケーションスクリプトで使用するための関数をグローバルスクリプトダイアログ内でユーザが定義
  • テーブル作成ルールまたは関数:ターゲットテーブルウィザードでのテーブル作成の仕方をカスタマイズするための関数
  • フィールドマッピングルールまたは関数:レプリケーションでソースとターゲットのカラムをどのように対応付けするか決定するための関数

グローバルスクリプトエディタを使用して、多くの場合、レプリケーションスクリプトおよびマッピングで使用する関数を作成します。

たとえば、以下のように、いくつかのレプリケーションスクリプトで使用する変換関数があるとします。 レプリケーションスクリプトごとに変換関数を繰り返し記述する代わりに、グローバルスクリプトで変換関数を定義し、レプリケーションスクリプトや関数マッピングで呼び出すことができます。

1.Syniti Data Replication (旧DBMoto)コンソールにてメタデータを右クリックし、グローバルスクリプトを選択します。デフォルトで言語にはC#が選択されています。

using System;
using System.Data;
using DBMotoPublic;
using DBMotoScript;
namespace DBRS
{
    public class GlobalScript : IGlobalScript
    {
    }
    public class MappingRule : IMappingRule
    {
    }
    public class GlobalEvents : IGlobalEvents
    {
    }
}

2. GlobalScriptクラスで、次の例のように関数を宣言します

public static DateTime DateConvert(int intDate){
   int cyy;
   int yyyy;
   int mm;
   int dd;   
   cyy = (int)(intDate / 10000);
   mm = (int)((intDate - cyy * 10000) / 100);
   dd = intDate % 100;
   if (cyy < 100)
       yyyy = 1900 + cyy;
   else
       yyyy = 2000 + (cyy % 100);
   DateTime dc = new DateTime(yyyy, mm, dd);
   return dc;
}

3.コンパイルボタンを使用し、スクリプトの構文チェックを行います。スクリプトに問題があった場合、別のダイアログで表示されます。レプリケーションを実行する前にコンパイルを行い、問題がないか確認してください。


4.このようにグローバルスクリプトで定義した関数を各レプリケーションのマッピング時などに利用できます。

※関数を定義する際にレプリケーションまたは関数スクリプト内でその関数を使用する場合、下記のようにpublicの後にstaticキーワードを追加します。

public static object GetQueryValue(IDbConnection objConnection, String strQuery)

※ Record_OnExecuteErrorイベントでは下記のように、イベントハンドラを宣言します。属性GlobalEventAttributeを指定することを忘れないでください。

[GlobalEventsAttribute("Record_OnExecuteError", "Define a general event for the event EventName")]
    public void MyErrorHandler(String sReplOrGroupName, DBMotoPublic.IRecord  recTarget, Exception e, 
	ref Boolean bRetryExecute, ref int iSleep, int iIteration)
        {
	}

※ライブラリをスクリプト内のインポートのリストに追加する場合、下記のようにリファレンスダイアログから追加可能です。

このようにグローバルスクリプトを活用したサンプルを本ブログサイトでもいくつかご紹介しています。

コメントする -->

保護中: Syniti Data Replication (旧DBMoto) 9.6.0.50 リリースノート

このコンテンツはパスワードで保護されています。閲覧するには以下にパスワードを入力してください。

保護中: Syniti Data Replication (旧DBMoto) 9.6.0.50 リリースノート はコメントを受け付けていません -->

Webセミナー録画 [遅延原因を楽々特定! DBパフォーマンスチューニングツール「DPA」のご紹介] 2019/09/19開催

データベースのパフォーマンス監視やチューニングにお悩みではありませんか?
SQLクエリやコード、リソース不足などの様々な要因が相互作用するため、データベースパフォーマンスのボトルネックを特定することは非常に困難かと存じます。

今回は、このようなお悩みをレスポンス・タイムの計測を用いた独自の監視手法により解決するDatabase Performance Analyzer(DPA)』についてご紹介いたします。
DPAは、Oracle : SQL Sevrer : MySQL : Db2 : Sybase といった様々なDBに対応しており、Amazon RDSやAzure SQLといったクラウド環境にも対応しております。

・データベースの適切なリソース割り当てでお悩みの方
・データベースパフォーマンスの可視化をご希望の方
・データベースのレスポンス遅延でお困りの方

などなどお悩みのDB管理者様必見です!

遅延原因を楽々特定! DBパフォーマンスチューニングツール「DPA」(スライド版)

動画版
タグ: , , , , ,

データベースはクラウド ファースト

終焉を迎えるオンプレミスの時代

データベースはオンプレミスで設定・運用して、毎晩自動でクラウドにバックアップ保存する、というパターンは今でもけっこう多いのではないでしょうか。クラウドが最初に導入された頃を思えば、大抵の企業において、入り口はそこだったし、そのまま、その入り口からあまり深入りしていない企業も少なくないようです。しかし、その長かった入り口の時代もついに終わりに近づいています。

米調査会社ガートナーが今夏に発表したレポート『The Future of Database Management Systems is Cloud!(データベース管理システムの未来はクラウド)』によれば、データベースをクラウドに置く企業が飛躍的に増えており、同分野の市場規模は2017年から2018年にかけて18.4%拡大、その68%はクラウド上のDBMSだといいます。市場拡大はAmazon AWSとMicrosoft Azureが牽引し、その2社で全体の75%を占めますが、両社の新規ビジネスはほぼ100%クラウド ベースだと報告されています。

Cloud Firstの時代

さらに重要なことは、DBMSの最新機能が完全にCloud First(クラウド ファースト)になっている点です(○○ファーストという表現は、トランプ大統領のアメリカ ファーストから広まった感がありますが、こんなところで聞くとは思いませんでした…)。つまり、最新技術や機能はまずクラウドで導入され、後から徐々にオンプレミスにも普及するか、あるいはオンプレミスにはもはや普及しない可能性があるそうです。時代はすっかりCloud Firstに突入し、オンプレミスにこだわると取り残されると警鐘が鳴らされています。

これは、データ アナリティクスや機械学習の活用が進んでいることとも大いに関連があるようです。データ分析アプリケーションのクラウド上での運用が進めば、データ管理も当然クラウドで行うのが理にかなっています。ビッグデータの有効利用がビジネス戦略の中心課題となった昨今、SaaSとDBaaSが切り離せなくなっていると言えます。

To Be or Not To Be

現実的には、すでに稼働中の業務システムに細かな改善が繰り返し追加される開発環境において、まるでTo Be or Not To Beのように、オンプレミスかクラウドの二者択一を迫るのは無理があります。現場はそんなに単純で恵まれた環境ではないと、ITチームの悲鳴が聞こえる気がします。データベースも各種アプリケーションもハイブリッド環境での可搬性と拡張性を目指すことが、もっとも現実的で合理的な戦略なはずで、それをサポートできるサービスの需要が今後もっとも見込まれるのではないでしょうか。

コメントする -->

Syniti Data Replication (旧DBMoto)でのスクリプトの書き方①

本ブログでもいくつか紹介していますが、Syniti Data Replication (旧DBMoto)ではスクリプトを使ってより高度なレプリケーションや設定の効率化などを行えます。このスクリプトに関して、改めてシリーズで基本的な使い方をご紹介します。

スクリプトの種類

スクリプトは記述する場所により、以下の3種類があります。

  • グローバルスクリプト

関数のグローバルクラスを定義する共有モジュールです。レプリケーションや関数スクリプトで呼び出す、共通の関数などを定義できます。

  • レプリケーションスクリプト

レプリケーションに発生した特定のイベントに対して実行する処理をスクリプトで定義できます。

  • 関数スクリプト

カラムのマッピングを行う際の値の変換等を行う際のスクリプトを記述できます。

スクリプト言語の変更

Syniti Data Replication (旧DBMoto)はC#またはVB .NET、いずれかでのスクリプトをサポートしており、デフォルトはC#です。使用する言語はグローバルスクリプトで指定し、ここで設定した言語をレプリケーション、関数スクリプトでも使用します。

Visual Basic .NETを使用する場合の参考情報

Visual Basic 6.0以前(以下VB)とVisual Basic .NET以降(以下VB.NET)には類似点も多くありますが、異なる点も多いことに注意してください。

https://docs.microsoft.com/ja-jp/dotnet/visual-basic/

  • VBにおけるIsNullの代わりにIsNothingを使用します。
  • 引数がない場合でも、関数には常に括弧を使用します。
  • 型付きのパラメータを常に使用します。関数の戻り値の型を定義します。
  • グローバルスクリプトで、静的関数として定義するために、キーワード「Shared」を使用してすべてのカスタムプロシージャ(SubおよびFunction)を定義します。
  • 実行する前に必ずスクリプトをコンパイルしてください。 VB.NETコンパイラは、古いVBAコンパイラよりも強力であり、より早い段階でエラーを見つけることができます。
  • Syniti Data Replication (旧DBMoto)がレコードの列に番号を付ける方法は、ソースまたはターゲットの列の順序と必ずしも同じではありません。たとえば、一部のフィールドがマップされていない場合、それらはRecordBeforeまたはRecordAfter構造から除外されるため、列は順序番号と数値的に一致しません。
コメントする -->

[録画] OSS系データベース、クラウド・データベースへ脱Oracleへの実現方法

db tech showcase Tokyo 2018でのプレゼンテーション:
昨今オンプレのOracleからPostgreSQL, MySQL等オープン系のデータベースへの移行、またクラウド上のデータベースへの移行を検討されているユーザに異種リアルタイム・データベース・レプリケーションツール「DBMoto」を活用した事例をご紹介します。また古いOracle バージョンから最新Oracleバージョンへの移行手法・事例もご紹介します。またStambiaというユニークなETLツールもご紹介しています。DBMotoのお問い合わせは 03-3660-9336 までお願いします。

タグ: ,

グラフ データベースの時代到来?

データベースの主流はその時代時代で移り変わってきました。1990年代はリレーショナル データベースが一躍脚光を浴びた時代です。リレーショナル データベース(RDB)は今でも変わらずがんばっていると、RDBファンに叱られてしまうかもしれませんが、いちおう2000年代にはベテランの域に達し、いぶし銀の活躍を見せながらも、華々しく脚光を浴びるポジションはXMLやNoSQLデータベースなどの若手に譲りました。2010年代になるとJSON型のデータベースが注目を集め、ビッグデータへの対応が求められる時代になってきました。そして、2020年代はグラフ データベースの時代が来るかもしれません。

とはいえ、グラフ データベースは2000年代前半から徐々に使われ出してはいたようです。データの構成を論理的に分析しやすい特性もあって、主に学術分野で利用されてきましたが、商業利用が進みませんでした。それが、2014年から頭角を現し、ハードウェアの高速化やクラウドをはじめとするインフラの発達にともない、活用範囲が急速に広がり始めました。

グラフ データベースと言っても、日本語でイメージする「グラフ」とは異なるので、どちらかと言うと「ネットワーク データベース」と呼んだほうがわかりやすいかもしれません。リレーショナル データベースは、テーブル間の関係を外部キーなどで定義し、多数のテーブルを複雑に関連付けながら構成されますが、グラフ データベースでは個々のデータ間の関係をネットワークで構成していきます。

よく使われる例は、SNSの人と人とのつながりです。たとえば、AさんがBさんをフォローし、BさんはCさんを、CさんはAさんとDさんをフォローする、というようなネットワーク構成です。

グラフ データベースでは、Aさん、Bさんなどの各ユーザーをnode、フォローする、されるといった関係はedge、Aさんの名前や年齢、所属などの属性を propertyと呼びます。

この データベースの最大の特長は、データの構成が目で見てわかりやすいという分析上の便利さもさることながら、特定データを見つけるスピードにあります。

たとえば、上の例で、Aさんと直接つながりのないDさんの情報をAさんに自動的に紹介する機能をシステムに加えたいとします。グラフ データベースなら、nodeのedgeをたどって簡単に情報を見つけ出すことができますが、同じことをリレーショナル データベースでやろうとすると、テーブルを外部キーで参照して、連結したビューを用意してから必要なデータを照会するなど、2重3重の手間がかかります。ここで挙げた単純な例ではテーブル数も限られ、グラフ データベースとの差はほとんどないのでしょうが、実用環境では膨大なデータが複雑に構成され、グラフ データベースのパフォーマンスが際立ってくるはずです。

以上、グラフ データベースの特長をほんのさわりだけ紹介しましたが、これを見ただけでも、マルチクラウドのデータセンターにビッグデータが溢れる時代の主役は、グラフ データベースをおいてほかにはいないような気がしてきませんか?

コメントする -->