2016年12月24日土曜日

海外カンファレンスに行く(1):海外行きを思い立つ

【海外行きを思い立つ】
Oracle OpenWorldを始め、海外カンファレンスは世界各地で開催されて、最新の技術やコアテクニックについて日々発表がされています。
その様子をSNSで知るにつれ、海外カンファレンスへの想いは強くなっていきました。

「いつかは行ってみたい」
そう常々思っていましたが、今の会社が費用を出してくれない、今の現場環境では一週間も休めないのではとあきらめかけていました。
しかし、現場環境が割りと休みを取りやすいところに移ったことで、費用面さえクリアができれば行けるようになりました。

しかし、そうは言っても世界最大のOracleのカンファレンス、"OracleOpenWorld"は参加費だけで25万円ほど。当然、他に渡航費やらホテル代もかかり、国内大手旅行会社のツアーでは70万円程度。会社の援助が無ければ難しい。
他にも無いだろうかと探したりしてみましたが、いいものは高いという当たり前の結論にたどりついてしまう。
そうしたなか、以前からTwitterでフォローしていたとあるOracle ACEが参加したアメリカのカンファレンスを知りました。

RMOUG training days (RMOUG: Rockey Mountain Oracle User Group)

調べてみると、アメリカで4番目に大きなカンファレンスであり、地域のOracleUserGroupとしてはアメリカで最大であり、おそらく世界最大のものでした。
2日半のカンファレンスで、OracleACEと一緒のランチやレセプションもある。そして費用は500ドルでした。
日程としては2月であることから、航空券も安くなることが想定され、元々独身時代にパンとビールだけの海外貧乏旅行に何度か行った経験を踏まえれば、なんとか自分のお小遣いの範囲で参加できそうだと考えました。

【どうして海外カンファレンスなのか】
日本のカンファレンスも、「神イベント」であるdb tech showcaseやJPOUG(Japan Oracle User Group)など、魅力あるカンファレンスや勉強会があります。では、なぜ敢えて海外なのか。
Oracle Databaseの生まれがアメリカであることから、アメリカに行ってみたいと言うのがありました。
いわゆる、
「アメリカの、その空気を吸うだけで僕は高く跳べると思っていたのかなぁ」
みたいなものです。
とはいえ、形だけではなく成長するためにアメリカに行きたいと考えていました。
アメリカのみならず、世界中からやってきた魅力的な技術者の話を聞くことで、情報を取りにいきたいと考えたのです。
特に、2017年2月の渡米となれば、Oracle Database12.2のリリース直後が想定される時期でもあり、いよいよ日本でもOracle Database 12cが真剣に検討されるため、その情報を速く知り、業務に生かしていきたいと考えたのです。

【準備】
海外への渡航費用のなかで、やはり大きなウェイトを占めるのが航空券、宿泊費です。それから、カンファレンス参加費もかかります。
航空券は日付が前後したり滞在日数が1日伸びたりするだけで数万円変わることから、いろいろな角度から調べていく必要がありました。
カンファレンスの日程は 2017年2月7日~9日であることが、既に2016年春のRMOUG会報に載っていたので、その時点で押さえました。
アメリカン航空の正規割引で5泊以上滞在条件で53,000円でした。ちょうど燃油サーチャージが無かったことで割安感がありました。やはり2月は安い!
しかしながら、これが4泊を選ぶと8万円以上となってしまいます。いろいろ調べてみるのが吉です。
次にホテル代。渡航先のデンバーはホテル代があまり安くありません。そこで、郊外を探してみることに。会期中は8:30スタートなのでなるべく近いところをと探してみたところ、実はデンバーは2016年~2017年に向けて鉄道が開通する計画があり、予約時点では不便な場所であるものの、渡航時には新路線の駅前になるホテルで1泊10,000円程度のところを発見。
独身時代の海外旅行なら3,000~6,000円・新婚旅行で7,000~8,000円のレンジで泊まっていた身としてはやや高いものの、それらは東ヨーロッパでの値段なのでアメリカならばやむなしです。
お金に余裕があれば、カンファレンス割引でハイアットが$180で泊まれるオファーがありました。通常はこの金額では泊まれないホテルですので、余裕ある人にはお勧めです。ただ、私にとっては海外高級ホテルにはいい思い出が無いので…。(まだ泊まるだけのステータスがないということですかな。)
それから、カンファレンス費用。これは安くできないものの、早期申込み割引で$500が$450まで下がるので、それを利用します。大統領選前に約定したので、日本円で48,000円で済みました。こればかりは運ですね。
ここまでで締めて15万円。OracleOpenWorldの参加費以下の費用でここまで賄えました。
さらに、カンファレンス費用は会社からの援助がもらえました。これはありがたい!

これから、何回かに分けてカンファレンス参加編を書いていこうと思います。

2016年12月15日木曜日

PostgreSQLのテーブルの内部と更新時の動作について

このエントリはバルテックアドベントカレンダー2016に向けた投稿です。
http://www.adventar.org/calendars/1637

PostgreSQLはオープンソースのデータベースの中でもメジャーです。私と同じ会社に所属する皆さまもPostgreSQLを触る機会がある人は多いのではないでしょうか。
私も今年の前半にPostgreSQLの導入検討の案件があり、触ってみました。

PostgreSQLは他のデータベースと比較して特徴的な個所として挙げられるのは、追記型であるということが言えます。

ログ先行書き込み(write ahead logging, WAL)というものをPostgreSQLでは採用しています。
簡単に言いますと、トランザクションをコミットする前にログを書き出し、それからデータファイルに書き込むことで、たとえクラッシュが起きてもデータベースをリカバリできるという手法です。

さて、PostgreSQLではどのように実装されているのでしょうか?
PostgreSQLのテーブルの中身を見てみますと、データファイルの中にテーブルの行の情報が格納されていますが、行ごとにヘッダがあります。
行ヘッダの中身は28バイトあり、その中にはt_xminとt_xmaxがあります。
行が挿入されると、t_xminにはトランザクションIDが入ります。
それから行が削除・更新されると、t_xmaxにトランザクションIDが入り、このデータは無効となります。
PostgreSQLはデータを追記していきますので、削除・更新をする際には実際に消したりするわけではなく、論理削除のようにフラグを立てていくだけで、
他のトランザクションは、自分のトランザクションのIDと照らし合わせて、読むべきかどうかを判断して処理していきます。

これらの動きを確認したい場合は、pageinspectという追加モジュールがあります。
http://www.postgresql.jp/document/9.6/html/pageinspect.html

ちょっと手持ち環境でpageinspectを入れられなかったのですが、イメージとしてはこんな感じです。
私は安飲み屋を巡るのを趣味の一つとして持っているので、「居酒屋巡礼」テーブルを考えてみました。

izakaya_name         place                last_visit       
==================== ==================== ====================
oosakaya             monzennakacho        2014-11-24
fujiyahonten         shibuya              2015-08-24
mantarou             shinjuku             2016-09-12
torimasa             inadazutsumi         2016-10-07

このテーブルのt_xminとt_xmaxを、仮にこう考えてみました。
xmin xmax izakaya_name         place                last_visit
==== ==== ==================== ==================== ==============
X100      oosakaya             monzennakacho        2014-11-24
X101      fujiyahonten         shibuya              2015-08-24
X102      mantarou             shinjuku             2016-09-12
X103      torimasa             inadazutsumi         2016-10-07

テーブルを追加します。
insert into izakaya values('ma-chan','shinagawa','2016-10-21');

このテーブルのt_xminとt_xmaxは、こんな感じになるでしょう。追記されています。
xmin xmax izakaya_name         place                last_visit
==== ==== ==================== ==================== ==============
X100      oosakaya             monzennakacho        2014-11-24
X101      fujiyahonten         shibuya              2015-08-24
X102      mantarou             shinjuku             2016-09-12
X103      torimasa             inadazutsumi         2016-10-07
X104      ma-chan              shinagawa            2016-10-21

更新はどうでしょうか。torimasaに2016-12-04に訪れたので、X103のレコードを更新します。

update izakaya set last_visit='2016-12-04' where izakaya_name='torimasa';

xmaxに値を入れることで、torimasaの2016-10-07の行は(最新のポイントでは)参照されなくなり、見えなくなり、代わりに2016-12-04の行が見えるようになります。
xmin xmax izakaya_name         place                last_visit 
==== ==== ==================== ==================== ==============
X100      oosakaya             monzennakacho        2014-11-24
X101      fujiyahonten         shibuya              2015-08-24
X102      mantarou             shinjuku             2016-09-12
X103 X105 torimasa             inadazutsumi         2016-10-07
X104      ma-chan              shinagawa            2016-10-21
X105      torimasa             inadazutsumi         2016-12-04

ちなみに、削除の場合は、xmaxに値が入るのみとなります。


それでは、テーブルのデータは溜まっていく一方ではないかと思われるかもしれません。
しかしながら、この問題は不必要な行を回収するバキュームという機能で解消されます。
バキュームについては、またの機会に書いてみようと思います。


<参照資料>
「WEB+DB PRESS Vol.24 徒然PostgreSQL散策」
http://www2b.biglobe.ne.jp/~caco/webdb-pdfs/vol24_214-221.pdf

「PostgreSQL Deep Dive PostgreSQLのストレージアーキテクチャ(基本編)」
http://pgsqldeepdive.blogspot.jp/2012/12/postgresql_16.html

2016年12月1日木曜日

リカバリをやり直す

このエントリは、JPOUG Advent Calendar 2016の1日目です。
https://jpoug.doorkeeper.jp/events/53797


データのリカバリをする機会はあまり無いかもしれませんが、いざというときに備えておきたいものです。
しかしながら、リカバリをしてみてデータを見てみたものの、別の時点にリカバリポイントを変更したいと思ったり、
単にリカバリポイントを間違えるといったことは発生するかもしれません。
そんなときに、もう一度リカバリをやり直すといった方法があります。 
今日はリカバリをやり直す手順を検証してみます。

はじめに、RMANバックアップは取っておきましょう。

[oracle@tama01 ~]$ rman
Recovery Manager: Release 11.2.0.1.0 - Production on Sun Nov 13 15:05:54 2016
Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
RMAN> connect target /
connected to target database: BALLOON (DBID=2896125069)
RMAN>
RMAN> backup as copy incremental level 0 database
format='/home/valtech/backup_lv0_%s_%t_%T'
tag='backup';
2> 3>
Starting backup at 13-NOV-16
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile copy
input datafile file number=00001 name=/u01/app/oracle/oradata/balloon/system01.dbf
output file name=/home/valtech/backup_lv0_35_927817918_20161113 tag=BACKUP RECID=30 STAMP=927818003
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:01:36
channel ORA_DISK_1: starting datafile copy
input datafile file number=00002 name=/u01/app/oracle/oradata/balloon/sysaux01.dbf
output file name=/home/valtech/backup_lv0_36_927818016_20161113 tag=BACKUP RECID=31 STAMP=927818214
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:03:27
channel ORA_DISK_1: starting datafile copy
input datafile file number=00003 name=/u01/app/oracle/oradata/balloon/undotbs01.dbf
output file name=/home/valtech/backup_lv0_37_927818224_20161113 tag=BACKUP RECID=32 STAMP=927818231
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:08
channel ORA_DISK_1: starting datafile copy
input datafile file number=00005 name=/u01/app/oracle/oradata/balloon/rman01.dbf
output file name=/home/valtech/backup_lv0_38_927818232_20161113 tag=BACKUP RECID=33 STAMP=927818236
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:07
channel ORA_DISK_1: starting datafile copy
copying current control file
output file name=/home/valtech/backup_lv0_39_927818239_20161113 tag=BACKUP RECID=34 STAMP=927818240
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:01
channel ORA_DISK_1: starting datafile copy
input datafile file number=00004 name=/u01/app/oracle/oradata/balloon/users01.dbf
output file name=/home/valtech/backup_lv0_40_927818241_20161113 tag=BACKUP RECID=35 STAMP=927818242
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:01
channel ORA_DISK_1: starting incremental level 0 datafile backup set
channel ORA_DISK_1: specifying datafile(s) in backup set
including current SPFILE in backup set
channel ORA_DISK_1: starting piece 1 at 13-NOV-16
channel ORA_DISK_1: finished piece 1 at 13-NOV-16
piece handle=/home/valtech/backup_lv0_41_927818243_20161113 tag=BACKUP comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01
Finished backup at 13-NOV-16
RMAN>

ちゃんと取れてますね。
RMAN> list copy;
List of Datafile Copies
=======================
Key     File S Completion Time Ckp SCN    Ckp Time     
------- ---- - --------------- ---------- ---------------
30      1    A 13-NOV-16       1126694    13-NOV-16     
        Name: /home/valtech/backup_lv0_35_927817918_20161113
        Tag: BACKUP
31      2    A 13-NOV-16       1126740    13-NOV-16    
        Name: /home/valtech/backup_lv0_36_927818016_20161113
        Tag: BACKUP
32      3    A 13-NOV-16       1127123    13-NOV-16    
        Name: /home/valtech/backup_lv0_37_927818224_20161113
        Tag: BACKUP
35      4    A 13-NOV-16       1127135    13-NOV-16    
        Name: /home/valtech/backup_lv0_40_927818241_20161113
        Tag: BACKUP
33      5    A 13-NOV-16       1127128    13-NOV-16    
        Name: /home/valtech/backup_lv0_38_927818232_20161113

        Tag: BACKUP
さて、リカバリを試す前にテーブルに変更をしてみます。

[oracle@tama01 ~]$ sqlplus /nolog
SQL*Plus: Release 11.2.0.1.0 Production on Sun Nov 13 15:19:41 2016
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
SQL> conn     / as sysdba
Connected.
SQL> select * from qb.keiyaku;
NAME       KEIYAKUBI>
-------------------- ---------

madoka       03-OCT-10
homura       01-AUG-09
mami       01-AUG-10
sayaka       15-OCT-10
kyoko       01-MAY-10
契約テーブルには5人分のレコードが含まれています。
このなかで、mamiのレコードを削除します。
SQL> delete from qb.keiyaku where name='mami';

1 row deleted.

mamiのレコードが削除されてしまいました。
SQL> select * from qb.keiyaku;
NAME       KEIYAKUBI
-------------------- ---------
madoka       03-OCT-10
homura       01-AUG-09
sayaka       15-OCT-10
kyoko       01-MAY-10
SQL> exit
さて、この状態から、mamiがまだ契約テーブルに残っている時間まで戻すためにリカバリを実施しましょう。
[oracle@tama01 ~]$ sqlplus /nolog
SQL*Plus: Release 11.2.0.1.0 Production on Sun Nov 13 15:33:17 2016
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
SQL> conn / as sysdba
Connected.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area  422670336 bytes
Fixed Size      1336960 bytes
Variable Size    301992320 bytes
Database Buffers   113246208 bytes
Redo Buffers      6094848 bytes
Database mounted.
SQL> exit
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP and Real Application Testing options

[oracle@tama01 ~]$ rman
Recovery Manager: Release 11.2.0.1.0 - Production on Sun Nov 13 15:34:15 2016
Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
RMAN> connect target /
connected to target database: BALLOON (DBID=2896125069, not open)
RMAN> run{

2> set until time "to_date('2016-11-13 15:30:00','YYYY-MM-DD HH24:MI:SS')";
3> restore database;
4> recover database;
5> }
executing command: SET until clause
Starting restore at 13-NOV-16
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=18 device type=DISK
channel ORA_DISK_1: restoring datafile 00001
input datafile copy RECID=30 STAMP=927818003 file name=/home/valtech/backup_lv0_35_927817918_20161113
destination for restore of datafile 00001: /u01/app/oracle/oradata/balloon/system01.dbf
channel ORA_DISK_1: copied datafile copy of datafile 00001
output file name=/u01/app/oracle/oradata/balloon/system01.dbf RECID=0 STAMP=0
channel ORA_DISK_1: restoring datafile 00002
input datafile copy RECID=31 STAMP=927818214 file name=/home/valtech/backup_lv0_36_927818016_20161113
destination for restore of datafile 00002: /u01/app/oracle/oradata/balloon/sysaux01.dbf
channel ORA_DISK_1: copied datafile copy of datafile 00002
output file name=/u01/app/oracle/oradata/balloon/sysaux01.dbf RECID=0 STAMP=0
channel ORA_DISK_1: restoring datafile 00003
input datafile copy RECID=32 STAMP=927818231 file name=/home/valtech/backup_lv0_37_927818224_20161113
destination for restore of datafile 00003: /u01/app/oracle/oradata/balloon/undotbs01.dbf
channel ORA_DISK_1: copied datafile copy of datafile 00003
output file name=/u01/app/oracle/oradata/balloon/undotbs01.dbf RECID=0 STAMP=0
channel ORA_DISK_1: restoring datafile 00004
input datafile copy RECID=35 STAMP=927818242 file name=/home/valtech/backup_lv0_40_927818241_20161113
destination for restore of datafile 00004: /u01/app/oracle/oradata/balloon/users01.dbf
channel ORA_DISK_1: copied datafile copy of datafile 00004
output file name=/u01/app/oracle/oradata/balloon/users01.dbf RECID=0 STAMP=0
channel ORA_DISK_1: restoring datafile 00005
input datafile copy RECID=33 STAMP=927818236 file name=/home/valtech/backup_lv0_38_927818232_20161113
destination for restore of datafile 00005: /u01/app/oracle/oradata/balloon/rman01.dbf
channel ORA_DISK_1: copied datafile copy of datafile 00005
output file name=/u01/app/oracle/oradata/balloon/rman01.dbf RECID=0 STAMP=0
Finished restore at 13-NOV-16

Starting recover at 13-NOV-16
using channel ORA_DISK_1

starting media recovery
media recovery complete, elapsed time: 00:00:03

Finished recover at 13-NOV-16

RMAN> exit



[oracle@tama01 ~]$ sqlplus /nolog
SQL*Plus: Release 11.2.0.1.0 Production on Sun Nov 13 15:38:08 2016
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
SQL> conn / as sysdba
Connected.
SQL> alter database open resetlogs;
Database altered.
さて、リカバリが完了しました。
さっそくmamiのレコードが契約テーブルに残っているか確認しましょう。
SQL> select * from qb.keiyaku;
NAME       KEIYAKUBI
-------------------- ---------
madoka       03-OCT-10
homura       01-AUG-09
sayaka       15-OCT-10
kyoko       01-MAY-10

なんと、mamiのレコードがありません。リカバリポイントを誤ってしまいました。
再度リカバリを試みます。
[oracle@tama01 ~]$ sqlplus /nolog
SQL*Plus: Release 11.2.0.1.0 Production on Sun Nov 13 15:46:56 2016
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
SQL> conn / as sysdba
Connected.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area  422670336 bytes
Fixed Size      1336960 bytes
Variable Size    301992320 bytes
Database Buffers   113246208 bytes
Redo Buffers      6094848 bytes
Database mounted.
SQL> exit
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP and Real Application Testing options
[oracle@tama01 ~]$ rman
Recovery Manager: Release 11.2.0.1.0 - Production on Sun Nov 13 15:48:03 2016
Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
RMAN> connect target /
connected to target database: BALLOON (DBID=2896125069, not open)
RMAN> run{
2> set until time "to_date('2016-11-13 15:20:00','YYYY-MM-DD HH24:MI:SS')";
3> restore database;
4> recover database;
5> }
executing command: SET until clause
Starting restore at 13-NOV-16
using target database control file instead of recovery catalog
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of restore command at 11/13/2016 15:49:44
RMAN-20207: UNTIL TIME or RECOVERY WINDOW is before RESETLOGS time

エラーが出てしまいました。
RESETLOGS以前のポイントにリカバリをしようとするとRMANエラーが出てしまうのです。

マニュアルを見ると、こうあります。
RMAN-20207: UNTIL TIMEまたはRECOVERY WINDOWがRESETLOGS時刻より前になっています
原因: UNTIL TIMEおよびRECOVERY WINDOWは、データベース作成時刻またはRESETLOGS時刻より後に設定する必要があります。
処置: UNTIL TIMEまたはRECOVERY WINDOWを確認してください。データベースを古いインカネーションにリストアする必要があれば、RESET DATABASE TO INCARNATIONコマンドを実行してください。

インカネーションとは、世代と言う意味のようです。
それでは、インカネーションの指定をしてみましょう。

RMAN> list incarnation;


List of Database Incarnations
DB Key  Inc Key DB Name  DB ID            STATUS  Reset SCN  Reset Time
------- ------- -------- ---------------- --- ---------- ----------
1       1       BALLOON  2896125069       PARENT  1          13-AUG-09
2       2       BALLOON  2896125069       PARENT  754488     29-JUL-15
3       3       BALLOON  2896125069       PARENT  837110     11-OCT-15
4       4       BALLOON  2896125069       CURRENT 1127568    13-NOV-16


RMAN> reset database to incarnation 3;
database reset to incarnation 3

リセットできたようです。
では、リカバリをしましょう。

RMAN> run{
2> set until time "to_date('2016-11-13 15:20:00','YYYY-MM-DD HH24:MI:SS')";
3> restore database;
4> recover database;
5> }

executing command: SET until clause

Starting restore at 13-NOV-16
using channel ORA_DISK_1
ORA-01013: user requested cancel of current operatio
channel ORA_DISK_1: restoring datafile 00001
input datafile copy RECID=30 STAMP=927818003 file name=/home/valtech/backup_lv0_35_927817918_20161113
destination for restore of datafile 00001: /u01/app/oracle/oradata/balloon/system01.dbf
RPC call appears to have failed to start on channel ORA_DISK_1
RPC call OK on channel ORA_DISK_1
channel ORA_DISK_1: copied datafile copy of datafile 00001
output file name=/u01/app/oracle/oradata/balloon/system01.dbf RECID=0 STAMP=0
channel ORA_DISK_1: restoring datafile 00002
input datafile copy RECID=31 STAMP=927818214 file name=/home/valtech/backup_lv0_36_927818016_20161113
destination for restore of datafile 00002: /u01/app/oracle/oradata/balloon/sysaux01.dbf
RPC call appears to have failed to start on channel ORA_DISK_1
RPC call OK on channel ORA_DISK_1
channel ORA_DISK_1: copied datafile copy of datafile 00002
output file name=/u01/app/oracle/oradata/balloon/sysaux01.dbf RECID=0 STAMP=0
channel ORA_DISK_1: restoring datafile 00003
input datafile copy RECID=32 STAMP=927818231 file name=/home/valtech/backup_lv0_37_927818224_20161113
destination for restore of datafile 00003: /u01/app/oracle/oradata/balloon/undotbs01.dbf
RPC call appears to have failed to start on channel ORA_DISK_1
RPC call OK on channel ORA_DISK_1
channel ORA_DISK_1: copied datafile copy of datafile 00003
output file name=/u01/app/oracle/oradata/balloon/undotbs01.dbf RECID=0 STAMP=0
channel ORA_DISK_1: restoring datafile 00004
input datafile copy RECID=35 STAMP=927818242 file name=/home/valtech/backup_lv0_40_927818241_20161113
destination for restore of datafile 00004: /u01/app/oracle/oradata/balloon/users01.dbf
RPC call appears to have failed to start on channel ORA_DISK_1
RPC call OK on channel ORA_DISK_1
channel ORA_DISK_1: copied datafile copy of datafile 00004
output file name=/u01/app/oracle/oradata/balloon/users01.dbf RECID=0 STAMP=0
channel ORA_DISK_1: restoring datafile 00005
input datafile copy RECID=33 STAMP=927818236 file name=/home/valtech/backup_lv0_38_927818232_20161113
destination for restore of datafile 00005: /u01/app/oracle/oradata/balloon/rman01.dbf
RPC call appears to have failed to start on channel ORA_DISK_1
RPC call OK on channel ORA_DISK_1
channel ORA_DISK_1: copied datafile copy of datafile 00005
output file name=/u01/app/oracle/oradata/balloon/rman01.dbf RECID=0 STAMP=0
Finished restore at 13-NOV-16

Starting recover at 13-NOV-16
using channel ORA_DISK_1

starting media recovery

archived log for thread 1 with sequence 15 is already on disk as file /home/valtech/arch/1_15_892824634.dbf
archived log file name=/home/valtech/arch/1_15_892824634.dbf thread=1 sequence=15
media recovery complete, elapsed time: 00:00:03
Finished recover at 13-NOV-16

RMAN> exit

[oracle@tama01 ~]$ sqlplus /nolog

SQL*Plus: Release 11.2.0.1.0 Production on Sun Nov 13 16:02:02 2016

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

SQL> conn / as sysdba
Connected.
SQL> alter database open resetlogs;
Database altered.

リカバリが無事完了しました。
それでは、契約テーブルを確認しましょう。

SQL> select * from qb.keiyaku;
NAME       KEIYAKUBI
-------------------- ---------
madoka       03-OCT-10
homura       01-AUG-09
mami       01-AUG-10
sayaka       15-OCT-10
kyoko       01-MAY-10


mamiさんが復活しています!!

[結論]
リカバリしてresetlogsでオープンしたデータベースに対し、resetlogs以前のポイントにリカバリをし直したい場合は、
reset incarnationで世代を指定することで可能となります。

[注意点]
自動ストレージ管理(ASM)ディスク・グループが使用されている場合、
インカーネーションを含むデータ・ファイルの完全名が既存のデータ・ファイル名と一致しない場合のみ、RMANリストア操作によってデータ・ファイルの新規コピーが作成されます。
ASMの場合ファイルがOMF(Oracle Managed Files)の機能で、指定の場所にファイルが自動的に作成されます。

以前、この事象に遭遇したことがあり、新しいファイルを作るスペースがDiskGroupに無くなってしまい、処理が止まってしまうというトラブルに遭ったことがあります。
回避策として、制御ファイルに各データ・ファイルに別名を使用する方法で回避できます。

2016年9月14日水曜日

JPOUG 15min talk #1 でお話しました

NTTデータ先端技術様で開催された、JPOUGの新企画「15min talk」にてお話をさせて頂きました。
「35歳でOracleDBAになった私がデータベースを壊して学んだこと」
ということで、DBAになるまでに困ったことと、勉強の為に自分で使用できる環境を作ったことをお話させて頂きました。
あまり技術的な話ではなく、経験者の多くの方にとっては当たり前すぎる内容かもしれませんが、
私がそうだったように、入口で困っていらっしゃる方もいらっしゃるのではという思いがありました。
http://www.slideshare.net/shinnosukeakita5/35dba


私の他に5人がお話をされ、統合監査の話、自動化の話、StandardEditionでの工夫、SWITCHコマンド、検証Tipsなど、
勉強になる内容ばかりでした。

11月に2回目を募集中です。
http://www.jpoug.org/2016/09/12/in15m2

2016年7月16日土曜日

db tech showcace2016に行ってきました

7月13・14・15で秋葉原UDXにて開催されたdb tech showcaceに参加してきました。
このカンファレンスはデータベーステクノロジーだけを取り上げたセッションで、
データベースに関しては日本最大級のイベントです。

ちょうど仕事が忙しかったこともあり、参加は13日に1時間、15日に午後のみとなってしまいました。
聴かせていただいたセッションは以下の通りです。

13日
・E13 Connecting Hadoop and Oracle

15日
・A33 2020年のデータベースコンサルタントのスキルセットを考える
・E34 Oracle SE - RAC, HA and Standby are Still Available. Even Cloud!
・E35 SQLチューニング総合診療所的予防医学
・E36 バックアップと障害復旧から考えるOracle Database, MySQL, PostgreSQLの違い
・E37 商用DBからPostgreSQLへの移行の検討ポイント

以下、セッションのメモ
<E13 Connecting Hadoop and Oracle>
・SQL ServerのLinux版、AzureにRedHatなど今、世界は変わろうとしている。
・様々なデータベースからデータをhadoopやazure、awsにアクセスできるようになる。
・そのなかでもHadoopはオープンデータであり、スケーラビリティもあり、多種のエンジンがあるので良い。
・データ格納には安いサーバを大量に並べれば良くなる。
・Hadoopに対するデータ移動はsqoopというものがある。
・oracle RDBMSのようにHadoopに格納したデータをクエリで扱うことができる

<2020年のデータベースコンサルタントのスキルセットを考える>
*ペンを忘れてしまったため記憶しているレベルでのお話
・CPUメモリとDISKの性能は年々上がっているが、CPUメモリに比べてDISKの性能はそれほど上がっていない
・オンプレミスでのサーバ設計の際はリソースの見積もりを考えていかなければならないが、クラウドによって数年先のリソース見積もりを考えていく必要は減っている。
・セキュリティなど懸念点もあり、すべてがクラウドになることはないだろうが、これからのDBエンジニアはクラウドのサービスについて知っておく必要はある

<Oracle SE - RAC, HA and Standby are Still Available. Even Cloud!>
*ペンを買ってきたので少し遅れて入る
・OracleのEditionの話。Express Editionはサポートもパッチもないが100%無料。
 Oracle Standard EditionはSE2になってソケットが減るなど制限が強くなったが、RACは無料。
・ただし、DataGuard Flashback パラレルクエリ AWRが無い
・DataGuardの代替として、アーカイブを転送するスクリプトを記述する方法やDBVISITを使用する方法、RMANによるバックアップを取得することで災害時リカバリに備えるという方法が考えられる
・Datapumpについては、Enterprise EditionからStandard Editionへの以降の際、ビットマップインデックスなどSEではサポートされないオブジェクトに注意が必要だ
・Backupや論理データレプリケーションについてもSEは可能。
・FlashbackはSE/SE2で動かすことはできない
・制限はあれど、SE/SE2は良いデータベースだ!

<SQLチューニング総合診療所的予防医学>
・性能トラブルの予防の基本として、試験環境でも本番相当のリソースを用意することがベストである
・試験データをどう作って行くかが一番重要である
・テストケースについても本番に相当するものを用意しておきたい

・良くない試験データ例
 ・性能試験データの質として、メモリ設定が1/4でテーブル読み込み件数が本番と同じ量としてしまった
 ・条件がマッチせず空振りし、意図した試験ができていない
 ・データの偏りを再現できない  etc

・CBOの性格を理解していこう
・オプティマイザは非機能要件(バッチ処理時間とか)までは理解できないので、オプティマイザモードの設定を考慮しよう

<バックアップと障害復旧から考える>
・バックアップを取得しただけでは、バックアップ時点のデータしか取得できない
・更新ログと組み合わせることにより、バックアップを障害直前時点の状態にまで戻すことができる
・Oracle/mysql/postgreSQLにそれぞれ更新ログ相当のものがあり、それらを保存しておくことで障害に備えることができる
・mysqlはログの種類が二つある mysqlbinlogは更新系ログとして存在。他にinnodb-logfileがあり、これはプロセス異常時のクラッシュリカバリに使用される
・postgreSQLについて、分離ブロックといってブロック内に更新されているデータと更新がまだされているものも混在している。バックアップモードをONにすることにより、チェックポイントが発生し、データファイルと同期が取れる

・(質疑より)postgreSQLは更新ログをデフォルトで二重化できないが、他社提供のもので二重化できるものがある

<商用DBからPostgreSQLへの移行の検討ポイント>
・PostgreSQL エンタープライズ・コンソーシアムの活動について
・昨年度は異種DBからのデータ移行に関する調査検証を行った
・データ型/移行ツール/SQL互換性のポイント紹介
・移行先データベースのスキーマ移行正常性担保について
・SQL文の実行順についての考慮

今回はあまりセッション聞けませんでしたが、新しいことを知ることができたり、仕事の課題を解決してくれるものもあり、スケジュールを空けてよかったです。
セッションスピーカーの方々はどのかたもその道の第一人者なだけあって、説明はわかりやすく、ああいうふうに伝わるように説明できるように自分もなりたいものだなあと思いました。

2016年7月10日日曜日

逆キーインデックスを試してみた

インデックスは木構造で作成されていることから、シーケンシャルにキーが追加されるような使われ方がする場

合は、
インデックスの右端の部分のブロックが集中的にアクセスされてしまいます。
この状態で並列処理がされると、大量のラッチ待ちが発生してしまいます。

Fig1:インデックス構造

このような場合、一つの解決策として逆キーインデックスがあります。
キーの値を逆にすることにより、集中的にアクセスするブロックを無くし、満遍なくアクセスされるようにするというわけです。
Fig2:逆キーインデックス

■逆キーインデックスの貼り方
インデックスの作成
CREATE INDEX <インデックス名> ON <テーブル名> (カラム1[,カラム2]) REVERSE;


既存のインデックスを逆キーインデックスにする
ALTER INDEX <インデックス名> REBUILD REVERSE;

既存のインデックスを通常のインデックスにする
ALTER INDEX <インデックス名> REBUILD NOREVERSE;

■実際にやってみた
インデックスキーが貼られている列に対してシーケンシャルに+1し続ける行追加を繰り返してみた。

同時実行数:2
100件インサート
インデックス    151.8秒
逆キーインデックス 144.3秒

あまり値が変わらなかった。同時実行数をさらに追加して今度試してみようと思う。

■制限事項
逆キーインデックスには以下の制限事項がある。
・範囲指定をする際に、逆キーインデックスは使用できない

2016年5月11日水曜日

Oracle Database Connect2016に行ってきました

久々のBlogとなります。sakitaです。


昨日はOracle Database Connect2016という、日本オラクルとJPOUG(Japan Oracle User Group)共催のイベントに行ってきました。
場所が品川プリンスホテルでしたので、職場が品川の私にとっては近くて助かります。

すべてのセッションを聞きましたが、知らなかったことを知るよい機会となりました。

・Juan R. Loaiza氏の基調講演
Oracle Databaseのこれまでとこれからについてお話がありました。
気になるところでは、Database Shardingが気になりました。データベースを1000のshared dbに分散して管理をするということで、多くのデータを管理するDWH分野で期待できそうです!

今話題のZeroDataLossRecoveryApplianceも気になりました。どのポイントにも不完全リカバリができるようですが、大量のアーカイブログを保持しなければならないのだろうかとか、容量面がきになりました。ここは要調査です。

・Wei Hu氏のMAA( Maximum Availability Architecture)についての講演
Oracle Active DataGuardの破損時の自動復旧機能がすばらしいなと思いました。

・しばちょう先生のリカバリについてのセッション
表単位リカバリ機能など、様々なリカバリの方法が出てきて勉強になりました。

・諏佐さんのアップグレードについての講演
Real Application Testingのお話などされていました。一度使ったことがありますが、アプリの準備が不要なので便利です。ただキャプチャファイルがデカいのが玉にきず・・・。

・ シバタツさんのチューニングのセッション
シーケンスで追加されていくようなインデックスを「Right Growing Index」という名前だというのをはじめて知りました。
このパターンは逆キーが良いということを言いますが、索引をつくらないPKとか、クエリリライトとか、使えるテクニックを教えて頂きました。
これはまた別の機会に検証してみたいです!

JPOUGのイベントに初めて参加した2012年から4年。多くのことを学ばせていただきました。
JPOUGが気になる方は、以下に登録して一度イベントに出かけてみてはいかがでしょうか。
以下のURLで「コミュニティに参加」を押すだけで完了です。
https://jpoug.doorkeeper.jp/

2016年2月15日月曜日

ORA-01866 日付時刻クラスが無効です

久しぶりのブログエントリーとなります。
残業続きの日々も終わり、今は仕事が落ち着いてきたので、ブログや検証を進めていきたいと思います。

さて、先日テーブルのカラムをTIMESTAMP型からCHAR型に変更しようとしたら、こんなエラーが出ました。

ORA-01866: 日付時刻クラスが無効です


TIMESTAMP型のカラムをよくよく確認してみると、デフォルト値にSYSTIMESTAMPが指定されていました。
つまり、CHAR型ではSYSTIMESTAMPをデフォルト値として指定できないので、エラーになってしまうようです。

今回はこのようにエラー回避して変更しました。

alter table table01 modify column01 default null;
alter table table01 modify column01 char(30);