MySQL數據目錄結構(1)

火星人 @ 2014-03-09 , reply:0
←手機掃碼閱讀

MySQL數據目錄結構(1)


從概念上講,大多數關係資料庫系統是相似的:它們有一系列資料庫組成,每個資料庫包含一系列資料庫表,但每個系統有各自組織其管理的數據方式,MySQL也不例外.
預設地,所有由MySQL伺服器mysqld管理的數據存儲在一個稱為MySQL數據目錄的地方,所有資料庫都存放在哪兒,也包括提供伺服器操作信息的狀態文件.如果你對一個MySQl安裝執行管理任務,你應該熟知數據目錄的布局及用途.

1、數據目錄的位置

一個預設數據目錄被編譯進了伺服器,如果你從一個源代碼分發安裝MySQL,典型的預設目錄為/usr/local/var,如果從RPM文件安裝則為/var/lib/mysql,如果從一個二進位分發安裝則是/usr/local/mysql/data.
在你啟動伺服器,通過使用一個--datadir=/path/to/dir選項可以明確指定數據目錄位置.如果你想把數據目錄置於其它預設位置外的某處,這很有用.
作為一名MySQL管理員,你應該知道你的數據目錄在哪裡.如果你運行多個伺服器,你應該是到所有數據目錄在哪裡,但是如果你不知道確切的位置,由多種方法找到它:
使用mysqladmin variables從你的伺服器直接獲得數據目錄路徑名.查找datadir變數的值,在Unix上,其輸出類似於:
%mysqladmin variables

---------------------- ----------------------   variable_name   Value   ---------------------- ----------------------   back_log   5    connect_timeout   5    basedir   /var/local/    datadir   /usr/local/var/  ....

在Windows上,輸出可能看上去像這樣:
c:\mysqladmin variables
---------------------- ----------------------   variable_name   Value   ---------------------- ----------------------   back_log   5    connect_timeout   5    basedir   c:\mysql\    datadir   c:\mysql\data\  ....

如果你有多個伺服器在運行,它們將在不同的TCP/IP埠或套接字上監聽,通過提供連接伺服器正在監聽的埠或套接字的--port或--socket選項,你可以輪流獲得它們每一個的數據目錄信息:
%msqladmin --port=port_name variables
%mysqladmin --socket=/path/to/socket variables
mysqladmin命令可運行在任何你能從其連接伺服器的主機上,如果你想在一個遠程主機連接伺服器,使用一個--host=host_name選項:
%mysqladmin --host=host_name variables
在Windows上,你可以通過使用--pipe強制一個命令管道連接和--socket=pipe_name指定管道名來連接監聽一個命令管道的NT伺服器:
c:\mysqladmin --pipe --socket=pipe_name variables
你可以使用ps命令查看任何正在運行mysqld 進程的命令行.
試一下下列命令之一併尋找--datadir:
%ps axww   grep mysql BSD風格
%ps -ef   grep mysqld System V風格
如果你的系統運行多個伺服器,ps命令可能特別有用,因為你能馬上發現多個數據目錄位置,缺點是在伺服器上運行,可能沒有有用的信息產生,除非在mysqld命令行上明確指定了--datadir選項.
如果MySQL是從一個源代碼分發安裝的,你可以檢查其配置信息確定數據目錄位置.例如,位置可從頂級Makefile中獲得,但是注意,位置是Makefile中的localstatedir值,不是datadir,,如果分發位於一個NFS掛載的文件系統並用來為多個主機構建MySQL,配置信息反映了分發被最新構建的主機,這可能不能提供你感興趣的主機的數據目錄信息.
如果上述方式失敗,你可以用find尋找資料庫文件,下列命令尋找「.frm」文件,它是任何MySQL安裝的一部分:

% find / -name ".frm" -print



在下文各例中,用DATADIR表示MySQL數據目錄位置.
2、數據目錄結構

MySQL數據目錄包含了伺服器管理的所有數據目錄,這些文件被組織成一個樹狀結構,通過利用Unix或Windows文件系統的層次結構直接實現.
每個資料庫對應於數據目錄下的一個目錄.
在一個資料庫中的表對應於數據目錄下的文件.

數據目錄也包含由伺服器產生的幾個狀態文件,如日誌文件.這些文件提供了關於伺服器操作的重要信息.對管理特別在出了問題而試圖確定問題原因時很有價值.例如,如果某個特定查詢殺死伺服器,你可以通過檢查日誌文件判別搗亂的查詢.
2.1 MySQL伺服器怎樣提供對數據的訪問

在數據目錄下的一切由一個單獨的實體-MySQL伺服器mysqld管理,客戶程序絕不直接操作數據.相反,伺服器提供數據可訪問的切入點,它是客戶程序與它們想使用的數據之間的中介.
當伺服器啟動時,如果有需要,它打開日誌文件,然後通過監聽網路連接位數據目錄呈現一個網路介面.要訪問數據,客戶程序建立對伺服器的一個連接,然後以MySQL查詢傳輸請求來執行希望的操作.伺服器執行每一個操作並將結果發回用戶.伺服器是多線程的並能服務多個同時的客戶連接.然而,因為修改操作一個執行一個,實際效果是順序化請求,以使兩個客戶決不能在同一時刻改變同一記錄.
在正常的情況下,讓伺服器作為資料庫訪問的唯一仲裁者提供了避免可從同時訪問資料庫表的多個進程的破壞的保證.管理員應該知道有時伺服器沒有對數據目錄的獨裁控制.
當你在一個單個數據目錄上運行多個伺服器.一般倪雲新一個伺服器管理主機上的所有資料庫,但是有可能運行多個伺服器.如果這完成提供對多個獨立數據目錄的訪問,沒有相互影響的問題,但喲也能啟動多個伺服器並指向同一個目錄.一般地,這不是一個好主意.如果你試圖這樣,最好是你的系統提供良好的文件鎖定功能,否則伺服器將不能正確協作.如果你將多個伺服器同時寫入日誌文件,你也冒著你的日誌文件稱為混亂的根源的風險.
在你運行isamchk和myisamchk時.isamchk和myisamchk實用程序用於表的維護、診錯和修復,就想你想的那樣,因為這些程序可以修改表內容,允許它們與伺服器正在操作的同時對錶操作,這樣能導致表損壞.理解如何限制這種相互影響是很重要的,這樣你不會損壞你的表.
2.2 數據目表示

每個MySQL伺服器管理的資料庫有自己的資料庫表,它是數據目錄下的一個子目錄,其名字與它表示的資料庫相同.例如資料庫my_db對應於資料庫目錄DATADIR/my_db.
這種表示允許多個資料庫級的語句在其實現中十分簡單.CREATE DATABASE db_name在數據目錄中創建一個db_name空目錄,具有隻允許MySQL伺服器用戶(運行伺服器的Unix用戶)的屬主和模式,這等價於下列手工在伺服器主機上創建資料庫:
%mkdir DATADIR/db_name%chmod 700 DADADIR/db_name

用一個空目錄表示一個新資料庫的最簡單方法與其它資料庫甚至為一個空資料庫創建大量的控制文件或系統文件正好相反.
DROP DATABASE語句實現同樣簡單.DROP DATABASE db_name刪除資料庫中的db_name目錄和所有表文件,這幾乎與下列命令一樣:
%rm -rf DATADIR/db_name

(差別是伺服器只刪除具有已知用於表的後綴名的文件.如果你在資料庫目錄創建了其它文件.則伺服器保留它們,目錄本身不被刪除.
SHOW DATABASE基本上不做什麼,只是列出位於數據目錄中的目錄名.有些資料庫系統保持一個主表,用於維護所有資料庫,但在MySQL無此構件.賦予數據目錄結構的簡潔性,資料庫列表隱含在數據目錄的內容中,這樣的表不必有額外的開銷.


2.3 資料庫表的表示

每個資料庫在資料庫目錄中有3個文件:一個樣式(描述文件)、一個數據文件和一個索引文件.每個文件的基本名是表名,文件名擴展名代表文件類型.擴展名如下表.數據和索引文件的擴展名指出表使用老式IASM索引或新式MyISAM索引.表 MySQL文件類型
文件類型 文件名擴展名 文件內容
樣式文件 .frm 描述表的結構(它的列、列類型、索引等).
數據文件 .ISD(ISAM)
或.MYD(MyISAM) 包含數據文件上的所有索引的索引樹.
索引文件 .ISM(ISAM)
或.MYI(MyISAM) 該索引文件依賴表是否有索引而存在.

當你發出一條CREATE TABLE tbl_name時語句定義表的結構時,伺服器創建一個名為tbl_name.frm的文件,它包括該結構的內部編碼,同時也創建一個空數據和索引文件,初始化為包含指出無記錄和無索引的信息(如果CREATE TABLE語句包括索引指定,索引文件反映出這些索引).對應於表的文件的屬主和模式被設置為只允許MySQL伺服器用戶訪問.
當你發出一條ALTER TABLE tbl_name語句時,伺服器重新編碼tbl_name.frm,並修改數據和索引文件的內容以反映語句指定的結構改變.對於CREATE INDEX和DROP INDEX也是一樣,因為它們被伺服器視為與ALTER TABLE等價.DROP TABLE通過刪除對應於表的三個文件來實現.
雖然你可以通過刪除資料庫目錄中對應於表的三個文件,但不能手工創建或修改一個表,如,如果my_db是當前資料庫,DROP TABLE my_tbl大概等價於下列命令.
% rm -rf DATADIR/my_db/my_tbl.*
SHOW TABLE my_db的輸出只是列出my_db資料庫目錄中的.frm文件的基文件名.有些資料庫系統一個註冊表,列舉所有包含在一個資料庫中的表,MySQL不是,因為不必要,「註冊表」隱含在數據目錄的結構中.
2.4 操作系統對資料庫和表命名的限制

MySQL對命名資料庫和表有一個原則:
名字可以由當前字符集中的任何字母數字字元組成,下劃線和美元符$也可以.
名字最長為64個字元.

然而,因為資料庫和表的名字對應於目錄和文件名,伺服器運行的操作系統可能強加額外的限制.
,資料庫和表名僅限於對文件名合法的字元,如$在MySQL的原則中是允許的,但是如果你的操作系統不允許,則你不能在目錄或表名中使用它.實際上,這對Unix或Windows不是所擔心的,最大的難度是在執行資料庫管理時直接在shell中引用名字,例如,如果你命名一個資料庫如$my_db,包含一個美元符,任何從shell中對該名字的引用可能被shell解釋為對一個變數的引用:
%ls $my_db
my_db:undefined variable
對此,你轉義$字元或用引號禁止其特殊含義:
%ls \$my_db
%ls '$my_db'
如果你用引號,一定要用單引號,而雙引號並不禁止變數解釋.
其次,雖然MySQL允許資料庫和表名最長到64個字元,但名字的長度受限於你的操作系統限定的長度,一般這不是一個問題(雖然老的System V強制14個字元).在這種情況下,你資料庫名的上限為14個字元,而表名上限為10個字元,因為表示表的文件名有一個點(.)和三個字元的擴展名.
第三,文件系統的大小寫敏感性影響到你如何命名和引用資料庫和表名.如果文件系統是大小寫敏感的(如Unix),兩個名字my_tbl和MY_TBL是不同的表.如果文件系統不是大小寫敏感的(如Windows),這兩個名字指的是相同的表.如果你用一個Unix伺服器開發資料庫,並且如果你有可能轉移到Windows,你應該記住這一點.
2.5 MySQL狀態文件



除了資料庫目錄,MySQL數據目錄還包含很多狀態文件,這些文件總結在下表中.大多數文件的預設名從伺服器主機名生成,在下表中表示為HOSTNAME.表 MySQL狀態文件
文件類型 預設名 文件內容
進程ID HOSTNAME.pid 伺服器進程的ID
出錯日誌 HOSTNAME.err 啟動和關閉事件和出錯情況
一般日誌 HOSTNAME.log 連接/斷開事件和查詢信息
更新日誌 HOSTNAME.nnn 修改表結構級內容的所有查詢文本

當伺服器啟動時,它將其進程ID寫入進程ID(PID)文件中,而在它關閉時,刪除該文件.PID文件是允許伺服器本身被其他進程找到的工具.例如,如果你運行mysql.server,在系統關閉時,關閉MySQL伺服器的腳本檢查PID文件以決定它需要向哪個進程發出一個終止信號.
出錯日誌由safe_mysqld創建,作為伺服器標準出錯輸出的重定向,它包含任何邪到stderr的消息.這意味著只有你通過調用safe_mysqld啟動伺服器,出錯文件才存在(無論如何,它是一個啟動伺服器的最好方法,因為如果它出錯而退出,safe_mysqld將重啟伺服器.).
一般日誌和更新日誌是可選的.你可以只開啟你需要的日誌類型,用--log和--log-update伺服器選項.
一般日誌提供伺服器操作的一般信息:誰從哪裡連接伺服器和他們發出什麼查詢.更新日誌提供查詢信息,但只有修改資料庫內容的查詢.更新日誌內容被寫成SQL語句,可以將它們提供給mysql客戶程序來執行.如果你遇上崩潰,並且倒回備份文件,更新日誌就很有用,因為你能重複執行自崩潰時的更新,通過將更新日誌反饋給伺服器,這允許你將資料庫恢復到崩潰發生時的狀態.
下面是一個簡單的例子,信息出現在一般日誌中,它是一個創建一個在資料庫test中表,插入一行,然後刪除表的會話:
990509 7:37:09 492 Connect Paul@localhost on test 492 Query show databases 492 Query show tables 492 Field List tbl_1 492 Field List tbl_2 ...990509 7:34:22 492 Query CREATE TABLE my_tbl (val INT)990509 7:34:34 492 Query INSERT INTO my_tbl values (1)990509 7:34:38 492 Query DROP TABLE my_tbl 990509 7:34:40 492 Quit

一般日誌包含日期和時間、伺服器進程ID、事件類型和事件信息欄目.
同一個會話出現在更新日誌中看上去像這樣:
use test;CREATE TABLE my_tbl (val int);INSERT INTO my_tbl VALUES(1);DROP TABLE my_tbl;

對更新日誌,用--log-long-format選項獲得一個擴展形式的日誌,擴展日誌提供有關誰何時發出每一條查詢,這使用更多的磁碟空間,但如果你想知道誰在做什麼,而不用將更新日誌對照一般日誌的內容找到連接事件.
對上面的會話,擴展更新日誌產生這樣的信息:
# Time: 990507 7:32:42# User@Host: paul [paul] @ localhost []use test;CREATE TABLE my_tbl (val int);# User@Host: paul [paul] @ localhost []INSERT INTO my_tbl VALUES(1);# Time: 990507 7:32:43# User@Host: paul [paul] @ localhost []DROP TABLE my_tbl; 

保證你的日誌文件安全並且不讓任意用戶讀取是個好主意.一般日誌和更新日誌都能包含諸如口令等的敏感信息,因為它們包含查詢文本.如:
990509 7:23:31 4 Query UPDATE user SET Password=PASSWORD("secret") WHERE user="root"

對於檢查和設置數據目錄的許可權,請見《MySQL安全性指南》.使數據目錄安性的指令包含下列命令:
% chmod 700 DATADIR
以擁有數據目錄的Unix用戶運行此命令.確保伺服器也以此用戶運行,否則該命令不僅將其它人拒之門外,它也阻止伺服器訪問你的資料庫.
狀態文件出現在數據目錄的頂級目錄,就象資料庫目錄,你可能擔心這些文件名是否與資料庫名衝突或出錯(如在伺服器執行SHOW DATABASES語句時).答案是不.狀態和日誌文件信息存儲在文件中,而資料庫是目錄,可執行程序能用一個簡單的stat()調用區分它們.如果你看一下數據目錄,你可以區分狀態文件和資料庫目錄,用ls -l並檢查模式的第一個字元是一個"_"還是一個"d".


你也可以簡單地看一下名字,所有狀態文件名包含一個點("."),而資料庫目錄沒有(.在資料庫名中是無效字元).





[火星人 via ] MySQL數據目錄結構(1)已經有228次圍觀

http://www.coctec.com/docs/linux/show-post-58194.html