關(guān)于MYSQLflushtable的作用

關(guān)于MySQL flush table的作用

水平有限,還待學(xué)習(xí)。如有錯(cuò)誤,請(qǐng)指正。

先給出官方文檔:
? FLUSH TABLES
Closes all open tables, forces all tables in use to be closed, and flushes the query cache. FLUSH
TABLES also removes all query results from the query cache, like the RESET QUERY CACHE
statement.
In MySQL 5.6, FLUSH TABLES is not permitted when there is an active LOCK TABLES ... READ.
To flush and lock tables, use FLUSH TABLES tbl_name... WITH READ LOCK instead.
? FLUSH TABLES tbl_name[, tbl_name] ...
With a list of one or more comma-separated table names, this statement is like FLUSH TABLES with
no names except that the server flushes only the named tables. No error occurs if a named table
does not exist.


描述說的是FLUSH TABLE就是關(guān)閉打開的表,并且刷新查詢緩存 ,如果有LOCK TABLES ... READ存在則不允許,
在如果需要同時(shí)進(jìn)行flush和實(shí)現(xiàn)READ LOCK 可以使用FLUSH TABLES tbl_name... WITH READ LOCK;




這里的關(guān)閉打開的表,一定會(huì)讓會(huì)感到困惑,什么是打開的表,
關(guān)閉打開的表又是什么意思,同時(shí)關(guān)閉打開的表需要同步臟數(shù)據(jù)到磁盤嗎?



    我們考慮使用innodb_file_per_table 方式建立的INNODB表每個(gè)表都有一個(gè)相應(yīng)的數(shù)據(jù)文件idb,格式文件frm
但是某些數(shù)據(jù)還是存儲(chǔ)在共享表空間。如果我們的線程要訪問這個(gè)表的數(shù)據(jù)必須要首先打開這些文件然后通過
pread()/read() lseek()等系統(tǒng)調(diào)用進(jìn)行文件位置尋找和讀取。那么我們打開文件的系統(tǒng)調(diào)用應(yīng)該是open()系統(tǒng)調(diào)用。
     當(dāng)然這些必要要有一個(gè)LINUX系統(tǒng)及編程基礎(chǔ),先說說一個(gè)每個(gè)進(jìn)程都包含了PCB(PCB在內(nèi)核態(tài)空間,進(jìn)程間是共享的)
PCB是一個(gè)進(jìn)程存在的標(biāo)識(shí)存到了進(jìn)程運(yùn)行的相關(guān)信息,內(nèi)核中他實(shí)際上是一個(gè)結(jié)構(gòu)體,其中包含很多信息如我
們熟知的PID PPID(大約100多種信息)其中PCB中保存了一份文件描述符,我們很容易在內(nèi)核代碼task_struct
結(jié)構(gòu)體也就是PCB的信息中找到如下:
/* open file information */
        struct files_struct *files;
其對(duì)應(yīng)了內(nèi)核中的file結(jié)構(gòu)體,可以看到進(jìn)程有一個(gè)files_struct結(jié)構(gòu)體用于保存,我們可以簡(jiǎn)單認(rèn)為進(jìn)程進(jìn)行進(jìn)程保存
了一份打開所有文件的文件描述符,這個(gè)文件描述符從0開始向后計(jì)數(shù),每個(gè)計(jì)數(shù)表示打開的一個(gè)文件。如果一個(gè)進(jìn)程要
打開一個(gè)文件我們LINUX是使用的open()系統(tǒng)調(diào)用,這個(gè)函數(shù)成功放回的就是打開的文件描述符,失敗則設(shè)置返回值為-1
同時(shí)給出perror,看看LINUX中對(duì)這個(gè)函數(shù)的解釋
open() and creat() return the new file descriptor, or -1 if an error occurred (in which case, errno 
is set appropriately).
      
     那么MYSQL既然是一個(gè)進(jìn)程多個(gè)線程,那么肯定也逃不掉這樣的LINUX安排,那么MYSQL既然要打開表,那么底層的
調(diào)用必然是OPEN函數(shù),既然文件有打開就有關(guān)閉,當(dāng)進(jìn)行LINUX系統(tǒng)編程或者C語言編程的時(shí)候,我們通常在使用完文件后
使用CLOSE()或者FCLOSE()來關(guān)閉文件,這樣系統(tǒng)釋放打開文件所保留的file信息,防止內(nèi)存泄露。


    那么我們來證明一下使用strace 分別在LINUX進(jìn)程TRACE LINUX線程信息。




一、關(guān)于打開表


1、首先關(guān)閉重啟mysql,避免其他的打開的表的文件描述的干擾。
[root@hadoop1 kernels]# service mysqldefault restart
     Shutting down MySQL....                                    [  OK  ]
     Starting MySQL...                                          [  OK  ]
2、使用pstree查看mysql所有線程(先找到MYSQL進(jìn)程ID)
   mysqld(10735)─┬─{mysqld}(10745)
              ├─{mysqld}(10746)
              ...
              ├─{mysqld}(10773)
              └─{mysqld}(10774)
   我們新打開一個(gè)MYSQL線程,
   [root@hadoop1 kernels]# pstree -p 10735
mysqld(10735)─┬─{mysqld}(10745)
              ├─{mysqld}(10746)
              ...
              ├─{mysqld}(10774)
              └─{mysqld}(10794)
   這樣我們找到我們新開的會(huì)話的線程ID 10794.
3、對(duì)線程10794進(jìn)行STRACE
   strace -T -p 10794
   然后再新的會(huì)話打開一個(gè)表,我這里打開的是
   select count(*) from tstr;
   
   
   Process 10794 attached - interrupt to quit
......
open("./test/tstr.ibd", O_RDONLY)       = 39 <0.000332>
getcwd("/mysql/data"..., 4096)          = 12 <0.000118>
lstat("/mysql/data/test", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0 <0.000114>
lseek(39, 0, SEEK_END)                  = 98304 <0.000109>
pread(39, "*z\322_\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\313\332\7\342\0\10\0\0\0\0\0\0"..., 16384, 0) = 16384 <0.016728>
close(39)                               = 0 <0.000243>
open("./test/tstr.ibd", O_RDWR)         = 39 <0.000015>
fcntl(39, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}) = 0 <0.000015>
......


我們來分析這里的關(guān)鍵步驟
open("./test/tstr.ibd", O_RDONLY)       = 39 <0.000332> 這里打開表的文件tstr.ibd只讀方式,返回文件描述符39
lseek(39, 0, SEEK_END)                  = 98304 這個(gè)是放回當(dāng)前打開文件的大小,也就是初始的96K,因?yàn)槲抑挥幸粭l數(shù)據(jù)
pread(39, "*z\322_\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\313\332\7\342\0\10\0\0\0\0\0\0"..., 16384, 0) = 16384 <0.016728>
這一行開始真正的讀取數(shù)據(jù) 讀取了16384個(gè)字節(jié)。
close(39)                               = 0 <0.000243> 然后關(guān)閉了文件tstr.ibd
open("./test/tstr.ibd", O_RDWR)         = 39 <0.000015> 然后再次以讀寫方式方式打開了tstr.ibd 數(shù)據(jù)文件,返回文件描述符39
fcntl(39, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}) = 0 <0.000015>
這一行設(shè)置了tstr.ibd文件的屬性,此函數(shù)用于改變文件屬性,為一需要寫入鎖的屬性,并且開始字節(jié)是0.


如果我們發(fā)現(xiàn)LINUX 在關(guān)閉文件后又一次以寫鎖方式打開了文件。我們現(xiàn)在來看看我們的線程中是否包含了這個(gè)文件描述符
4、


[root@hadoop1 fd]# pwd
/proc/10794/fd
[root@hadoop1 fd]# ls -lrt|grep tstr.ibd
lrwx------ 1 root root 64 Dec  5 06:36 39 -> /mysql/data/test/tstr.ibd




二、關(guān)于FLUSH TABLE做了什么操作


1、在某些情況FLUSH TABLE 會(huì)被堵塞,如 LOCK TABLES ... READ
   其次我還得到表操作期間文件,比如DML期間(不是事物),表重構(gòu)期間,SELECT 讀取數(shù)據(jù)很慢
   一切不允許進(jìn)程關(guān)閉文件描述符的操作。
   比如alter table add key(DDL) 這個(gè)操作需要將索引系統(tǒng)保存到表空間數(shù)據(jù)文件。
   比如delete from(DML) 這個(gè)操作需要將數(shù)據(jù)從表空間數(shù)據(jù)文件刪除。
   比如SELECT 很慢期間 。
   
   
   其等待系統(tǒng)調(diào)用futex(0xbb3f35c, FUTEX_WAIT_PRIVATE, 1, {31535999, 999934000}
   
   
2、FLUSH 實(shí)際上做的操作為:


[root@hadoop1 fd]# strace -T -p 15101
Process 15101 attached - interrupt to quit
....
close(24)                               = 0 <0.000115>
close(25)                               = 0 <0.000108>
close(28)                               = 0 <0.000099>
close(29)                               = 0 <0.000097>
close(26)                               = 0 <0.000242>
close(27)                               = 0 <0.000008>
close(30)                               = 0 <0.000008>
close(31)                               = 0 <0.000007>
close(32)                               = 0 <0.000007>
close(33)                               = 0 <0.000007>
close(22)                               = 0 <0.000152>
close(23)                               = 0 <0.000147>
close(20)                               = 0 <0.000110>
close(21)                               = 0 <0.000376>
close(34)                               = 0 <0.000008>
close(35)                               = 0 <0.000007>
close(38)                               = 0 <0.000008>
lseek(37, 0, SEEK_SET)                  = 0 <0.000011>
write(37, "\376\1\354:\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 35) = 35 <0.000025>
fsync(37)                               = 0 <0.008020>
close(37)                               = 0 <0.000071>
close(39)                               = 0 <0.000061>
...
Process 15101 detached


我們來觀察這些操作全部是關(guān)閉文件描述符,但是我發(fā)現(xiàn)這里關(guān)閉的文件全部為MYISAM的和CSV文件,如下:
lrwx------ 1 root root 64 Dec  5 08:27 4 -> /mysql/data/test/ibdata1
lrwx------ 1 root root 64 Dec  5 08:27 39 -> /mysql/data/mysql/general_log.CSV
lr-x------ 1 root root 64 Dec  5 08:27 38 -> /mysql/data/mysql/general_log.CSV
lrwx------ 1 root root 64 Dec  5 08:27 37 -> /mysql/data/mysql/general_log.CSM
lrwx------ 1 root root 64 Dec  5 08:27 36 -> socket:[42669]
lrwx------ 1 root root 64 Dec  5 08:27 35 -> /mysql/data/mysql/event.MYD
lrwx------ 1 root root 64 Dec  5 08:27 34 -> /mysql/data/mysql/event.MYI
lrwx------ 1 root root 64 Dec  5 08:27 33 -> /mysql/data/mysql/servers.MYD
lrwx------ 1 root root 64 Dec  5 08:27 32 -> /mysql/data/mysql/servers.MYI
lrwx------ 1 root root 64 Dec  5 08:27 31 -> /mysql/data/mysql/procs_priv.MYD
lrwx------ 1 root root 64 Dec  5 08:27 30 -> /mysql/data/mysql/procs_priv.MYI
lrwx------ 1 root root 64 Dec  5 08:27 3 -> /mysql/data/binlog.index
lrwx------ 1 root root 64 Dec  5 08:27 29 -> /mysql/data/mysql/columns_priv.MYD
lrwx------ 1 root root 64 Dec  5 08:27 28 -> /mysql/data/mysql/columns_priv.MYI
lrwx------ 1 root root 64 Dec  5 08:27 27 -> /mysql/data/mysql/tables_priv.MYD
lrwx------ 1 root root 64 Dec  5 08:27 26 -> /mysql/data/mysql/tables_priv.MYI
lrwx------ 1 root root 64 Dec  5 08:27 25 -> /mysql/data/mysql/proxies_priv.MYD
lrwx------ 1 root root 64 Dec  5 08:27 24 -> /mysql/data/mysql/proxies_priv.MYI
lrwx------ 1 root root 64 Dec  5 08:27 23 -> /mysql/data/mysql/db.MYD
lrwx------ 1 root root 64 Dec  5 08:27 22 -> /mysql/data/mysql/db.MYI
lrwx------ 1 root root 64 Dec  5 08:27 21 -> /mysql/data/mysql/user.MYD
lrwx------ 1 root root 64 Dec  5 08:27 20 -> /mysql/data/mysql/user.MYI


同時(shí),會(huì)對(duì)
同步的數(shù)據(jù)進(jìn)行寫到內(nèi)核緩沖區(qū)同時(shí)FSYNC此文件然后關(guān)閉。
但是對(duì)于INNODB數(shù)據(jù)文件,未發(fā)現(xiàn)關(guān)閉文件的情況。


那么我們可以視乎的得出2個(gè)結(jié)論


1、flush table 會(huì)關(guān)閉MYISAM和CSV(對(duì)其他存儲(chǔ)引擎作用未知)的文件描述符,同時(shí)會(huì)寫臟數(shù)據(jù)到文件,同時(shí)關(guān)閉文件描述符,
   關(guān)閉文件。
2、flush table 在INNODB中不會(huì)真正的關(guān)閉文件描述符,同時(shí)也不會(huì)寫臟數(shù)據(jù),但是FLUSH TABLE確實(shí)會(huì)由于
   innodb中對(duì)文件操作而造成堵塞,堵塞等待為futex系統(tǒng)調(diào)用。所以flush tbale對(duì)INNODB可能用處并不大。
   
   
水平有限,還待學(xué)習(xí)。如有錯(cuò)誤,請(qǐng)指正。


   
   
   
   
   






分享標(biāo)題:關(guān)于MYSQLflushtable的作用
鏈接地址:http://bm7419.com/article10/gepodo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google營銷型網(wǎng)站建設(shè)、做網(wǎng)站、企業(yè)建站、網(wǎng)站設(shè)計(jì)響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司