• ベストアンサー
  • 暇なときにでも

オフライン中のトランザクションについて

表領域をオフラインにした場合、オフライン前に開始されたトランザクションは有効ですが、オフラインのまま、コミット、または、ロールバックして、表領域をオンラインにしても、整合がとれるのはなぜなのでしょうか。 コミットするか、ロールバックするかの情報はどこに保持してるのか疑問です。 (オフラインにしてから、ファイルをリネームし、 トランザクションをロールバックして、 ログをアーカイブし、DB再起動後に、ファイル名を戻して、 オンラインにすると、ちゃんとロールバックされています。 同じ操作で、コミットするとちゃんとコミットされています。 知っている方には当然なのでしょうが、私にとっては、不思議です) 詳しい方がみえましたらご教授お願いいたします。

共感・応援の気持ちを伝えよう!

  • 回答数6
  • 閲覧数386
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • 回答No.6

データベース概要のマニュアルに 「表領域がオフラインになると、Oracleでは後続のSQL文でその表領域内に含まれるオブジェクトを参照できなくなります。表領域内のデータを参照する完了済の文を含むアクティブ・トランザクションは、トランザクション・レベルでは影響を受けません。それらの完了済の文に対応するロールバック・データは、SYSTEM表領域にある遅延ロールバック・セグメントに保存されます。表領域が再びオンライン化されると、このロールバック・データは必要に応じて表領域に適用されます。」 とあるので「SYSTEM表領域にある遅延ロールバック・セグメントに保存」されるようです。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ありがとうございます!! まさに、知りたかった内容が、"遅延ロールバック・セグメント" を検索することで知ることができました。 本当にありがとうございました!

関連するQ&A

  • トランザクション処理について

    トランザクション処理について、ちょっと疑問に思うことがあります。 トランザクション処理とは、クライアントの異常終了などで、中途半端な状態で終わったデータはロールバックされ、元の状態にもどされることですよね?では、サーバが突然フリーズした場合どうなるのでしょうか?トランザクション処理もできないため、中途半端な状態で終わったデータは手動で整合性を合わせる必要があるのでしょうか? かなり、基本的なことを聞いていますが、DBの知識がないためどなたか教えてください。

  • トランザクションのネストについて

    トランザクションのネストについて お世話になります。 今、ストアドの中でストアドを実行するようなSQLを作成しているのですが、 このときのトランザクション処理について教えていただきたいです。 簡単な流れとしましては Aトランザクション開始(大枠のストアド) ↓ 処理a  ↓  Bトランザクション開始  ↓  (Aストアドの中のストアド実行)  ↓  Bコミット  ↓ 処理b ↓ Aコミット といった感じなのですが、BストアドでコミットするとBストアドをCALLする前の処理aが コミットされてしまいます。 ここはBはBだけでコミットされてほしいのです。 独自で調べた限りでは、「トランザクションのネストはMySQLではできない」ということらしいのですが、 こういった場合、どのようにしたらよいのでしょうか。 もし方法があれば、ご教示のほどお願い致します。 -環境- [DB MySQL 5.0] [OS Windows XP]

    • ベストアンサー
    • MySQL
  • トランザクションを張って対話型でのコミット・ロール

    トランザクションを張って更新処理を行った後に、 ユーザの「はい」「いいえ」ボタンによって、 トランザクションのコミットとロールバックを切り替えることは可能でしょうか。 処理の流れは以下の様になります。 1.データ更新前の値を取得 2.トランザクションの開始 3.データ更新 4.データ更新前の値とデータ更新後の値を比較して、   差分がある場合は確認メッセージを表示する。 5.確認メッセージで「はい」がクリックされた場合はコミットする。 6.確認メッセージで「いいえ」がクリックされた場合はロールバックする。 実装方法はどのようでも構いません。 どなたかご教授ください。

その他の回答 (5)

  • 回答No.5

>ひょっとして、オフラインの表領域のトランザクションが未確定の場合、 >ログスイッチによって、その部分のログがアーカイブされないで >カレントログに残るってことでしょうか? 「オフラインの表領域のトランザクションが未確定の場合、」というのはcommit/rollbackしていないトランザクションを指しますか? commit/rollbackしていないトランザクションはREDOログバッファにあって、REDOLOGファイルには基本的には入りません。 (例外:REDO ログ・バッファがいっぱいになるか、別のトランザクションがコミットされるなどでREDOログファイルに含まれます) 表領域をオフラインにする際(NORMAL(デフォルト)指定)、データベースは表領域のデータ・ファイルすべてのチェックポイントを取ってから、それらのファイルをオフライン化します。

共感・感謝の気持ちを伝えよう!

質問者からの補足

>ひょっとして、オフラインの表領域のトランザクションが未確定の場合、 すいません。 オフラインの表領域のトランザクションがコミット・ロールバックされた場合 の間違いでした。 >表領域をオフラインにする際(NORMAL(デフォルト)指定)、データベースは表領域のデータ・ファイルすべてのチェックポイントを取ってから、それらのファイルをオフライン化します。 そのとおりなのですが、、 わからないのは、オフライン化の後で、コミット・ロールバックした場合、 その情報をどこに保持してるかが知りたいのですが、、、。

  • 回答No.4

あまり自身ないですが・・・。 変更の情報はREDOログにあります。 インスタンスリカバリに関してはcommitした/しないに関わらず、適用し、その後にcommitしていない情報をrollbackします。 REDOログに残っているのであれば、インスタンスリカバリでREDOが適用されてcommitされた内容が表示されているのだと思います。 #REDOログが上書きされるタイミングで対象表領域すべてがOFFLINEだとどうなるかは不明ですけど・・・ また、トランザクションがコミットされると、ロールバックまたはトランザクション・リカバリの実行にUNDO データは不要になります。とマニュアル(10g)にあるのでcommit後のUNDOの変更は関係ないと思います。

共感・感謝の気持ちを伝えよう!

質問者からの補足

回答ありがとうございます。 >変更の情報はREDOログにあります。 >インスタンスリカバリに関してはcommitした/しないに関わらず、適用し、その後にcommitしていない情報をrollbackします。 >REDOログに残っているのであれば、インスタンスリカバリでREDOが適用されてcommitされた内容が表示されているのだと思います。 ひょっとして、オフラインの表領域のトランザクションが未確定の場合、 ログスイッチによって、その部分のログがアーカイブされないで カレントログに残るってことでしょうか? ただ、検証が難しそうですね、、。

  • 回答No.3
  • MZ-80B
  • ベストアンサー率56% (46/81)

> 不完全リカバリになるのではないかな・・・ 「ログをアーカイブし、~」と書かれていますから アーカイブログ運用しているということですよね。 不完全リカバリになる。ではなくアーカイブを使って 完全リカバリ可能に訂正いたします。

共感・感謝の気持ちを伝えよう!

  • 回答No.2
  • MZ-80B
  • ベストアンサー率56% (46/81)

UNDO表領域を変更とは 正常なUNDO表領域の切り替えですか?メディアリカバリですか? デフォルトの切り替えであればUNDOセグメントヘッダ情報が 移動したのではないでしょうか

共感・感謝の気持ちを伝えよう!

質問者からの補足

以下のようにUNDO表領域をUNDOTBS01 -> UNDOTBS02に変更しました。 shutdown immediate; startup nomount; alter system set undo_tablespace = 'UNDOTBS02' scope=spfile; alter database mount; alter database open; オープン時には、UNDOTBS01にはoracleからアクセスできないと思うので、 UNDOセグメントヘッダ情報が移動はできないような気がするのですが、、

  • 回答No.1
  • MZ-80B
  • ベストアンサー率56% (46/81)

質問内容はデータ表領域がオフラインなのになぜコミットできるかというと同じです。 コミット操作はUNDOセグメント(ロールバックセグメント)ヘッダの トランザクション表にSCN付きで記録されますのでデータ表領域のIOは遅延することができます。 次の表アクセス時にUNDOセグメントヘッダからデータ表領域に書き込まれます。 シャットダウンしてUNDO表領域も同時に壊しておくと、たぶんオフライン前までの 不完全リカバリになるのではないかな・・・

共感・感謝の気持ちを伝えよう!

質問者からの補足

回答ありがとうございます。 早速、以下のように検証してみました。 更新処理 -> オフラインに変更 -> コミット -> シャットダウン -> UNDO表領域を変更 -> オープン -> オンラインに変更 残念ながら、正しくコミットしたデータが確認できてしまいました。 ロールバックでも正しくロールバックしたデータが確認できました。 ひょっとして、SYSTEM表領域にこっそり情報を保持してるんでしょうか?

関連するQ&A

  • トランザクション処理について

    質問させて下さい。 以下の処理を行なっております。 1. トランザクション処理開始 2. テーブルAからデータをDELETE 3. テーブルBへデータをINSERT 4. トランザクション処理終了 上記処理の場合の「TYPE=InnoDB」指定の仕方が不安です。 現在はロールバックの可能性のあるテーブルAのみ「TYPE=InnoDB」を指定しています。 その状態でコミットもうまくいっているのですが、テーブルBに「TYPE=InnoDB」を 指定しなくてもよいものなのでしょうか。 環境 MySql 4.0.24

    • ベストアンサー
    • MySQL
  • C# トランザクション処理

    DataSetのTableAdapterでSQL Serverへのデータ挿入、更新、削除を行います。 try { ta.UpdataQuery(.....); } catche { Exception; } といった処理をしますが、トランザクション処理をする場合、 try { // トランザクション開始 ta.UpdataQuery(.....); // コミット } catche { // ロールバック Exception; } といった感じになるかと思いますが、どのようにコードを書けばよいのでしょうか?手元にコードがありませんので詳細が書けませんが、よろしくお願いします。

  • カーソルがコミットするとクローズされてしまう。

    オラクルのDBで環境はUNIX(IBMのマシン)です。 DBについて詳しくありませんが、以下のようなことを行いたいと考えています。 1.あるDB(DB-A)のレコードを特定のキーの昇順に全レコード読み込む。(特定のキーは、例えば商品コードなど) 2.1レコードを読み込む毎に、他のDB(DB-B)を読み込んだレコードを元に、更新したい。 その際、1レコードを読み込む都度、 2-1.トランザクションの開始 2-2.DB-Bの更新 2-3.コミット又はロールバック のようにしたい。 上記のことを考えて以下のような作りにしました。 1.カーソルのオープン 2.以下のループを作成  2-1.DB-Aから1レコードのフェッチ  2-2.トランザクションの開始  2-3.DB-Bの更新  2-4.コミット(ロールバック) しかしながら、コミット(又はロールバック)を行うことにより、カーソルがクローズされてしまい、最初の位置にカーソルが戻ってしまいます。(私がコーディングして試験したわけではありません。このような報告をうけました) それで、カーソルが戻らずに、全レコードを処理するようにしたいのですが、どのようにしたら良いのでしょうか。ご存じの方おりましたらアドバイスをお願いします。

  • C#でトランザクション開始後参照出来ない

    言語:C# DB:SQLServer2008 1.トランザクション開始 2.テーブルAをUPDATE 3.色々な処理(省略) 4.テーブルAのUPDATE前の情報を参照 5.参照したテーブルをもとにテーブルBをUPDATE 6.すべての処理が正常だったら全テーブルコミット、1つでも失敗したら全テーブルロールバック 問題となっているのは 4.テーブルAのUPDATE前の情報を参照する際に、テーブルAがロックされていて参照出来ないことです。 トランザクション開始時に分離レベルを設定してみましたが同じ結果でした。 tran = con.BeginTransaction(分離レベル); お分かりになる方ご教授お願いします。

  • ADO接続のトランザクション処理

    SQL2005のDBに対して ADOのconnectionオブジェクトで接続しているのですが、 下記のようにトランザクションを開始し、SQLを実行し、 エラーが発生してロールバックを行っていない場合、 2個目のSQLがいつまでたってもロック状態でタイムアウトになりません。 このような場合、ADOconnectionのコマンドタイムアウトのデフォルト値30秒で タイムアウトとなり、ロールバックされないのでしょうか? 以下adoコネクションオブジェクトをConnobjと表記します Connobj.BeginTrans Connobj.Execute "Insert into AAA・・・・" ← このInsert文で失敗 Connobj.Execute "Update BBB SET ・・・・" ← このUpdateは成功 ※ロールバックもコミットも行わない  (プログラムの不具合でロールバックができなかった場合や、  アプリで異常が発生してロールバックが行えない等) お手数をおかけしますが、何かご存知の方、ご教授願います。

  • トランザクションとlast_insert_id

    トランザクション中にinsertする予定のテーブル(未コミット)のauto_increment値を取得することはできるのでしょうか。 以下のような処理を期待しているのですが、hoge1テーブルのauto_increment値が取得できずに困っております。last_insert_id に関わらず、hoge1テーブルのauto_increment値が取得できる方法があれば教えてください。 (1) トランザクション開始 (2) $sql=" INSERT INTO hoge1(name) value('あああ'); "; (3) ( ロールバック ) (4) $key=mysql_insert_id(); (5) $sql2=" INSERT INTO hoge2(hoge1_primary,age) value($key,'20歳'); "; (6) ( ロールバック ) (7) コミット (8) トランザクション終了 よろしくお願いします。 環境: php5,mysql5 (InnoDB)

    • ベストアンサー
    • MySQL
  • トランザクション管理について

    皆さんはトランザクション管理を何処で行ってますか? 大体のプロジェクトでは以下の2パターンに集約されると思います。 1.ビジネスロジックでトランザクション管理して、DAOへ引数としてトランザクションを渡す。  当然、コミット・ロールバックはビジネスロジック側で管理。 2.ビジネスロジック側では管理せず、DAO側で管理。  ビジネスロジックへは結果のみ返却。 実は今回のプロジェクト、Java初心者(プログラムって何?レベルとC++なら受講したことあるよ!レベル)が9割を占めるチームです。 初心者の方々はビジネスロジックを設計・実装します。 それ以外の部分(DB・SpringFramework等)を私が設計・実装します。 ビジネスロジックの部分の設計も、概要設計レベルしか記述されておらず、トランザクション無視の設計しかありません。 バグにまみれてデスマーチなんてごめんなので、2のパターンでトランザクションからDB周りを設計したいと思っているのですが、リーダー(スキルは不明。経験はあるらしい)が「DAO側でやると上手くいかない場合が多い」と言われ、却下されそうです。 何処がどう上手くいかないのか聞いても、明確に返答は貰えません。 でもなんとか2のパターンでいきたいのですが、上手い説得方法が見つかりません。 なんて言えば納得してくれそうか、皆様のお知恵を拝借したく投稿しました。 足らない部分は補足させていただきます。 よろしくお願いします。

    • ベストアンサー
    • Java
  • 複数のSQL文を一つのトランザクションで行いたい(SQL Server)

    Visual Basic 2005 から SQL Server に接続してINSERTやUPDATE処理を行いたいのですが、トランザクション処理の記述方法が分かりません。 コネクションオープン トランザクション開始  クラスA呼び出し(INSERTやUPDATEの処理記述)  クラスB呼び出し(INSERTやUPDATEの処理記述)  … コミット(またはロールバック) トランザクション終了 コネクションクローズ 上記の様に、いくつかのクラスに分けて記述したINSERTやUPDATEの処理を、一つのトランザクションで行いたいです。 コネクションやトランザクションを引数とすればよいのでしょうか?

  • accessVBAでのワークスペース

    こんばんわ。 今年の四月から新米SEとして働いているものです。 他の言語の場合どうなるかわかりませんが、accessの場合、トランザクションを開始してSQL文を実行する際、「データベース.Execute SQL文」となると思うのですがDAOやADOで接続する際、最初のほうでワークスペースを定義しますよね。 トランザクションの開始、コミットやロールバックは、「ワークスペース.BeginTrans、ワークスペース.CommitTrans、ワークスペース.RollBack」なのになぜSQLを実行するときだけ「データベース.Execute SQL文」なのでしょうか? 私なりの考えでは、ワークスペースは中間作業領域。中間作業領域でなにかしらのエラーが起きたらロールバック、もし問題なければコミットするのでワークスペース.Commit等というのは理解したのですが、SQL文を実行するのはトランザクション中なのでワークスペースで実行「ワークスペース.Execute SQL文」なのではないのでしょうか? ワークスペースへの理解が誤っているのでしょうか? よろしくお願いします。

  • ロールバックとロールフォワード(データベーススペシャリスト試験)

      t0  t1  t2   t3   t4   t5         |           | A s---e  |           |         |           | B s-------------e       |         |           | C s------------------------|         |           | D       |   s----e   |         |           | E       |   s---------| 図がずれていたらごめんなさい。 A~Eはトランザクション sはトランザクション開始 eはコミット t0~t5は時間を表していて 時間t2でチェックポイント 時間t5で障害が発生したとします。 参考書によると復旧時に CとEはロールバックを行い、 BとDはロールフォワードを行うとあります。 B、C、Dはわかるのですが Eにロールバックが必要な理由がわかりません Eを再び実行するためにはデータは トランザクションを開始したt3時点の状態であればよいはずです。 そしてチェックポイント(=t2)の状態はt3と同じなので、 Eの更新前ファイルを使ってデータをロールバックする必要はないように思えます。 どこで間違っているでしょうか。。。