天天看點

MySQL核心月報 2014.09-MySQL· 引擎差異·create_time in status

<b>背景</b>

  在mysql資料庫中,我們利用show table status指令可以得到表的狀态資訊,其中一列資訊為create_time,表示表的建立時間。對于不同的存儲引擎(如innodb/myisam/memory)我們都能得到create_time的數值。我們知道不同的存儲引擎表的檔案結構是不同的,是以實作表的建立時間create_time的機制也是不同的。下面着重探讨innodb和myisam在create_time上的差別。

<b>實驗</b>

  我們先做一些實驗來看看create_time的特點。在innodb引擎下建立一個表:

  在myisam引擎下也建立結構相同的一個表,如何可以更新create_time呢?我們在表上做以下3種操作,觀察create_time的變化。

  1. 對表進行增删改查操作,innodb、myisam的create_time不變。

  2. 對表進行alter table add column e varchar(32),innodb、myisam的create_time都更新到目前時間。

  3. 對表進行truncate table tb,innodb的create_time不變、myisam的create_time更新到目前時間。

  通過這些操作我們發現雖然2種引擎的内部實作不同,但前2種操作的現象是一樣的。對表進行增删改查并不重建表,是以create_time沒有更新。而alter table會更新create_time的原因是建立了一個原表的副本,在副本上實作alter table的功能(增加新列等等),最後删除原表,用副本替代原表。是以alter table下create_time是原表副本的建立時間。

  第3種操作,兩者的現象不同,這是為什麼呢?我們從代碼實作上分析原因。

<b>show table status的create_time的實作</b>

<dl><dd>1.innodb</dd></dl>

  在innodb下執行show table status獲得create_time來自于代碼:

  stats.create_time最終來自于以下代碼的statinfo變量:

  stat為c語言的庫函數,含義是将檔案路徑path定位的檔案(tablename.frm)的狀态資訊(包括了建立時間create_time)存入statinfo。

  通過對源碼的分析,我們知道在innodb引擎,create_time來源于.frm檔案的建立日期。在truncate table之後,innodb并沒有重建.frm檔案,是以show table status的create_time不變。

<dl><dd>2. myisam下</dd></dl>

  在myisam下執行show table status獲得create_time來自于代碼:

  對應的misam_info.create_time來源于:

  即myisam通過讀.myi檔案來獲得state資訊(包含了create_time),也就是說myisam下show table status的create_time最終來源于myi檔案中的state資訊。

  在myisam下,建立表(create table..)的create_time來源于以下代碼:

  myisam下的create_time來源于share變量,每次執行這部分代碼都會更新share.state.create_time。share是myisam引擎下的全局資訊,share.state區間資訊包含了鍵和資料檔案長度、時間戳(即create_time)和打開表的次數等等參數。share.state會記入myi檔案,代碼如下:

  執行truncate table也會經過以上2處的代碼,更新.myi檔案的state區間的資訊,然後show table status時讀入.myi檔案最新的state資訊(包含了create_time),是以create_time會被更新。

繼續閱讀