ぱと隊長日誌

ブログ運用もエンジニアとしての生き方も模索中

トランザクションの Strictness と Rigorousness の定義を再確認する

はじめに

トランザクションの Recoverability を理解するうえで Strictness (ST) と Rigorousness (RG) を避けては通ることができません。ただ、日本語の資料が少ないうえに用語の定義が若干あいまいなケースも見受けられました。そこで、本エントリでは資料をまとめつつ、定義を再確認します。

参考資料

本エントリで参照する資料と本エントリ内での略記をまとめます。

(1) TX本

Transactional Information Systems: Theory, Algorithms, and the Practice of Concurrency Control and Recovery (The Morgan Kaufmann Series in Data Management Systems)

Transactional Information Systems: Theory, Algorithms, and the Practice of Concurrency Control and Recovery (The Morgan Kaufmann Series in Data Management Systems)

言わずと知れたトランザクション技術に関する原典ともいうべき本。以降に紹介する資料もこの本を参考にしていると思われます。

(2) Rosati資料
http://www.dis.uniroma1.it/~rosati/gd/1-concurrency.pdf
Rosati教授の講義用資料のようです。
今回の内容は資料の "2.5 Recoverability of transactions" にまとめられています。

(3) kumagi資料
S2PLと永続化
@ さんがトランザクション技術について解説した「一人トランザクション技術 Advent Calendar 2016」のうち、今回のテーマに関する記事です。

(4) 星野資料

星野 喬 さんが筑波大学 集中講義で利用したスライドとのことです。

Strictness (ST) とは

まず、TX本(P393)から確認します。

DEFINITION 11.7 Strictness
A schedule s is strict if the following holds for all transaction ti ∈ trans(s) and for all pi(x) ∈ op(ti), p ∈ {r,w}: if wj(x) <s pi(x), i ≠ j, then aj <s pi(x) ∨ cj <s pi(x).
Let ST denote the class of all strict schedules.

In words, a schedule is strict if no data item is read or overwritten until the transaction that wrote it last has ended (either by commit or by abort).

Rosati資料(P105)では式を使わずに説明しています。

We say that a schedule S is strict if every transaction reads only values written by transactions that have already committed, and writes only on transactions that have already committed

kumagi資料での説明を引用します。

Strictとは「あるトランザクションによる、ある値への書き込みが他のトランザクションの読み込み・書き込みより先なら、他のトランザクションの読み書きは最初のトランザクションのコミットかアボートより後になる」というルールである。

星野資料(P20)での説明を引用します。

Tx1 が write している data item を read/write しようとする Tx2 は Tx1 が commit/abort するまでそれを待つ必要がある

いずれの説明も同じといえます。

Rigorousness (RG) とは

今回取り上げた日本語の資料は Rigorousness の説明に補足すべき点があります。順に確認していきます。

まず、TX本(P394)から確認します。

DEFINITION 11.8 Rigorousness
A schedule s is rigorous if it is strict and additionally satisfies the following condition: for all transactions ti, tj ∈ trans(s), if rj(x) <s wi(x), i ≠ j, then aj <s wi(x) ∨ cj <s wi(x).
Let RG denote the class of all rigorous schedules.

In words, a schedule is rigorous if it is strict and no object x is overwritten until all transactions that read x last are finished.

Rosati資料(P107)を確認します。Strictness も含めた定義となっています。

We say that a schedule S is rigorous if for each pair of conflicting actions ai (belonging to transaction Ti) and bj (belonging to transaction Tj) appearing in S, the commit command ci of Ti appears in S between ai and bj.

kumagi資料での説明を引用します。

RigorousとはStrictの条件を守った上で「あるトランザクションによる、ある値への読み込みが他のトランザクションの読み込みより先なら、他のトランザクションの読み込みは最初のトランザクションのコミットかアボートより後になる」というルールである。

この説明には誤記があり、「他のトランザクションの読み込み」ではなく「他のトランザクションの書き込み」です。

正しく書き換えると以下の説明となります。
『RigorousとはStrictの条件を守った上で「あるトランザクションによる、ある値への読み込みが他のトランザクションの書き込みより先なら、他のトランザクションの書き込みは最初のトランザクションのコミットかアボートより後になる」というルールである。』

星野資料(P23)での説明を引用します。

Tx1 が read/write している data item を read/write しようとする Tx2 は Tx1 が commit/abort するまでそれを待つ必要がある

この説明には若干ミスリードな個所があり、Tx1 / Tx2 共に read のみであれば commit/abort 済みであるかは問題となりません。星野資料(P15)の「Conflict(競合)」の説明より、同じ data item に対する r-r は競合しないからです。

まとめ

Strictness / Rigorousness の定義は既に確認した通りです。今回の用語に限らず、改めてTX本を見直すことで発見があるかもしれません。

Strictness は w-r / w-w 競合を、Rigorousness は r-w 競合も対象としています。r-r は競合しません。

PostgreSQLの一部の関数はトランザクション分離レベルに従わない

はじめに

PostgreSQL 8.4.1 で pg_dump と index の再作成を同時に実行すると "ERROR: cache lookup failed for index" の発生することがあるのはなぜか?との質問に、tom lane さんがこんな回答をしていました。

pg_dump runs in a serializable transaction, so it sees a consistent snapshot of the database including system catalogs. However, it relies in part on various specialized backend functions like pg_get_indexdef(), and those things tend to run on SnapshotNow time, ie they look at the currently committed state.

PostgreSQL: Re: Cache lookup failure for index during pg_dump

pg_dump はシリアライザブルトランザクションPostgreSQL 9.1以降のリピータブルリードに相当)で実行されるが、pg_get_indexdef() のような一部の関数は現在のコミット済みの状態を返すとあります。

PostgreSQL 9.1 以降はトランザクション分離レベルが変更されていますが、これによって挙動の変化はあったのでしょうか?本エントリで確認結果をまとめます。

検証

検証環境・方針

PostgreSQL 10.3 で検証を行いました。

トランザクション1(T1)でインデックスを drop し、トランザクション2(T2)で pg_get_indexdef() を実行して挙動を確認しました。また、以下の条件を組み合わせています。

  • DROP INDEX コミット前/後
  • リピータブルリード/シリアライザブル

今回の検証ではリピータブルリード/シリアライザブルで結果に差異がありませんでした。そこで、検証結果はシリアライザブルの例でまとめます。

DROP INDEX コミット前に pg_get_indexdef() を実行する

-- T1

=# CREATE TABLE index_test(value integer);

=# CREATE INDEX value_idx ON index_test(value);

=# BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;

=# SELECT oid FROM pg_class WHERE relname = 'value_idx';
  oid
-------
 16929
(1 row)
-- T2

=# BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;

=# SELECT oid FROM pg_class WHERE relname = 'value_idx';
  oid
-------
 16929
(1 row)

=# SELECT pg_get_indexdef(16929);
                         pg_get_indexdef
-----------------------------------------------------------------
 CREATE INDEX value_idx ON public.index_test USING btree (value)
(1 row)
-- T1

=# DROP INDEX value_idx;
-- T2

=# SELECT oid FROM pg_class WHERE relname = 'value_idx';
  oid
-------
 16929
(1 row)
-- DROP INDEX 発行後もOIDが取得できる。
-- スナップショットを利用するため、この挙動は妥当といえる。

=# SELECT pg_get_indexdef(16929);
-- レスポンスが保留される。
-- T1

=# COMMIT;
-- T2

保留されていたレスポンスが戻り、
"ERROR:  cache lookup failed for relation 16929"
と表示される。
インデックスが削除された状態、つまりT1コミット後の状態を見ている。

DROP INDEX コミット後に pg_get_indexdef() を実行する

-- T1

=# CREATE TABLE index_test(value integer);

=# CREATE INDEX value_idx ON index_test(value);

=# BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;

=# SELECT oid FROM pg_class WHERE relname = 'value_idx';
  oid
-------
 16931
(1 row)
-- T2

=# BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;

=# SELECT oid FROM pg_class WHERE relname = 'value_idx';
  oid
-------
 16931
(1 row)

=# SELECT pg_get_indexdef(16931);
                         pg_get_indexdef
-----------------------------------------------------------------
 CREATE INDEX value_idx ON public.index_test USING btree (value)
(1 row)
-- T1

=# DROP INDEX value_idx;

=# COMMIT;
-- T2

=# SELECT oid FROM pg_class WHERE relname = 'value_idx';
  oid
-------
 16931
(1 row)
-- DROP INDEX 発行後かつコミット後もOIDが取得できる。
-- スナップショットを利用するため、この挙動は妥当といえる。

=# SELECT pg_get_indexdef(16931);
 pg_get_indexdef
-----------------

(1 row)
-- CREATE INDEX 文を取得できない(T1コミット後の状態を見ている)が、エラーにはならなかった。

まとめ

PostgreSQL 10 かつ シリアライザブル分離レベルであっても、pg_get_indexdef() はスナップショットではなくコミット済みの状態を返しました。また、DROP INDEX のコミット前後によって pg_get_indexdef() の挙動が変わることもわかりました。PostgreSQL 10 以外のバージョンでも同様にふるまう可能性が高そうです。

冒頭で紹介した回答にはこんな記述もあります。

The right fix for this is to make all those inquiry functions use the calling query's snapshot; but duplicating a lot of backend infrastructure is going to be a major pain in the rear, so the discussion has kind of petered out every time it's come up in the past.

PostgreSQL: Re: Cache lookup failure for index during pg_dump

今回のふるまいについてマニュアルを確認しましたが、該当する記述を見つけられませんでした。TRUNCATEのようにMVCCセーフでないとマニュアルに明記されているコマンドもありますが、記載がなくともトランザクション分離レベルに従わないふるまいをする関数があるということです。

また、該当する関数を直接使わずとも、pg_dump のように利用しているケースがあります。今回のようなケースがあることを頭の片隅に入れておくとよいでしょう。

更新情報

2018/10/03

検証においてT1のBEGINの直後にSELECTコマンドを追加することで、参照するスナップショットをより明確にしました。サンプルのふるまい及びエントリ全体の結論には影響ありません。
参考:PostgreSQL のシリアライザブル分離レベルにおけるスナップショットのタイミング - ぱと隊長日誌

DB Online Day 2018 Summer「日本のデータベーススペシャリストは最終的にどこを目指すべきか?」聴講メモ

セッションについて

DB Online Day 2018 Summer (DB Online Day 2018 Summer)
基調講演  日本のデータベーススペシャリストは最終的にどこを目指すべきか?
の聴講メモです。

講演者は 関 俊洋 さん [株式会社アシスト] です。

自分のメモをベースにまとめています。発言の聞き間違い、解釈違いの可能性があることをご了承ください。

【参考】としている個所は私が挿入しています(補足や参考資料など)。講演者の講演内容ではありませんので、その旨ご了承ください。
資料の公開予定がないということでしたので、当日のスライドに表示されたものと同じような情報を探して紹介しています。

はじめに

スペシャリストというより、データベース(以下、DB)に携わっているという立場の方が多いと思われるため、タイトルを変更し「エンジニアがどこを目指すべきか」とした。
【参考】
当日の発表ではタイトルを変更されていました。その説明となります。

DBエンジニアの明確な定義はない。そこで、この講演では少しでもDBに携わっている方をDBエンジニアと定義する。

市場環境、技術トレンド、収入と働き方の3つについて話す。

市場環境について

人口ピラミッド。2030年には人口の1/3が65歳以上となる。
【参考】
f:id:pato_taityo:20180801214516p:plain
出典:国立社会保障・人口問題研究所ホームページ (http://www.ipss.go.jp/

IT人材不足は年々悪化し、人材供給は2019年をピークに減少する。
【参考】

マクロな規模でのIT人材(IT企業及びユーザ企業情報システム部門に所属する人材)は、現在の人材数は約90万人、不足数は約17万人と推計された。今後2019年をピークに人材供給は減少傾向となり、より一層不足数が拡大する。

IT人材の最新動向と将来推計に関する調査結果を取りまとめました(METI/経済産業省)

IT予算は増加傾向にあり、2017年で3割が増加すると回答している。2018年も同じ傾向。
人はいないが予算は増え続けるという真逆の動きとなっている。
【参考】

2017年度(2017年4月~2018年3月)のIT予算は、前年度から「増額」とした企業の割合が34%と、前年調査における2016年度の値から大きく上昇して3割を超えました。一方、「減額」とした企業の割合は前年調査の結果からさらに下回り、2001年の調査開始以来で最も低い水準となりました。

2018年度(2018年4月~2019年3月)に向けた見通しでは、「増額予定」が「減額予定」を大きく上回る傾向と、減額を見込む企業の割合が一桁台という様相は2017年度と同様であり、総合的にはIT予算の増額傾向は継続する予想です。

国内IT投資動向調査報告書2018 | ITR

ディープラーニングやAI/機械学習への投資意欲は非常に強いが、NoSQL, RDBMSへの投資意欲も少なくない。
【参考】
以下のリンク先の資料を参照ください。
国内IT投資動向調査報告書2018 | ITR
<参考資料4> 製品/サービスに対する投資意欲(OS/ミドルウェア分野)

汎用RDBMSは堅調。オンプレミスのシステム更改があるため。
DBaaSは活性化。クラウド移行が続いている。
アプライアンスOracle製品によって成熟期にある。
DWHはIoT・ビッグデータ需要で高成長している。

AI、機械学習ビッグデータは何のために使うのか。マーケティングでいえばレコメンデーション。カスタマーサービスならチャットボット。これらを実現するためのデータはデータベースにある。

だが、データ基盤が整っていないと回答する企業が多い。整理されていなかったり、エンジニアが不足していたり。もちろん、一部の先進的な企業では進んでいるが、多くの企業ではこれからであり、そこにエンジニアの需要がある。

DBエンジニアはデータ基盤と活用の間にいる。データ基盤の仕事は大きく変わらないが、手を伸ばせば活用できる場がすぐそばにある。

技術的なトレンドで考えるDBエンジニア

OracleのExadataが2008年に登場した。ハードとDBが切り離せなくなったという点で大きな転換点となった。
そして今、Oracleがオートノマスというテーマでサービスを提供している。

データベースの選択肢が増えた。RDBMS、KVS、ドキュメント指向など。これらの特性を考えて使い分けられるエンジニアが求められている。

アプライアンスの利用拡大により、アシストのようなソフトウェア屋がハードウェア屋も兼ねることになった。これに伴い、ネットワークやプロジェクトマネジメントのスキルも求められるようになった。この傾向は今も続いている。

OSSの利用拡大により、企業の基幹システムにOSSが使われている。
これに伴い、ソース解読の知識、複数DBの使い分け、異種間DB移行、コミュニティ活動などが求められてきた。
複数DBの使い分けは段階的にできるところから移行するために必要となる。
コミュニティ活動は個人だけでなく企業としても進める必要がある。

ビッグデータ時代は Hadoop, NoSQL, クラウドの知識が求められた。

クラウド時代に DB が as a Service 化し、ハードウェアの運用保守から解放された。代わりに、会計知識、システムデザイン、セキュリティ、クラウド使い分け、クラウド間の移行知識が求められた。

時代が進むごとに求められる知識が増え続けている。

5年前から近い将来に半数近い仕事がなくなると予想されている。
また、Oracle CEOはDBAが数十万人規模で失業すると予想している。こちらの予想はDBAにセグメントを絞り込んでいることに注意。
【参考】
OracleのCEOが予言「数十万人のOracleデータベース管理者は失業する」:Oracle Database 18cは管理者不要……らしい - TechTargetジャパン 情報系システム
OracleのCEOが予言「数十万人のOracleデータベース管理者は失業する」』という見出しの記事で、該当の発言部分は記事をダウンロードしないと確認できません。記事を確認したところ、同様の記載がありました(記事の引用は避けます)。

DBAの仕事は現在カバーしている範囲が虫食いのようになくなるのではないか。例えば運用フェーズの仕事がなくなるだろう。だが、隙間は残る。
また、機械で代替できるとしても、それをすぐに導入できるかは個々の企業によって異なるはず。

業務知識とIT知識とビジネススキルは代えがたい価値となる。
若手エンジニアのチューニングは ADWC (Oracle Autonomous Data Warehouse Cloud Service) に負けるが、ベテランはまだ勝てる。今後は機械に大部分を任せつつ、コアな部分を人間がチューニングするようになるのでは。
【参考】
Oracle Autonomous Databaseの自動チューニング vs 人間による性能チューニング。どちらが高性能をたたき出せるか実際に比べてみた[PR] - Publickey
エンジニアとADWCとの勝負はPublickeyで日本オラクル提供のタイアップ記事として紹介されています。

DBエンジニアはこれまでのDBAの枠を越えていく必要がある。

収入と働き方

アシストの場合、中途採用はプレイヤーとして採用している。管理職や専門職としては採用していない。
プレイヤーは管理職と専門職の2つのキャリアパスを選べるようになった。
昔は階段式なキャリアパスだったが、いまは複線型で自由な選択が求められるようになってきた。

エンジニア単価はコンサルタントとアーキテクトが特に伸びている。プロジェクトマネジメントやDBスペシャリストもまあまあ。単なるDBエンジニアはあまり伸びていない。

DBエンジニアが成長するためには経験による育成が特に重用と考えている。

DBエンジニアが感じるであろう変化は以下の通り。

  • 市場の変革
  • 組織の変革
  • 技術の高度化

変化に捕らわれるにではなく、変化を捉える。
データ活用のニーズは10年前も10年後も変わらない。
データを扱う技術を持つことで、社内でも社外でも、そして経営層に対してもリーダーシップをとることができる。

Ask The Speaker

セッション後、関さんに質問してみました。

Q.
(アシストのような)ベンダーの立場として、業務知識を得るためにどのような工夫をしているのか?
A.
営業経由で情報を得たり、現場に常駐して習得してもらったりしている。ユーザー企業のエンジニアとは異なり、業務知識の習得は中々難しいところ。

Q.
商用ソフトは書籍等の情報が豊富にあるが、PostgreSQLのようなOSSの情報入手はどうしている?
A.
PostgreSQLであれば個人レベルではユーザー会に参加したり、企業としてはコンソーシアムに参加して他社事例を得たりしている。

所感

DBA が失業するとの Oracle CEO 発言が紹介されていましたが、現時点でこの発言はやや強気すぎる気がします。というのも、この後のセッションで以下の話が出ていたからです。

Oracleとしては自動化でDBエンジニアのタスクを半分程度に減らせると考えている。

DB Online Day 2018 Summer「データで見る、経験で語る、日本のデータベーススペシャリストのリアリティ」聴講メモ - ぱと隊長日誌

ただ、将来の進化を織り込むと、Oracle CEO の発言にも現実味を感じます。DBAだけでなく、全てのエンジニアが技術+αが求められるようになり、それが「DBAの枠を越えていく」ということではないでしょうか。