web-dev-qa-db-ja.com

Dataguardスイッチオーバーをシームレスに行う方法

12c環境でのDataguard構成で、プライマリ(foo)からスタンバイ(bar)へのスイッチオーバーを実行し、user@fooでsqlplusを実行しようとすると、新しいプライマリ(バー)に接続できず、「ORA-011033: Oracle initialization or shutdown in progress」エラー。

これは、接続がfooアドレスではなくbarアドレスをまだポイントしているためであることがわかっています。多くの記事によれば、新しい「仮想」サービスを作成して、さまざまな接続を処理するとともに、ロール変更後にこのサービスを停止/開始するトリガー。

私はこれを行い、service_namesパラメータをこの新しい「仮想」サービスに設定すると、スイッチオーバーが機能し、元に戻すこともできますが、user@fooでsqlplusを実行しようとすると、ORA-011033がスローされます。トリガーは役に立たず、サービスはfooとbarの両方で引き続き実行されます。これは、そのパラメーターセットを使用すると、トリガーが試行するすべてのことをオーバーライドするように見えるためです。

このパラメーターを定義しないと、スイッチオーバーが正常に機能し、トリガーが機能します。sqlplus user@fooを実行すると、barアドレスに正しくリダイレ​​クトされます。ただし、fooにスイッチオーバーしようとすると、DGアラートログに次のメッセージが表示されます。

Redo transport problem detected: redo transport to database foo has the following error:
ORA-16047: DGID mismatch between destination setting and target database 08/05/2016 16:01:02 Initialization of connection failed. Expected destination db_unique_name is foo. Database actually reached is bar Failed to send message to site foo. Error code is ORA-16642. Data Guard Broker Status Summary:
Type Name Severity Status Configuration foo_dg Warning ORA-16607 Primary Database bar Error ORA-16778 Physical Standby Database foo Error ORA-16642

FOO:

log_archive_dest_2 = 'service = "bar"'、 'ASYNC NOAFFIRM delay = 0 optional compression = disable max_failure = 0 max_connections = 1 reopen = 300 db_unique_name = "bar" net_timeout = 30'、 'valid_for =(online_logfile、all_roles)' fal_client = 'foo' fal_server = 'bar'

オンバー:

log_archive_dest_2 = 'service = "foo"、ASYNC NOAFFIRM delay = 0 optional compression = disable max_failure = 0 max_connections = 1 reopen = 300 db_unique_name = "foo" valid_for =(online_logfile、all_roles)' fal_client = 'bar' fal_server = 'foo'

LDAPのエントリ:foo:

(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =(PROTOCOL = TCP)(Host = foo_home)(PORT = 15940)))(ADDRESS =(PROTOCOL = TCP)(Host = bar_home)(PORT = 15940)))(CONNECT_DATA =(SERVICE_NAME = virtual_foo)(FAILOVER_MODE =(TYPE = SESSION)(METHOD = basic))))

バー:

(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =(PROTOCOL = TCP)(Host = bar_home)(PORT = 15940))))(CONNECT_DATA =(SERVICE_NAME = bar)))

何が欠けているのか、誤解しているのかわかりません。誰かが私が間違っているかもしれないことについて何か光を当てることができますか?必要に応じて、より多くの情報を提供できます。

2
exit_1

11.2以降では、トリガーを作成する必要はありません。グリッドインフラストラクチャで役割ベースのサービスを定義できます。

foo

srvctl add service -db foo -service virtual_foo -role primary
srvctl start service -db foo -service virtual_foo

bar

srvctl add service -db bar -service virtual_foo -role primary
srvctl start service -db bar -service virtual_foo

グリッドインフラストラクチャを使用しない場合は、トリガーを使用してください。

仮想サービスが正しく構成されていないため、ORA-01033を受け取りました。 service_namesの値を手動で更新しないでください。それを行ってスイッチオーバーを実行した後も、virtual_fooサービスはfooで実行されました。クライアントはリストの最初のアドレスを試しましたが、リスナーが生きていて、要求された名前のサービスが存在するため、ログインしようとしました。しかし、スタンバイデータベースはMOUNT状態だったため、クライアントはログインできませんでした-->ORA-01033

foo部分に戻るスイッチオーバーの場合:クライアントとData Guard構成に同じTNSエントリを使用しないでください。クライアントはどのサイトに接続するかを知る必要はありませんが、Data Guard Brokerおよびデータベースバックグラウンドプロセスはfooまたはbarに正確に接続する必要があります。仮想サービスはその機能を提供しません。 Data Guard構成に必要なTNSエントリとクライアントが使用するTNSエントリを分離します。

通常、私は以下の命名とTNSエントリでDGを設定します。

Db_nameがfooの場合、次のようになります。

  • プライマリ:db_unique_name = foo_site1
  • スタンバイ:db_unique_name = foo_site2

(またはサイトを識別する類似のもの)

TNS:

  • foo_site1:TNSエントリはsite1のホストを指し、service_nameはfoo_site1として定義されています-DG構成で使用されます
  • foo_site2:site2のホストを指すTNSエントリ、service_nameはfoo_site2として定義-DG構成で使用
  • foo:両方のサイトを指すTNSエントリ。service_nameはfooとして定義されています(ロールベースのサービスとして定義されています)-クライアントが使用します

最後に、接続文字列のこの部分:

(FAILOVER_MODE=(TYPE=SESSION)(METHOD=basic))

サイトごとに複数のインスタンスを持つRACデータベースがあり、foo_homeおよびbar_homeが実際にはSCAN名でない限り、これは不要です。これらのパラメータは、透過的アプリケーションフェイルオーバー(RACインスタンス間のセッションフェイルオーバー)を構成するために使用されます。

ちなみに、これは本当にシームレスなスイッチオーバーとはほど遠いものです。これにより、ロールの移行後にクライアントが単一の接続文字列を使用してデータベースに接続できるようになりました。

クライアントセッションは失敗し、手動で再接続する必要があります。これには数分かかる場合があります。または、アプリケーションを停止して、そのためのダウンタイムを計画する必要があります。

本当にシームレスなスイッチオーバーを実現するには、はるかに多くの作業が必要です(ONS、FANの構成など)。詳細:

高可用性Oracleデータベースのクライアントフェイルオーバーのベストプラクティス

高速アプリケーション通知

6
Balazs Papp