【Oracle】データ復旧

Oracleのデータ復旧メモ。
TEST_TBLからデータを削除してコミットしてしまったけど復旧したい。

1.バックアップしたデータからの復旧(全てのバージョン)
2.ログ・マイナーを使用した復旧(Oracle8i以降)
3.フラッシュバック・クエリを使用した復旧(Oracle9i以降)

フラッシュバック・クエリの例を記載します。

CREATE TABLE TMP_TEST_TBL AS SELECT COMPANY_CD, USER_ID, SLIP_NO,
TO_DATE(TO_CHAR(UPD_DT, 'YYYY/MM/DD HH24:MI:SS'), 'YYYY/MM/DD HH24:MI:SS') AS UPD_DT
FROM TEST_TBL AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '100' MINUTE);

100分前の状態に戻します。
「AS OF TIMESTAMP」句からフラッシュバック・クエリとなっている。
「SYSTIMESTAMP」はシステムの日時を戻す関数なので、
「SYSTIMESTAMP」から「INTERVAL ‘100’ MINUTE」を引くことで「今から100分前」を表している。
「INTERVAL」には「MINUTE」の他にも「HOUR」や「DAY」を扱えるが、遡るのに限度はあるようです。

INSERT INTO TEST_TBL SELECT COMPANY_CD, USER_ID, SLIP_NO,
TO_DATE(TO_CHAR(UPD_DT, 'YYYY/MM/DD HH24:MI:SS'), 'YYYY/MM/DD HH24:MI:SS') AS UPD_DT
FROM TMP_TEST_TBL

これで助かったことがあるので、メモ。

【Oracle】実行中のセッションとSQL

実行中のセッションとSQLを確認します。

  • 実行中のセッション

    SELECT SID, SERIAL#, USERNAME, STATUS, MACHINE, PROGRAM, SQL_ID FROM V$SESSION WHERE USERNAME IS NOT NULL AND SID != USERENV('SID');
    
  • 実行中のSQL

    SELECT SQL_TEXT FROM V$SQLTEXT WHERE SQL_ID='実行中のセッションで確認したSQLIDを指定する。';
    

【Oracle】インスタンスの起動停止とリスナーの起動停止

Oracleのインスタンスの起動停止とリスナーの起動停止の方法です。

  • インスタンス起動

    su - oracle
    ※パスワードなし
    sqlplus / as sysdba
    
    startup
    

    以下の内容が画面に出力されます。

    ORACLEインスタンスが起動しました。
    
    Total System Global Area  413372416 bytes
    Fixed Size                  2227040 bytes
    Variable Size             306185376 bytes
    Database Buffers          100663296 bytes
    Redo Buffers                4296704 bytes
    データベースがマウントされました。
    データベースがオープンされました。
    
  • リスナー起動

    su - oracle
    ※パスワードなし
    lsnrctl start listener
    

    listenerを省略するとデフォルトリスナーを指定したことになります。

  • リスナー停止

    su - oracle
    ※パスワードなし
    lsnrctl stop listener
    

    listenerを省略するとデフォルトリスナーを指定したことになります。

  • インスタンス停止

    su - oracle
    ※パスワードなし
    sqlplus / as sysdba
    
    shutdown
    

    以下の内容が画面に出力されます。

    データベースがクローズされました。
    データベースがディスマウントされました。
    ORACLEインスタンスがシャットダウンされました。
    
  • インスタンス停止(セッションがすべてINCACTIVEになるのを待つ場合)
    immediateをつけることで以下の動作となる。

    新しい接続は許可されず、新しいトランザクションは開始できません。
    すべての未コミットのトランザクションは、ロールバックされます。
    現在データベースに接続しているユーザーが切断されるのを待機しません。
    既存の接続を全て切断しますが、SQL実行中やロールバック中などのアクティブなセッションが存在すると、その完了を待機します。
    1時間たっても完了しない場合、「ORA-01013」が発生する。
    

    「ORA-01013」が発生すると既に新規セッションを受け付けていないため、
    どのセッションが残っているのか調査が難しいため、セッションが残っているかを確認してからの方が良い。

    shutdown immediate
    
  • インスタンス停止(ACTIVEやKILLEDセッションが合っても強制終了したい場合)

    shutdown abort
    

【LDAP】LDAP操作

LDAP操作に関するメモ。

  • データ抽出

    ldapsearch -h IPアドレス -p ポート番号 -1 -B -F ": " -D cn=XXXXX -w パスワード -z 0 -b o=YYYYY, c=ZZ "(&(objectClass=テーブル名)(属性名=値))" >> result.ldif
    

    オプション補足。

    -h:IPアドレスを指定
    -p:ポート番号を指定
    -1:なんだっけこれ
    -B:BASE64をデコード
    -F:属性名と値との間に指定文字列を出力
    -D:バインドするdnを指定
    -w:パスワードを指定
    -z:検索のサイズ言語を指定(0で制限なし?)
    -b:基本識別名を指定
    
  • dnごと削除

    dn: 属性名=値, ou=AAAAA, o=YYYYY,  c=ZZ
    changetype: delete
    
  • dnの属性を削除

    dn: 属性名=値, ou=AAAAA, o=YYYYY,  c=ZZ
    changetype: modify
    delete:属性名
    
  • dnの属性の値を削除

    dn: 属性名=値, ou=AAAAA, o=YYYYY,  c=ZZ
    changetype: modify
    delete:属性名
    属性名:値
    

    属性がマルチバリューの場合、特定の値のみを削除できる。

  • dnに属性を追加

    dn: 属性名=値, ou=AAAAA, o=YYYYY,  c=ZZ
    changetype: modify
    add:属性名
    属性名:値
    
  • 属性の値を書き換え

    dn: 属性名=値, ou=AAAAA, o=YYYYY,  c=ZZ
    changetype: modify
    replace:属性名
    属性名:値
    

    replaceする属性がない場合、addと同じ動作になる。

  • dnを追加

    dn: 属性名=値, ou=AAAAA, o=YYYYY,  c=ZZ
    changetype: add
    objectClass: テーブル名
    objectClass: top
    属性名1:値1
    属性名2:値2
    ・・・略
    

    changetypeがmodifyではなく、addになっている。

【Oracle】Oracle導入

  • Oracle取得
    Oracleを導入したくなったので、VMware上のCentOSに導入します。
    導入するバージョンは「Oracle Database XE」です。
    Oracle 11gの無料版でLinuxは64bit版のみのようです。

    インストールするのにCentOSに下記が必要。

    glibcは2.3.4-2.41以上
    makeは3.80以上
    binutilsは2.16.91.0.5以上
    gccは4.1.2以上
    libaioは0.3.104以上
    
  • Oracle導入
    yumコマンドでインストール済のパッケージを全て確認します。

    yum list installed
    
    glibc.x86_64            2.12-1.107.el6_4.5
    make.x86_64             1:3.81-20.el6
    binutils.x86_64         2.20.51.0.2-5.36.el6
    gcc.x86_64              4.4.7-3.el6
    libaio.x86_64           0.3.107-10.el6
    

    問題なしということで、インストール作業を進めます。
    このOracleは外とは繋がないので、専用ユーザは作成せずにいきました。

    Linux64bit版のzipファイルをCentOSにアップロードします。

    cd /home/ユーザ名/oracle
    unzip oracle-xe-11.2.0-1.0.x86_64.rpm.zip
    

    Disk1ディレクトリの中に解凍されているので、
    中にあるrpmパッケージをインストールします。

    cd Disk1
    rpm -ivh oracle-xe-11.2.0-1.0.x86_64.rpm
    
    準備中...                ########################################### [100%]
    
    This system does not meet the minimum requirements for swap space.  Based on
    the amount of physical memory available on the system, Oracle Database 11g
    Express Edition requires 1976 MB of swap space. This system has 1854 MB
    of swap space.  Configure more swap space on the system and retry the
    installation.
    
    エラー: %pre(oracle-xe-11.2.0-1.0.x86_64) scriptlet failed, exit status 1
    エラー:   install: スクリプト %pre の実行に失敗しました (2)。oracle-xe-11.2.0-1.0 をスキップします。
    

    失敗・・・。
    スワップ領域が不足しているようです。。
    スワップ領域を調べてみることに。

    swapon -s
    

    既にいくつかスワップ領域を消費していました。
    ずっとサスペンドだったからでしょうか。
    再起動するとスワップ領域の消費が0になりました。
    というわけで、再度インストールします。

    cd Disk1
    rpm -ivh oracle-xe-11.2.0-1.0.x86_64.rpm
    
    準備中...                ########################################### [100%]
       1:oracle-xe              ########################################### [100%]
    Executing post-install steps...
    You must run '/etc/init.d/oracle-xe configure' as the root user to configure the database.
    

    無事インストールできました。

  • Oracle導入後の設定
    次に「/etc/init.d/oracle-xe configure」を実行しろと記載があるので、実行します。

    /etc/init.d/oracle-xe configure
    

    ポート:XXXX(デフォルトの8080は他と競合しそうなので変えました。)
    リスナー:1522(気分で変えました。)
    DBパスワード:パスワード
    OS起動時に自動起動:y

    Oracleの環境変数は下記で確認できます。

    view /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh
    

    Oracleを使うユーザに適用しておきます。

    vi /etc/profile
    
    下記内容を最終行に追加
    . /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh
    
  • Oracle導入後の動作確認(サーバ側)
    TeraTermを再起動し、「/etc/profile」を読み込みなおし、
    動作確認を行います。
    インストール時にOracleユーザとしてsystemが作られています。

    sqlplus system/パスワード@サービス名
    

    SQLに接続できれば成功です。
    インストール時のファイルを削除しておきます。

    rm -fr /home/ユーザ名/oracle
    

    無料版なのにプロシージャまで試せるようなので、なかなか満足です。
    インストール手順詳細は下記参照。
    http://docs.oracle.com/cd/E36055_01/install.112/b66469/toc.htm#CIHHJEHF

  • Oracle導入後の動作確認(クライアント側)
    VMwareをインストールしているPCにもOracleクライアントをインストールし
    sqlplusで接続できるように
    サーバ側のリスナーポートを開放しておきます。

    iptables -I INPUT 23 -p tcp -m tcp --dport 1522 -j ACCEPT
    

    23は「iptables -L –line-numbers」で確認し、
    挿入したい行番号の次番号を指定しました。

【Raspbian】DiCE導入

IPアドレスは固定にしていなので、
DynamicDNSサービスを利用していたのですか、
ずっと更新していなかったら怒られました。
そこでDiCEを導入することに。
Windows版を導入しました。

http://www.hi-ho.ne.jp/yoshihiro_e/dice/

上記URLにアクセスし、「DiCE for Windows Version 1.59」の「Download MSI Package」をダウンロードします。
インストールディレクトリを選択し、画面に従いインストールを行います。

インストール後に起動したら、下記設定を行う。

「イベント」-「追加」ボタン押下。
説明:自宅サーバ
イベントタイプ:DNS更新
一般タブ-サービス:MyDNS.JP
一般タブ-ホスト名:z-area-.net
一般タブ-ドメイン名:mydns.jp
一般タブ-ユーザ名:MyDNS.JPのログインユーザID
一般タブ-パスワード:MyDNS.JPのログインパスワード
一般タブ-IPアドレス:空欄
スケジュール-頻度:IPアドレス変化時
スケジュール-変化がない時:21日毎
イベント有効にチェック
それ以外は変更せずデフォルト設定としました。

「イベント」-「今すぐ実行」を選択するとIPアドレスが通知される。
MyDNS.JPにログインしLOG INFOを確認すると、IPアドレスの更新を確認できる。

VMwareの仮想PCネットワーク構成

やはり気になってしまい、見直してみました。
RaspbainとCentOSですが、そもそもネットワークが繋がっているのかと
Raspbainからpingを飛ばしてみました。

ping CentOSのIP
PING XXX.XXX.XXX.XXX (XXX.XXX.XXX.XXX) 56(84) bytes of data.
From ZZZ.ZZZ.ZZZ.ZZZ icmp_seq=5 Destination Host Unreachable

「Destination Host Unreachable」はIPに該当するマシンはあるけど
到達できないことを示しているようです。
メインPCからは何も考えずに接続できてるから意識してませんでしたが、
そもそもRaspbainとCentOSはネットワークが異なる場所に存在・・・。

ルーター:192.168.XX.1
メインPC:192.168.XX.2
Raspbain:192.168.XX.3
VMnet8(メインPCのVMWare用アダプタ):192.168.YY.1
CentOS:192.168.YY.2

調べてみるとVMWare上のゲストOSはNAT接続からブリッジ接続にかえると
メインPCと同じネットワーク上(192.168.XX.x)に持ってこれるようです。

ただしゲストOSから外部に接続しようとした場合、
ブリッジ接続にかえたことで通信時に仮想MACアドレスを利用するので、
ルーターから不正扱い受けたりすることもあるそうですが、
ゲストOSでは外部に接続する予定はないので無視。

【変更前】

ルーター (192.168.XX.1)
 ├ メインPC (192.168.XX.2) ─ VMnet8 (192.168.YY.1)
 │                └ CentOS (192.168.YY.2)
 └ Raspbain (192.168.XX.3)

【変更後】

ルーター (192.168.XX.1)
 ├ メインPC (192.168.XX.2)
 ├ Raspbain (192.168.XX.3)
 └ CentOS (192.168.XX.4)

【設定方法】

VMWareの[Player]-[取外し可能デバイス]-[ネットワークアダプタ]-[設定]を選択。
ネットワーク接続で「NAT」から「ブリッジ」のラジオボタンを選択。
「アダプタの設定」ボタンを押下する。
利用しているNICにチェックを入れ「OK」ボタンを押下。
最後に「OK」ボタンを押下。
ホストOS、ゲストOSともに再起動する。

これでRaspbainからCentOSにpingが飛んだので、再度昨日の設定を復活させ
Webアプリに繋いでみたところ、Tomcatの処理だけCentOSで処理できました。

ルーター:これまで通り80、443をRaspbainに向けているだけで、8009の設定不要。
Raspbain:FWそのまま。
CentOS:FWで80のポートを開ける。8009の設定不要。

平日はCentOS立ち上げていないので、
結局Raspbainだけで処理するわけですが、色々満足しました。

【APサーバ】Apache2とTomcat外部連携

TomcatをVMWearのCentOSに移してみようかと思い設定してみました。

  • Raspbian側の設定

    vi /etc/apache2/sites-available/default
    
    # 下記内容に変更
    <Location /examples/servlets/>
        ProxyPass ajp://localhost:8009/examples/servlets/
        allow from all
    </Location>
    ↓
    <Location /examples/servlets/>
        ProxyPass ajp://CentOSのIP:8009/examples/servlets/
        allow from all
    </Location>
    
    ufw disable
    
  • VMWearのCentOS側の設定

    /etc/rc.d/init.d/iptables stop
    

    「http://Raspbain側のIP/examples/servlets/」でアクセスして
    VMWearのCnetOS側にTomcatログが出力されているようであれば成功です。
    ・・・しかし私の環境では接続が上手く出来ませんでした。
    急いではいないので、また別の機会に試そうと思います。

  • バージョン確認の方法

    【CentOS】

    httpd -v
    $CATALINA_HOME/bin/version.sh
    
    Apache2:Server version: Apache/2.2.15 (Unix)
    Tomcat:Apache Tomcat/7.0.42
    Architecture:amd64
    JVM Version:1.7.0_45-b18
    Apache2とTomcatを連携済。
    

    【Raspbain】

    apache2 -v
    $CATALINA_HOME/bin/version.sh
    
    Apache2:Apache/2.2.22 (Debian)
    Tomcat:Apache Tomcat/7.0.55
    Architecture:arm
    JVM Version:1.7.0_40-b43
    Apache2とTomcatを連携済。
    

【WEBサーバ】アクセスログ確認

自宅サーバをもって約3週間。
アクセスログを確認してみると、何やらレスポンスを確認しているかような怪しいログが。
アクセスログをgpreしてみました。

zgrep "File does not exist" error*.log* >> /home/ユーザ名/result1.txt
zgrep "phpMyAdmin" access.log* >> /home/ユーザ名/result2.txt

gpre結果から自身のIPを除き、どこのパスにアクセスしているか、
確認すると下記のパスに連続してGETしていました。

/phpMyAdmin/scripts/setup.php
/myadmin/scripts/setup.php
/pma/scripts/setup.php

プロキシサーバ使われていると調べようもないですが、
IP元は台湾、タイ、中国、ドイツ、トルコ等様々。
アジアが多い感じ。

mySQLはCUIで触るので、そもそもphpMyAdminを導入していないから問題ないですが、勉強になりました。

【APサーバ】Tomcat起動ログ確認

Tomcatの起動ログ確認してみたところ、
予想はしていましたが、WARNINGやjarファイルに関するログが出てました。

【1つ目】

jar not loaded. See Servlet Spec

自動展開後の「$CATALINA_HOME/webapps/コンテキスト名/WEB-INF/lib」にあるjarファイルと
Tomcat固有で保持している「$CATALINA_HOME/lib」にあるjarファイルが重複していると
jarファイルをロードしていない旨のログが発生するようです。

というわけで、「el-api.jar」と「servlet-api.jar」を前者から削除しました。

【2つ目】

inside the host appBase has been specified, and will be ignored

コンテキスト名.xmlのdocBase属性値がTomcatのデフォルト設定値と等しい場合、
冗長な設定ということで、コンテキスト名.xmlを修正しました。

vi /tomcat/apache-tomcat-7.0.55/conf/Catalina/localhost/コンテキスト名.xml
# 下記内容を変更
<Context path="/コンテキスト名" reloadable="true" docBase="/tomcat/apache-tomcat-7.0.55/webapps/コンテキスト名" />
↓
<Context path="/コンテキスト名" />

reloadableも重そうな気がしたし、更新する時は大抵再起動するので、削除しました。
Tomcatを再起動すると、WARNINGやjarファイルに関するログは消えました。

Tomcatの再起動時にrestart指定で実行すると、まれにエラーが発生してる。
呼び出しが早すぎるのか、stopする前にstartが呼ばれてたりするのかはよくわからず。
stop指定してから3秒後くらいにstart指定で再起動するとエラーは発生せず。
今のところは気にせずいきます。