Consistent Gets,Physical Reads和DB Block Gets的解釋(轉)
在Oracle的文件中有這樣的解釋:
db block gets:Number of times a CURRENT block was requested.
consistent gets:Number of times a consistent read was requested for a block.
physical reads:Total number of data blocks read from disk. This number equals the value of "physical reads direct" plus all reads into buffer cache.
針對以上3個概念進行的說明解釋及關係如下:
1、DB Block Gets(當前請求的塊數目)
當前模式塊意思就是在操作中正好提取的塊數目,而不是在一致性讀的情況下而產生的塊數。正常的情況下,一個查詢提取的塊是在查詢開始的那個時間點上存在的資料塊,當前塊是在這個時刻存在的資料塊,而不是在這個時間點之前或者之後的資料塊數目。
2 、Consistent Gets(資料請求總數在回滾段Buffer中的資料一致性讀所需要的資料塊)
這裡的概念是在處理你這個操作的時候需要在一致性讀狀態上處理多少個塊,這些塊產生的主要原因是因為由於在你查詢的過程中,由於其他會話對資料塊進行操作,而對所要查詢的塊有了修改,但是由於我們的查詢是在這些修改之前呼叫的,所以需要對回滾段中的資料塊的前映像進行查詢,以保證資料的一致性。這樣就產生了一致性讀。 不過精確翻譯來說,前兩個不是塊數而是IO請求次數,不過對於這兩者應該是一次讀一塊的。
3 Physical Reads(物理讀)
就是從磁碟上讀取資料塊的數量,其產生的主要原因是:
在資料庫快取記憶體中不存在這些塊
全表掃描
磁碟排序
它們三者之間的關係大致可概括為:
邏輯讀指的是Oracle從記憶體讀到的資料塊數量。一般來說是'consistent gets' + 'db block gets'。當在記憶體中找不到所需的資料塊的話就需要從磁碟中獲取,於是就產生了'phsical reads'。
DB Block Gets. Number of times a CURRENT block was requested.
Current mode blocks are retrieved as they exist right now, not in a consistent read fashion. Normally, blocks retrieved for a query are retrieved as they existed when the query began. Current mode blocks are retrieved as they exist right now, not from a previous point in time. During a SELECT, you might see current mode retrievals due to reading the data dictionary to find the extent information for a table to do a full scan (because you need the "right now" information, not the consistent read). During a modification, you will access the blocks in current mode in order to write to them.
Consistent Gets. Number of times a consistent read was requested for a block.
This is how many blocks you processed in "consistent read" mode. This will include counts of blocks read from the rollback segment in order to roll back a block. This is the mode you read blocks in with a SELECT, for example. Also, when you do a searched UPDATE/DELETE, you read the blocks in consistent read mode and then get the block in current mode to actually do the modification.
DB Block Gets. 當前塊被請求的次數。
當存在時,當前模式塊將被立即檢索,而不會以一致讀的方式檢索。通常,查詢檢索的塊如果在查詢開始時存在,它們就被檢索。當前模式塊如果存在就立即被檢索,而不是從一個以前的時間點檢索。在一個SELECT期間,你可以看到當前模式檢索,因為對於需要進行全面掃描的表來說,需要讀資料字典來找到範圍資訊(因為你需要"立即"資訊,而不是一致讀)。在修改期間,為了向塊中寫入內容,你要以當前模式訪問塊。
Consistent Gets. 對於一個塊一致讀被請求的次數。
這是你以"一致讀"模式處理的塊數。為了回滾一個塊,這將包括從回滾段讀取的塊的數目。例如,這是你在SELECT語句中讀取塊的模式。當你進行一個指定的UPDATE/DELETE操作時,你也以一致讀模式讀取塊,然後以當前模式獲得塊以便實際進行修改。
引自(biti_rainy):
db block gets
當前的block是什麼資料,那麼讀到的就是什麼資料 比如資料是session自己產生的 在dml的時候讀block中 資料 也必須是當前block的 而在查詢中,block中資料如果是別人更改過的,需要去回滾段中讀取變化前的資料,這時產生consistent reads 。這個叫 一致讀,也就是塊處於 query mode 下 但是 consistent gets 是在query mode下的讀,即使沒有產生 consistent reads ,但是也叫 consistenet gets
db block gets : current mode , 不管這個塊上的資料是否可能存在before image ,也就是說不管是否存在回滾中的資料可以回滾,只看見當前最新塊的資料,即使別人正在更新,也看見別人更新狀態的資料,比如dml的時候就不需要看見別人更改前的資料,而是看見正在更改的,當然同時,若操作相同資料則被lock住。也就是說一次查詢中看見的資料可能不在同一個時間點上。
consistent gets : 看見的資料是查詢開始的時間點的,所以若存在block在查詢開始後發生了變化的情況,則必須產生 before image 然後讀資料,這就是一致讀的含義。
下面這段話比較重要:
db block gets 僅僅表達,即使有回滾段內容也不用去產生before image consistent get 僅僅表達,如果有回滾段內容並且block的變化的提交時間點晚於查詢開始的時間點就要產生 before image ,但只有滿足這個條件的時候才產生(回滾),並不是說一定要回滾 或者 是從回滾段獲取來的資料
查詢就是表示 consistent gets (query mode),因為查詢要保證所獲取的資料的時間點的一致性,所以叫一致讀,即使是從當前 buffer 獲得的資料,也叫 consistent gets ,這僅僅表達一種模式一種期望,並不表示真實的是從 當前buffer 獲得還是從回滾段獲取資料產生的 bufore image ,還有什麼問題嗎?
如果是 db block gets , current mode ,比如一個大的dml,當dml 開始更新一個非常大的表後,這個表更新的過程中,有一個程式去把該表末尾的一個記錄更新了,然後這個大更新抵達該記錄的時候會被阻塞的,若該程式事物提交,則大更新會覆蓋該事務的更新,也就是說,這個大更新所看見的資料是當前的,不具有時間點的一致性,所以叫 current mode
把問題簡單並粗略化:
db block gets 看作是 DML 的讀取 ,其看到的資料可能不具有時間點的一致性。 consistent gets 是 select 這樣的讀取,無論是否來自回滾段的資料都是 consistents gets ,僅僅表示其看到的資料具有時間點上的一致性。
db block gets : number of data blocks read in CURRENT mode ie) not in a read consistent fashion, but the current version of the data blocks. 產生db_block_gets的主要方式: 1.DML like Update, Delete will need to access the blocks in the current mode for modification. 2.Most data dictionary calls are done in CURRENT mode. 3.Buffers are often retrieved in current mode for INSERT, UPDATE, and DELETE, and SELECT FOR UPDATE statements. Blocks must be requested in current mode in order to be changed. 4.Also certain classes of blocks, like segment header blocks are always requested in current mode. 5.this will happen when you're doing a FULL TABLE SCAN on a table or a FAST FULL SCAN on an index. In those cases, the segment header is read (usually multiple times for some unknown reason) in current mode.
在current mode模式下產生的對block的訪問叫db block gets,這些block在SGA中,不需要訪問硬碟。 db_block_gets counts logical reads in CURRENT mode in the buffer cache and also includes direct read blocks (sort-on-disk) blocks. consistent gets : number of data blocks accessed in READ CONSISTENT mode. When a block is requested in consistent mode, if any changes have been committed or made to that block since the requesting statement (or transaction) began, then they must be rolled back for the purposes of the read, to give a consistent view of the data at that time.(當資料庫是在consistent mode模式下被請求的,則假如該資料塊的資料修改是在查詢語句發出之後被提交的,則此查詢語句讀到該資料塊時,還必須為本次查詢將資料回滾,得到查詢語句發出時該資料塊的值,以便給查詢給出一個與該查詢有關的所有資料塊的一致性檢視,這也就是oracle所說的一致性讀) In order to maintain statement level read consistency, Oracle has to read the blocks in a consistent fashion(as of the snapshot SCN) and hence may fetch from rollback segments , which is also added to this statistic. Buffers are usually retrieved in consistent mode for queries. 如普通的select語句、索引訪問而引起的將資料讀入到buffer中(也可能為physical read)或直接從buffer中讀資料。注意,DML語句也能引起consistent gets,如update tab1 set col_b='Hello world' where col_a=1;,因為該語句需要找到需要被修改的所有資料塊,在找資料塊的過程中就會引起consistent gets。 在Read consistent mode模式下產生的對block的訪問叫consistent gets。
Session logical read is: The sum of "db block gets" plus "consistent gets".
db_block_changes: db_block_changes counts modifications made to CURRENT blocks 'db block changes' = changes made to current blocks under LOGING ( UPDATE, INSERT, DELETE) + changes made to SORT blocks ( NOLOGING).
'consistent changes' : changes made to block for CONSISTENT READ and changes made to SORT blocks
physical reads : Physical( disk and/or filesystem page cache) reads. Basically those that cannot be satisfied by the cache and those that are direct reads. Total number of data blocks read from disk. This number equals the value of "physical reads direct" (direct from disk, excludes buffer cache) plus all reads into buffer cache.
physical writes : Total number of data blocks written to disk. This number equals the value of "physical writes direct" (Number of writes directly to disk, bypassing the buffer cache as in a direct load operation) plus all writes from buffer cache.
要注意Oracle 的physical read 與 physical writes並不總是等於硬碟真正意義上的物理讀與物理寫,因為現在都存在作業系統快取記憶體與磁碟子系統快取記憶體,這樣即使I/O沒有被實際寫入磁碟,作業系統I/O子系統或磁碟系統也會確認為一個成功的I/O,所以ORACLE 的physical read 與 physical writes並不是物理上發生讀寫的次數。
redo block size: redo block size is platform. specific. There is a method to determine the size by dumping the redo header, refer to note 154864.1. Redo blocks written does not include archive writes or multiplexed writes.
redo entries: The redo log buffer is a circular buffer in the SGA that holds information about changes made to the database. This information is stored in redo entries. Redo entries contain the information necessary to reconstruct, or redo, changes made to the database . Redo entries are used for database recovery, if necessary. Redo entries are copied by Oracle server processes from the user's memory space to the redo log buffer in the SGA. (this copy is what the statistic represents).
db block changes包含dml修改的block,也包含為實現rollback功能而修改的block,但是不包含為實現redo功能而修改的block。
the number of blocks visited = consistent gets + db block gets the number of blocks visited相當與logical read,即從記憶體中都資料塊的次數。
做一個測試: 用下面語句取得統計資訊:
select sid,value,name from v$sesstat x,v$statname y
where x.statistic#=y.statistic#
and ( name like '%db block%gets%' or name like '%consistent%gets%'
or name like '%consistent%change%' or name like '%db block%change%'
or name like '%physical writes%' or name like '%physical reads%'
or name = 'index fetch by key' or name like '%read%' or name like '%scans%'
)
and sid = 12 and value > 0
order by value;
Lets take an example to illustrate relationship between 'db block gets' and 'db block changes' .
create table toto( i number);
select sid,value,name from v$sesstat x,v$statname y
where x.statistic#=y.statistic#
and ( name like '%db block%gets%' or name like '%consistent%gets%'
or name like '%consistent%change%' or name like '%db block%change%'
or name like '%physical writes%' or name like '%physical reads%'
or name = 'index fetch by key' or name like '%read%' or name like '%scans%'
)
and sid = 11 and value > 0
order by value;
SID VALUE NAME
---------- ---------- ------------------------------
11 95 db block gets
11 108 db block changes
11 0 consistent changes
select count(*) from toto x, toto y, toto z;
COUNT(*)
----------
0
select sid,value,name from v$sesstat x,v$statname y
where x.statistic#=y.statistic#
and ( name like '%db block%gets%' or name like '%consistent%gets%'
or name like '%consistent%change%' or name like '%db block%change%'
or name like '%physical writes%' or name like '%physical reads%'
or name = 'index fetch by key' or name like '%read%' or name like '%scans%'
)
and sid = 11 and value > 0
order by value
SID VALUE NAME
---------- ---------- ------------------------------
11 98 db block gets
11 108 db block changes
11 0 consistent changes
Here we can see that a select increment 'db block gets' by 3 and 'db block changes' remains the same : this illustrates that we can get block in current mode ( to have most recent information) without performing any changes." – 這也可以作為current mode的定義。
下面這段寫的非常好,如果上面的還是不理解,則需要仔細的看一下!
A 'consistent get' is your server process telling the database "I need this dba (data block address) consistent with the point in time represented by this SCN, x."
So, lots of things can happen here. First, Oracle will look in the buffer cache for a CR (consistent read) buffer of the block that's consistent w/ the requested SCN. It may find it, if it does, that's counted as a 'consistent get' and either a 'consistent gets - no work' or 'consistent gets - cleanouts only', depending on whether the block needed to be cleaned out. (See V$SYSSTAT/V$SESSTAT for the statistics.) If it doesn't, it may take an existing CR buffer and roll it back further, or it may clone the current block and roll it back. If it needs to apply rollback (aka undo) then it will increment 'consistent gets' and either 'consistent gets - rollbacks only' or 'consistent gets - cleanouts and rollbacks'.
So, each 'consistent get' is your server process successfully getting access to the contents of a dba consistent w/ a particular SCN. This number should represent the number of buffer gets required to satisfy a particular query.
Now, 'db block gets'. A 'db block get' is a copy of the 'current mode block'. That is, the data in the block, as it exists currently, or at this point in time. Note that while multiple CR copies of a block may exist in the buffer cache, there can only ever be one current mode copy of a block in the buffer cache at any one time. (RAC is a special case, w/ shared current and exclusive current, but I'm not going to get into that here.) So, a 'db block get' is a buffer get in current mode. 'db block gets' are usually associated w/ DML, and in that scenario, will implicitly lock one or more rows in that block. Also, there is a notable case where db block gets can occur with a select statement. That will happen when you're doing a FULL TABLE SCAN on a table or a FAST FULL SCAN on an index. In those cases, the segment header is read (usually multiple times for some unknown reason) in current mode.
Next, 'physical reads': A physical read will occur any time a consistent get or a db block get goes looking for block and can't find it in the buffer cache. So, for each block read from disk, physical reads will be incremented. Gets which result in physical reads are counted both as as get and as a read in the statistics. So, if you do 10 consistent gets and 5 of them require physical reads, you should see consistent gets incremented by 10 and physical reads incremented by 5.
Now, what's up w/ arraysize? Well, arraysize is the client side setting for SQL*Plus specifying the size of the array that will receive result sets. The default, as you learned, is 15. Now, suppose you have a table where there are 30 records per block, and 3,000 rows in the table. But, your arraysize is 15. So, your server process will get the first 15 rows, and return them from the first block buffer. Now, for the next 15, you need to get that same block again, for rows 16-30. So, you need to do two buffer gets per block to get all the rows. For a 3,000 row table, you'll do (approximately) 3,000/15 = 200 buffer gets. If you change your arraysize to 30, you can get away w/ visitng each block only once and do 3,000/30 = 100 buffer gets.
So, consider that even after you've optimized a particular SQL statement, if the arraysize is too small, you're going to force your server process to do excess database calls (FETCH calls), and extra buffer gets as well. This can best be illustrated with a test similar to what you did, but try looking at the raw trace file for FETCH calls. The number of FETCH calls ought to be very close to (number of rows returned / arraysize). The 'r=xxx' in the FETCH call data in the trace file is the number of rows returned, which is probably what your arraysize is set to.
So, db block gets, consistent gets, and physical reads are all measured in buffers (or blocks). If the same block is requested multiple times, it will be counted that many times in these statistics. Oracle will always access data from the buffer cache by the buffer. All 'get' operations are by the buffer, never by row. After the buffer is 'gotten', Oracle parses the block to get the data for the relevant rows.
When a "consistent get" is done, this doesn't necessarily mean that Oracle had to do any rollback/undo of DML in order to get the consistent image. Rather, it just means that Oracle requested a copy of the block as of the point in time that the query was started (a "consistent snapshot"). So, I believe it is quite normal to have many, many consistent gets even if there is NO DML occuring.
My Conclusion:
1. db block gets :
dml 一定會在current mode 以後去request新的塊, select 有時也會因為要做order by 如果需要的PGA很高會去使用DISK 排序,從而會需要使用多餘的DB BLOCK GETS.
2. consistent gets:
我對這個指標的理解是, 如何需要使用到記憶體的讀取都是一致性讀的範疇, 包括fetch, fetch 一次算是一次 consistent get. 一般而言consistent gets包含了對記憶體, 資料字典, 以及資料在快取中的分批讀取的次數.
還有一種比較特殊的情況,
就是X$表,或者又X$構建出的V$試圖,這個表很有意思, 是一個虛表, 同一條SQL比如select * from x$ksupr, 或者select* from x$dual, 執行了一次,
第二次便不再需要consistent gets, 這我估計是由於X$表的這種虛表的特殊性質造成的。使用實表多多少少需要因為資料字典而產生consistent gets.
而至的注意的是, 在做select * from x$ksupr connect by level <= 2;的時候db block gets不再為0(這個也很好理解).
使用管道FUNCTION來模擬了一個table查詢, 似乎也是一樣的。同一句SQL第一次有很多consistent gets第2次為0.
關於x$的這個consistent gets的特殊情況放著也許突然某個概念可以解決這個問題。
3. logical reads:
logical reads = db block gets + consistent gets
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29067253/viewspace-2136504/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- db block gets 與 consistent read getsBloC
- C語言關於指標,gets()和gets_s()函式的理解C語言指標函式
- getc();fgetc();getchar();gets();fgets();
- [20190416]檢視shared latch gets的變化.txt
- Oracle一致性讀(consistents gets)Oracle
- [20210208][20200426]檢視shared latch gets的變化.txt
- cell single block physical read等待事件BloC事件
- 緩衝區溢位漏洞那些事:C -gets函式函式
- C/C++輸入函式 scanf() gets() getline() cin.getline() cin.get() getchar()C++函式
- 2.6.5.1 DB_BLOCK_SIZE 初始化引數BloC
- Unused Block Compression和Null Block CompressionBloCNull
- display:block display:inline-block 的屬性、呈現和作用BloCinline
- iOS-block迴圈引用詳解和應用iOSBloC
- Oracle 11.2.0.4 physical dataguard和snapshot dataguard切換Oracle
- c++ -- &和 * 的解釋C++
- SUPTOOL: BBED - 7.3.2+ Database Block Editor(轉)DatabaseBloC
- Block學習①--block的本質BloC
- 2018-09-13 批量md5sum 檢測ENA和NCBI reads
- consistent hash 原理,優化及實現優化
- Oracle一致性讀(Consistent Read)的原理Oracle
- CSS佈局(inline和block)CSSinlineBloC
- 堆和棧的解釋和區別
- Oracle Physical Database LimitsOracleDatabaseMIT
- Block迴圈引用的三種解決方式BloC
- Block學習②--block的變數捕獲BloC變數
- iOS block巢狀block中weakify的使用iOSBloC巢狀
- python中的一個現象,db.commit和db.commit()PythonMIT
- C語言——常用標準輸入輸出函式 scanf(), printf(), gets(), puts(), getchar(), putchar(); 字串拷貝函式 strcpy(), strncpy(), strchr(), strstr()函式用法特點C語言函式字串
- [讀書筆記] Ruby 中的 Block 和 Iterator筆記BloC
- CSS 中的 float、BFC、position 和 inline-blockCSSinlineBloC
- 網路回撥:Block和Delegate的對比BloC
- 詳解GPFS檔案系統架構、組網和Building Block架構UIBloC
- 微軟釋出Azure Cosmos DB產品以及新的物聯網解決方案微軟
- Hyperf 如何快速釋放 DB 連線
- Performing a Failover to a Physical Standby DatabaseORMAIDatabase
- Physical Samples Management in SAP QM
- iOS | 用於解決迴圈引用的block timeriOSBloC
- HBase查詢優化之Short-Circuit Local Reads優化UI
- Block的型別BloC型別