Redgate Hub

Oracle databaseを使用している多くの人々にとって、SCN(System Change Number)は非常に興味のあるトピックですが、それは魅力的なトピックですが、 この記事では、SCNの核心を学びます:それが何であるか、それが使用されている場所、そしてそれがどのように機能するか。

これはSCNに関するすべての詳細を完全にカバーするものではなく、完全にカバーすることはできないことに言及する価値があります。 そうは言っても、始めましょう。

SCN-なぜそれが必要なのですか?

それは月の終わりとその給料日だと仮定します。 給与グループに属しており、適切な権限を持って、すべての従業員の現在の給与計算を取得するクエリを発行しています。 数字は画面を横切って流れている、すべてが素晴らしい起こっています。

出力を見ている間に、同僚が新しい支払実行を開始し、そのバッチジョブが現在の計算の要約をクリアしたとします。 あなたの出力が突然出てくる新しい行のために’0’を示した場合、物事は確かに混乱するでしょう。

実際、このシナリオでは、クエリを発行した時点で存在していた方法である各行の内容である”データベースの状態”を出力に反映させることが期待され

Oracleデータベースの保証の1つは、”ユーザー-データのダーティ-リードがない”ということです。 必要に応じて、問合せが発行された時点で各行を安定した状態に再構築します。

Oracleは、システム変更番号、別名SCNとして知られる独自の”タイマー”を介して、それをうまくかつ非常に正確に行います。

私たちは、SCNのこれらの側面について説明します:

  • 数自体
  • 数ジェネレータ
  • 数が格納されている場所

それでは始めましょう!

SCNを理解するためのビルディングブロック

SCNを調査するためには、いくつかの用語を理解する必要があります。 これらの定義は十分に文書化されていますが、ここで繰り返す価値があります。

Transaction

From The Concepts guide of Oracle online Documentation:

“トランザクションは、1つ以上のSQL文を含む論理的でアトミックな作業単位です。 トランザクションでは、SQLステートメントがすべてコミットされる(データベースに適用される)か、すべてロールバックされる(データベースから元に戻される)かのいずれかになるように、SQLステートメントをグループ化します。 Oracle Databaseでは、すべてのトランザクションにトランザクションIDと呼ばれる一意の識別子が割り当てられます。

もっと簡単に言えば、トランザクションを開始すると、一連の変更を開始します。 これらは全体的に完了するか、まったく完了してはなりません。 データベースでトランザクションが発生すると、変更された領域を読み取るユーザーは、結果を変更する可能性のある副作用から影響を受けてはなりません。

トランザクションがどのデータベースでも正常に動作するためには、四つのACIDルールの後にデータベースが続く必要があります。 これらは:

  • 原子性;
  • 一貫性;
  • 分離;
  • 耐久性。

では、SCNはこのすべてにどこに適合しますか? そして、その質問の答えは、SCNを使用するとOracleのみがデータの一貫性を維持するということです。 これは、あるユーザーが何かを変更しているときに他のユーザーに表示される結果に矛盾がないことを保証するために行われ、その逆もあります。

要約すると、オラクルでは、”読者は作家を待たず、作家は読者を必要としない”という原則が完全かつ真に守られています。 そのためには、現在あらゆる種類の変更を受けているデータが、それらの変更を行っている人以外の誰にも利用できないことが最も重要です。 トランザクションの場合、これはデータの整合性を維持するために必要です。 この整合性を混乱させる可能性がある3つのことが発生する可能性があります–ダーティ読み取り、ファジー読み取り、ファントム読み取り。 これらのトランザクションで整合性の問題が発生しないようにするために、さまざまなレベルの分離を利用できます。 これらは:

  • Read Uncommitted
  • Read Committed
  • Repeatable Read
  • Serializable

トランザクション分離レベル

これらから、OracleはRead Committedをデフォルトの分離レベルとして提供し、まだコミットされていない別のユーザー “ダーティ”とマークされているデータを読み取ってはならず、これをすべて可能にするのに十分な堅牢なメカニズムがなければなりません。

これを可能にするために、SCNは重要な役割を果たしています。

SCN、導入

システムコミット番号は、Oracleの時間表現として理解することができます。 Oracleは、一貫性の制御、リカバリの実行、およびredo内の変更ベクトルの順序付けにSCNを使用します。

SCNは、メモリ内とディスク上の両方の多くの場所にあります。 データベースシステムがデータベースのさまざまな状態を識別するのに役立つ、さまざまな場所が使用されます。 たとえば、一部の場所では、トランザクションの完了ステータスと、それがアクティブかコミットかを示すために使用されます。

一般的な信念に反して、それはコミット時にのみ生成されるわけではありませんが、それは名前自体が示唆していることです。 SCNはデータベース内のすべての時間があり、その瞬間に発生している操作の時間部分を表します。 SCNがコミットで生成されないと言うのは完全に不正確ではありませんが、それはSCNが生成される唯一の方法ではありません。

SCNは、イベントに応答して要求に応じて生成される二部構成の番号です。 それは幾分カレンダーおよび時計の組合せから得られる日付および時間のようである;時計はすぐに変わり、完全な24時間周期を経たときだけ流出–カレ ただし、時計を変更するイベントは「振り子」であり、規則的ですが、SCNを変更するイベントは1つの特定の内部関数の呼び出しです。

カレンダー/時計のタイムスタンプと同様に、値はさまざまな場所に記録され、それぞれが異なる用途のために記録されることがあります。

SCNに似た現実世界の例の一つは、空港の時計です。 二人は同時に空港に入り、時計の時間に注意することができます。 その瞬間、私たちは両方の人々のために同じであることを起こる”エントリSCN”を与えます。 一人はチェックイン前に荷物のためのカートを取得し、他の人はチェックインカウンターに直接進みます。 座席が割り当てられている場合、時間がわずかに異なるため、それぞれの人が異なる”チェックインSCN”を取得することができます。 「搭乗SCN」は、それぞれがいつ搭乗したかを示すために割り当てられることがありますが、両方とも同じ「離陸SCN」を取得します。

カレンダーと時計の組み合わせと同様に、SCNは通常の動作下で増加することが保証されています。 番号が連続しているという保証はありません(数字が欠落しています)。では、ORACLEデータベースでSCNに関するこの情報はどこで使用されていますか? まあ、ほとんどどこでも。 私たちが時間を私たちのすべての活動に関連付けるのと同じように、SCNはデータベースの機能のすべての部分にも関連付けられています。 たとえば、テーブルからデータを選択しようとすると、そのデータが一貫しているかどうかを確認するためにSCNが使用されます。 SCNは、データブロックのトランザクションヘッダーにもあります。 このSCNは、トランザクションが開始された時刻とコミットされた時刻を表します。 同様に、実行された変更ごとに、redoログのエントリが維持され、これらのエントリごとに、SCNがトランザクションの発生時刻を表すために使用されま

読み取り一貫性は、SCNを使用して、セッションの読み取り一貫性のあるデータ要求を完了できるように、ダーティバッファーにUndoを適用する時間を決定します。 よく知られているように、SCNはコミット操作ごとに増分されます。

SCNフォーマットと構造

SCNは、それに2つのコンポーネントを持つ膨大な数です:SCNベース&SCBラップ。

SCNは6バイト(48ビット)の数値です。 これらの48ビットのうち、SCN_WRAPは16ビット(2バイト)の数値であり、SCN_BASEは32ビット(4バイト)の数値です。 両方のBASE&WRAPは、SCNの増分を制御し、データベースがそれを使い果たさないようにするために使用されます。 Scn_BASEが40億の値に達し、SCN_BASEが0になると、SCN_WRAPは1ずつ増加します。Oracleバージョン12cでは、SCN番号は8バイトの番号です。

では、現在のSCN値をどのように表示しますか? 最も簡単な方法は、view V DATABASEデータベースを照会することです。 見てみましょう:

1
2
3
4
5

SQL>select current_scn from V database database;
CURRENT_SCN
———–
1123790

ご覧のとおり、そのSCNは数値として表示されます。 これは、回復、フラッシュバックなどを実行するステートメントでSCNの使用を容易にするため、これは良いことです。 必要に応じて、SCNを16進値に変換することもできます:

1
2
3
4
5

SQL>select to_char(‘1123790′,’xxxxxxxx’)scn_hex from dual;
SCN_HEX
———
1125位

次に、同じビューからの出力の例を示します。:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

SQL>select Current_scn from V database database;
———–
1178883
SQL> /
CURRENT_SCN
———–
1178885
SQL> /
CURRENT_SCN
———–
1178886

興味深いことに、このSCN値の増加はSCNの重要な側面を示しています。 実行ごとに、SCNの数が増加していることがわかります。 View V DATABASE DATABASEを照会することで、実際にはSCN番号のジャンプが発生しています。これらの両方の値を表示する最も簡単な方法は、SYS user-SMON_SCN_TIMEが所有する内部テーブルからのものです。 以下は同じ(11204)からの出力です。

1
2
3
4
5
6

SQL>SELECT Scn_Wrp,Scn_Bas,SCN from SMON_SCN_TIME where rownum<3;
SCN_WRP SCN_BAS SCN
———- ———- ———-
0 998222 998222
0 998406 998406

この表には、生成されたScnのエントリが含まれています。 これは、約5分単位でデータを格納し、データの5日間分を保持しています。 つまり、テーブルには約1440件のレコードが含まれています。 ストレージの増分が正確に5分ではないため、レコードの正確な数はわずかに異なります。

1
2
3
4
5

SQL>SELECT count(*)from SMON_SCN_TIME;
COUNT(*)from SMON_SCN_TIME;
COUNT(*)
———-
1494

10gより前のバージョンのOracleでは、SCNと時間の時間マッピングは+/-5分でしたが、10g以降では+/-3秒に変更されています。 これは内部表に格納されているため、Oracleはこの表からの情報に直接アクセスすることを許可しません。 それにアクセスするために、Apiが提供されます。 そのようなAPIの1つは、パッケージDBMS_FLASHBACKからのものです。GET_SYSTEM_CHANGE_NUMBERは、このテーブルからシーケンス番号にアクセスするために使用できます。 これの例を以下に示します(クエリのTom Kyteに感謝します):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

SQL>l
select Scn_To_Timestamp(SCN)ts,min(SCN),max(SCN)
from(
dbms_flashbackを選択します。get_system_change_number()-レベルSCN
デュアルから
レベル別に接続します<= 100
)
グループ化Scn_To_Timestamp(SCN)
•order by SCN_To_Timestamp(SCN)
SQL> /
TS MIN(SCN)MAX(SCN)
————————————————————————— ———- ———-
06-月-16 05.22.04.000000000PM1245323 1245323
06-月-16 05.22.07.000000000PM1245324 1245324
06-月-16 05.22.10.000000000 1245325 1245325
06-月-16 05.22.13.000000000午後1245326 1245326
06-月-16 05.22.16.000000000PM1245327 1245327
06-月-16 05.22.19.000000000PM1245328 1245328
06-月-16 05.22.22.000000000午後1245329 1245329
06-月-16 05.22.25.000000000午後1245330 1245330
06-月-16 05.22.28.000000000PM1245331 1245331
06-月-16 05.22.31.000000000午後1245332 1245332
06-月-16 05.22.34.000000000午後1245333 1245333
06-月-16 05.22.37.000000000 1245334 1245334
06-月-16 05.22.40.000000000午後1245335 1245335
06-月-16 05.22.43.000000000午後1245336 1245336
06-月-16 05.22.46.000000000午後1245337 1245337
06-月-16 05.22.49.000000000PM1245338 1245338
06-月-16 05.22.52.000000000午後1245339 1245339

10gより前のバージョンでSCNをTimestampにマップするにはどうすればよいですか?

この表には、SCN番号の増加率がなぜ増加するのかが示されていないことを覚えておくことが重要です。 少し書式設定すると、生成されたSCN番号のアイデアを得ることは可能ですが、その成長の原因はこの表からは明らかではありません。これを確認する別の方法は、ビュー V$LOG_HISTORYからです。 ビューにはFIRST_CHANGE#列とNEXT_CHANGE#列の形式でSCNが含まれており、これらの2つの列を通して、一定期間にわたってデータベースで生成されたScnの量を確認できます。 “First_change#は、このスレッドの指定されたシーケンス番号でアーカイブされたログファイルに表示される最低のSCNです。 “Next_change#”は、次のアーカイブ-ログ-ファイルに表示される最低のSCNです。

1
2
3
4
5
6
7
8
9
10
11
12

SQL>select thread#,first_change#,next_change#from V$log_history;
スレッド#FIRST_CHANGE#NEXT_CHANGE#
———- ————- ————
1 925702 958823
1 958823 959634
1 959634 972579
1 972579 993714
1 993714 1020785
1 1020785 1023738
1 1023738 1023873
1 1023873 1023995

SMON_SCN_TABLEと同様に、このテーブルビューからSCN番号の生成の増加の原因を見つけることはできません。 このビューは、単一インスタンスおよびRAC環境でも使用できます。

SCNはシーケンスを使用して増加しますか?

今では、SCNが絶えず増加している数字であるように見えることはかなり明白であるはずです。 興味深いことに、たとえそれが数値であっても、Oracleはそれを増やすためにシーケンスを使用しませんが、代わりに内部関数を使用します。 たとえば、SCN_BASEを増やすために、内部で使用される関数はKCMGAS(Get AND Advance SCN)です。 この関数は、新しいSCNが要求され、この関数の呼び出しが増加するたびに呼び出されます。 この関数と同様に、KCMGCS(Get Current SCN)は、現在のSCNとそれに使用される呼び出しを取得するために使用されます。 これらの関数呼び出しは、V$sysstatビューから見ることができます。 これらの統計の説明は、12.1リファレンスガイドに記載されています。

これらの呼び出しがSCN生成とどのようにリンクしているかを見てみましょう。 ここでは2つのセッションを使用しています–1つはビュー V$SYSSTATビューでの呼び出しを表示し、もう1つはSCNをプルするセッションです。

1
2
3
4
5
6
7
8
9
10

セッション-1
SQL>l
1*select CURRENT_SCN from V database database
SQL> /
CURRENT_SCN
———–
698815
SQL>

このSCNの場合、これらはV$sysstatの値でした:

1
2
3
4
5
6
7
8
9
10
11
12
13

SQL>l
1Vから名前、値を選択$sysstat
2*ここで、名前は’%calls to%’のようになります
SQL> /
名前の値
—————————————————————- ———-
kcmgcs427
へのコールkcmgrs0
へのコールkcmgas7272

へのコール

スナップショットSCNを取得するための呼び出し:kcmgss159790
SQL>

セッション1で現在のSCNを表示するクエリを発行しましょう:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

SQL> l
1* select current_SCN from V$database
SQL> /
CURRENT_SCN
———–
698815
SQL> /
CURRENT_SCN
———–
698889
SQL>

And ここでは、第二のセッション2の結果です:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

SQL> /
名前の値
—————————————————————- ———-
kcmgcs427
kcmgrs0
kcmgas7272
スナップショットSCNを取得するための呼び出し: 159790
> /
名前の値
—————————————————————- ———-
kcmgcsの呼び出し427
kcmgrsの呼び出し0
kcmgasの呼び出し7278
スナップショットSCNを取得するための呼び出し:KCMGSS159905
SQLの呼び出し159905
sqlの呼び出し159905
sql>

KCMGASへの呼び出しは、最後の値7272から7278に増加していることがわかります。 Oracleは番号の増加に順序を使用しないため、SCN番号が常に同じ順序で増加するという保証はありません。

結論

この記事では、SCNが何であるか、それを表示する方法、およびその要件を見てきました。 次の記事では、使用可能なScnの種類と、データベースでのScnの使用方法について説明します。 お楽しみに!

Write a Comment

メールアドレスが公開されることはありません。