瞭解MySQl資料庫目錄

工程師WWW發表於2014-05-29

資料庫目錄是MySQL資料庫伺服器存放資料檔案的地方,不僅包括有關表的檔案,還包括資料檔案和MySQL的伺服器選項檔案。不同的分發,資料庫目錄的預設位置是不同的。

一、資料目錄的位置

預設的資料庫位置

預設資料庫的位置編譯在伺服器中。

◆如果您是在一個源程式分發包中安裝 MySQL,典型的預設位置可能是 /usr/local/var;

◆如果在二進位制分發包中安裝 MySQL,則為 /usr/local/mysql/ data;

◆在 RPM 檔案中安裝,為 /var/lib/mysql

◆對於windwos平臺上的分發,其位置時BASEDIR\data

資料目錄的位置可以在啟動伺服器時通過--datadir = / path / to / dir明確地指定。如果您想將資料目錄放置在其他地方而非預設的位置,則這個選項是有用的。

瞭解資料庫目錄的位置

作為一名 MySQL 管理員,您應該知道資料目錄在哪裡。如果執行多個伺服器,那麼您應該掌握所有資料目錄的位置。但是,如果不知道目錄的位置(或許您正在代替前一位管理員,而他留下的記錄很糟糕),有幾種方法可以用來查詢它:

1、可使用 mysqladmin 變數直接從伺服器中得到資料目錄路徑名。在 UNIX 中,輸出結果類似於如下所示:

$mysqladmin variables  (show variables;)
+-------------------------+---------------------------
| Variable_name           | Value                     
+-------------------------+---------------------------
| ansi_mode               | OFF                       
| back_log                | 50                        
| basedir                 | /var/local          
| connect_timeout         | 5                         
| concurrent_insert       | ON                        
| datadir                 | /usr/local/var  

該輸出結果指明瞭伺服器主機中資料目錄的位置 /usr/local/var。
在 Windows 中,輸出結果類似於如下所示:

c:\mysql\bin>mysqladmin variables
+-------------------------+---------------------------
| Variable_name           | Value                     
+-------------------------+---------------------------
| ansi_mode               | OFF                       
| back_log                | 50                        
| basedir                 | c:\mysql\          
| connect_timeout         | 5                         
| concurrent_insert       | ON          

如果正在執行多個伺服器,它們將監聽不同的 TCP/IP 埠號和套接字。可以通過提供合適的--port 或 --socket 選項連線到每個伺服器監聽的埠和套接字上:

$mysqladmin –port=port=port_num variables
$mysqladmin –socket=/path/to/socket variables

mysqladmin 命令可在您連線伺服器的任何一臺主機上執行。如果需要連線到遠端主機上的伺服器,則使用 --host = host_name 選項:

$mysqladmin –host=host_name varibles

2、在Unix平臺上,可使用 ps 來檢視任何當前執行 mysql 程式的命令列。試一試下列的命令(根據您的系統所支援的 ps 版本)並查詢顯示在輸出結果中的這些命令的 --datadir:

$ps au | grep mysqld

如果系統執行多個伺服器(因為一次發現了多個資料目錄位置),則 ps 命令將會特別有用。它的缺點是:ps 必須執行在伺服器的主機上,並且除非 --datadir 選項在 mysqld 命令列中明確指定,否則將產生無用的資訊。

3、如果 MySQL 從源程式分發包中安裝,可以檢查其配置資訊以確定資料目錄的位置。例如,在最高階的 Makefile 中該位置是可用的。但是,要小心:位置是 Makefile 中的變數localstatedir 的值,而不是 datadir 的值。同樣,如果分發包定位在 NFS 裝配檔案系統中,並且是用於為幾個主機建立 MySQL的,則配置資訊反映最近建立分發包的主機。它可能不顯示您感興趣的主機的資料目錄。

4、如果前面的任何方法都不成功,可使用 find 搜尋資料庫檔案。下列命令將搜尋 .frm(描述)檔案,它是 MySQL 安裝程式的組成部分:

$find / -name  “*.frm” –print

在windows平臺上的搜尋非常簡單,本節就不給出例子了。

在本章的這些例子中,筆者將 MySQL 資料目錄的位置表示為 DATADIR。您可以將其解釋成為您自己的機器中的資料目錄的位置。

二、資料庫的表示法

由 MySQL 管理的每個資料庫都有自己的資料庫目錄,它們是資料目錄的子目錄,與所表示的資料庫有相同的名稱。例如,資料庫 my_db 對應於資料庫目錄DATADIR/my_db。

這個表示法使得幾個資料庫級的語句的實現是非常容易的。CREATE DATABASE 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 DATADIR/db_name

其區別是,伺服器只刪除帶有表的副檔名的檔案。如果已經在該資料庫目錄中建立了其他的檔案,伺服器將使它們保持完整,並且不刪除該目錄本身。

SHOW DATABASE 只不過是對應位於資料目錄中的子目錄名稱的一個列表。有些資料庫系統需要保留一個列出所有需要維護的資料庫的主表,但是,在 MySQL 中沒有這樣的結構。由於資料目錄結構的簡單性,資料庫的列表是隱含在該資料目錄的內容中的,像主表這樣的表可能會引起不必要的開銷。

三、資料庫表的表示法

資料庫中的每個表在資料庫目錄中都作為三個檔案存在:一個格式(描述)檔案、一個資料檔案和一個索引檔案。每個檔案的基名是該表名,副檔名指明該檔案的型別。副檔名如表5-1所示。資料和索引檔案的副檔名指明該表是否使用較老的 ISAM 索引或較新的 MyISAM 索引。

當釋出定義一個表結構的 CREATE TABLE tbl_name 語句時,伺服器建立 tbl_name.frm 檔案,它包含該結構的內部編碼。該語句還建立空的資料檔案和索引檔案,這些檔案的初始資訊表明沒有記錄和索引(如果 CREATE TABLE 語句包含索引說明,則該索引檔案將反映這些索引)。描述表的檔案的所有權和方式被設定為只允許對 MySQL 伺服器使用者的訪問。

當釋出 ALTER TABLE 語句時,伺服器對 tbl_name.frm 重新編碼並修改資料檔案和索引檔案的內容以反映由該語句表明的結構變化。對於 CREATE 和 DROP INDEX 也是如此,因為伺服器認為它們等價於 ALTER TABLE 語句。DROP TABLE 刪除代表該表的三個檔案。

儘管可以通過刪除資料庫目錄中的對應某個表的三個檔案來刪除該表,但不能手工建立或更改表。例如,如果 my_db 是當前的資料庫,DROP TABLE my_tbl 大致等價於下列命令:

來自於 SHOW TABLES my_db 的輸出結果正是 my_db 資料庫目錄中 .frm 檔案基名的一個列表。某些資料庫系統維護一個列出了資料庫中的所有表的登記。但 MySQL 不這樣做,因為沒有必要,這個“登記”隱含在了資料目錄的結構中。

四、MySQL的狀態檔案

除資料庫目錄外,MySQL 資料目錄還包含許多狀態檔案。表10-3 概括介紹了這些檔案。大多數狀態檔案的預設名稱從伺服器主機名字中生成,在此表中表示為 HOSTNAME。

伺服器在啟動時將它的程式 ID(PID )寫入 PID 檔案,並在關閉時刪除該檔案。PID 檔案是一種方法,用這種方法,其他的程式可以找到該伺服器。例如,如果您在系統關閉時執行 mysql.server 指令碼來關閉 MySQL 伺服器,則該指令碼將檢查 PID 檔案以確定它需要哪個程式來傳送一個終止訊號。

錯誤日誌由 safe_mysqld 產生,作為伺服器標準錯誤輸出結果的重定向,它包含伺服器寫入 stderr 的所有訊息。這意味著僅當通過呼叫 safe_mysqld 啟動伺服器時,錯誤日誌才存在(總之,這是啟動伺服器的首選方法,因為,如果由於一個錯誤使錯誤日誌存在,則 safe_mysqld將重新啟動伺服器)。
常規日誌和更新日誌是可選的,可以用 --log 和 --log-update 伺服器選項開啟需要的日誌型別。

常規程式提供有關伺服器運作的常規資訊:誰從哪裡進行了連線,以及他們釋出了什麼查詢。更新日誌也提供查詢資訊,但僅僅是修改過的資料庫內容的查詢資訊。更新日誌的內容是一些 SQL 語句,這些語句可以通過將它們輸入到 mysql 客戶機程式來執行。如果出現崩潰且必須轉到備份檔案時,更新日誌將是有用的,因為您能夠通過將更新日誌輸入到伺服器來重複這些自崩潰以來所完成的更新操作。這將使得資料庫恢復到崩潰發生時所處的狀態上。

下面是一個例項,它是作為一個短客戶機會話的結果出現在常規日誌中的資訊中的,這個會話在 test 資料庫中從mytest.pet複製一個表,並插入一行到該表中,然後刪除該表:

注意第二行是一個錯誤的語句,但是也被記錄下來。 
    
常規日誌包含日期和時間、伺服器執行緒 ID、事件型別以及特定事件資訊的列。
同一個會話出現在如下的更新日誌中:

use test;
create table mytest select * from mytest.pet;
insert into mytest set name='tom',owner='jerry',species='cat',sex='f',birth='2000-01-01';
drop table mytest;

更新紀錄中沒有記錄錯誤的語句,因此對於恢復被破壞的資料庫內容非常有意義。
  
對於更新日誌,日誌的擴充套件格式是可用的,即使是用 --log - long - format 選項。擴充套件的日誌提供有關誰何時釋出查詢的資訊。當然,這將使用更多的磁碟空間,但是,如果您不將更新日誌的內容與常規日誌中的連線事件相聯絡就想知道誰正在做什麼的話,擴充套件日誌或許是可用的。

確保日誌檔案的安全且不被使用者任意讀取是個好注意。常規日誌和更新日誌都包含有諸如口令這樣的敏感資訊,這是因為它們包含了查詢的文字。下面是您不想讓任何人都能讀取的日誌項,因為它顯示了 root 使用者的口令:

010206 23:30:02       4 Query      update mysql.user set password=password("peking77.") where User="root"

有關檢查可設定資料目錄許可權的資訊,資料目錄安全的簡短指令由下列命令組成:

$ chmod 700 DATADIR

以擁有該資料目錄的 UNIX 使用者身份來執行此命令。還要確保伺服器以該使用者身份執行,否則此命令不僅將其他使用者排斥在該資料目錄之外(您想要的),還將阻止伺服器訪問您的資料庫(您不要的)。

狀態檔案出現在資料目錄的最高階,就像資料庫目錄一樣,因此您可能會想到那些檔案的名字是否會相互混淆或者被誤認為是資料庫名(例如,當伺服器正在執行 SHOW DATABASE 語句時)。答案是:不會的。狀態和日誌資訊儲存在檔案中,而資料庫是目錄,因此可執行程式可以將它們與一個簡單的 stat() 呼叫相區別(是伺服器告訴它們怎樣區分的)。如果您正在監視資料目錄,則可以通過使用 ls -l 將狀態檔案從資料庫目錄中區分開來,並且檢查該模式資訊的第一個字元以檢視它是‘-’還是‘d’:

您還可以通過檢視名字而簡單地告之:所有狀態檔名都包含一個句點,但是資料庫目錄名沒有句點(句點不是資料庫名的合法字元)。

五、總結

通過本節,讀者可以對MySQL的資料儲存方式有了一定的認識。本節中較為重要的內容有:

    1、資料庫目錄的位置
2、MySQL是如何表示資料表的
        3、MySQL的狀態檔案的種類和作用

瞭解MySQL如何儲存資料,以及狀態檔案的作用,對於備份資料庫是有重要意義的,根據MySQL資料庫目錄的特點,直接拷貝就是備份資料的重要方法之一。

 

相關文章