23639


sql*plusからsqlを実行し、1000万レコードくらいのtableから500万レコードくらいを削除する場合のcommitを、最後の最後で1回実行したところcommitのレスポンスが返って来なくなりました。  
このtableには、blobのカラムもあって、データ容量も大きいのが関係しているんでしょうか？  
上記のようなcommitが終わらない場合の対処方法をお教えください。

現状を把握する知識も持ち合わせておりません。  
dba table群の中身を確認することで、現状を把握することもできるのでしょうか？  
ここをチェックすれば良いなどの情報も教えていただきたいです。

個人的には、現状から復帰させるには、サービスの再起動やosの再起動しか手段が無さそうに思うのですが、そうした場合、やはりdatabaseが壊れる可能性もあるのでしょうか？  
commitを中断したり、強制的に終了させる方法もあるのでしょうか？

最後に、大量の処理をcommitする場合のcommitのタイミングはどのように決めれば良いのでしょうか？  
今回の場合だと、100万レコードずつcommitすれば良かったなどの可能性もあるのでしょうか？

申し訳ありませんが、よろしくご教示下さい。

* * *

windows server 2008R2  
Oracle Database 11gR2


CC BY-SA 3.0
2015-09-30T05:20:26.007
17089
2016-03-31T02:21:21.010
2015-09-30T05:45:20.667
2383
2383
question
oracle
Oracleのcommitが終わらない


知識が古いのとWindowsはよくわからないので参考までに書きます。  
おおよそ、ご自身で書かれているとおりだと思います。

COMMIT の応答を待てないのであれば、インスタンスをSHUTDOWNするしか無いと思います。  
IMMEDIATE でだめなら ABORT でとなりますが 次回起動時にクラッシュ・リカバリが走ります。  
リカバリに必要な時間は処理量に依存するのでわかりません。かなり時間が掛かる可能性も考えられます。  
また、ABORTはリスクがありますので起動できなくなった場合に備えて、バックアップからの復元等も視野に入れて準備した方が良いでしょう。

COMMITのタイミングですが、件数が多すぎても少なすぎても遅くなりますので事前の検証をお勧めいたします。経験則だと
1万～100万件くらいではないでしょうか。

その他の削除を高速化する対策として次のようなものもありますので検討されてはどうでしょうか。

  * テーブルを TRUNCATE して必要なデータをロードする => 削除をロールバックできない分速い。ロードするデータをCSVで用意する必要あり
  * `COMMIT WRITE BATCH NOWAIT` で REDOログへの書込を非同期化する => 見た目上は早く終る


CC BY-SA 3.0
2015-10-01T04:50:11.673
17132
2015-10-01T04:50:11.673
5008
17089
answer


大変遅くなりましたが、対処した時の手順をメモっておきます。

まず、sqlplusの強制終了を試みる。  
どうも、接続が強制終了されると要求だしてたのが、強制的に元に戻されるらしいので...

* * *

sqlplusを実行してるコマンドプロンプトを強制終了してから、別のコマンドプロンプトを起動して再びsqlplusで接続。

[code]

    SQL> SELECT * FROM V$SESSION WHERE PROGRAM='sqlplus.exe';
    
[/code]

で、現在接続してるヤツを調べたら複数レコードが見つかりました。

接続が実行してるSQLを調べてみたら...

[code]

    SQL> SELECT S.*, Q.SQL_TEXT FROM V$SESSION S, V$SQL Q WHERE PROGRAM = 'sqlplus.exe' AND S.SQL_ID = Q.SQL_ID;
    
[/code]

片方は、応答なくなったsqlplusだと分かったので、その接続の強制終了を試みます。

先のSQLで、問題の接続のSIDとSERIAL#がわかるので、

[code]

    SQL> ALTER SYSTEM KILL SESSION '【SID】,【SERIAL#】';
    
[/code]

を実行。

再び、現在の接続を確認。

[code]

    SQL> SELECT * FROM V$SESSION WHERE PROGRAM='sqlplus.exe';
    
[/code]

しばらく...数分くらいかな？の間、問題の接続が残っていましたが、消えてくれました。

要求出してたテーブルを調べてみましたが、要求前の状態のようでしたので、事なきを得ました。

* * *

自分の対処方法はこのような感じです。  
全ての場合で同様の対処方法が成功するとは思いませんが、参考になれば嬉しいです。


CC BY-SA 3.0
2016-03-31T02:21:21.010
23639
2016-03-31T02:21:21.010
2383
17089
answer