mysql|資料|資料目錄 MySQL資料目錄中包含由伺服器管理的所有資料庫和表。它們被組織成一個樹狀結構,該結構是通過UNIX 或Windows 檔案系統的階層用簡單的方式實現的:
每個資料庫對應該資料目錄下的一個目錄。
資料庫中的表對應資料庫目錄中的檔案。
資料目錄還包含幾個由伺服器產生的狀態檔案,如記錄檔。這些檔案提供了關於伺服器運作的重要訊息,對管理員是有用的,尤其是當問題出現且試圖確定問題的原因時特別有用。例如,如果某個特定的檠倩盜聳菘猓梢醞ü觳槿罩疚募詞侗鷲飧鎏盅岬牟檠?br>
MySQL伺服器怎樣提供對資料的訪問
資料目錄中的一切都由一個單個的實體進行管理,即MySQL伺服器的mysqld。客戶機程式不能直接操縱資料。而伺服器提供了訪問資料庫的唯一的連結點,它擔當著客戶機程式和所需資料之間的媒介(參見圖10 - 1)
當啟動伺服器時,如果有任何請求,它都將開啟記錄檔,然後通過對網路連接的監聽向資料目錄展現網路介面。為了訪問資料,客戶機建立一個到伺服器的串連,然後傳達作為SQL 查詢的請求,以完成所期望的操作(例如,建立表、選擇記錄、更新記錄)。伺服器執行每個操作並將結果發送回客戶機。伺服器是多線程的,可以服務於多個並發的客戶機的串連。但是,由於更新操作一次只能執行一個,因此實際上這些請求是順序化的,兩個客戶機決不可能在同一時刻修改同一個記錄。
在正常條件下,使伺服器擔當資料庫訪問的唯一仲裁者將提供對防止各種訛誤的擔保,這些訛誤可導致多個進程同時訪問資料庫的表。然而,管理員應該知道:存在著伺服器不具有對資料目錄獨佔控制的時期:
何時在單個資料目錄中運行多個伺服器。通常情況下是運行一個單個的伺服器來管理主機中的所有資料庫,但是運行多個伺服器也是可能的。如果這樣做可以提供對多個獨立的資料目錄的訪問,則不存在互動作用的問題。但是,有可能啟動多個伺服器並在相同的資料目錄中指向它們。這是一個好主意,如果您想試試它,最好應確保系統提供了良好的檔案鎖定效能,否則伺服器之間將不能協調地工作。如果將多個伺服器同時寫入記錄檔,則將會使記錄檔成為混亂的來源(而不是有用資訊的來源)。
何時運行isamchk 和my i s a m c h k。isamchk 和myisamchk 公用程式用於表的維護、故障排除和修複。正如您所猜測的,由於這些公用程式能改變表的內容,所以如果在伺服器運作的同時允許公用程式對錶進行操作,將引起表的毀壞。瞭解怎樣限制這種類型的互動作用以避免表毀壞是重要的。有關恰當使用這些程式的說明,請參閱第13章“資料庫維護和修複”。
資料庫的標記法
由MySQL管理的每個資料庫都有自己的資料庫目錄,它們是資料目錄的子目錄,與所表示的資料庫有相同的名稱。例如,資料庫my_db 對應於資料庫目錄DATA D I R/ my _ db。
這個標記法使得幾個資料庫級的語句的實現幾乎是微乎其微的。CREATE DATA B A S E db _ name 使用只允許對MySQL伺服器使用者(伺服器啟動並執行UNIX 使用者)進行訪問的所有權和方式,並在資料目錄中建立一個空目錄db _ name。這等價於以伺服器主機中的伺服器使用者的身份通過執行下列命令手工建立資料庫:
% mkdir DATADIR/db_name 建立資料庫目錄
% chmod 700 DATADIR/db_name 使它僅對MySQL伺服器使用者可訪問
通過空目錄表示新資料庫的方法與其他資料庫系統完全不同,那些資料庫系統甚至要為“空”資料庫建立許多控制檔案或系統檔案。
DROP DATABASE 語句也很容易實現。DROP DATABASE db _ name 刪除資料目錄中的db _ name 目錄以及其中的所有表檔案。這個語句類似於下列命令:
%rm -rf DATA D I R / db _ name
其區別是,伺服器只刪除帶有表的副檔名的檔案。如果已經在該資料庫目錄中建立了其他的檔案,伺服器將使它們保持完整,並且不刪除該目錄本身。
SHOW DATABASE 只不過是對應位於資料目錄中的子目錄名稱的一個列表。有些資料庫系統需要保留一個列出所有需要維護的資料庫的主表,但是,在MySQL中沒有這樣的結構。由於資料目錄結構的簡單性,資料庫的列表是隱含在該資料目錄的內容中的,像主表這樣的
表可能會引起不必要的開銷。
資料庫表的標記法
資料庫中的每個表在資料庫目錄中都作為三個檔案存在:一個格式(描述)檔案、一個資料檔案和一個索引檔案。每個檔案的基名是該表名,副檔名指明該檔案的類型。副檔名如表10 - 1所示。資料和索引檔案的副檔名指明該表是否使用較老的ISAM 索引或較新的MyISAM 索引。
當發布定義一個表結構的CREATE TABLE tbl_name 語句時,伺服器建立tbl_name. f r m檔案,它包含該結構的內部編碼。該語句還建立空的資料檔案和索引檔案,這些檔案的初始資訊表明沒有記錄和索引(如果CREATE TABLE 語句包含索引說明,則該索引檔案將反映這些索引)。描述表的檔案的所有權和方式被設定為只允許對MySQL伺服器使用者的訪問。
當發布ALTER TABLE 語句時,伺服器對tbl_name.frm 重新編碼並修改資料檔案和索引檔案的內容以反映由該語句表明的結構變化。對於CREATE 和DROP INDEX 也是如此,因為伺服器認為它們等價於ALTER TABLE 語句。DROP TABLE 刪除代表該表的三個檔案。
儘管可以通過刪除資料庫目錄中的對應某個表的三個檔案來刪除該表,但不能手工建立或更改表。例如,如果my_db 是當前的資料庫,DROP TABLE my_tbl 大致等價於下列命令:
% rm -f DATADIR/my_db_tbl.*
來自於SHOW TABLES my_db 的輸出結果正是my_db 資料庫目錄中.frm 檔案基名的一個列表。某些資料庫系統維護一個列出了資料庫中的所有表的登記。但MySQL不這樣做,因為沒有必要,這個“登記”隱含在了資料目錄的結構中。
資料庫和表命名中的作業系統約束
MySQL具有對資料庫和表命名的一般規則:
名字可以由當前字元集中的字母數字字元以及底線和貨幣符號(‘_’ 和‘$’)組成。
名字最長可達64 個字元。
但是,由於資料庫和表的名字對應於目錄和檔案名稱,因此,對資料庫啟動並執行作業系統可以施加另外的約束。
首先,將資料庫和表名限制為檔案名稱中的合法字元。例如,按照MySQL的規則,名字中允許使用‘ $’,但是,如果作業系統不允許使用它,則不能在目錄名或表名中使用。實際上,這與UNIX 或Windows 無關。可能會遇到的最大困難是在進行資料庫管理時從外殼程式
中直接命名。例如,如果給某個資料庫定義了諸如$my_db 的名字,該名字包括貨幣符號,對來自外殼程式命令列的該名字的任何引用都可由外殼程式解釋為一個變數引用:
% ls $my_db
my_db:Undefined variable
如果這種情況發生,必須將‘ $’字元換碼,或使用引號來取消其特殊的含義:
% ls \$my_db
% ls '$my_db'
如果要使用引號,則應使用單引號。雙引號不能取消對變數的解釋。
第二,儘管MySQL允許資料庫和表的名字最大長度為6 4個字元,但名字的長度也要受到作業系統所允許長度的限制。通常,這不是什麼問題,儘管在UNIX 中您可能會進入有14個字元限制的舊版本System V-ish 系統中。在這種情況下,資料庫名字的有效限制為14 個字元,表名的限制為10個字元,因為表示表的檔案名稱可用一個句點和三字元的副檔名終結。
第三,基礎檔案系統的大小寫敏感性影響您對資料庫和表的命名及引用。如果檔案系統是區分大小寫(如UNIX),則my_tbl 和MY_TBL 這兩個名字涉及不同的表。如果檔案系統不是區分大小寫(如Windows),則my_tbl 和MY_TBL 是同一個表。您應當留意是否使用了UNIX 伺服器來開發資料庫,如果有可能的話,在某時應將該資料庫移到Windows 伺服器上。
系統效能的資料目錄結構的含義
資料目錄的結構易於理解,因為它使用了檔案系統的階層的方式。同時,該結構具有特定的效能含義,尤其是關於開啟表示資料庫表檔案的操作。
這種資料目錄結構的一個後果是,由於表由多個檔案來表示,因此每個開啟的表都需要多個檔案描述符,而不是一個。伺服器智能化地快取這些描述符,但是一個繁忙的伺服器可能會很輕易地耗盡描述符資源,如果伺服器同時為許多並發的客戶機串連服務或運行引
用多個表的複雜查詢的話。檔案描述符在許多系統中都是匱乏的資源,尤其是將預設的總進程(per- p r o c e s s)限制設定得相當低的系統。第11章“常規的MySQL管理”將提供有關估計所需描述符數量的資訊,以及在需要時重新設定伺服器或作業系統的資訊。
由表自己的檔案表示每個表的另一個後果是,表的開啟時間隨表的數量而增加。開啟表的操作映射成由作業系統提供的檔案開啟操作,因此將受到系統的目錄尋找程式( d i r e c t o r y - lookup routine)效率的影響。通常這不是個問題,但是,如果在資料庫中需要大量的表時,它則是個要考慮的問題。
例如,如果想要得到10 000 個表,則資料庫目錄中應該包含30 000 個檔案。對於這麼多的檔案,將會引起由於檔案開啟操作所花費的時間而使運行速度降低( Linux ext2 和S o l a r i s 檔案系統存在這個問題)。如果這個問題涉及到利害關係,則應根據應用程式的需要明智地重新考慮表的結構,從而重新組織這些表。應查看一下是否真的需要這麼多的表,因為有時應用程式會不必要地繁殖許多表。為每個使用者建立一個單個表的應用程式將導致許多表的產生,其實所有這些表都有相同的結構。如果您想將這些表合并成一個表,可以通過增加另一列以標識每行所使用的使用者來達到目的。如果這能使表的數量明顯減少,則會相應提高應用程式的效能。
在資料庫設計階段,您必須考慮這個特定的階段對於一個給定的應用程式是否是值得的。不按上面所描述的方法來合并表的原因如下:
增大的磁碟空間的需求。合并表是為了減少所需表的數量(減少表開啟的時間),但增加了另一列內容(增加磁碟空間的需求)。這是典型的空間與時間的折衷,您需要決定哪個因素更重要。如果認為速度極為重要,您或許願意犧牲一點額外的磁碟空間。如果空間太緊張,則只能忍受使用多個表的時間。
安全性考慮。這些可能會約束您的能力或對錶合并的願望。每個使用者分別使用單獨的表的一個原因是:使只有擁有表級許可權的使用者才能對每個表進行訪問。如果合并了表,則所有使用者資料都將在同一個表中出現。
MySQL沒有限制一個已知使用者對特定行的訪問的規定,因此,如果沒有泄密存取控制就不能合并表。另一方面,如果所有的資料訪問都由應用程式控制(使用者不可能直接連接到伺服器),則可以合并表並使用應用程式的邏輯強制合并後的行級訪問。
MySQL對於表的大小有其自己內部的限制,但是,由於它將表表示為檔案, MySQL還將受到檔案尺寸最大值的限制,該最大值是由作業系統給出的。因此,有效表尺寸最大值要小於MySQL的內部限制和系統檔案尺寸的限制。
通常,隨著時間的推移,對尺寸大小的約束將有所緩和。例如, IBM AIX4.1有2GB 檔案大小的限制,但是在AIX4.2 中該限制值大約為6 4 G B。在MySQL中內部的表大小限制值也隨著最新版本的出現而增加。在3.23 系列之前,內部的限制值為4 G B。從3 . 2 3系列起,該限制值大約為9 000 000太位元組。表10-2 說明了MySQL內部的表大小限制和AIX 檔案大小限制怎樣相互作用來確定有效表大小的最大值。類似的相互作用也可應用於其他的作業系統。
MySQL的狀態檔案
除資料庫目錄外,MySQL資料目錄還包含許多狀態檔案。表10-3 概括介紹了這些檔案。大多數狀態檔案的預設名稱從伺服器主機名稱字中產生,在此表中表示為H O S T N A M E。
表10-3 MySQL狀態檔案
檔案類型 |
預設名 |
檔案內容 |
進程ID |
HOSTNAME.pid |
伺服器處理序ID |
錯誤記錄檔 |
HOSTNAME.err |
啟動和關閉事件和錯誤狀態 |
常規日誌 |
HOSTNAME.log |
串連/斷開事件和查詢資訊 |
更新日誌 |
HOSTNAME.nnn |
修改表的內容或結構的所有查詢的文本 |
伺服器在啟動時將它的進程ID(PID )寫入PID 檔案,並在關閉時刪除該檔案。PID 檔案是一種方法,用這種方法,其他的進程可以找到該伺服器。例如,如果您在系統關閉時運行mysql.server 指令碼來關閉MySQL伺服器,則該指令碼將檢查PID 檔案以確定它需要哪個進程來發送一個終止訊號。
錯誤記錄檔由safe_mysqld 產生,作為伺服器標準錯誤輸出結果的重新導向,它包含伺服器寫入stderr 的所有訊息。這意味著僅當通過調用safe_mysqld 啟動伺服器時,錯誤記錄檔才存在(總之,這是啟動伺服器的首選方法,因為,如果由於一個錯誤使錯誤記錄檔存在,則
s a f e _ mysqld將重新啟動伺服器)
常規日誌和更新日誌是可選的,可以用--log 和--log-update 伺服器選項開啟需要的日誌類型。
常規進程提供有關伺服器運作的常規資訊:誰從哪裡進行了串連,以及他們發布了什麼查詢。更新日誌也提供查詢資訊,但僅僅是修改過的資料庫內容的查詢資訊。更新日誌的內容是一些SQL 陳述式,這些語句可以通過將它們輸入到mysql客戶機程式來運行。如果出現崩
潰且必須轉到備份檔案時,更新日誌將是有用的,因為您能夠通過將更新日誌輸入到伺服器來重複這些自崩潰以來所完成的更新操作。這將使得資料庫恢複到崩潰發生時所處的狀態上。
下面是一個執行個體,它是作為一個短客戶機會話的結果出現在常規日誌中的資訊中的,這個會話在test 資料庫中建立一個表,並插入一行到該表中,然後刪除該表:
常規日誌包含日期和時間、伺服器線程ID、事件類型以及特定事件資訊的列。
同一個會話出現在如下的更新日誌中:
對於更新日誌,日誌的擴充格式是可用的,即使是用--log - long - format 選項。擴充的日誌提供有關誰何時發布查詢的資訊。當然,這將使用更多的磁碟空間,但是,如果您不將更新日誌的內容與常規日誌中的串連事件相聯絡就想知道誰正在做什麼的話,擴充日誌或許是可用的。
對於剛才顯示出的會話,擴充日誌將產生下列資訊:
確保記錄檔的安全且不被使用者任意讀取是個好注意。常規日誌和更新日誌都包含有諸如口令這樣的敏感資訊,這是因為它們包含了查詢的文本。下面是您不想讓任何人都能讀取的日誌項,因為它顯示了root 使用者的口令:
有關檢查可設定資料目錄許可權的資訊,請參閱第12 章。資料目錄安全的簡短指令由下列命令組成:
% chmod 700 DATADIR
以擁有該資料目錄的UNIX 使用者身份來運行此命令。還要確保伺服器以該使用者身份運行,否則此命令不僅將其他使用者排斥在該資料目錄之外(您想要的),還將阻止伺服器訪問您的資料庫(您不要的)。
狀態檔案出現在資料目錄的最進階,就像資料庫目錄一樣,因此您可能會想到那些檔案的名字是否會相互混淆或者被誤認為是資料庫名(例如,當伺服器正在執行S H O W DATABASE 語句時)。答案是:不會的。狀態和日誌資訊儲存在檔案中,而資料庫是目錄,因此可執行程式可以將它們與一個簡單的stat() 調用相區別(是伺服器告訴它們怎樣區分的)。如果您正在監視資料目錄,則可以通過使用ls -l 將狀態檔案從資料庫目錄中區分開來,並且檢查該模式資訊的第一個字元以查看它是‘ -’還是‘d’:
您還可以通過查看名字而簡單地告之:所有狀態檔案名稱都包含一個句點,但是資料庫目錄名沒有句點(句點不是資料庫名的合法字元)。
有關記錄檔維護和迴圈技術的資訊,請參閱第11章的內容。