[Lab 2] Oracle からの移行を促進する新機能
Contents CONTENTS... 2 1. はじめに... 3 2. 内容... 3 3. レジストリ変数の設定とデータベースの作成... 3 3.1 レジストリ変数なしでのデータベースの作成... 3 3.2 レジストリ変数ありでのデータベースの作成... 4 3.3 データタイプの互換性パラメーターの確認... 5 4. ORACLE 固有のデータ タイプの使用... 6 4.1 互換機能が無効なデータベースでの使用... 6 4.2 互換機能が有効なデータベースでの使用... 7 4.3 データの挿入と参照... 7 5. ORACLE 互換のビルトイン関数の使用... 9 6. PL/SQL の無名ブロックの実行... 11 7. PL/SQL パッケージの作成と実行... 13 7.1 PL/SQL パッケージの作成... 13 7.2 パッケージの実行... 15 8. 新しいロック方式 (CURRENTLY ( COMMITTED) の確認... 17 8.1 パラメーターの無効化... 17 8.2 テスト準備... 18 8.3 Currently Commited の動作の確認... 19 2
1. はじめに このハンズオンでは Oracle 互換機能のいくつかの機能を実際に実行し これらの機能の理解を深めます 2. 内容 このハンズオンでは以下の内容を実施します レジストリ変数の設定とデータベースの作成 Oracle 固有のデータ タイプの使用 Oracle 互換のビルトイン関数の使用 PL/SQL の無名ブロックの実行 PL/SQL パッケージの作成と実行 新しいロック方式 (CURRENTLY COMMITED) の確認 3. レジストリ変数の設定とデータベースの作成 3.1 レジストリ変数なしでのデータベースの作成 _ データベースの作成 最初にレジストリ変数 DB2_COMPATIBILITY_VECTOR を設定していない状態でデータベースを作成します Terminal を開き db2inst1 ユーザーで以下のを実行し データベースを作成します su - db2inst1 db2start db2 create db oratest1 on /db2 using codeset utf-8 territory jp 実行例 db2inst1@db2v97onsles10:~> su - db2inst1 db2inst1@db2v97onsles10:~> db2start db2inst1@db2v97onsles10:~> db2 create db oratest1 on /db2 using codeset utf-8 territory jp DB20000I CREATE DATABASE が正常に完了しました 3
3.2 レジストリ変数ありでのデータベースの作成 _ レジストリ変数の設定次にレジストリ変数 DB2_COMPATIBILITY_VECTOR=ORA を設定した状態でデータベースを作成します レジストリ変数 DB2_COMPATIBILITY_VECTOR=ORA と同時に DB2_DEFERRED_PREPARE_SEMANTICS=YES の設定も行います Terminal を開き db2inst1 ユーザーで以下のを実行します レジストリ変数の設定後 インスタンスの再起動も行います : db2set DB2_COMPATIBILITY_VECTOR=ORA db2set DB2_DEFERRED_PREPARE_SEMANTICS=YES db2stop force db2start db2set all 実行例 db2inst1@db2v97onsles10:~> db2set DB2_COMPATIBILITY_VECTOR=ORA db2inst1@db2v97onsles10:~> db2set DB2_DEFERRED_PREPARE_SEMANTICS=YES db2inst1@db2v97onsles10:~> db2stop force 2009-08-06 20:55:35 0 0 SQL1064N DB2STOP の処理が正常に終了しました SQL1064N DB2STOP の処理が正常に終了しました db2inst1@db2v97onsles10:~> db2start 08/06/2009 20:55:40 0 0 SQL1063N DB2START の処理が正常に終了しました SQL1063N DB2START の処理が正常に終了しました db2inst1@db2v97onsles10:~> db2set -all [i] DB2_DEFERRED_PREPARE_SEMANTICS=YES [i] DB2_COMPATIBILITY_VECTOR=ORA [i] DB2COMM=tcpip [g] DB2SYSTEM=db2V97onSLES10 db2inst1@db2v97onsles10:~> _ データベースの作成レジストリ変数の設定後 データベースの作成を行います 以下のを db2inst1 ユーザーで実行します db2 create db oratest2 on /db2 using codeset utf-8 territory jp 実行例 db2inst1@db2v97onsles10:~> db2 create db oratest2 on /db2 using codeset utf-8 territory jp DB20000I CREATE DATABASE が正常に完了しました 4
3.3 データタイプの互換性パラメーターの確認 _ データベース構成パラメーターの確認データベースの作成後 ORATEST1 と ORATEST2 のデータベース構成パラメーターを確認します データ タイプの互換性機能のパラメーターを確認します 以下のを db2inst1 ユーザーで実行します db2 get db cfg for oratest1 grep 互換性 db2 get db cfg for oratest2 grep 互換性 実行例 db2inst1@db2v97onsles10:~> db2 get db cfg for oratest1 grep 互換性 NUMBER データ タイプの互換性 = OFF VARCHAR2 データ タイプの互換性 = OFF データ タイプ DATE の TIMESTAMP(0) への互換性 = OFF db2inst1@db2v97onsles10:~> db2 get db cfg for oratest2 grep 互換性 NUMBER データ タイプの互換性 = ON VARCHAR2 データ タイプの互換性 = ON データ タイプ DATE の TIMESTAMP(0) への互換性 = ON レジストリ変数 DB2_COMPATIBILITY_VECTOR を設定する前に作成したデータベース ORATEST1 では データ タイプの互換性に関連するパラメーターが OFF になっていることが確認できます レジストリ変数 DB2_COMPATIBILITY_VECTOR=ORA を設定後に作成したデータベース ORATEST2 では データ タイプの互換性に関連するパラメーターが ON になっていることが確認できます 5
4. Oracle 固有のデータ タイプの使用の使用 4.1 互換機能が無効なデータベースデータベースでの使用 _ 表の作成の失敗 Oracle 固有のデータ タイプである VARCHAR2 型 NUMBER 型 DATE 型の列を持つ表を ORATEST1 ORATEST2 に作成します 最初に ORATEST1 データベースに接続して CREATE TABLE 文を実行します 以下のを実行します db2 connect to oratest1 db2 create table t1(c1 varchar2(10),c2 number(10,2),c3 date) 実行例 db2inst1@db2v97onsles10:~> db2 connect to oratest1 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST1 db2inst1@db2v97onsles10:~> db2 "create table t1(c1 varchar2(10),c2 number(10,2),c3 date)" DB21034E が 有効な行プロセッサー でないため SQL ステートメントとして処理されました SQL 処理中に そのが返されました SQL0104N "create table T1(C1 " に続いて予期しないトークン "varchar2" が見つかりました 予期されたトークンに "VARCHAR" が含まれている可能性があります SQLSTATE=42601 db2inst1@db2v97onsles10:~> データ タイプの互換性のパラメーターが OFF のため VARCHAR2 型や NUMBER 型の列を持つ表の作成に失敗します VARCHAR2 型や NUMBER 型が認識されないため 文法エラー (SQL0104N) となります 6
4.2 互換機能が有効なデータベースでの使用 _ 表の作成次に ORATEST2 データベースに接続して 同じ CREATE TABLE 文を実行してみます 次のを実行します db2 connect to oratest2 db2 "create table t1(c1 varchar2(10),c2 number(10,2),c3 date)" 実行例 db2inst1@db2v97onsles10:~> db2 connect to oratest2 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST2 db2inst1@db2v97onsles10:~> db2 "create table t1(c1 varchar2(10),c2 number(10,2),c3 date)" DB20000I SQL が正常に完了しました db2inst1@db2v97onsles10:~> データ タイプの互換性のパラメーターが ON のため VARCHAR2 型や NUMBER 型の列を持つ表の作成が成功します 4.3 データの挿入と参照 _ 表へのデータの挿入 参照次にこの表に対して列属性の確認を行い データの挿入 参照を行ってみます 以下のを実行します db2 describe table t1 db2 "insert into t1 values (100,10.2,sysdate)" db2 "select * from t1" 7
実行例 db2inst1@db2v97onsles10:~> db2 describe table t1 データ タイデータ 列の スケ 列名 プ スキーマタイプ名 長さ ール NULL ---------------------------- --------- ------------------- ---------- ----- ------ C1 SYSIBM VARCHAR 10 0 はい C2 SYSIBM DECIMAL 10 2 はい C3 SYSIBM TIMESTAMP 7 0 はい 3 レコードが選択されました db2inst1@db2v97onsles10:~> db2 "insert into t1 values (100,10.2,sysdate)" DB20000I SQL が正常に完了しました db2inst1@db2v97onsles10:~> db2 "select * from t1" C1 C2 C3 ---------- ------------ ------------------- 100 10.20 2009-08-06-22.55.07 1 レコードが選択されました DESCRIBE TABLE で列属性を確認すると VARCHAR2 で作成された列は VARCHAR NUMBER で作成された列は DECIMAL DATE で作成された列は TIMESTAMP(0) として作成されていることがわかります INSERT 文では VARCHAR 列に数値を指定しても暗黙的に変換が行われ INSERT 文が成功しています また SYSDATE 関数の使用も可能です この暗黙的な型変換や SYSDATE 関数は DB2_COMPATIBILITY_VECTOR の設定とは関係なく使用できます 8
5. Oracle 互換のビルトイン関数の使用 _TO_CHAR 関数の使用ここでは Oracle 互換のビルトイン関数を使用してみます 最初に TO_CHAR 関数を使用してみます 以下のを実行します db2 connect to oratest2 db2 "select sysdate,to_char(sysdate,'hh:mi:ss') from dual" 実行例 db2inst1@db2v97onsles10:~> db2 connect to oratest2 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST2 db2inst1@db2v97onsles10:~> db2 "select sysdate,to_char(sysdate,'hh:mi:ss') from dual" 1 2 ------------------- ---------------------------------------------------------------- 2009-08-11-11.04.05 11:04:05 1 レコードが選択されました TO_CHAR 関数によって出力フォーマットを指定しています _TO_NUMBER,TO_DATE 関数の使用次に TO_NUMBER 関数と TO_DATE 関数を使用してみます 以下のを実行します db2 "select to_number('123,456,789','999,999,999') from dual" db2 "select to_date('2000/10/10','yyyy/mm/dd') from dual" 9
実行例 db2inst1@db2v97onsles10:~> db2 "select to_number('123,456,789','999,999,999') from dual" 1 ------------------------------------------ 123456789 1 レコードが選択されました db2inst1@db2v97onsles10:~> db2 "select to_date('2000/10/10','yyyy/mm/dd') from dual" 1 -------------------------- 2000-10-10-00.00.00.000000 1 レコードが選択されました TO_NUMBER 関数では 指定されたフォーマットを使用して文字列から数値データを取り出しています TO_DATE 関数では 指定されたフォーマットを使用して文字列から TIMESTAMP データを取り出しています 10
6. PL/SQL の無名ブロックの実行 _PL/SQL 無名ブロックの記述 PL/SQL の無名ブロックをファイルに作成し 実行します vi を起動して PL/SQL の無名ブロックを記述します (/workshop/lab2 ディレクトリに plsqltest.sql があります お時間のない場合や vi の操作に慣れていない方はこちらのファイルをご使用ください ) cd /workshop/lab2 vi plsqltest.sql ファイルには以下の内容を記述します plsqltest.sql set sqlcompat plsql; set serveroutput on; declare rec t1%rowtype; begin delete from t1; for i in 1..3 loop insert into t1 values (i,i,add_months(sysdate,i) ) returning c1,c2,c3 into rec; dbms_output.put_line('inserted : ' rec.c1 ',' rec.c2 ',' rec.c3); end loop; end; / set sqlcompat db2; set serveroutput off; _PL/SQL 無名ブロックの実行 db2inst1 ユーザーで ORATEST2 データベースに接続して 以下ので plsqltest.sql ファイルに記述された PL/SQL の無名ブロックを実行します db2 connect to oratest2 db2 -tvf plsqltest.sql 11
実行例 db2inst1@db2v97onsles10:~> db2 connect to oratest2 この PL/SQL の無名ブロックでは T1 表のデータを削除し 3 行のデータを挿入しています 挿入後 挿入したデータを DBMS_OUTPUT.PUT_LINE プロシージャーで出力しています _ データの確認実際に T1 表にデータが格納されたことを以下のを実行して確認します db2 select * from t1 実行例 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST2 db2inst1@db2v97onsles10:~> db2 -tvf plsqltest.sql set sqlcompat plsql DB20000I SET SQLCOMPAT が正常に完了しました set serveroutput on DB20000I SET SERVEROUTPUT が正常に完了しました declare rec t1%rowtype; begin delete from t1; for i in 1..3 loop insert into t1 values (i,i,add_months(sysdate,i) ) returning c1,c2,c3 into rec; dbms_output.put_line('inserted : ' rec.c1 ',' rec.c2 ',' rec.c3); end loop; end; DB20000I SQL が正常に完了しました inserted : 1,1,2009-09-09-13.45.14 inserted : 2,2,2009-10-09-13.45.14 inserted : 3,3,2009-11-09-13.45.14 set sqlcompat db2 DB20000I SET SQLCOMPAT が正常に完了しました set serveroutput off DB20000I SET SERVEROUTPUT が正常に完了しました db2inst1@db2v97onsles10:~> db2 "select * from t1" C1 C2 C3 ---------- ------------ ------------------- 1 1.00 2009-09-06-23.11.13 2 2.00 2009-10-06-23.11.13 3 3.00 2009-11-06-23.11.13 3 レコードが選択されました 3 行のデータが格納されていることを確認します 12
7. PL/SQL パッケージの作成と実行 7.1 PL/SQL パッケージの作成 _PL/SQL パッケージの作成ここでは PL/SQL のパッケージを作成して実行します 最初に vi を起動して CREATE PACKAGE 文を記述します (/workshop/lab2 ディレクトリに pkgtest.sql があります お時間のない場合方や vi の操作に慣れていない方はこちらのファイルをご使用ください ) cd /workshop/lab2 vi pkgtest.sql ファイルには以下の内容を記述します pkgtest.sql set sqlcompat plsql; create or replace package pkg1 is var varchar2(100) := 'default'; procedure print_var; procedure set_var(ivar varchar2); end; / create or replace package body pkg1 is procedure print_var is begin dbms_output.put_line(var); end; procedure set_var(ivar varchar2(100)) is begin var := ivar; end; end; / set sqlcompat db2; db2inst1 ユーザーで ORATEST2 データベースに接続して 以下ので pkgtest.sql ファイルに記述された CREATE PACKAGE 文を実行し パッケージを作成します db2 connect to oratest2 db2 -tvf pkgtest.sql 13
実行例 db2inst1@db2v97onsles10:~> db2 connect to oratest2 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST2 db2inst1@db2v97onsles10:~> db2 -tvf pkgtest.sql set sqlcompat plsql DB20000I SET SQLCOMPAT が正常に完了しました create or replace package pkg1 is var varchar2(100) := 'default'; procedure print_var; procedure set_var(ivar varchar2); end; DB20000I SQL が正常に完了しました create or replace package body pkg1 is procedure print_var is begin dbms_output.put_line(var); end; procedure set_var(ivar varchar2(100)) is begin var := ivar; end; end; DB20000I SQL が正常に完了しました set sqlcompat db2 DB20000I SET SQLCOMPAT が正常に完了しました _ パッケージ作成の確認以下の SQL を実行してパッケージが作成されたことを確認します db2 "select char(modulename,20) modulename,moduletype from syscat.modules" db2 "select * from syscat.moduleobjects where objectmodulename = 'PKG1'" 14
実行例 db2inst1@db2v97onsles10:~> db2 "select char(modulename,20) modulename,moduletype from syscat.modules" MODULENAME MODULETYPE -------------------- ---------- 省略 UTL_MAIL M DBMS_STANDARD M PKG1 P 15 レコードが選択されました db2inst1@db2v97onsles10:~> db2 "select * from syscat.moduleobjects where objectmodulename = 'PKG1'" OBJECTSCHEMA OBJECTMODULENAME OBJECTNAME OBJECTTYPE PUBLISHED SPECIFICNAME USERDEFINED --------------------------------------------------------------------------------------------- ----------------------------------- --------------------------------------------------------- ----------------------------------------------------------------------- --------------------- --------------------------------------------------------------------------------------------- -------------- ---------- --------- --------------------------------------------------------- ----------------------------------------------------------------------- ----------- DB2INST1 PKG1 VAR VARIABLE Y - Y DB2INST1 PKG1 SET_VAR PROCEDURE Y SQL090809134922100 Y DB2INST1 PKG1 PRINT_VAR PROCEDURE Y SQL090809134922000 Y 3 レコードが選択されました SYSCAT.MODULES カタログビューに PKG1 パッケージがあることが確認できます SYSCAT.MODULEOBJECTS カタログビューには PKG1 パッケージに属しているオブジェクトが確認できます 7.2 パッケージの実行 _ パッケージの実行次に PKG1 のプロシージャーを実行します 以下のを実行します db2 set serveroutput on db2 call pkg1.print_var db2 "call pkg1.set_var('abc')" db2 call pkg1.print_var db2 set serveroutput off 15
実行例 db2inst1@db2v97onsles10:~> db2 set serveroutput on DB20000I SET SERVEROUTPUT が正常に完了しました db2inst1@db2v97onsles10:~> db2 call pkg1.print_var リターン状況 = 0 default db2inst1@db2v97onsles10:~> db2 "call pkg1.set_var('abc')" リターン状況 = 0 db2inst1@db2v97onsles10:~> db2 call pkg1.print_var リターン状況 = 0 ABC db2inst1@db2v97onsles10:~> db2 set serveroutput off DB20000I SET SERVEROUTPUT が正常に完了しました db2inst1@db2v97onsles10:~> DBMS_OUTPUT.PUT_LINE プロシージャーによるバッファーへの書き出しを CLP で受け取るために set serveroutput on を実行します PKG1.PRINT_VAR プロシージャーにより VAR 変数の内容を表示します 最初の呼び出しでは デフォルト値に設定した default が確認できます 次に PKG1.SET_VAR プロシージャーで ABC を VAR 変数にセットします この後 PKG1.PRINT_VAR プロシージャーで VAR 変数の内容を出力すると VAR 変数に ABC が入っていることがわかります 最後に serveroutput の設定を元に戻すために set serveroutput off を実行します 16
8. 新しいロック方式 (Currently Committed) の確認 8.1 パラメーターの無効化 _ パラメーターの確認最初に Currently Committed の機能を有効にするパラメーターがどのような値に設定されているか確認します db2 get db cfg for oratest1 grep CUR_COMMIT db2 get db cfg for oratest2 grep CUR_COMMIT 実行例 db2inst1@db2v97onsles10:~> db2 get db cfg for oratest1 grep CUR_COMMIT CS 分離レベルで現在コミット済みの結果を戻す (CUR_COMMIT) = ON db2inst1@db2v97onsles10:~> db2 get db cfg for oratest2 grep CUR_COMMIT CS 分離レベルで現在コミット済みの結果を戻す (CUR_COMMIT) = ON db2inst1@db2v97onsles10:~> CUR_COMMIT パラメーターは V9.7 で新規に作成されたデータベースでのデフォルト値は ON です DB2_COMPATIBILITY_VECTOR の設定値には関連しません ここでは ORATEST1 の CUR_COMMIT の設定を OFF にして ORATEST2 を CUR_COMMIT を ON のままにしておきます これらの 2 つのデータベースに同じ処理を実施し このパラメーターの動作の違いを確認します _ パラメーターの無効化最初に ORATEST1 の CUR_COMMIT の設定を OFF にします 以下のを実行じます db2 update db cfg for oratest1 using cur_commit off db2 terminate db2 force applications all db2 connect to oratest1 db2 get db cfg for oratest1 show detail grep CUR_COMMIT 17
実行例 db2inst1@db2v97onsles10:~> db2 update db cfg for oratest1 using cur_commit off DB20000I UPDATE DATABASE CONFIGURATION が正常に完了しました db2inst1@db2v97onsles10:~> db2 terminate DB20000I TERMINATE が正常に完了しました db2inst1@db2v97onsles10:~> db2 force applications all DB20000I FORCE APPLICATION が正常に完了しました DB21024I このは非同期であり 即時に有効にならない場合もあります db2inst1@db2v97onsles10:~> db2 connect to oratest1 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST1 db2inst1@db2v97onsles10:~> db2 get db cfg for oratest1 show detail grep CUR_COMMIT CS 分離レベルで現在コミット済みの結果を戻す (CUR_COMMIT) = DISABLED DISABLED db2inst1@db2v97onsles10:~> 設定後 データベースを DEACTIVATE するために db2 terminate db2 force applications を実行します また 実際にパラメーターが変更されているか db2 get db cfg を show detail オプションを付けて実行します 左側に出力される値が現行値です DISABLED になっていることが確認できるはずです 8.2 テスト準備 Currently Committed のハンズオン準備のために ORATEST1 データベース ORATEST2 データベースに同じテーブルを用意します _ORATEST1 へのテーブル作成最初に ORATEST1 データベースに テーブルを作成します 次のを実行します db2 connect to oratest1 db2 "create table l1(c1 int,c2 int)" db2 "insert into l1 values (1,1)" テーブル名は エル イチです 18
実行例 db2inst1@db2v97onsles10:~> db2 connect to oratest1 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST1 db2inst1@db2v97onsles10:~> db2 "create table l1(c1 int,c2 int)" DB20000I SQL が正常に完了しました db2inst1@db2v97onsles10:~> db2 "insert into l1 values (1,1)" DB20000I SQL が正常に完了しました _ORATEST2 へのテーブル作成同様に ORATEST2 データベースにもテーブルを作成します 以下のを実行します db2 connect to oratest2 db2 "create table l1(c1 int,c2 int)" db2 "insert into l1 values (1,1)" 実行例 db2inst1@db2v97onsles10:~> db2 connect to oratest2 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST2 db2inst1@db2v97onsles10:~> db2 "create table l1(c1 int,c2 int)" DB20000I SQL が正常に完了しました db2inst1@db2v97onsles10:~> db2 "insert into l1 values (1,1)" DB20000I SQL が正常に完了しました db2inst1@db2v97onsles10:~> 8.3 Currently Commited の動作の確認 _ORATEST1 での CC 動作確認ここから Currently Committed の動作の違いを確認します 2 つの Terminal を使用して動作の確認を行うため 最初に 2 つの Terminal を起動します Currently Committed の機能が有効になっていない ORATEST1 データベースでの動作の確認を行います 1 つの Terminal(Terminal 1 とします ) で以下のを実行し L1 表の行にロックを取得した状態にします 19
db2 connect to oratest1 db2 +c "update l1 set c1 = 100, c2 = 100" db2 +c "select * from l1" db2pd -db oratest1 -locks 実行例 (Terminal 1) db2inst1@db2v97onsles10:~> db2 connect to oratest1 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST1 db2inst1@db2v97onsles10:~> db2 +c "update l1 set c1 = 100, c2 = 100" DB20000I SQL が正常に完了しました db2inst1@db2v97onsles10:~> db2 +c "select * from l1" C1 C2 ----------- ----------- 100 100 1 レコードが選択されました db2inst1@db2v97onsles10:~> db2pd -db oratest1 -locks Database Partition 4294967295 -- Database ORATEST1 -- Active -- Up 0 days 00:01:10 Locks: Address TranHdl Lockname Type Mode Sts Owner Dur HoldCount Att 0x8E60C680 2 02000400040000000000000052 Row..X G 2 1 0 0x8E60C580 2 53514C43324832307F4760B841 Internal P..S G 2 1 0 0x8E60C780 2 02000400000000000000000054 Table.IX G 2 1 0 db2inst1@db2v97onsles10:~> db2pd db oratest1 locks の結果に Type が Row で Mode X の行があることがわかります これは 前に実行している Update 文による更新中の行に X ロックが取られていることを表しています 次に 2 つめの Terminal(Terminal 2 とします ) で このロックがとられた行を参照してみます 以下のを実行します db2 connect to oratest1 db2 select * from l1 20
実行例 (Terminal 2) db2inst1@db2v97onsles10:~> db2 connect to oratest1 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST1 db2inst1@db2v97onsles10:~> db2 "select * from l1" ロック待ち ここでは L1 表のデータが更新中であるため SELECT 文 ( 読み取り ) がロック待ちします Terminal 1 で以下のを発行してロック待ちの状況を確認します 確認後 ロールバックしてロックの解除を行います db2pd -db oratest1 -locks db2 rollback 実行例 (Terminal 1) db2inst1@db2v97onsles10:~> db2pd -db oratest1 -locks Database Partition 4294967295 -- Database ORATEST1 -- Active -- Up 0 days 00:06:47 Locks: Address TranHdl Lockname Type Mode Sts Owner Dur HoldCount 0x8E60C680 2 02000400040000000000000052 Row..X G 2 1 0 0x8E615B80 8 02000400040000000000000052 Row.NS W 0 1 0 0x8E60C580 2 53514C43324832307F4760B841 Internal P..S G 2 1 0 0x8E60DB80 8 53514C43324832307F4760B841 Internal P..S G 8 1 0 0x8E616700 8 01000000010000000100C05E56 Internal V..S G 8 1 0 0x8E60C780 2 02000400000000000000000054 Table.IX G 2 1 0 0x8E60F800 8 02000400000000000000000054 Table.IS G 8 1 0 db2inst1@db2v97onsles10:~> db2 rollback DB20000I SQL が正常に完了しました db2inst1@db2v97onsles10:~> db2pd -db oratest1 -locks Database Partition 4294967295 -- Database ORATEST1 -- Active -- Up 0 days 00:08:41 Locks: Address TranHdl Lockname Type Mode Sts Owner Dur HoldCount Att ReleaseFlg rriid db2inst1@db2v97onsles10:~> db2pd -db oratest1 locks の結果に Type が Row Mode が NS Sts が W となっている行があることがわかります これは SELECT 文によるロック (NS ロック ) がロック待機していることを表しています ロック待機が確認できたら rollback しロックを開放します その後 db2pd -db oratest1 locks を実行して ロックが解除されているのを確認します また Terminal 2 でロック待機していた処理も終了しているはずです 21
_ORATEST2 での動作確認次に Currently Committed の機能が有効になっている ORATEST2 データベースでの動作の確認を行います Terminal 1 で以下のを実行し L1 表の行にロックを取った状態にします db2 connect to oratest2 db2 +c "update l1 set c1 = 100, c2 = 100" db2 +c "select * from l1" db2pd -db oratest2 -locks 実行例 (Terminal 1) db2inst1@db2v97onsles10:~> db2 connect to oratest2 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST2 db2inst1@db2v97onsles10:~> db2 +c "update l1 set c1 = 100, c2 = 100" DB20000I SQL が正常に完了しました db2inst1@db2v97onsles10:~> db2 +c "select * from l1" C1 C2 ----------- ----------- 100 100 1 レコードが選択されました db2inst1@db2v97onsles10:~> db2pd -db oratest2 -locks Database Partition 4294967295 -- Database ORATEST2 -- Active -- Up 0 days 00:00:37 Locks: Address TranHdl Lockname Type Mode Sts Owner Dur HoldCount 0x9A6CC580 2 53514C43324832307F4760B841 Internal P..S G 2 1 0 0x9A6CC680 2 02000500040000000000000052 Row..X G 2 1 0 0x9A6CC780 2 02000500000000000000000054 Table.IX G 2 1 0 db2inst1@db2v97onsles10:~> ORATEST1 データベースの時と同様に 更新中の行に X ロックが取得されていることがわかります 次に Terminal 2 で L1 表のデータを SELECT してみます 以下のを実行します db2 connect to oratest2 db2 select * from l1 22
実行例 (Terminal 2) db2inst1@db2v97onsles10:~> db2 connect to oratest2 データベース接続情報 データベース サーバー = DB2/LINUX 9.7.0 SQL 許可 ID = DB2INST1 ローカル データベース別名 = ORATEST2 db2inst1@db2v97onsles10:~> db2 "select * from l1" C1 C2 ----------- ----------- 1 1 1 レコードが選択されました db2inst1@db2v97onsles10:~> ORATEST1 の時とは違い ロック待ちせず 更新前のデータが参照できます ORATEST2 では Currently Committed の機能が有効になっているため 更新中のデータをロック待ちせず 更新前データを返すような動作となっています Terminal 1 で rollback を行い ロックの開放を行います 以下のを実行します db2 rollback 実行例 (Terminal 1) db2inst1@db2v97onsles10:~> db2 rollback DB20000I SQL が正常に完了しました 以上です 23
Copyright IBM Corporation 2011 All Rights Reserved. 本書に含まれている情報は 正式な IBM のテストを受けていません また 明記にしろ 暗黙的にしろ なんらの保証もなしに配布されるものです この情報の使用またはこれらの技術の実施は いずれも 使用先の責任において行われるべきものであり それらを評価し 実際に使用する環境に統合する使用先の判断に依存しています それぞれの項目は ある特定の状態において正確であることが IBM によって調べられていますが 他のところで同じまたは同様の結果が得られる保証はありません これらの技術を自身の環境に適用することを試みる使用先は 自己の責任において行う必要があります 24