原創文章,轉載請標明原文鏈接:http://www.cnblogs.com/wingsless/p/5708992.html 昨天寫了有關事務日誌的一些基本點(http://www.cnblogs.com/wingsless/p/5705314.html),今天結合我最近的學習成果繼續總結事務日誌的 ...
原創文章,轉載請標明原文鏈接:http://www.cnblogs.com/wingsless/p/5708992.html
昨天寫了有關事務日誌的一些基本點(http://www.cnblogs.com/wingsless/p/5705314.html),今天結合我最近的學習成果繼續總結事務日誌的知識點。
三 日誌結構
我們都知道InnoDB最小的存儲單元叫做頁(page)或者塊(block),日誌系統也是如此,它是一個512位元組的塊,被這個參數定義:OS_FILE_LOG_BLOCK_SIZE。
一個塊肯定不會只有存儲數據這麼簡單,肯定是有頭部和尾部寫一些信息進去的,而這在代碼里很好找:
/* Offsets of a log block header */
#define LOG_BLOCK_HDR_NO 0 /* block number which must be > 0 and
is allowed to wrap around at 2G; the
highest bit is set to 1 if this is the
first log block in a log flush write
segment */
#define LOG_BLOCK_FLUSH_BIT_MASK 0x80000000UL
/* mask used to get the highest bit in
the preceding field */
#define LOG_BLOCK_HDR_DATA_LEN 4 /* number of bytes of log written to
this block */
#define LOG_BLOCK_FIRST_REC_GROUP 6 /* offset of the first start of an
mtr log record group in this log block,
0 if none; if the value is the same
as LOG_BLOCK_HDR_DATA_LEN, it means
that the first rec group has not yet
been catenated to this log block, but
if it will, it will start at this
offset; an archive recovery can
start parsing the log records starting
from this offset in this log block,
if value not 0 */
#define LOG_BLOCK_CHECKPOINT_NO 8 /* 4 lower bytes of the value of
log_sys->next_checkpoint_no when the
log block was last written to: if the
block has not yet been written full,
this value is only updated before a
log buffer flush */
#define LOG_BLOCK_HDR_SIZE 12 /* size of the log block header in
bytes */
/* Offsets of a log block trailer from the end of the block */
#define LOG_BLOCK_CHECKSUM 4 /* 4 byte checksum of the log block
contents; in InnoDB versions
< 3.23.52 this did not contain the
checksum but the same value as
.._HDR_NO */
#define LOG_BLOCK_TRL_SIZE 4 /* trailer size in bytes */
畫張圖:
頭部長度是12位元組,尾部長度是4位元組,代碼中標明瞭頭尾的長度,其他的都是偏移量,因此每個部分的長度也就是下一個偏移量減去當前值。這麼算下來,實際上能存儲數據的部分只有496位元組了,這部分網上很多資料里都叫做log data,我在這裡也這麼叫吧。
頭部里我覺得有意思的一個地方是這個:LOG_BLOCK_FIRST_REC_GROUP,這是block里第一個日誌的起始位置的偏移量。例如一個日誌有500位元組,那麼寫完了一個塊之後,還有4個位元組會被寫在下一個塊里,此時又有一個100位元組的頁寫到了第二個block里(起個名字叫log2吧),於是第二個塊里變成了這種情況:
第二個日誌從16位置開始,到116位置結束,這個時候LOG_BLOCK_FIRST_REC_GROUP值會寫什麼呢?很顯然是16,因為log2才是這個block里的第一個頁。
知道了日誌結構,其實只是瞭解redo log的第一步,因為redo log是InnoDB實現事務的重要手段,裡面的水很深,我也會不斷地把我的學習心得寫在這裡,並不斷地補充寫好的東西。
原創文章,轉載請標明原文鏈接:http://www.cnblogs.com/wingsless/p/5708992.html