Oracle事务的完整流程的分析

Jun 07, 2016 pm 05:04 PM
データベース

Oracle服务进程如何处理用户进程的请求服务器进程在完成用户进程的请求过程中,主要完成如下7个任务:0.sql语句的解析1.数据块的

Oracle服务进程如何处理用户进程的请求服务器进程在完成用户进程的请求过程中,主要完成如下7个任务:

0.sql语句的解析

1.数据块的读入db buffer

2.记日志

3.为事务建立回滚段

4.本事务修改数据块

5.放入dirty list

6.用户commit或rollback

oracle服务进程如何处理用户进程的请求服务器进程在完成用户进程的请求过程中,主要完成如下7个任务:

0.sql语句的解析

1.数据块的读入db buffer(写入数据缓存)

2.记日志

3.为事务建立回滚段

4.本事务修改数据块

5.放入dirty list

6.用户commit或rollback

 

0.sql语句的解析

下面要讲oracle服务器进程如可处理用户进程的请求,当一用户进程提交一个sql时:update temp set a=a*2;首先oracle服务器进程从用户进程把信息接收到后,在PGA中就要此进程分配所需内存,存储相关的信息,如在会话内存存储相关的登录信息等;服务器进程把这个sql语句的字符转化为ASCII等效数字码,接着这个ASCII码被传递给一个HASH函数,并返回一个hash值,然后服务器进程将到shared pool中的library cache中去查找是否存在相同的hash值,如果存在,服务器进程将使用这条语句已高速缓存在SHARED POOL的library cache中的已分析过的版本来执行,如果不存在,服务器进程将在CGA中,配合UGA内容对sql,进行语法分析,首先检查语法的正确性,接着对语句中涉及的表,索引,视图等对象进行解析,并对照数据字典检查这些对象的名称以及相关结构,并根据ORACLE选用的优化模式以及数据字典中是否存在相应对象的统计数据和是否使用了存储大纲来生成一个执行计划或从存储大纲中选用一个执行计划,然后再用数据字典核对此用户对相应对象的执行权限,最后生成一个编译代码。ORACLE将这条sql语句的本身实际文本、HASH值、编译代码、与此语名相关联的任何统计数据和该语句的执行计划缓存在SHARED POOL的library cache中。服务器进程通过SHARED POOL 锁存器(shared pool latch)来申请可以向哪些共享PL/SQL区中缓存这此内容,也就是说被SHARED POOL锁存器锁定的PL/SQL区中的块不可被覆盖,因为这些块可能被其它进程所使用。在SQL分析阶段将用到LIBRARY CACHE,从数据字典中核对表、视图等结构的时候,需要将数据字典从磁盘读入LIBRARY CACHE,因此,在读入之前也要使用LIBRARY CACHE锁存器(library cache pin,library cache lock)来申请用于缓存数据字典。

 

到现在为止,这个sql语句已经被编译成可执行的代码了,但还不知道要操作哪些数据,所以服务器进程还要为这个sql准备预处理数据。

 

 

1.数据块的读入db buffer

Oracle处理数据,都需要把数据读取到内存中(即db buffer中),首先服务器进程要判断所需数据是否在db buffer存在,如果存在且可用,则直接获取该数据,同时根据LRU算法增加其访问计数;如果buffer不存在所需数据,则要从数据文件上读取。首先服务器进程将在表头部请求TM锁(保证此事务执行过程其他用户不能修改表的结构),如果成功加TM锁,再请求一些行级锁(TX锁),如果TM、TX锁都成功加锁,那么才开始从数据文件读数据,在读数据之前,要先为读取的文件准备好buffer空间。服务器进程需要扫面LRU list寻找free db buffer,,扫描的过程中,服务器进程会把发现的所有已经被修改过的db buffer注册到dirty list中,

 

这些dirty buffer会通过dbwr的触发条件,随后会被写出到数据文件,找到了足够的空闲buffer,就可以把请求的数据行所在的数据块放入到db buffer的空闲区域或者覆盖已经被挤出LRU list的非脏数据块缓冲区,并排列在LRU list的头部,也就是在数据块放入DB BUFFER之前也是要先申请db buffer中的锁存器,成功加锁后,才能读数据到db buffer。

 

2.记日志

 

现在数据已经被读入到db buffer了,现在服务器进程将该语句所影响的并被读入db buffer中的这些行数据的rowid及要更新的原值和新值及scn等信息从PGA逐条的写入redo log buffer中。在写入redo log buffer之前也要事先请求redo log buffer的锁存器,成功加锁后才开始写入,当写入达到redo log buffer大小的三分之一或写入量达到1M或超过三秒后或发生检查点时或者dbwr之前发生,都会触发lgwr进程把redo log buffer的数据写入磁盘上的redo file文件中(这个时候会产生log file sync等待事件),已经被写入redo file的redo log buffer所持有的锁存器会被释放,并可被后来的写入信息覆盖,redo log buffer是循环使用的。Redo file也是循环使用的,当一个redo file 写满后,lgwr进程会自动切换到下一redo file(这个时候可能出现log file switch(checkpoint complete)等待事件)。如果是归档模式,归档进程还要将前一个写满的redo file文件的内容写到归档日志文件中(这个时候可能出现log file switch(archiving needed))。

 

3.为事务建立回滚段

在完成本事务所有相关的redo log buffer之后,服务器进程开始改写这个db buffer的块头部事务列表并写入scn,然后copy包含这个块的头部事务列表及scn信息的数据副本放入回滚段中,将这时回滚段中的信息称为数据块的“前映像“,这个”前映像“用于以后的回滚、恢复和一致性读。(回滚段可以存储在专门的回滚表空间中,这个表空间由一个或多个物理文件组成,并专用于回滚表空间,回滚段也可在其它表空间中的数据文件中开辟。)

 

4.本事务修改数据块

准备工作都已经做好了,现在可以改写db buffer块的数据内容了,并在块的头部写入回滚段的地址。

 

5. 放入dirty list

如果一个行数据多次update而未commit,则在回滚段中将会有多个“前映像“,除了第一个”前映像“含有scn信息外,其他每个“前映像“的头部都有scn信息和“前前映像”回滚段地址。一个update只对应一个scn,然后服务器进程将在dirty list中建立一条指向此db buffer块的指针(方便dbwr进程可以找到dirty list的db buffer数据块并写入数据文件中)。

 

接着服务器进程会从数据文件中继续读入第二个数据块,重复前一数据块的动作,数据块的读入、记日志、建立回滚段、修改数据块、放入dirty list。当dirty queue的长度达到阀值(一般是25%),服务器进程将通知dbwr把脏数据写出,就是释放db buffer上的锁存器,腾出更多的free db buffer。前面一直都是在说明oracle一次读一个数据块,其实oracle可以一次读入多个数据块(db_file_multiblock_read_count来设置一次读入块的个数)

 

说明: 

 

 

在预处理的数据已经缓存在db buffer或刚刚被从数据文件读入到db buffer中,就要根据sql语句的类型来决定接下来如何操作。

 

1>.  如果是select语句,则要查看db buffer块的头部是否有事务,如果有事务,则从回滚段中读取数据;如果没有事务,则比较select的scn和db buffer块头部的scn,如果前者小于后者,仍然要从回滚段中读取数据;如果前者大于后者,说明这是一非脏缓存,可以直接读取这个db buffer块的中内容。

 

2>.  如果是DML操作,则即使在db buffer中找到一个没有事务,而且SCN比自己小的非脏缓存数据块,服务器进程仍然要到表的头部对这条记录申请加锁,加锁成功才能进行后续动作,如果不成功,则要等待前面的进程解锁后才能进行动作(这个时候阻塞是tx锁阻塞)。 

 

6.用户commit或rollback 

 

到现在为止,数据已经在db buffer或数据文件中修改完成,但是否要永久写到数文件中,要由用户来决定commit(保存更改到数据文件)和rollback(撤销数据的更改),下面来看看在commit和rollback时,oracle都在做什么。

linux

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Go 言語はデータベースの追加、削除、変更、クエリ操作をどのように実装しますか? Go 言語はデータベースの追加、削除、変更、クエリ操作をどのように実装しますか? Mar 27, 2024 pm 09:39 PM

Go 言語は、効率的かつ簡潔で習得が容易なプログラミング言語であり、同時プログラミングやネットワーク プログラミングに優れているため、開発者に好まれています。実際の開発ではデータベースの操作が欠かせませんが、今回はGo言語を使ってデータベースの追加・削除・変更・クエリ操作を実装する方法を紹介します。 Go 言語では、データベースを操作するために通常、よく使用される SQL パッケージや gorm などのサードパーティ ライブラリを使用します。ここでは SQL パッケージを例として、データベースの追加、削除、変更、クエリ操作を実装する方法を紹介します。 MySQL データベースを使用していると仮定します。

Hibernate はポリモーフィック マッピングをどのように実装しますか? Hibernate はポリモーフィック マッピングをどのように実装しますか? Apr 17, 2024 pm 12:09 PM

Hibernate ポリモーフィック マッピングは、継承されたクラスをデータベースにマップでき、次のマッピング タイプを提供します。 join-subclass: 親クラスのすべての列を含む、サブクラス用の別個のテーブルを作成します。 table-per-class: サブクラス固有の列のみを含む、サブクラス用の別個のテーブルを作成します。 Union-subclass: join-subclass と似ていますが、親クラス テーブルがすべてのサブクラス列を結合します。

iOS 18では、紛失または破損した写真を復元するための新しい「復元」アルバム機能が追加されます iOS 18では、紛失または破損した写真を復元するための新しい「復元」アルバム機能が追加されます Jul 18, 2024 am 05:48 AM

Apple の最新リリースの iOS18、iPadOS18、および macOS Sequoia システムでは、さまざまな理由で紛失または破損した写真やビデオをユーザーが簡単に回復できるように設計された重要な機能が写真アプリケーションに追加されました。この新機能では、写真アプリのツール セクションに「Recovered」というアルバムが導入され、ユーザーがデバイス上に写真ライブラリに含まれていない写真やビデオがある場合に自動的に表示されます。 「Recovered」アルバムの登場により、データベースの破損、カメラ アプリケーションが写真ライブラリに正しく保存されない、または写真ライブラリを管理するサードパーティ アプリケーションによって失われた写真やビデオに対する解決策が提供されます。ユーザーはいくつかの簡単な手順を実行するだけで済みます

HTML がデータベースを読み取る方法の詳細な分析 HTML がデータベースを読み取る方法の詳細な分析 Apr 09, 2024 pm 12:36 PM

HTML はデータベースを直接読み取ることはできませんが、JavaScript と AJAX を通じて実現できます。この手順には、データベース接続の確立、クエリの送信、応答の処理、ページの更新が含まれます。この記事では、JavaScript、AJAX、および PHP を使用して MySQL データベースからデータを読み取る実践的な例を示し、クエリ結果を HTML ページに動的に表示する方法を示します。この例では、XMLHttpRequest を使用してデータベース接続を確立し、クエリを送信して応答を処理することで、ページ要素にデータを埋め込み、データベースを読み取る HTML の機能を実現します。

PHP で MySQLi を使用してデータベース接続を確立するための詳細なチュートリアル PHP で MySQLi を使用してデータベース接続を確立するための詳細なチュートリアル Jun 04, 2024 pm 01:42 PM

MySQLi を使用して PHP でデータベース接続を確立する方法: MySQLi 拡張機能を含める (require_once) 接続関数を作成する (functionconnect_to_db) 接続関数を呼び出す ($conn=connect_to_db()) クエリを実行する ($result=$conn->query()) 閉じる接続 ( $conn->close())

PHP でデータベース接続エラーを処理する方法 PHP でデータベース接続エラーを処理する方法 Jun 05, 2024 pm 02:16 PM

PHP でデータベース接続エラーを処理するには、次の手順を使用できます。 mysqli_connect_errno() を使用してエラー コードを取得します。 mysqli_connect_error() を使用してエラー メッセージを取得します。これらのエラー メッセージをキャプチャしてログに記録することで、データベース接続の問題を簡単に特定して解決でき、アプリケーションをスムーズに実行できるようになります。

PHP を使用してデータベース内の中国語の文字化けを処理するためのヒントと実践 PHP を使用してデータベース内の中国語の文字化けを処理するためのヒントと実践 Mar 27, 2024 pm 05:21 PM

PHP は Web サイト開発で広く使用されているバックエンド プログラミング言語であり、強力なデータベース操作機能を備えており、MySQL などのデータベースとの対話によく使用されます。ただし、中国語の文字エンコーディングは複雑であるため、データベース内で中国語の文字化けを処理するときに問題が発生することがよくあります。この記事では、文字化けの一般的な原因、解決策、具体的なコード例を含め、データベース内の中国語の文字化けを処理するための PHP のスキルと実践方法を紹介します。文字化けの一般的な原因は、データベースの文字セット設定が正しくないことです。データベースの作成時に、utf8 や u などの正しい文字セットを選択する必要があります。

Golangでデータベースコールバック関数を使用するにはどうすればよいですか? Golangでデータベースコールバック関数を使用するにはどうすればよいですか? Jun 03, 2024 pm 02:20 PM

Golang でデータベース コールバック関数を使用すると、次のことを実現できます。 指定されたデータベース操作が完了した後にカスタム コードを実行します。追加のコードを記述せずに、個別の関数を通じてカスタム動作を追加します。コールバック関数は、挿入、更新、削除、クエリ操作に使用できます。コールバック関数を使用するには、sql.Exec、sql.QueryRow、または sql.Query 関数を使用する必要があります。

See all articles