第5章:資料庫管理

目錄

5.1. MySQL伺服器和伺服器啟動指令
5.1.1. 伺服器端指令和實用工具概述
5.1.2. mysqld-max延伸MySQL伺服器
5.1.3. mysqld_safe:MySQL伺服器啟動指令
5.1.4. mysql.server:MySQL伺服器啟動指令
5.1.5. mysqld_multi:管理多個MySQL伺服器的程式
5.2. mysqlmanager:MySQL實例管理器
5.2.1. 用MySQL實例管理器啟動MySQL伺服器
5.2.2. 連接到MySQL實例管理器並建立用戶帳號
5.2.3. MySQL實例管理器命令行選項
5.2.4. MySQL實例管理器配置檔案
5.2.5. MySQL實例管理器識別的命令
5.3. mysqld:MySQL伺服器
5.3.1. mysqld命令行選項
5.3.2. SQL伺服器模式
5.3.3. 伺服器系統變數
5.3.4. 伺服器狀態變數
5.4. mysql_fix_privilege_tables:升級MySQL系統資料表
5.5. MySQL伺服器關機程序
5.6. 一般安全問題
5.6.1. 通用安全指南
5.6.2. 使MySQL在攻擊者面前保持安全
5.6.3. Mysqld安全相關啟動選項
5.6.4. LOAD DATA LOCAL安全問題
5.7. MySQL訪問權限系統
5.7.1. 權限系統的作用
5.7.2. 權限系統工作原理
5.7.3. MySQL提供的權限
5.7.4. 與MySQL伺服器連接
5.7.5. 訪問控制, 階段1:連接核實
5.7.6. 訪問控制, 階段2:請求核實
5.7.7. 權限更改何時生效
5.7.8. 拒絕訪問錯誤的原因
5.7.9. MySQL 4.1中的密碼哈希處理
5.8. MySQL用戶帳號管理
5.8.1. MySQL帳號和密碼
5.8.2. 向MySQL增加新用戶帳號
5.8.3. 從MySQL刪除用戶帳號
5.8.4. 限制帳號資源
5.8.5. 設置帳號密碼
5.8.6. 使您的密碼安全
5.8.7. 使用安全連接
5.9. 備份與恢復
5.9.1. 資料庫備份
5.9.2. 示範用備份與恢復策略
5.9.3. 自動恢復
5.9.4. 資料表維護和崩潰恢復
5.9.5. myisamchk:MyISAM資料表維護實用工具
5.9.6. 建立資料表維護計劃
5.9.7. 獲取關於資料表的訊息
5.10. MySQL本地化和國際應用
5.10.1. 數據和排序用字元編碼
5.10.2. 設置錯誤消息語言
5.10.3. 新增新的字元編碼
5.10.4. 字元定義數組
5.10.5. 字串比較支援
5.10.6. 多字節字元支援
5.10.7. 字元編碼問題
5.10.8. MySQL伺服器時區支援
5.11. MySQL日誌檔案
5.11.1. 錯誤日誌
5.11.2. 通用查詢日誌
5.11.3. 二進制日誌
5.11.4. 慢速查詢日誌
5.11.5. 日誌檔案維護
5.12. 在同一台機器上運行多個MySQL伺服器
5.12.1. 在Windows下運行多個伺服器
5.12.2. 在Unix中運行多個伺服器
5.12.3. 在多伺服器環境中使用客戶端程式
5.13. MySQL查詢高速緩衝
5.13.1. 查詢高速緩衝如何工作
5.13.2. 查詢高速緩衝SELECT選項
5.13.3. 查詢高速緩衝配置
5.13.4. 查詢高速緩衝狀態和維護

本章涵蓋了MySQL安裝管理主題,例如配置伺服器、管理用戶帳號和備份。

5.1. MySQL伺服器和伺服器啟動指令

MySQL伺服器,即mysqld,是在MySQL安裝中負責大部分工作的主程式。伺服器隨附了幾個相關指令,當您安裝MySQL時它們可以執行設置操作,或者是幫助您啟動和停止伺服器的幫助程式。

本節提供了伺服器和相關程式的概述,以及伺服器啟動指令相關訊息。關於配置伺服器的訊息參見5.3節,「mysqld:MySQL伺服器」

5.1.1. 伺服器端指令和實用工具概述

MySQL程式採用各種不同的選項。但每個MySQL程式提供一個--help選項,您可以用來查閱程式選項相關說明。例如,您可以試試mysqld --help

您可以在命令行中或在選項檔案中指定選項來替換所有標準程式中的預設選項。參見4.3節,「指定程式選項」

下面簡單描述了MySQL伺服器和伺服器相關程式:

·         mysqld

SQL後台程式(MySQL伺服器)。要想使用客戶端程式,該程式必須運行,因為客戶端通過連接伺服器來訪問資料庫。參見5.3節,「mysqld:MySQL伺服器」

·         mysqld-max

包括更多特性的一個伺服器版本。參見5.1.2節,「mysqld-max延伸MySQL伺服器」

·         mysqld_safe

伺服器啟動指令。如果mysqld-max存在,mysqld_safe試圖啟動它,否則啟動mysqld。參見5.1.3節,「mysqld_safe:MySQL伺服器啟動指令」

·         mysql.server

伺服器啟動指令。該指令用於使用包含為特定級別的運行啟動服務的指令的運行目錄的系統。它使用mysqld_safe來啟動MySQL伺服器。參見5.1.4節,「mysql.server:MySQL伺服器啟動指令」

·         mysqld_multi

伺服器啟動指令,可以啟動或停止系統上安裝的多個伺服器。參見5.1.5節,「mysqld_multi:管理多個MySQL伺服器的程式」

·         mysql_install_db

該指令用預設權限建立MySQL授權資料表。通常只是在系統上首次安裝MySQL時執行一次。參見2.9.2節,「Unix下安裝後的過程」

·         mysql_fix_ privilege_tables

在升級安裝後,如果新版本MySQL中的 授權資料表有更改,則使用該指令來更改授權資料表。參見2.10.2節,「升級授權資料表」

伺服器主機上還運行其它幾個程式:

·         myisamchk

用來描述、檢查、最佳化和維護MyISAM資料表的實用工具。在5.9.5節,「myisamchk:MyISAM資料表維護實用工具」中描述了myisamchk

·         make_binary_distribution

該程式可以生成編譯過的MySQL的二進製版本。可以通過FTP上傳到ftp.mysql.com/pub/mysql/upload/,供其它MySQL用戶使用。

·         mysqlbug

MySQL 問題報告指令。它可以用來向MySQL郵件系統發送問題報告。(您也可以訪問http://bugs.mysql.com/線上建立問題報告檔案。參見1.7.1.3節,「如何通報問題和問題」

5.1.2. mysqld-max延伸MySQL伺服器

MySQL-Max伺服器是mysqld MySQL伺服器的一個版本,包含了更多的特性。

該分發版的使用取決於您的平台:

·         對於WindowsMySQL二進制分發版包括標準伺服器 (mysqld.exe)MySQL-Max伺服器(mysqld-max.exe),因此您不再需要專用分發版。只需要使用一個常規Windows分發版,可以從http://dev.mysql.com/downloads/獲得。參見2.3節,「在Windows上安裝MySQL」

·         對於Linux,如果您使用RPM分發版安裝MySQL,首先使用常規MySQL-server RPM來安裝標準mysqld伺服器。然後使用MySQL-Max RPM來安裝mysqld-max伺服器。MySQL-Max RPM假定您已經安裝了常規伺服器RPM。關於Linux RPM軟件包的詳細訊息,參見2.4節,「在Linux下安裝MySQL」

·         所有其它MySQL-Max分發版包含一個mysqld伺服器,但具有更多的特性。

您可以從MySQL AB網址http://dev.mysql.com/downloads/找到MySQL-Max二進製版本。

MySQL AB使用下面的configure選項構建MySQL-Max伺服器:

·         --with-server-suffix=-max

該選項為mysqld版本字串新增一個-max後綴。

·         --with-innodb

該選項啟用InnoDB儲存引擎支援。MySQL-Max伺服器包括InnoDB支援。在MySQL 4.0及以上版本中,預設InnoDB包括在所有二進制分發版中,因此您不需要用MySQL-Max伺服器只是用來獲取InnoDB支援。

·         --with-bdb

該選項啟用Berkeley DB (BDB)儲存引擎支援。

·         --with-blackhole-storage-engine

該選項啟用BLACKHOLE儲存引擎支援。

·         USE_SYMDIR

啟用該定義來為Windows打開資料庫符號連結支援。符號連結支援適用於所有Windows伺服器,因此Max伺服器不需要支援該特性。

·         --with-ndbcluster

該選項啟用NDB Cluster儲存引擎支援。目前(5.1.2-alpha)只有LinuxSolarisMac OS X支援Cluster。已有一些用戶報告在BSD 作業系統上成功使用了從原始碼構建的MySQL Cluster,但目前還沒有得到官方支援。

MySQL-Max二進制分發版對於想要安裝預編譯程式的用戶很方便。如果您使用原始碼分發版構建MySQL,您可以通過在配置時啟用MySQL-Max二進制分發版構建所用的相同的特性來構建您自己的Max-like伺服器。

MySQL-Max伺服器包括BerkeleyDB (BDB)儲存引擎,但並非所有平台支援BDB

SolarisMac OS XLinux(在大多數平台上)MySQL-Max伺服器包括NDB CLUSTER儲存引擎支援。請注意必須用ndbcluster選項啟動伺服器,以便使伺服器做為MySQL Cluster的一部分來運行。(詳細訊息參見17.4節,「MySQL叢集的配置」

下面的資料表顯示了MySQL-Max二進制在哪個平台上包括BDB/NDB CLUSTER支援:

系統

BDB支援

NDB支援

AIX 4.3

N

N

HP-UX 11.0

N

N

Linux-Alpha

N

Y

Linux-IA-64

N

N

Linux-Intel

Y

Y

Mac OS X

N

N

NetWare

N

N

SCO OSR5

Y

N

Solaris-SPARC

Y

Y

Solaris-Intel

N

Y

UnixWare

Y

N

Windows NT/2000/XP

Y

N

要想找出您的伺服器支援哪個儲存引擎,執行下面的語句:

mysql> SHOW ENGINES;
+------------+---------+----------------------------------------------------------------+
| Engine     | Support | Comment                                                        |
+------------+---------+----------------------------------------------------------------+
| MyISAM     | DEFAULT | Default engine as of MySQL 3.23 with great performance         |
| MEMORY     | YES     | Hash based, stored in memory, useful for temporary tables      |
| HEAP       | YES     | Alias for MEMORY                                               |
| MERGE      | YES     | Collection of identical MyISAM tables                          |
| MRG_MYISAM | YES     | Alias for MERGE                                                |
| ISAM       | NO      | Obsolete storage engine, now replaced by MyISAM                |
| MRG_ISAM   | NO      | Obsolete storage engine, now replaced by MERGE                 |
| InnoDB     | YES     | Supports transactions, row-level locking, and foreign keys     |
| INNOBASE   | YES     | Alias for INNODB                                               |
| BDB        | YES     | Supports transactions and page-level locking                   |
| BERKELEYDB | YES     | Alias for BDB                                                  |
| NDBCLUSTER | NO      | Clustered, fault-tolerant, memory-based tables                 |
| NDB        | NO      | Alias for NDBCLUSTER                                           |
| EXAMPLE    | NO      | Example storage engine                                         |
| ARCHIVE    | YES     | Archive storage engine                                         |
| CSV        | NO      | CSV storage engine                                             |
| FEDERATED  | YES     | Federated MySQL storage engine                                 |
| BLACKHOLE  | YES     | /dev/null storage engine (anything you write to it disappears) |
+------------+---------+----------------------------------------------------------------+
18 rows in set (0.00 sec)

(另參見13.5.4.8節,「SHOW ENGINES語法」

您還可以使用下面的語句代替SHOW ENGINES,並檢查您感興趣的儲存引擎的變數值:

mysql> SHOW VARIABLES LIKE 'have%';
+-----------------------+----------+
| Variable_name         | Value    |
+-----------------------+----------+
| have_archive          | YES      |
| have_bdb              | NO       |
| have_blackhole_engine | YES      |
| have_compress         | YES      |
| have_crypt            | YES      |
| have_csv              | YES      |
| have_example_engine   | NO       |
| have_federated_engine | NO       |
| have_geometry         | YES      |
| have_innodb           | YES      |
| have_isam             | NO       |
| have_ndbcluster       | DISABLED |
| have_openssl          | NO       |
| have_partition_engine | YES      |
| have_query_cache      | YES      |
| have_raid             | NO       |
| have_rtree_keys       | YES      |
| have_symlink          | YES      |
+-----------------------+----------+
18 rows in set (0.01 sec)

SHOW命令的精確輸出隨使用的MySQL版本(和啟用的特性)的不同而有變化。第2列的值資料表示各特性支援的伺服器級別,如下所示:

含義

YES

 支援該特性並已經激活。

NO

 不支援該特性。

DISABLED

 支援該特性但被禁用。

NO值資料表示編譯的伺服器不支援該特性,因此在運行時不能激活。

出現DISABLED值是因為伺服器啟動時該特性被禁用,或沒有給出啟用它的所有選項。在後一種情況,host_.err錯誤日誌檔案應包含該選項被禁用的原因。

如果伺服器支援InnoDBBDB儲存引擎,您還可以看見DISABLED,但在運行啟動時使用了--skip-innodb--skip-bdb選項。對於NDB CLUSTER儲存引擎,DISABLED資料表示伺服器支援MySQL Cluster,但啟動時未啟用--ndb-cluster選項。

所有MySQL伺服器支援MyISAM資料表,因為MyISAM是 預設儲存引擎。

5.1.3. mysqld_safe:MySQL伺服器啟動指令

UnixNetWare中推薦使用mysqld_safe來啟動mysqld伺服器mysqld_safe增加了一些安全特性,例如當出現錯誤時重啟伺服器並向錯誤日誌檔案寫入運行時間訊息。本節後面列出了NetWare的特定行為。

釋:為了保持同舊版本MySQL的向後相容性,MySQL二進制分發版仍然包括safe_mysqld作為mysqld_safe的符號連結。但是,您不應再依賴它,因為再將來將刪掉它。

預設情況下,mysqld_safe嘗試啟動可執行mysqld-max(如果存在),否則啟動mysqld。該行為的含義是:

·         Linux中,MySQL-Max RPM依賴該mysqld_safe的行為。RPM安裝可執行mysqld-max,使mysqld_safe從該點起自動使用可執行命令。

·         如果您安裝包括mysqld-max伺服器的MySQL-Max分發版,後面升級到非-MaxMySQL版本,mysqld_safe仍然試圖運行舊的 mysqld-max伺服器。升級時,您應手動刪除舊的mysqld-max伺服器以確保mysqld_safe運行新的mysqld伺服器

要想越過預設行為並顯式指定您想要運行哪個伺服器,為mysqld_safe指定--mysqld--mysqld-version選項。

mysqld_safe的許多選項與mysqld的相同的。參見5.3.1節,「mysqld命令行選項」

所有在命令行中為mysqld_safe指定的選項被傳遞給mysqld如果您想要使用mysqld不支援的mysqld_safe選項,不要在命令行中指定。相反,在選項檔案的[mysqld_safe]組內將它們列出來。參見4.3.2節,「使用選項檔案」

mysqld_safe從選項檔案的[mysqld][server][mysqld_safe]部分讀取所有選項。為了保證向後相容性,它還讀取 [safe_mysqld]部分,儘管在MySQL 5.1安裝中您應將這部分重新命名為[mysqld_safe]

mysqld_safe支援下面的選項:

·         --help

顯示幫助消息並退出。

·         --autoclose

(只在NetWare)NetWare中,mysqld_safe可以保持窗口。當您關掉mysqld_safe NLM時,窗口不按預設設置消失。相反,它提示用戶輸入:

*<NLM has terminated; Press any key to close the screen>*

如果您想讓NetWare自動關閉窗口,在mysqld_safe中使用--autoclose選項。

·         --basedir=path

MySQL安裝目錄的路徑。

·         --core-file-size=size

mysqld能夠建立的內核檔案的大小。選項值傳遞給ulimit -c

·         --datadir=path

數據目錄的路徑。

·           --defaults-extra-file=path

除了通用選項檔案所讀取的選項檔案名。如果給出,必須首選該選項。

·         --defaults-file=path

讀取的代替通用選項檔案的選項檔案名。如果給出,必須首選該選項。

·         --ledir=path

包含mysqld程式的目錄的路徑。使用該選項來顯式資料表示伺服器位置。

·         --log-error=path

將錯誤日誌寫入給定的檔案。參見5.11.1節,「錯誤日誌」

·         --mysqld=prog_name

想要啟動的伺服器程式名(ledir目錄)。如果您使用MySQL二進制分發版但有二進制分發版之外的數據目錄需要該選項。

·         --mysqld-version =suffix

該選項類似--mysqld選項,但您只指定伺服器程式名的後綴。基本名假定為mysqld例如,如果您使用--mysqld-version =maxmysqld_safe啟動ledir目錄中的mysqld-max程式。如果--mysqld-version的參數為空,mysqld_safe使用目錄中的mysqld

·         --nice=priority

使用nice程式根據給定值來設置伺服器的調度優先級。

·         --no-defaults

不要讀任何選項檔案。如果給出,必須首選該選項。

·         --open-files-limit=count

mysqld能夠打開的檔案的數量。選項值傳遞給 ulimit -n。請注意您需要用root啟動mysqld_safe來保證正確工作!

·         --pid-file=path

程序ID檔案的路徑。

·         --port=port_num

 用來幀聽TCP/IP連接的端口號。端口號必須為1024或更大值,除非MySQLroot系統用戶運行。

·         --skip-character-set-client-handshake

忽略客戶端發送的字元編碼訊息,使用伺服器的預設字元編碼。(選擇該選項,MySQL的動作與MySQL 4.0相同)

·         --socket=path

用於本地連接的Unix套接字檔案。

·         --timezone=zone

為給定的選項值設置TZ時區環境變數。從作業系統文檔查閱合法的時區規定格式。

·         --user={user_name | user_id}

以帳號user_name或數字用戶ID user_id運行mysqld伺服器(本文中的「用戶」指系統登錄帳號,而不是 授權資料表中的MySQL用戶)

執行mysqld_safe時,必須先給出--defaults-file--defaults-extra-option,或不使用選項檔案。例如,該命令將不使用選項檔案:

mysqld_safe --port=port_num --defaults-file=file_name

相反,使用下面的命令:

mysqld_safe --defaults-file=file_name --port=port_num

一般情況mysqld_safe指令可以啟動從原始碼或二進制MySQL分發版安裝的伺服器,即使這些分發版將伺服器安裝到稍微不同的位置。(參見2.1.5節,「安裝佈局」 mysqld_safe期望下面的其中一個條件是真的:

·         可以根據使用mysqld_safe的目錄找到伺服器和資料庫。在二進制分發版中,mysqld_safe看上去在bindata目錄的工作目錄下。對於原始碼分發版,為libexecvar目錄。如果您從MySQL安裝目錄執行mysqld_safe應滿足該條件(例如,二進制分發版為/usr/local/mysql)

·         如果不能根據工作目錄找到伺服器和資料庫,mysqld_safe試圖通過絕對路徑對它們定位。典型位置為/usr/local/libexec/usr/local/var。實際位置由構建分發版時配置的值確定如果MySQL安裝到配置時指定的位置,它們應該是正確的。

因為mysqld_safe試圖通過工作目錄找到伺服器和資料庫,只要您從MySQL安裝目錄運行mysqld_safe可以將MySQL二進制分發版安裝到其它位置:

shell> cd mysql_installation_directory
shell> bin/mysqld_safe &

如果mysqld_safe失敗,即使從MySQL安裝目錄使用仍然失敗,您可以指定--ledir--datadir選項來指示伺服器和資料庫在您的系統中的安裝目錄。

一般情況,您不應編輯mysqld_safe指令。相反,應使用命令行選項或my.cnf選項檔案的[mysqld_safe]部分的選項來配置mysqld_safe。一般不需要編輯mysqld_safe來正確啟動伺服器。但是,如果您編輯,將來升級MySQL後會覆蓋您修改的mysqld_safe版本,因此您應對您修改的版本進行備份以便將來重裝。

NetWare中,mysqld_safe是一個NetWare Loadable Module (NLM),從原Unix shell指令移植。它執行:

1.    檢查系統和選項。

2.    檢查MyISAM資料表。

3.    保持MySQL伺服器窗口。

4.    啟動並監視mysqld,如果因錯誤終止則重啟。

5.    mysqld錯誤消息發送到數據目錄中的host_name.err 檔案。

6.    mysqld_safe的屏幕輸出發送到數據目錄中的host_name.safe檔案。

5.1.4. mysql.server:MySQL伺服器啟動指令

Unix中的MySQL分發版包括mysql.server指令。它可以用於使用System V-style運行目錄來啟動和停止系統服務的系統,例如LinuxSolaris。它還用於MySQLMac OS X Startup Item

mysql.server位於MySQL原始碼樹MySQL安裝目錄下的support-files目錄中。

如果您使用Linux 伺服器RPM軟件包(MySQL-server-VERSION.rpm)mysql.server指令將安裝到/etc/init.d目錄下,名為mysql。您不需要 手動安裝。關於Linux RPM軟件包的詳細訊息參見2.4節,「在Linux下安裝MySQL」

一些賣方提供的RPM軟件包安裝的啟動指令用其它名,例如mysqld

如果您從不自動安裝mysql.server的原始碼分發版或二進制分發版格式安裝MySQL,也可以手動安裝。相關說明參見2.9.2.2節,「自動啟動和停止MySQL」

mysql.server[mysql.server]和選項檔案的[mysqld]部分讀取選項。(為了保證向後相容性,它還讀取 [safe_mysqld]部分,儘管在MySQL 5.1安裝中您應將這部分重新命名為[mysqld_safe]

5.1.5. mysqld_multi:管理多個MySQL伺服器的程式

mysqld_multi可以管理多個幀聽不同Unix套接字檔案和TCP/IP端口的連接的mysqld 程序。它可以啟動或停止伺服器,或報告它們的當前狀態。

程式尋找my.cnf中的[mysqldN](--config-file選項指定的檔案)N 可以為任何正整數。在下面的討論中該數字指選項組號,或GNR。組號區別各選項組,並用作mysqld_multi的參數來指定想要啟動、停止哪個伺服器或獲取哪個伺服器的狀態報告。這些組中的選項與將用來啟動mysqld[mysqld]組中的相同。(例如,參見2.9.2.2節,「自動啟動和停止MySQL」但是,當使用多個伺服器時,需要每個伺服器使用自己的選項值,例如Unix套接字檔案和TCP/IP端口號。關於在多伺服器環境中,每個伺服器對應唯一選項的詳細訊息,參見5.12節,「在同一台機器上運行多個MySQL伺服器」

要想使用mysqld_multi,使用下面的語法:

shell> mysqld_multi [options] {start|stop|report} [GNR[,GNR] ...]

startstopreport資料表示您想要執行的操作。您可以在單個伺服器或多個伺服器上執行指定的操作,取決於選項名後面的GNR 列。如果沒有該列,mysqld_multi為選項檔案中的所有伺服器執行該操作。

每個GNR值代資料表一個選項組號或組號範圍。GNR值應為選項檔案中組名末尾的號。例如,組[mysqld17]GNR17。要想指定組號的範圍,用破折號間隔開第1個和最後1個號。GNR10-13代資料表組[mysqld10][mysqld13]。可以在命令行中指定多個組或組範圍,用逗號間隔開。GNR列不能有空格字元(空格或tab);空格字元後面的內容將被忽略掉。

該命令使用選項組[mysqld17]啟動單個伺服器:

shell> mysqld_multi start 17

該命令停止多個伺服器,使用選項組[mysql8][mysqld10][mysqld13]

shell> mysqld_multi stop 8,10-13

使用該命令列出設置選項檔案的示範:

shell> mysqld_multi --example

mysqld_multi支援下面的選項:

·         --config-file=name

指定選項檔案名。這關係到mysqld_multi從哪裡尋找[mysqldN]選項組。沒有該選項,從通用my.cnf檔案讀所有選項。選項不影響 mysqld_multi從哪裡讀取自己的選項,總是從通用my.cnf檔案的[mysqld_multi]組讀取。

·         --example

顯示示範選項檔案。

·         --help

顯示幫助消息並退出。

·         --log=name

指定日誌檔案名。如果該檔案存在,後面為日誌輸出。

·         --mysqladmin=prog_name

用來停止伺服器的mysqladmin二進制。

·         --mysqld=prog_name

可用的mysqld二進制。請注意您還可以將該選項的值指定為mysqld_safe。選項被傳遞給 mysqld確保在PATH環境變數設定值或mysqld_safe中有mysqld所在目錄。

·         --no-log

按照標準輸出打印日誌訊息,不要寫入日誌檔案。預設情況下,輸出寫入日誌檔案。

·         --password=password

使用mysqladmin時使用的MySQL帳號的密碼。請注意該密碼值不是可選項,不像其它MySQL程式。

·         --silent

禁用警告。

·         --tcp-ip

通過TCP/IP端口而不是Unix套接字檔案來連接每個MySQL伺服器。(如果找不到套接字檔案, 伺服器仍然可以運行,但只能通過 TCP/IP端口訪問)預設情況下,使用Unix套接字檔案進行連接。該選項影響stopreport操作。

·         --user=user_name

使用mysqladmin時使用的MySQL帳號的帳號。

·         --verbose

更詳細。

·         --version

顯示版本訊息並退出。

關於mysqld_multi的一些註解:

·         確保停止mysqld伺服器(mysqladmin程式)MySQL帳號在各個伺服器中的帳號和密碼相同。並且應確保帳號具有SHUTDOWN權限。如果您想要管理的伺服器的管理帳號有許多不同的帳號或密碼,您需要在每個伺服器上建立一個帳號,並具有相同的帳號和密碼。例如,您可以執行下面的命令為每個伺服器設置一個普通multi_admin帳號:

·                shell> mysql -u root -S /tmp/mysql.sock -proot_password
·                mysql> GRANT SHUTDOWN ON *.*
·                    -> TO 'multi_admin'@'localhost' IDENTIFIED BY 'multipass'

參見5.7.2節,「權限系統工作原理」。您必須為每個mysqld伺服器執行該操作。當連接時適當更改連接參數。請注意帳號名的主機部分必須允許您用multi_admin從您想要運行mysqld_multi的主機進行連接。

·         如果您使用mysqld_safe來啟動mysqld(例如,--mysqld=mysqld_safe)--pid-file選項很重要。每個mysqld應有自己的程序ID檔案。使用mysqld_safe而不使用mysqld的好處是mysqld_safe守護」其mysqld程序,如果用kill 9發送的信號或由於其它原因(例如分段故障)程序終止,則重啟程序。請注意mysqld_safe指令需要您從某個位置啟動它。這說明運行mysqld_multi前您必須進入某個目錄。如果啟動時有問題,請參見mysqld_safe指令。特別是要檢查下列行:

·                ----------------------------------------------------------------
·                MY_PWD=`pwd`
·                # Check if we are starting this relative (for the binary release)
·                if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
·                -x ./bin/mysqld
·                ----------------------------------------------------------------

參見5.1.3節,「mysqld_safe:MySQL伺服器啟動指令」。上述行執行的測試應成功,否則您可能遇到了問題。

·         每個mysqldUnix套接字檔案和TCP/IP端口號必須不同。

·         您可能想要為mysqld使用--user選項,但為此您需要用Unix root用戶運行mysqld_multi指令。選項檔案中有選項不要緊;如果您不是超級用戶,並且您用自己的Unix帳號重啟mysqld程序,您只會得到警告。

·         重要:確保mysqld程序啟動所用Unix帳號可以完全訪問數據目錄。不要使用Unix root帳號,除非您知道您在做什麼。

·         非常重要:使用mysqld_multi前,確保理解傳遞給mysqld伺服器的選項的含義以及您為什麼想要獨立的mysqld程序。應清楚 在相同的數據目錄下使用多個mysqld伺服器的危險。使用單獨的數據目錄,除非您知道您在做什麼。線上程系統中,在相同的數據目錄下啟動多個伺服器不會得到超性能。參見5.12節,「在同一台機器上運行多個MySQL伺服器」

下面的示範顯示了您如何設置選項檔案來使用mysqld_multi。專門省去第1個和第5[mysqldN]組來說明您的選項檔案可以稍有不同。這樣給您更大的靈活性。mysqld程式重啟或停止的順序由它們在選項檔案中的順序決定。

# This file should probably be in your home dir (~/.my.cnf)
# or /etc/my.cnf
# Version 2.1 by Jani Tolonen
 
[mysqld_multi]
mysqld     = /usr/local/bin/mysqld_safe
mysqladmin = /usr/local/bin/mysqladmin
user       = multi_admin
password   = multipass
 
[mysqld2]
socket     = /tmp/mysql.sock2
port       = 3307
pid-file   = /usr/local/mysql/var2/hostname.pid2
datadir    = /usr/local/mysql/var2
language   = /usr/local/share/mysql/english
user       = john
 
[mysqld3]
socket     = /tmp/mysql.sock3
port       = 3308
pid-file   = /usr/local/mysql/var3/hostname.pid3
datadir    = /usr/local/mysql/var3
language   = /usr/local/share/mysql/swedish
user       = monty
 
[mysqld4]
socket     = /tmp/mysql.sock4
port       = 3309
pid-file   = /usr/local/mysql/var4/hostname.pid4
datadir    = /usr/local/mysql/var4
language   = /usr/local/share/mysql/estonia
user       = tonu
 
[mysqld6]
socket     = /tmp/mysql.sock6
port       = 3311
pid-file   = /usr/local/mysql/var6/hostname.pid6
datadir    = /usr/local/mysql/var6
language   = /usr/local/share/mysql/japanese
user       = jani

參見4.3.2節,「使用選項檔案」

5.2. mysqlmanager:MySQL實例管理器

MySQL實例管理器(IM)是通過TCP/IP端口運行的後台程式,用來監視和管理MySQL資料庫伺服器實例。MySQL實例管理器 適合Unix-類作業系統和Windows

可以在mysqld_safe指令使用MySQL實例管理器來啟動和停止MySQL伺服器,甚至可以從一個遠程主機MySQL實例管理器還執行mysqld_multi指令的功能(和大多數語法)。下面為MySQL實例管理器的詳細描述。

5.2.1. 用MySQL實例管理器啟動MySQL伺服器

一般情況,用mysql.server指令啟動MySQL Database ServerMySQL資料庫伺服器),通常駐留在/etc/init.d/ 檔案夾。預設情況下該指令使用mysqld_safe指令。但是,您可以在指令中將use_mysqld_safe變數設置為0()以便使用MySQL實例管理器來啟動伺服器。

在這種情況下,Instance Manager的行為取決於MySQL配置檔案中的選項。如果沒有配置檔案,MySQL實例管理器建立mysqld實例並試圖用預設(編譯嵌入的)配置來啟動。這說明如果mysqld沒有安裝到 預設位置,IM不能猜出它的位置。如果您已經在非標準位置安裝了MySQL伺服器,您應使用配置檔案。參見2.1.5節,「安裝佈局」

如果有配置檔案,IM將分析配置檔案搜索[mysqld]部分(例如[mysqld][mysqld1][mysqld2])。每個部分指定一個實例。啟動時IM將啟動所有找到的實例。IM關閉時預設停止所有實例。

請注意有一個特殊選項mysqld-path(mysqld-path = path-to-mysqld- binary),只能用IM識別。使用該變數讓IM知道mysqld二進制駐留在哪兒。您還應該為伺服器設置basedirdatadir選項。

啟用MySQL實例管理器的典型MySQL伺服器啟動/關閉循環為:

·          /etc/init.d/mysql指令啟動MySQL實例管理器。

·          MySQL實例管理器啟動所有實例並監視它們。

·         如果某個伺服器實例失敗,MySQL實例管理器重啟它。

·         如果MySQL實例管理器被關閉(例如用/etc/init.d/mysql stop命令),所有實例被MySQL實例管理器關閉。

5.2.2. 連接到MySQL實例管理器並建立用戶帳號

使用MySQL客戶端-伺服器協議來處理同MySQL實例管理器之間的通信。您不能使用標準mysql客戶端程式和MySQL C API來連接IMIM支援客戶端工具和mysql-4.1或以後的版本所分發的庫所用的MySQL客戶端-伺服器協議版本。

IM將用戶訊息保存到密碼檔案中。密碼檔案的預設位置為/etc/mysqlmanager.passwd

密碼應類似於:

petr:*35110DC9B4D8140F5DE667E28C72DD2597B5C848

要想生成密碼用--passwd選項使用IM。則輸出可以重定向到/etc/mysqlmanager.passwd檔案以新增新用戶。下面為示範命令。

./mysqlmanager --passwd >> /etc/mysqlmanager.passwd
Creating record for new user.
Enter user name: mike
Enter password: <password>
Re-type password: <password>

下面的行將加到/etc/mysqlmanager.passwd

mike:*00A51F3F48415C7D4E8908980D443C29C69B60C9

如果/etc/mysqlmanager.passwd檔案中沒有該條,則不能連接IM

5.2.3. MySQL實例管理器命令行選項

MySQL實例管理器支援許多命令行選項。執行./mysqlmanager --help命令可以簡單列出。有下面的選項:

·         --help-?

顯示幫助消息並退出。

·         --bind-address=name

綁定地址用於連接。

·         --default-mysqld-path=name

Unix中,如果實例部分沒有路徑,則為尋找MySQL伺服器二進制的地點。例如:default-mysqld-path = /usr/sbin/mysqld

·         --defaults-file=file_name

從給定檔案讀Instance ManagerMySQL伺服器設定值。所有Instance Manager更改的配置將加入該檔案。只能用於Instance Manager的第一選項。

·         --install

Windows中,將Instance Manager安裝為Windows服務。

·         --log=name

IM日誌檔案的路徑。結合--run-as-service選項使用。

·         --monitoring-interval=Seconds

監視實例的間隔,單位為秒。Instance Manager將嘗試連接每個監視的實例來檢查它們是否是活動的/沒有掛起。出現故障,IM將重啟幾次(實際上是多次)實例。可以用nonguarded選項為特定實例禁用該行為。如果未給定任何值, 預設使用20秒。

·         --passwd-P

編寫passwd檔案並退出。

·         --password-file=name

從該檔案中尋找Instance Manager用戶和密碼。預設檔案是/etc/mysqlmanager.passwd

·         --pid-file=name

使用的程序ID檔案。預設情況下,該檔案檔案名為mysqlmanager.pid

·         -- port=port_num

用於連接的端口號。(IANA分配的 預設端口號為2273)

·         --print-defaults

打印當前的預設值並退出。只能用作Instance Manager的第一選項。

·         --remove

Windows中,刪掉Instance Manager Windows服務。假定前面已經用--install運行了Instance Manager

·         --run-as-service

使完善程序變為後台程式並啟動。完善程序很簡單,不易崩潰。出現故障後它將自己重啟IM

·         --socket=name

Unix中用於連接的套接字檔案。預設情況下,檔案名為/tmp/mysqlmanager.sock

·         --standalone

Windows中以單機模式運行Instance Manager

·         --user=name

啟動並運行mysqlmanager的帳號。建議使用運行mysqld伺服器的用戶帳號來運行mysqlmanager

·         --version, -V

輸出版本訊息並退出。

5.2.4. MySQL實例管理器配置檔案

Instance Manager使用標準my.cnf檔案。它使用[manager]部分為自己讀取選項並讀取[mysqld]部分來建立實例。[manager]部分包含上述列出的選項。下面為[manager]部分示範:
# MySQL Instance Manager options section
[manager]
default-mysqld-path = /usr/local/mysql/libexec/mysqld
socket=/tmp/manager.sock
pid-file=/tmp/manager.pid
password-file = /home/cps/.mysqlmanager.passwd
monitoring-interval = 2
port = 1999
bind-address = 192.168.1.5

MySQL實例管理器只在Unix中讀取並管理/etc/my.cnf檔案。在Windows中,MySQL實例管理器從Instance Manager的安裝目錄讀取my.ini檔案。用--defaults-file=file_ name選項可以更改預設選項檔案的位置。

實例部分指定啟動時給每個實例的選項。這些主要是普通MySQL伺服器選項,但有一些IM-專用選項:

·         mysqld-path = <path-to-mysqld-binary>

mysqld伺服器二進制的路徑。

·         shutdown-delay = Seconds

IM應等待實例關閉的秒數。 預設為35秒。超過延遲時間後,IM假定實例正掛起並試圖「kill 9它。如果您使用帶large資料表的InnoDB,您應當增加該值。

·         nonguarded

如果您想要為某個實例禁用IM監視功能,應設置該選項。

下面給出了幾個實例示範。

[mysqld]
mysqld-path=/usr/local/mysql/libexec/mysqld
socket=/tmp/mysql.sock
port=3307
server_id=1
skip-stack-trace
core-file
skip-bdb
log-bin
log-error
log=mylog
log-slow-queries
 
[mysqld2]
nonguarded
port=3308
server_id=2
mysqld-path= /home/cps/mysql/trees/mysql-5.1/sql/mysqld
socket     = /tmp/mysql.sock5
pid-file   = /tmp/hostname.pid5
datadir= /home/cps/mysql_data/data_dir1
language=/home/cps/mysql/trees/mysql-5.1/sql/share/english
log-bin

log=/tmp/fordel.log

5.2.5. MySQL實例管理器識別的命令

一旦您已經為MySQL實例管理器設置了一個密碼檔案並且IM正在運行,您可以連接它。您可以使用mysql客戶端工具通過標準MySQL API來連接。以下是MySQL實例管理器目前可以接收的命令的清單和例子。

·         START INSTANCE <instance_name>

該命令將試圖啟動一個實例:

mysql> START INSTANCE mysqld4;
Query OK, 0 rows affected (0,00 sec)

·         STOP INSTANCE <instance_name>

將試圖停止一個實例:

mysql> STOP INSTANCE mysqld4;
Query OK, 0 rows affected (0,00 sec)

·         SHOW INSTANCES

顯示所有載入的實例名:

mysql> show instances;
+---------------+---------+
| instance_name | status  |
+---------------+---------+
| mysqld3       | offline |
| mysqld4       | online  |
| mysqld2       | offline |
+---------------+---------+
3 rows in set (0,04 sec)

·         SHOW INSTANCE STATUS <instance_name>

顯示選定的實例的狀態和版本訊息:

mysql> SHOW INSTANCE STATUS mysqld3;
+---------------+--------+---------+
| instance_name | status | version |
+---------------+--------+---------+
| mysqld3       | online | unknown |
+---------------+--------+---------+
1 row in set (0.00 sec)

·         SHOW INSTANCE OPTIONS <instance_name>

顯示實例使用的選項:

mysql> SHOW INSTANCE OPTIONS mysqld3;
+---------------+---------------------------------------------------+
| option_name   | value                                             |
+---------------+---------------------------------------------------+
| instance_name | mysqld3                                           |
| mysqld-path   | /home/cps/mysql/trees/mysql-4.1/sql/mysqld        |
| port          | 3309                                              |
| socket        | /tmp/mysql.sock3                                  |
| pid-file      | hostname.pid3                                     |
| datadir       | /home/cps/mysql_data/data_dir1/                   |
| language      | /home/cps/mysql/trees/mysql-4.1/sql/share/english |
+---------------+---------------------------------------------------+
7 rows in set (0.01 sec)

·         SHOW <instance_name> LOG FILES

該命令提供實例使用的所有日誌檔案。結果包含日誌檔案的路徑和日誌檔案的大小。如果沒有在配置檔案中指定日誌檔案的路徑 (例如log=/var/mysql.log)IM試圖猜出它的位置。如果IM不能猜出日誌檔案的位置,您應明確指定日誌檔案的位置。

mysql> SHOW mysqld LOG FILES;
+-------------+------------------------------------+----------+
| Logfile     | Path                               | Filesize |
+-------------+------------------------------------+----------+
| ERROR LOG   | /home/cps/var/mysql/owlet.err      | 9186     |
| GENERAL LOG | /home/cps/var/mysql/owlet.log      | 471503   |
| SLOW LOG    | /home/cps/var/mysql/owlet-slow.log | 4463     |
+-------------+------------------------------------+----------+
3 rows in set (0.01 sec)

·         SHOW <instance_name> LOG {ERROR | SLOW | GENERAL} size[,offset_from_end]

該命令搜尋指定的日誌檔案的一部分。因為大多數用戶關注最新的日誌消息,用size參數定義您想要從日誌末尾開始索取的字節數。您可以指定可選offset_from_end參數從日誌檔案中部索取數據。下面的示範可以索取21個字節的數據,從日誌檔案末尾開始23個字節,2個字節用於結束:

mysql> SHOW mysqld LOG GENERAL 21, 2;
+---------------------+
| Log                 |
+---------------------+
| using password: YES |
+---------------------+
1 row in set (0.00 sec)

·         SET instance_name.option_name=option_value

該命令編輯指定的實例的配置檔案以更改/增加實例選項。IM假定配置檔案位於/etc/my.cnf。您應檢查檔案是否存在,並具有合適的權限。

mysql> SET mysqld2.port=3322;
Query OK, 0 rows affected (0.00 sec)

MySQL伺服器重啟前,對配置檔案進行的更改不會生效。並且,執行FLUSH INSTANCES命令後,才會將這些更改保存到Instance Manager的實例設定值的本地緩存中。

·         UNSET instance_name.option_name

該命令從實例的配置檔案刪除一個選項。

mysql> UNSET mysqld2.port;
Query OK, 0 rows affected (0.00 sec)

MySQL伺服器重啟前,對配置檔案進行的更改不會生效。並且,執行FLUSH INSTANCES命令後,才會將這些更改保存到Instance Manager的實例設定值的本地緩存中。

·         FLUSH INSTANCES

該命令強制IM重讀配置檔案並清空內部結構。編輯配置檔案後應執行該命令。該命令不重啟實例:

mysql> FLUSH INSTANCES;
Query OK, 0 rows affected (0.04 sec)

5.3. mysqld:MySQL伺服器

mysqldMySQL伺服器。下面討論MySQL伺服器的配置:

·         伺服器支援的啟動選項

·         如何設置伺服器SQL模式

·         伺服器系統變數

·         伺服器狀態變數

5.3.1. mysqld命令行選項

當啟動mysqld伺服器時,您可以使用4.3節,「指定程式選項」中描述的方法指定程式選項。最常用的方法是在選項檔案中或在命令行提供選項。但是,在大多數情況下,希望伺服器每次運行時使用相同的選項。最好的方法是確保將它們列在選項檔案中。參見4.3.2節,「使用選項檔案」

mysqld[mysqld][server]組讀取選項。mysqld_safe[mysqld][server][mysqld_safe][safe_mysqld]組讀取選項。mysql.server[mysqld][mysql.server]組讀取選項。嵌入式MySQL伺服器通常從[server][embedded][xxxxx_SERVER]組讀取選項,其中xxxxx是伺服器嵌入的應用程式名。

mysqld接受許多命令行選項。執行mysqld --help可以簡單列出來。要想看全部列資料表列,使用命令mysqld --verbose --help

下面列出了一些最常用的伺服器選項。其它的選項在其它地方描述:

·         影響安全的選項:參見5.6.3節,「Mysqld安全相關啟動選項

·         SSL-相關選項:參見5.8.7.6節,「SSL命令行選項」

·         二進制日誌控制選項:參見5.11.3節,「二進制日誌」

·         複製相關選項:參見6.8節,「複製啟動選項」

·         特定儲存引擎相關選項:參見15.1.1節,「MyISAM啟動選項」15.5.3節,「BDB啟動選項」15.2.4節,「InnoDB啟動選項」

您還可以將變數名作為一個選項,設置伺服器系統變數的值,如本節後面所述。

·         --help-?

顯示簡短的幫助消息並退出。使用--verbose--help選項來看全部內容。

·         --allow-suspicious-udfs

該選項控制是否用戶定義的函數只有一個xxx符,用作可載入的主函數。預設情況下,該選項被關閉,只有至少有一個附屬符的UDF  可以載入。這樣可以防止從未包含合法UDF的共享檔案裝載函數。參見27.2.3.6節,「用戶定義函數安全注意事項」

·         --ansi

使用標準(ANSI)SQL語法代替MySQL語法。參見1.8.3節,「在ANSI模式下運行MySQL」。使用--sql-mode選項可以更精確控制伺服器SQL模式。

·         --basedir=path, -b path

MySQL安裝目錄的路徑。通常所有路徑根據該路徑來解析。

·         --bind-address=IP

待綁定的IP地址。

·         --bootstrap

mysql_install_db指令使用該選項來建立MySQL授權資料表,不需要啟動MySQL伺服器。

·         --console

將錯誤日誌消息寫入stderrstdout,即使指定了--log-error。在Windows中,如果使用該選項,mysqld不關閉控制台窗口。

·         --character-sets-dir=path

字元編碼安裝的目錄。參見5.10.1節,「數據和排序用字元編碼」

·         --chroot=path

通過chroot()系統使用在啟動過程中將mysqld伺服器放入一個封閉環境中。這是推薦的一個安全措施。請注意使用該選項可以 限制LOAD DATA INFILESELECT ... INTO OUTFILE

·         --character-set-server=charset

使用charset作為 預設伺服器字元編碼。參見5.10.1節,「數據和排序用字元編碼」

·         --core-file

如果mysqld終止,寫內核檔案。在某些系統中,您還必須為mysqld_safe指定--core-file-size 選項。參見5.1.3節,「mysqld_safe:MySQL伺服器啟動指令」。請注意對於一些系統,例如Solaris,如果您使用--user選項不會獲得內核檔案。

·         --collation-server=collation

使用collation作為 預設伺服器校對規則。參見5.10.1節,「數據和排序用字元編碼」

·         --datadir=path, -h path

數據目錄的路徑。

·         --debug[=debug_options], -# [debug_options]

如果MySQL配置了--with-debug,您可以使用該選項來獲得一個跟蹤檔案,跟蹤mysqld正進行的操作。debug_options字串通常為'd:t:ofile_name'。參見E.1.2節,「建立跟蹤檔案」

·         (DEPRECATED) --default-character-set=charset

使用char設置作為 預設字元編碼。由於--character-set-server,反對使用該選項。參見5.10.1節,「數據和排序用字元編碼」

·         --default-collation=collation

使用collation 作為預設校對規則。由於--collation-server,反對使用該選項。參見5.10.1節,「數據和排序用字元編碼」

·         --default-storage-engine=type

該選項為--default-table-type的同義詞。

·         --default-table-type=type

設置資料表的預設類型。參見第15章:儲存引擎和資料表類型

·         --default-time-zone=type

設置預設伺服器時區。該選項設置全局time_zone系統變數。如果未給出該選項, 預設時區與系統時區相同(system_time_zone系統變數值給定)

·         --delay-key-write[= OFF | ON | ALL]

如何使用DELAYED KEYS選項。鍵寫入延遲會造成再次寫MyISAM資料表時鍵緩衝區不能被清空。OFF禁用延遲的鍵寫入。ON啟用用DELAYED KEYS選項建立的資料表的延遲的鍵寫入。ALL延遲所有MyISAM資料表的鍵寫入。參見7.5.2節,「調節伺服器參數」。參見15.1.1節,「MyISAM啟動選項」

釋:如果您將該變數設置為ALL,您不應從另一個正使用MyISAM資料表的程式中使用MyISAM資料表(例如從另一個MySQL伺服器或用myisamchk)。這樣操作會導致索引破壞。

·         --des-key-file=file_name

從該檔案讀DES_ENCRYPT()DES_DECRYPT()使用的 預設鍵。

·         --enable-named-pipe

啟用命名管道支援。該選項只適用Windows NT2000XP2003系統,並且只適用支援命名管道連接的mysqld-ntmysqld-max-nt伺服器。

 

·         --exit-info[=flags], -T [flags]

這是不同標誌的一個位掩碼,您可以用來調試mysqld伺服器。不要使用該選項,除非您確切知道它在做什麼!

·         --external-locking

啟用系統鎖定。請注意如果您在lockd不能完全工作的系統上使用該選項(例如在Linux)mysqld容易死鎖。該選項以前叫--enable-locking

釋:如果您在許多MySQL程序中使用該選項來更新MyISAM資料表,您必須確保滿足下述條件:

o        使用正被另一個程序更新的資料表的查詢的緩存不可使用。

o        不應在共享資料表中使用--delay-key-write=ALLDELAY_KEY_WRITE=1

最簡單的方法是結合使用--external-locking--delay-key-write=OFF --query-cache-size=0

(預設不能實現,因為在許多設置中,結合使用上述選項很有用)

·         --flush

執行SQL語句後向硬盤上清空更改。一般情況執行SQL語句後 MySQL向硬盤寫入所有更改,讓作業系統處理與硬盤的同步。參見A.4.2節,「如果MySQL依然崩潰,應作些什麼」

·         --init-file=file

啟動時從該檔案讀SQL語句。每個語句必須在同一行中並且不應包括註釋。

·         --language=lang_name, -L lang_name

用給定語言給出客戶端錯誤消息。lang_name可以為語言名或語言檔案安裝目錄的全路徑名。參見5.10.2節,「設置錯誤消息語言」

·         --large-pages

一些硬件/作業系統架構支援大於 預設值(通常4 KB)的內存頁。實際支援取決於使用的硬件和OS。大量訪問內存的應用程式通過使用較大的頁,降低了Translation Lookaside Buffer (TLB)損失,可以改善性能。

目前,MySQL只在Linux中支援大頁面(Linux中被稱作HugeTLB)。我們已經計劃將該支援延伸到FreeBSDSolaris和其它可能的平台。

Linux中可以使用大頁面前,需要配置HugeTLB內存池。參考Linux內核原始碼中的hugetlbpage.txt檔案。

預設情況下該選項被禁用。

·         ---log[=file], -l [file]

日誌連接和對檔案的查詢。參見5.11.2節,「通用查詢日誌」。如果您不指定檔案名,MySQL使用host_name.log作為檔案名。

·         --log-bin=[file]

二進制日誌檔案。將更改數據的所有查詢記入該檔案。用於備份和複製。參見5.11.3節,「二進制日誌」。建議指定一個檔案名(原因參見A.8.1節,「MySQL中的打開事宜」),否則MySQL使用host_name-bin作為日誌檔案基本名。

·         --log-bin-index[=file]

二進制日誌檔案名的索引檔案。參見5.11.3節,「二進制日誌」。如果您不指定檔案名,並且如果您沒有在--log-bin中指定,MySQL使用host_name-bin.index作為檔案名。

·         --log-bin-trust-routine-creators[={0|1}]

沒有參數或參數為1,該選項將系統變數log_bin_trust_routine_creators設置為1。為參數 0時,該選項將系統變數設置為0log_bin_trust_routine_creators影響MySQL如何對保存的程式的建立強加限制。參見20.4節,「儲存子程式和觸發程式的二進制日誌功能」

·         --log-error[=file]

該檔案的日誌錯誤和啟動消息。參見5.11.1節,「錯誤日誌」。如果您不指定檔案名,MySQL使用host_name.err作為檔案名。如果檔案名沒有延伸名,則加上.err延伸名。

·         --log-isam[=file]

將所有MyISAM更改記入該檔案(只有調試MyISAM時才使用)

·         (DEPRECATED) --log-long-format

記錄激活的更新日誌、二進制更新日誌、和慢查詢日誌的大量訊息。例如,所有查詢的帳號和時間戳將記錄下來。不贊成選用該選項,因為它現在代資料表 預設記錄行為。(參見--log-short-format描述)--log-queries-not-using-indexes選項適合將未使用索引的查詢記錄到慢查詢日誌中。

·         --log-queries-not-using-indexes

如果您結合--log-slow-queries使用該選項,未使用索引的查詢也被記錄到慢查詢日誌中。參見5.11.4節,「慢速查詢日誌」

·         --log-short-format

記錄激活的更新日誌、二進制更新日誌、和慢查詢日誌的少量訊息。例如,帳號和時間戳不記錄下來。

·         ---log-slow-admin-statements

將慢管理語句例如OPTIMIZE TABLEANALYZE TABLEALTER TABLE記入慢查詢日誌。

·         --log-slow-queries[=file]

將所有執行時間超過long_query_time 秒的查詢記入該檔案。參見5.11.4節,「慢速查詢日誌」。詳細訊息參見--log-long-format--log-short-format選項描述。

 

·         --log-warnings, -W

將警告例如Aborted connection...打印到錯誤日誌。建議啟用該選項,例如,如果您使用複製 (您可以得到關於所發生事情的詳細訊息,例如關於網絡故障和重新連接的消息)。預設情況下啟用該選項;要想禁用它,使用--skip-log-warnings。中斷的連接不會記入錯誤日誌,除非值大於1。參見A.2.10節,「通信錯誤和失效連接」

·         --low-priority-updates

資料表修改(INSERT, REPLACE, DELETE, UPDATE)比選擇的優先級要低。也可以通過{INSERT | REPLACE | DELETE | UPDATE} LOW_PRIORITY ... 來降低某個查詢的優先級來實現,或通過SET LOW_PRIORITY_UPDATES=1來更改一個線程的優先級。參見7.3.2節,「資料表鎖定事宜」

·          --memlock

mysqld 程序鎖定在內存中。在支援mlockall()系統使用的系統上有效,例如Solaris。如果作業系統使mysqld在硬盤上交換時出現問題,可以為您提供幫助。請注意使用該選項時需要以root運行伺服器,但從安全考慮並不是一個好注意。

·         --myisam-recover [=option[,option...]]]

將儲存引擎MyISAM設置為恢復模式。該選項值是DEFAULTBACKUPFORCEQUICK值的任何組合。如果您指定多個值,用逗號間隔開。您還可以使用""值來禁用該選項。使用如果該選項,當mysqld打開MyISAM資料表時,檢查是否資料表標記為崩潰或沒有正確關閉。(只有用--skip-external-lockingare運行時,最後的選項才工作)如果是這種情況,mysqld則檢查 資料表。如果資料表被破壞,mysqld試圖維護它。

下面的選項影響維護工作:

選項

描述

DEFAULT

與沒有使用--myisam-recover選項相同。

BACKUP

如果在恢復過程中,數據檔案被更改了,將tbl_name.MYD檔案備份為tbl_name-datetime.BAK

FORCE

即使.MYD檔案將丟掉多個行也進行恢復。

QUICK

如果沒有刪除塊,不要檢查資料表中的行。

在資料表自動修復前,MySQL錯誤日誌新增一條註解。如果您不想用戶干涉干涉大多數問題,您應使用BACKUP,FORCE選項。該選項強制維護資料表,即使一些行將會被刪除也不例外,但它保持舊的數據檔案做為備份,以便您可以在後來進行檢查。

·         --ndb-connectstring=connect_string

當使用NDB儲存引擎時,可以指出通過設置連接字串選項來分發群集配置的管理伺服器。相關語法參見17.4.4.2節,「MySQL叢集連接字串」

·         --ndbcluster

如果二進制支援NDB CLUSTER儲存引擎,使用該選項可以代替禁用MySQL Cluster支援的 預設設置。參見第17章:MySQL叢集

·         --old-passwords

強制伺服器為新密碼生成短(4.1)密碼哈希。如果伺服器必須支援舊客戶端程式,為保證相容性這很有用。參見5.7.9節,「MySQL 4.1中的密碼哈希處理」

·         --one-thread

只使用一個線程(用於在Linux中調試)。只有伺服器啟用了調試,該選項才可用。參見E.1節,「調試MySQL伺服器」

·         --open-files-limit=count

用來更改mysqld檔案描述符的數量。如果沒有設置或設置為0,則mysqld通過setrlimit()使用該值來保存檔案描述符。如果該值為0,則mysqld 保存max_connections*5max_connections + table_cache*2(取較大者)個檔案。如果mysqld給出您錯誤"打開的檔案太多。",您應試試增加該值。

·         --pid-file=path

mysqld_safe使用的程序ID檔案的路徑。

·         --port=port_num, -P port_num

幀聽TCP/IP連接時使用的端口號。

·         --safe-mode

跳過一些最佳化階段。

·         (DEPRECATED) --safe-show-database

參見5.7.3節,「MySQL提供的權限」

·         --safe-user-create

啟用後如果用戶沒有mysql.user資料表或資料表中列的INSERT權限,則用戶不能用GRANT語句建立新用戶。

·         --secure-auth

不允許使用舊(4.1之前)密碼的帳號進行鑒定。

·         --shared-memory

啟用本地客戶端的共享內存連接。該選項只用於Windows

·         --shared-memory-base-name=name

共享內存連接名。該選項只用於Windows

·         --skip-bdb

禁用BDB儲存引擎。這樣可以節省內存,並可能加速某些操作。如果您需要BDB資料表則不要使用該選項。

·         --skip-concurrent-insert

關閉在同一時間在MyISAM資料表中選擇和插入的能力。(只有您發現問題時才使用該選項)

·         --skip-external-locking

不要使用系統鎖定。要想使用myisamchk,您必須關閉伺服器。(參見1.4.3節,「MySQL穩定性」要避免該需求,使用MySQL Monitor中的CHECK TABLEREPAIR TABLE來檢查並維護MyISAM資料表。

·         --skip-grant-tables

該選項使伺服器不使用權限系統。該權限允許訪問伺服器的用戶不受限制地訪問所有資料庫。您可以從系統外殼命令行執行mysqladmin flush-privilegesmysqladmin reload命令,或執行MySQL FLUSH PRIVILEGES語句讓運行的伺服器重新開始使用 授權資料表。

·         --skip-host-cache

為了更快地在名稱-IP之間進行解析,不要使用內部主機名緩存。相反,每次客戶端連接時查詢DNS伺服器。參見7.5.6節,「MySQL如何使用DNS」

·         --skip-innodb

禁用InnoDB儲存引擎。這樣可以節省內存,並可能加速某些操作。如果您需要BDB資料表則不要使用該選項。

·         --skip-name-resolve

不要解析正檢查客戶端連接的主機名。只使用IP號。如果您使用該項, 授權資料表中的所有Host列值必須為IP號或localhost。參見7.5.6節,「MySQL如何使用DNS」

·         --skip-ndbcluster

禁用NDB CLUSTER儲存引擎。這是支援NDB CLUSTER儲存引擎的二進制的預設設置,說明只有用--ndbcluster選項顯式覆蓋--skip-ndbcluster選項時,系統才為該儲存引擎分配內存和其它資源。使用示範參見17.4.3節,「MySQL叢集的快速測試設置」

·         --skip-networking

不幀聽TCP/IP連接。必須通過命名管道或共享內存(Windows)Unix套接字檔案(Unix)完成mysqld的相互操作。對於只允許本地客戶端的系統,大力推薦該選項。參見7.5.6節,「MySQL如何使用DNS」

·         --standalone

只適合基於Windows-NT的系統;指導MySQL伺服器不做為服務來運行。

·         --symbolic-links, --skip-symbolic-links

啟用或禁用符號連結支援。在WindowsUnix中,該選項的作用是不同的:

o        Windows中,啟用符號連結,您可以通過建立包含實際目錄路徑的directory.sym檔案來建立資料庫目錄的符號連結。參見7.6.1.3節,「在Windows平台上使用關於資料庫的符號連結」

Unix中,啟用符號連結資料表示您可以用CREATE TABLE語句的INDEX DIRECTORYDATA DIRECTORY選項將MyISAM索引檔案或數據檔案連結到另一個目錄。如果您刪除或重新命名資料表,符號連結所指的檔案也被刪除或重新命名。參見13.1.5節,「CREATE TABLE語法」

·         --skip-safemalloc

如果MySQL配置了--with-debug=full,所有MySQL程式在內存分配和釋放時檢查內存是否溢出。檢查很慢,因此如果您不需要您可以用--skip-safemalloc選項來避免。

·         --skip-show-database

使用該選項,只允許具有SHOW DATABASES權限的用戶執行SHOW DATABASES語句,該語句顯示所有資料庫名。不使用該選項,允許所有用戶執行SHOW DATABASES,但只向具有SHOW DATABASES權限或部分資料庫權限的用戶顯示每個資料庫名。請注意全局權限為資料庫的一種權限。

·         --skip-stack-trace

不跟蹤寫堆棧。當調試運行mysqld時該選項有用。在一些系統中,您還必須使用該選項來獲得內核檔案。參見E.1節,「調試MySQL伺服器」

·         --skip-thread-priority

在快速響應中禁用線程優先級。

·         --socket=path

Unix中,該選項指定用於本地連接的Unix套接字檔案。 預設值是/tmp/mysql.sock。在Windows中,該選項指定本地連接所使用的管道名。 預設值是MySQL

·         --sql-mode=value[,value[,value...]]

MySQL設置為SQL模式。參見5.3.2節,「SQL伺服器模式」

·         --temp-pool

該選項使伺服器建立的大多數臨時檔案使用一系列檔案名,而不是每個新檔案使用唯一的檔案名。這樣解決了在Linux內核中用 不同的名建立許多新檔案的問題。在以前,Linux似乎「洩漏」內存,因為它被直接分配到directory entry緩存而不是硬盤緩存。

·         --transaction-isolation=level

設置預設事務隔離級別,可以READ-UNCOMMITTEDREAD-COMMITTEEREPEATABLE-READSERIALIZABLE。參見13.4.6節,「SET TRANSACTION語法」

·         --tmpdir=path, -t path

建立臨時檔案的目錄路徑。預設/tmp目錄在太小不能容納臨時資料表的分區時該選項很有用。該選項接受round-robin模式的幾個路徑。在Unix中路徑應用冒號(:) 間隔開,在WindowsNetWareOS/2中用分號() 間隔開。如果MySQL伺服器為複製從機,您不應讓--tmpdir指向基於內存的檔案系統中的目錄或伺服器主機重啟時會清除的目錄。複製從機需要臨時檔案,機器重啟時可以複製臨時資料表或執行LOAD DATA INFILE操作。如果伺服器重啟時臨時檔案目錄中的檔案丟失,複製失敗。

·         --user={user_name | user_id}, -u {user_name | user_id}

user_name或數字用戶ID user_id運行mysqld伺服器(用戶」指系統登錄帳號,而不是 授權資料表中所列的MySQL用戶)

root啟動mysqld強制使用該選項。伺服器在啟動序列中更改用戶ID,讓它做為具體用戶而不是root運行。參見5.6.1節,「通用安全指南」

要避免用戶在my.cnf檔案中新增--user=root選項(使伺服器用root運行)時可能出現的安全漏洞,mysqld只使用指定的第1--user選項,如果有多個--user選項則會出現警告。在命令行選項前處理/etc/my.cnf$MYSQL_HOME/my.cnf中的選項,因此建議您在/etc/my.cnf中放一個--user選項,並指定root之外的其它值。在其它--user選項前先找到/etc/my.cnf中的選項,確保伺服器用其它用戶運行,如果找到其它--user選項則會出現警告。

·         --version, -V

顯示版本訊息並退出。

您可以使用--var_name=value形式的選項為伺服器系統變數。例如,--key_buffer_size=32M將變數key_buffer_size設為32MB

請注意設置變數時,MySQL可以自動將它糾正到某個給定範圍內,或如果只允許某個值,則將設置值調節到最接近允許的值。

還可以通過--set-variable=var_name=value-O var_name=value語法來設置變數。但是,現在不贊成使用該語法。

5.3.3節,「伺服器系統變數」完全描述了全部系統變數。調節伺服器參數部分包括如何對他們進行最佳化。參見7.5.2節,「調節伺服器參數」

您可以用SET語句更改大多數伺服器系統變數的值。參見13.5.3節,「SET語法」

如果您想用SET 限制啟動項可設的最大值,您可以使用--maximum-var_name命令行選項來定義。

5.3.2. SQL伺服器模式

MySQL伺服器可以以不同的SQL模式來操作,並且可以為不同客戶端應用不同模式。這樣每個應用程式可以根據自己的需求來定制伺服器的操作模式。

模式定義MySQL應支援哪些SQL語法,以及應執行哪種數據驗證檢查。這樣可以更容易地在不同的環境中使用MySQL,並結合其它資料庫伺服器使用MySQL

您可以用--sql-mode="modes"選項啟動mysqld設置預設SQL模式。如果您想要重設,該值還可以為空(--sql-mode ="")

您還可以在啟動後用SET [SESSION|GLOBAL] sql_mode='modes'語句設置sql_mode變數來更改SQL模式。設置 GLOBAL變數時需要擁有SUPER權限,並且會影響從那時起連接的所有客戶端的操作。設置SESSION變數只影響當前的客戶端。任何客戶端可以隨時更改自己的會話 sql_mode值。

Modesis是用逗號()間隔開的一系列不同的模式。您可以用SELECT @@sql_mode語句查詢當前的模式。預設值是空(沒有設置任何模式)

主要重要sql_mode值為:

·         ANSI

更改語法和行為,使其更符合標準SQL

·         STRICT_TRANS_TABLES

如果不能將給定的值插入到事務資料表中,則放棄該語句。對於非事務資料表,如果值出現在單行語句或多行語句的第1行,則放棄該語句。本節後面給出了更詳細的描述。

·         TRADITIONAL

Make MySQL的行為象「傳統SQL資料庫系統。該模式的簡單描述是當在列中插入不正確的值時「給出錯誤而不是警告」。釋:一旦發現錯誤立即放棄INSERT/UPDATE。如果您使用非事務儲存引擎,這種方式不是您想要的,因為出現錯誤前進行的數據更改不會「滾動」,結果是更新「只進行了一部分」。

本手冊指「嚴格模式」,資料表示至少STRICT _TRANS_TABLESSTRICT _ALL_TABLES被啟用的模式。

下面描述了支援的所有模式:

·         ALLOW_INVALID_DATES

在嚴格模式下不要檢查全部日期。只檢查112之間的月份和131之間的日。這在Web應用程式中,當您從三個不同的字段獲取年、月、日,並且想要確切保存用戶插入的內容(不進行日期驗證)時很重要。該模式適用於DATEDATETIME列。不適合TIMESTAMP列,TIMESTAMP列需要驗證日期。

啟用嚴格模式後,伺服器需要合法的月和日,不僅僅是分別在112131範圍內。例如,禁用嚴格模式時'2004-04-31'是合法的,但啟用嚴格模式後是非法的。要想在嚴格模式允許遮掩固定日期,還應啟用ALLOW_INVALID_DATES

·         ANSI_QUOTES

將『"』視為識別符引號(`』引號字元),不要視為字串的引號字元。在ANSI模式,您可以仍然使用『`』來引用識別符。啟用ANSI_QUOTES後,您不能用雙引號來引用字串,因為它被解釋為識別符。

·         ERROR_FOR_DIVISION_BY_ZERO

在嚴格模式,在INSERTUPDATE過程中,如果被零除(MOD(X0)),則產生錯誤(否則為警告)。如果未給出該模式,被零除時MySQL返回NULL。如果用到INSERT IGNOREUPDATE IGNORE中,MySQL生成被零除警告,但操作結果為NULL

·         HIGH_NOT_PRECEDENCE

NOT操作符的優先順序是資料表達式例如NOT a BETWEEN b AND c被解釋為NOT (a BETWEEN b AND c)。在一些舊版本MySQL中, 資料表達式被解釋為(NOT a) BETWEEN b AND c。啟用HIGH_NOT_PRECEDENCESQL模式,可以獲得以前的更高優先級的結果。

mysql> SET sql_mode = '';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
        -> 0
mysql> SET sql_mode = 'broken_not';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
        -> 1

·         IGNORE_SPACE

允許函數名和『(』之間有空格。強制將所有函數名視為保存的字。結果是,如果您想要訪問保存為字的資料庫、資料表或列名,您必須引用它。例如,因為有USER()函數,mysql資料庫中的user資料表名和該資料表內的User列被保存下來,因此您必須引用它們:

SELECT "User" FROM mysql."user";

·         NO_AUTO_CREATE_USER

防止GRANT自動建立新用戶,除非還指定了密碼。

·         NO_AUTO_VALUE_ON_ZERO

NO_AUTO_VALUE_ON_ZERO影響AUTO_INCREMENT列的處理。一般情況,您可以向該列插入NULL0生成下一個序列號。NO_AUTO_VALUE_ON_ZERO禁用0,因此只有NULL可以生成下一個序列號。

如果將0保存到資料表的AUTO_INCREMENT列,該模式會很有用。(不推薦採用該慣例)。例如,如果您用mysqldump轉儲資料表並重載,MySQL遇到0值一般會生成新的序列號,生成的資料表的內容與轉儲的資料表不同。重載轉儲檔案前啟用NO_AUTO_VALUE_ON_ZERO可以解決該問題。mysqldump在輸出中自動包括啟用NO_AUTO_VALUE_ON_ZERO的語句。

·         NO_BACKSLASH_ESCAPES

禁用反斜線字元(\)做為字串內的退出字元。啟用該模式,反斜線則成為普通字元。

·         NO_DIR_IN_CREATE

建立資料表時,忽視所有INDEX DIRECTORYDATA DIRECTORY指令。該選項對從複製伺服器有用。

·         NO_ENGINE_SUBSTITUTION

如果需要的儲存引擎被禁用或未編譯,可以防止自動替換儲存引擎。

·         NO_FIELD_OPTIONS

不要在SHOW CREATE TABLE的輸出中打印MySQL專用列選項。該模式在可移植模式(portability mode)下用於mysqldump

·         NO_KEY_OPTIONS

不要在SHOW CREATE TABLE的輸出中打印MySQL專用索引選項。該模式在可移植模式(portability mode)下用於mysqldump

·         NO_TABLE_OPTIONS

不要在SHOW CREATE TABLE的輸出中打印MySQL專用資料表選項(例如ENGINE)。該模式在可移植模式(portability mode)下用於mysqldump

·         NO_UNSIGNED_SUBTRACTION

在減運算中,如果某個操作數沒有符號,不要將結果標記為UNSIGNED。請注意這樣使UNSIGNED BIGINT不能100%用於上下文中。參見12.8節,「Cast函數和操作符」

 

·         NO_ZERO_DATE

在嚴格模式,不要將 '0000-00-00'做為合法日期。您仍然可以用IGNORE選項插入零日期。在非嚴格模式,可以接受該日期,但會生成警告。

·         NO_ZERO_IN_DATE

在嚴格模式,不接受月或日部分為0的日期。如果使用IGNORE選項,我們為類似的日期插入'0000-00-00'。在非嚴格模式,可以接受該日期,但會生成警告。

·         ONLY_FULL_GROUP_BY

不要讓GROUP BY部分中的查詢指向未選擇的列。

·         PIPES_AS_CONCAT

||視為字串連接操作符(+)(CONCAT()),而不視為OR

·         REAL_AS_FLOAT

REAL視為FLOAT的同義詞,而不是DOUBLE的同義詞。

·         STRICT_TRANS_TABLES

為所有儲存引擎啟用嚴格模式。非法數據值被拒絕。後面有詳細說明。

·         STRICT_TRANS_TABLES

為事務儲存引擎啟用嚴格模式,也可能為非事務儲存引擎啟用嚴格模式。後面有詳細說明。

嚴格模式控制MySQL如何處理非法或丟失的輸入值。有幾種原因可以使一個值為非法。例如,數據類型錯誤,不適合列,或超出範圍。當新插入的行不包含某列的沒有顯示定義DEFAULT子句的值,則該值被丟失。

對於事務資料表,當啟用STRICT_ALL_TABLESSTRICT_TRANS_TABLES模式時,如果語句中有非法或丟失值,則會出現錯誤。語句被放棄並滾動。

對於非事務資料表,如果插入或更新的第1行出現壞值,兩種模式的行為相同。語句被放棄,資料表保持不變。如果語句插入或修改多行,並且壞值出現在第2或後面的行,結果取決於啟用了哪個嚴格選項:

·         對於STRICT_ALL_TABLESMySQL返回錯誤並忽視剩餘的行。但是,在這種情況下,前面的行已經被插入或更新。這說明您可以部分更新,這可能不是您想要的。要避免這點,最好使用單行語句,因為這樣可以不更改資料表即可以放棄。

·         對於STRICT_TRANS_TABLESMySQL將非法值轉換為最接近該列的合法值並插入調整後的值。如果值丟失,MySQL在列中插入隱式 預設值。在任何情況下,MySQL都會生成警告而不是給出錯誤並繼續執行語句。13.1.5節,「CREATE TABLE語法」描述了隱式預設值。

嚴格模式不允許非法日期,例如'2004-04-31'。它不允許禁止日期使用「零」部分,例如'2004-04-00'或「」日期。要想禁止,應在嚴格模式基礎上,啟用NO_ZERO_IN_DATENO_ZERO_DATE SQL模式。

如果您不使用嚴格模式(即不啟用STRICT_TRANS_TABLESSTRICT_ALL_TABLES模式),對於非法或丟失的值,MySQL將插入調整後的值並給出警告。在嚴格模式,您可以通過INSERT IGNOREUPDATE IGNORE來實現。參見13.5.4.22節,「SHOW WARNINGS語法」

下面的特殊模式快速組合了前面所列的模式。

其中包括大多數最新版本MySQL中的所有模式值。舊版本中,組合模式不包括新版本中沒有的不適用的具體模式值。

·         ANSI

等同REAL_AS_FLOATPIPES_AS_CONCATANSI_QUOTESIGNORE_SPACE。參見1.8.3節,「在ANSI模式下運行MySQL」

·         DB2

等同PIPES_AS_CONCATANSI_QUOTESIGNORE_SPACENO_KEY_OPTIONSNO_TABLE_OPTIONSNO_FIELD_OPTIONS

·         MAXDB

等同PIPES_AS_CONCATANSI_QUOTESIGNORE_SPACENO_KEY_OPTIONSNO_TABLE_OPTIONSNO_FIELD_OPTIONSNO_AUTO_CREATE_USER

·         MSSQL

等同PIPES_AS_CONCATANSI_QUOTESIGNORE_SPACENO_KEY_OPTIONSNO_TABLE_OPTIONSNO_FIELD_OPTIONS

·         MYSQL323

等同NO_FIELD_OPTIONSHIGH_NOT_PRECEDENCE

·         MYSQL40

等同NO_FIELD_OPTIONSHIGH_NOT_PRECEDENCE

·         ORACLE

等同PIPES_AS_CONCATANSI_QUOTESIGNORE_SPACENO_KEY_OPTIONSNO_TABLE_OPTIONSNO_FIELD_OPTIONSNO_AUTO_CREATE_USER

·         POSTGRESQL

等同PIPES_AS_CONCATANSI_QUOTESIGNORE_SPACENO_KEY_OPTIONSNO_TABLE_OPTIONSNO_FIELD_OPTIONS

·         TRADITIONAL

等同STRICT_TRANS_TABLES、STRICT_ALL_TABLES、NO_ZERO_IN_DATE、NO_ZERO_DATE、ERROR_FOR_DIVISION_BY_ZERO、NO_AUTO_CREATE_USER。

5.3.3. 伺服器系統變數

伺服器將維護許多資料表示其配置的系統變數。所有變數均有預設值。可以在命令行中或選項檔案設置選項在伺服器啟動時對它們進行設置。大多數可以在運行時使用SET語句來設置。

mysqld伺服器維護兩種變數。全局變數影響伺服器的全局操作。會話變數影響具體客戶端連接相關操作。

伺服器啟動時,將所有全局變數初始化為預設值。可以在選項檔案或命令行中指定的選項來更改這些預設值。伺服器啟動後,通過連接伺服器並執行SET GLOBAL var_name語句可以更改動態全局變數。要想更改全局變數,必須具有SUPER權限。

伺服器還為每個客戶端連接維護會話變數。連接時使用相應全局變數的當前值對客戶端會話變數進行初始化。客戶可以通過SET SESSION var_name語句來更改動態會話變數。設置會話變數不需要特殊權限,但客戶可以只更改自己的會話變數,而不更改其它客戶的會話變數。

任何訪問全局變數的客戶端都可以看見對全局變數的更改。但是,它只影響在更改後連接的從該全局變數初始化相應會話變數的客戶端。它不會影響已經連接上的客戶端的會話變數(甚至是執行SET GLOBAL語句的客戶端)

當使用啟動選項設置變數時,變數值可以使用後綴KMG分別資料表示千字節、兆字節或gigabytes。例如,下面的命令啟動伺服器時的鍵值緩衝區大小為16 megabytes

mysqld --key_buffer_size=16M

後綴的大小寫美關係;16M16m是同樣的。

運行時,使用SET語句來設置系統變數。此時,不能使用後綴,但值可以採取下列資料表達式:

mysql> SET sort_buffer_size = 10 * 1024 * 1024;

要想顯式指定是否設置全局或會話變數,使用GLOBALSESSION選項:

mysql> SET GLOBAL sort_buffer_size = 10 * 1024 * 1024;
mysql> SET SESSION sort_buffer_size = 10 * 1024 * 1024;

兩個選項均沒有,則語句設置會話變數。

5.3.3.1節,「動態系統變數」中列出了可以在運行時設置的變數。

如果您想用SET語句限制系統變數可設的最大值,可以在伺服器啟動時通過--maximum-var_name形式的選項來指定。例如,要想防止query_cache_size的值運行時超過32MB,使用選項--maximum-query_cache_size=32M

您可以通過SHOW VARIABLES語句查看系統變數及其值。詳細訊息參見9.4節,「系統變數」

mysql> SHOW VARIABLES;
+---------------------------------+-------------------------------------------+
| Variable_name                   | Value                                     |
+---------------------------------+-------------------------------------------+
| auto_increment_increment        | 1                                         |
| auto_increment_offset           | 1                                         |
| automatic_sp_privileges         | ON                                        |
| back_log                        | 50                                        |
| basedir                         | /home/jon/bin/mysql/                      |
| binlog_cache_size               | 32768                                     |
| bulk_insert_buffer_size         | 8388608                                   |
| character_set_client            | latin1                                    |
| character_set_connection        | latin1                                    |
| character_set_database          | latin1                                    |
| character_set_results           | latin1                                    |
| character_set_server            | latin1                                    |
| character_set_system            | utf8                                      |
| character_sets_dir              | /home/jon/bin/mysql/share/mysql/charsets/ |
| collation_connection            | latin1_swedish_ci                         |
| collation_database              | latin1_swedish_ci                         |
| collation_server                | latin1_swedish_ci                         |
| completion_type                 | 0                                         |
| concurrent_insert               | 1                                         |
| connect_timeout                 | 5                                         |
| datadir                         | /home/jon/bin/mysql/var/                  |
| date_format                     | %Y-%m-%d                                  |
| datetime_format                 | %Y-%m-%d %H:%i:%s                         |
| default_week_format             | 0                                         |
| delay_key_write                 | ON                                        |
| delayed_insert_limit            | 100                                       |
| delayed_insert_timeout          | 300                                       |
| delayed_queue_size              | 1000                                      |
| div_precision_increment         | 4                                         |
| engine_condition_pushdown       | OFF                                       |
| expire_logs_days                | 0                                         |
| flush                           | OFF                                       |
| flush_time                      | 0                                         |
| ft_boolean_syntax               | + -><()~*:""&|                            |
| ft_max_word_len                 | 84                                        |
| ft_min_word_len                 | 4                                         |
| ft_query_expansion_limit        | 20                                        |
| ft_stopword_file                | (built-in)                                |
| group_concat_max_len            | 1024                                      |
| have_archive                    | YES                                       |
| have_bdb                        | NO                                        |
| have_blackhole_engine           | YES                                       |
| have_compress                   | YES                                       |
| have_crypt                      | YES                                       |
| have_csv                        | YES                                       |
| have_example_engine             | NO                                        |
| have_federated_engine           | NO                                        |
| have_geometry                   | YES                                       |
| have_innodb                     | YES                                       |
| have_isam                       | NO                                        |
| have_ndbcluster                 | DISABLED                                  |
| have_openssl                    | NO                                        |
| have_partition_engine           | YES                                       |
| have_query_cache                | YES                                       |
| have_raid                       | NO                                        |
| have_rtree_keys                 | YES                                       |
| have_symlink                    | YES                                       |
| init_connect                    |                                           |
| init_file                       |                                           |
| init_slave                      |                                           |
| innodb_additional_mem_pool_size | 1048576                                   |
| innodb_autoextend_increment     | 8                                         |
| innodb_buffer_pool_awe_mem_mb   | 0                                         |
| innodb_buffer_pool_size         | 8388608                                   |
| innodb_checksums                | ON                                        |
| innodb_commit_concurrency       | 0                                         |
| innodb_concurrency_tickets      | 500                                       |
| innodb_data_file_path           | ibdata1:10M:autoextend                    |
| innodb_data_home_dir            |                                           |
| innodb_doublewrite              | ON                                        |
| innodb_fast_shutdown            | 1                                         |
| innodb_file_io_threads          | 4                                         |
| innodb_file_per_table           | OFF                                       |
| innodb_flush_log_at_trx_commit  | 1                                         |
| innodb_flush_method             |                                           |
| innodb_force_recovery           | 0                                         |
| innodb_lock_wait_timeout        | 50                                        |
| innodb_locks_unsafe_for_binlog  | OFF                                       |
| innodb_log_arch_dir             |                                           |
| innodb_log_archive              | OFF                                       |
| innodb_log_buffer_size          | 1048576                                   |
| innodb_log_file_size            | 5242880                                   |
| innodb_log_files_in_group       | 2                                         |
| innodb_log_group_home_dir       | ./                                        |
| innodb_max_dirty_pages_pct      | 90                                        |
| innodb_max_purge_lag            | 0                                         |
| innodb_mirrored_log_groups      | 1                                         |
| innodb_open_files               | 300                                       |
| innodb_support_xa               | ON                                        |
| innodb_sync_spin_loops          | 20                                        |
| innodb_table_locks              | ON                                        |
| innodb_thread_concurrency       | 20                                        |
| innodb_thread_sleep_delay       | 10000                                     |
| interactive_timeout             | 28800                                     |
| join_buffer_size                | 131072                                    |
| key_buffer_size                 | 8388600                                   |
| key_cache_age_threshold         | 300                                       |
| key_cache_block_size            | 1024                                      |
| key_cache_division_limit        | 100                                       |
| language                        | /home/jon/bin/mysql/share/mysql/english/  |
| large_files_support             | ON                                        |
| large_page_size                 | 0                                         |
| large_pages                     | OFF                                       |
| license                         | GPL                                       |
| local_infile                    | ON                                        |
| locked_in_memory                | OFF                                       |
| log                             | ON                                        |
| log_bin                         | ON                                        |
| log_bin_trust_routine_creators  | OFF                                       |
| log_error                       | /home/jon/bin/mysql/var/master1.err       |
| log_slave_updates               | OFF                                       |
| log_slow_queries                | OFF                                       |
| log_warnings                    | 1                                         |
| long_query_time                 | 10                                        |
| low_priority_updates            | OFF                                       |
| lower_case_file_system          | OFF                                       |
| lower_case_table_names          | 0                                         |
| max_allowed_packet              | 1048576                                   |
| max_binlog_cache_size           | 4294967295                                |
| max_binlog_size                 | 1073741824                                |
| max_connect_errors              | 10                                        |
| max_connections                 | 100                                       |
| max_delayed_threads             | 20                                        |
| max_error_count                 | 64                                        |
| max_heap_table_size             | 16777216                                  |
| max_insert_delayed_threads      | 20                                        |
| max_join_size                   | 4294967295                                |
| max_length_for_sort_data        | 1024                                      |
| max_relay_log_size              | 0                                         |
| max_seeks_for_key               | 4294967295                                |
| max_sort_length                 | 1024                                      |
| max_tmp_tables                  | 32                                        |
| max_user_connections            | 0                                         |
| max_write_lock_count            | 4294967295                                |
| multi_range_count               | 256                                       |
| myisam_data_pointer_size        | 6                                         |
| myisam_max_sort_file_size       | 2147483647                                |
| myisam_recover_options          | OFF                                       |
| myisam_repair_threads           | 1                                         |
| myisam_sort_buffer_size         | 8388608                                   |
| ndb_autoincrement_prefetch_sz   | 32                                        |
| ndb_cache_check_time            | 0                                         |
| ndb_force_send                  | ON                                        |
| ndb_index_stat_cache_entries    | 32                                        |
| ndb_index_stat_enable           | ON                                        |
| ndb_index_stat_update_freq      | 20                                        |
| ndb_use_exact_count             | ON                                        |
| ndb_use_transactions            | ON                                        |
| net_buffer_length               | 16384                                     |
| net_read_timeout                | 30                                        |
| net_retry_count                 | 10                                        |
| net_write_timeout               | 60                                        |
| new                             | OFF                                       |
| old_alter_table                 | OFF                                       |
| old_passwords                   | OFF                                       |
| open_files_limit                | 1024                                      |
| optimizer_prune_level           | 1                                         |
| optimizer_search_depth          | 62                                        |
| pid_file                        | /home/jon/bin/mysql/var/hostname.pid1     |
| port                            | 3306                                      |
| preload_buffer_size             | 32768                                     |
| protocol_version                | 10                                        |
| query_alloc_block_size          | 8192                                      |
| query_cache_limit               | 1048576                                   |
| query_cache_min_res_unit        | 4096                                      |
| query_cache_size                | 0                                         |
| query_cache_type                | ON                                        |
| query_cache_wlock_invalidate    | OFF                                       |
| query_prealloc_size             | 8192                                      |
| range_alloc_block_size          | 2048                                      |
| read_buffer_size                | 131072                                    |
| read_only                       | OFF                                       |
| read_rnd_buffer_size            | 262144                                    |
| relay_log_purge                 | ON                                        |
| relay_log_space_limit           | 0                                         |
| rpl_recovery_rank               | 0                                         |
| secure_auth                     | OFF                                       |
| server_id                       | 1                                         |
| skip_external_locking           | ON                                        |
| skip_networking                 | OFF                                       |
| skip_show_database              | OFF                                       |
| slave_compressed_protocol       | OFF                                       |
| slave_load_tmpdir               | /tmp/                                     |
| slave_net_timeout               | 3600                                      |
| slave_skip_errors               | OFF                                       |
| slave_transaction_retries       | 10                                        |
| slow_launch_time                | 2                                         |
| socket                          | /tmp/mysql.sock                           |
| sort_buffer_size                | 2097144                                   |
| sql_mode                        |                                           |
| sql_notes                       | ON                                        |
| sql_warnings                    | ON                                        |
| storage_engine                  | MyISAM                                    |
| sync_binlog                     | 0                                         |
| sync_frm                        | ON                                        |
| sync_replication                | 0                                         |
| sync_replication_slave_id       | 0                                         |
| sync_replication_timeout        | 10                                        |
| system_time_zone                | EST                                       |
| table_cache                     | 64                                        |
| table_lock_wait_timeout         | 50                                        |
| table_type                      | MyISAM                                    |
| thread_cache_size               | 0                                         |
| thread_stack                    | 196608                                    |
| time_format                     | %H:%i:%s                                  |
| time_zone                       | SYSTEM                                    |
| timed_mutexes                   | OFF                                       |
| tmp_table_size                  | 33554432                                  |
| tmpdir                          |                                           |
| transaction_alloc_block_size    | 8192                                      |
| transaction_prealloc_size       | 4096                                      |
| tx_isolation                    | REPEATABLE-READ                           |
| updatable_views_with_limit      | YES                                       |
| version                         | 5.1.2-alpha-log                           |
| version_comment                 | Source distribution                       |
| version_compile_machine         | i686                                      |
| version_compile_os              | suse-linux                                |
| wait_timeout                    | 28800                                     |
+---------------------------------+-------------------------------------------+
218 rows in set (0.03 sec)

此處描述了大多數系統變數。沒有版本的變數在所有MySQL 5.1 發佈中適用。關於其使用歷史訊息,請參見MySQL 5.0參考指南MySQL 4.1參考指南InnoDB系統變數列於 15.2.4節,「InnoDB啟動選項」

若沒有另行規定,緩衝區大小、長度和堆棧大小的單位均為字節。

關於這些變數的調節訊息參見7.5.2節,「調節伺服器參數」

·         auto_increment_increment

auto_increment_incrementauto_increment_offset用於主伺服器-主伺服器(master-to-master)複製,並可以用來控制AUTO_INCREMENT列的操作。兩個變數均可以設置為全局或局部變數,並且假定每個值都可以為165,535之間的整數值。將其中一個變數設置為0會使該變數為1。如果試圖將這些變數設置為大於65,535或小於0的值,則會將該值設置為65,535。如果向將auto_increment_incrementauto_increment_offset設置為非整數值,則會給出錯誤,並且變數的實際值在這種情況下保持不變。

這兩個變數影響AUTO_INCREMENT列的方式:

o        auto_increment_increment控制列中的值的增量值。例如:

o                       mysql> SHOW VARIABLES LIKE 'auto_inc%';
o                       +--------------------------+-------+
o                       | Variable_name            | Value |
o                       +--------------------------+-------+
o                       | auto_increment_increment | 1     |
o                       | auto_increment_offset    | 1     |
o                       +--------------------------+-------+
o                       2 rows in set (0.00 sec)
o                      
o                       mysql> CREATE TABLE autoinc1 (col INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
o                       Query OK, 0 rows affected (0.04 sec)
o                      
o                       mysql> SET @auto_increment_increment=10;
o                       Query OK, 0 rows affected (0.00 sec)
o                      
o                       mysql> SHOW VARIABLES LIKE 'auto_inc%';
o                       +--------------------------+-------+
o                       | Variable_name            | Value |
o                       +--------------------------+-------+
o                       | auto_increment_increment | 10    |
o                       | auto_increment_offset    | 1     |
o                       +--------------------------+-------+
o                       2 rows in set (0.01 sec)
o                      
o                       mysql> INSERT INTO autoinc1 VALUES (NULL), (NULL), (NULL), (NULL);
o                       Query OK, 4 rows affected (0.00 sec)
o                       Records: 4  Duplicates: 0  Warnings: 0
o                      
o                       mysql> SELECT col FROM autoinc1;
o                       +-----+
o                       | col |
o                       +-----+
o                       |   1 |
o                       |  11 |
o                       |  21 |
o                       |  31 |
o                       +-----+
o                       4 rows in set (0.00 sec)

(註明如何使用SHOW VARIABLES來獲取這些變數的當前值)

o        auto_increment_offset確定AUTO_INCREMENT列值的起點。假定在與前面的例子的相同的會話中執行下面的命令:

o                       mysql> SET @auto_increment_offset=5;
o                       Query OK, 0 rows affected (0.00 sec)
o                      
o                       mysql> SHOW VARIABLES LIKE 'auto_inc%';
o                       +--------------------------+-------+
o                       | Variable_name            | Value |
o                       +--------------------------+-------+
o                       | auto_increment_increment | 10    |
o                       | auto_increment_offset    | 5     |
o                       +--------------------------+-------+
o                       2 rows in set (0.00 sec)
o                      
o                       mysql> CREATE TABLE autoinc2 (col INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
o                       Query OK, 0 rows affected (0.06 sec)
o                      
o                       mysql> INSERT INTO autoinc2 VALUES (NULL), (NULL), (NULL), (NULL);
o                       Query OK, 4 rows affected (0.00 sec)
o                       Records: 4  Duplicates: 0  Warnings: 0
o                      
o                       mysql> SELECT col FROM autoinc2;
o                       +-----+
o                       | col |
o                       +-----+
o                       |   5 |
o                       |  15 |
o                       |  25 |
o                       |  35 |
o                       +-----+
o                       4 rows in set (0.02 sec)
o                      

如果auto_increment_offset的值大於auto_increment_increment的值,則auto_increment_offset的值被忽略。

如果其中一個或兩個變數被更改了,然後更改插入到包含AUTO_INCREMENT列的資料表中的新行,結果可能看上去有問題,由於計算AUTO_INCREMENT系列值時沒有考慮列內已經存在的值,並且插入的下一個值是列內最小的值,大於AUTO_INCREMENT列內已有的最大值。換句話說,數值的計算方法為:

auto_increment_offset+ N * auto_increment_increment

其中N為系列內的正整數值[1,2,3,...]。例如:

mysql> SHOW VARIABLES LIKE 'auto_inc%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 10    |
| auto_increment_offset    | 5     |
+--------------------------+-------+
2 rows in set (0.00 sec)
 
mysql> SELECT col FROM autoinc1;
+-----+
| col |
+-----+
|   1 |
|  11 |
|  21 |
|  31 |
+-----+
4 rows in set (0.00 sec)
 
mysql> INSERT INTO autoinc1 VALUES (NULL), (NULL), (NULL), (NULL);
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0
 
mysql> SELECT col FROM autoinc1;
+-----+
| col |
+-----+
|   1 |
|  11 |
|  21 |
|  31 |
|  35 |
|  45 |
|  55 |
|  65 |
+-----+
8 rows in set (0.00 sec)

auto_increment_incrementauto_increment_offset所示的值可以生成系列5 + N * 10,即,[5,15,25,35,45,...]。在INSERTcol 列內最大的值為31,AUTO_INCREMENT數列的下一個值為35,因此col中插入的值從該點開始,結果如SELECT查詢所示。

一定要記住不可能將這兩個變數的結果限制到一個資料表中,因此不會替代其它資料庫管理系統提供的序列;這些變數控制MySQL伺服器上all資料表AUTO_INCREMENT列的所有行為。如果某個變數設為全局變數,則只有通過局部設置將全局值更改和覆蓋後或mysqld重啟後其作用方可改變;如果局部設置,則新值影響所有資料表的AUTO_INCREMENT列,在這個會話期間當前用戶在這些資料表中插入了新行,除非在會話期間更改了這些值。

auto_increment_increment的 預設值為1。參見6.12節,「多伺服器複製中的Auto-Increment」

·         auto_increment_offset

該變數的預設值為1。詳見auto_increment_increment的描述。

·         back_log

MySQL有的主要連接請求的數量。當主MySQL線程在短時間內得到許多連接請求時發揮作用。主線程需要花一些時間(儘管很少)來檢查連接並啟動一個新線程。back_log值說明MySQL臨時停止響應新請求前在短時間內可以堆起多少請求。如果您需要在短時間內允許大量連接,可以增加該數值。

換句話說,該值為「進」TCP/IP連接幀聽隊列的大小。作業系統有該隊列自己的限制值。本手冊中Unix listen()系統使用頁應有更詳細的訊息。該變數最大值請查閱OS文檔。企圖將back_log設置為高於您的作業系統限值是徒勞無益的。

·         basedir

MySQL安裝基準目錄。可以用--basedir選項設置該變數。

·         bdb_cache_size

BDB資料表緩存索引和行分配的緩衝區的大小。如果您不使用BDB資料表,您應用--skip-bdb啟動mysqld以便不浪費該緩存。

·         bdb_home

BDB資料表基準目錄。應與datadir變數的值相同。

·         bdb_log_buffer_size

BDB資料表緩存索引和行分配的緩衝區的大小。如果您不使用BDB資料表,您應將該值設置為0或用--skip-bdb啟動mysqld以便不浪費該緩存。

·         bdb_logdir

BDB儲存引擎寫它日誌檔案的目錄。可以用--bdb-logdir選項設置該變數。

·         bdb_max_lock

BDB資料表下可以激活的最大鎖數(預設為10,000)。如果當您執行長事務或當mysqld必須檢查許多行來計算查詢時出現下面的錯誤,您應增加該值:

bdb: Lock table is out of available locks
Got error 12 from ...

·         bdb_shared_data

如果您正使用--bdb-shared-data應為ON

·         bdb_tmpdir

--bdb-tmpdir選項的值。

 

·         binlog_cache_size

在事務過程中容納二進制日誌SQL語句的緩存大小。二進制日誌緩存是伺服器支援事務儲存引擎並且伺服器啟用了二進制日誌(--log-bin選項)的前提下為每個客戶端分配的內存。如果您經常使用大的,多語句事務,您可以增加該值以獲得更有的性能。Binlog_cache_useBinlog_cache_disk_use狀態變數可以用來調整該變數的大小。參見5.11.3節,「二進制日誌」

·         bulk_insert_buffer_size

MyISAM 使用專用樹狀緩存來使INSERT ... SELECTINSERT ... VALUES (...)(...) ...LOAD DATA INFILE的大塊插入更快。該變數用每線程的字節數限制緩存樹的大小。將它設置為0禁用最佳化。釋:只有向非空資料表新增數據時才使用該緩存。 預設值是8MB

·         character_set_client

來自客戶端的語句的字元編碼。

·         character_set_connection

用於沒有字元編碼導入符的文字和數字-字串轉換。

·         character_set_database

預設資料庫使用的字元編碼。當預設資料庫更改時,伺服器則設置該變數。如果沒有預設資料庫,變數的值同character_set_server

·         character_set_results

用於向客戶端返回查詢結果的字元編碼。

·         character_set_ server

伺服器的預設字元編碼。

·         character_set_system

伺服器用來保存識別符的字元編碼。該值一定是utf8

·         character_sets_dir

字元編碼安裝目錄。

·         collation_connection

連接字元編碼的校對規則。

·         collation_database

預設資料庫使用的校對規則。當預設資料庫改變時伺服器則設置該變數。如果沒有預設資料庫,變數的值同collation_server

·         collation_server

伺服器的預設校對規則。

·         completion_type

事務結束類型:

o        如果該值為0(預設)COMMITROLLBACK不受影響。

o        如果該值為1COMMITROLLBACK分別等同於COMMIT AND CHAINROLLBACK AND CHAIN(新事務用剛剛結束的事務相同的間隔等級立即啟動)

o        如果該值為2COMMITROLLBACK分別等同於COMMRELEASEROLLBACK RELEASE(事務終止後,伺服器中斷)

·         concurrent_insert

如果為ON(預設值)MySQL允許INSERTSELECT語句在中間沒有空數據塊的MyISAM資料表中並行運行。您可以用--safe--skip-new啟動mysqld關閉該選項。

該變數為整數,有3個值:

描述

0

1

(預設)在沒有空數據塊的MyISAM資料表中啟用並行插入

2

為所有MyISAM資料表啟用並行插入。如果資料表有空記錄或正被另一線程使用,新行將插入到資料表的最後。如果資料表未使用,MySQL將進行普通讀鎖定並將新行插入空記錄。

·         connect_timeout

mysqld伺服器Bad handshake響應前等待連接包的秒數。

·         datadir

MySQL數據目錄。可以用--datadir選項設置該變數。

·         date_format

該變數未使用。

·         datetime_format

該變數未使用。

·         default_week_format

WEEK() 函數使用的預設模式。

·         delay_key_write

該選項只適用MyISAM資料表。它具有下述值可以影響CREATE TABLE語句使用的DELAY_KEY_WRITE資料表選項的處理。

選項

描述

OFF

DELAY_KEY_WRITE被忽略。

ON

MySQLCREATE TABLE中用DELAY_KEY_WRITE選項。這是 預設值。

ALL

用啟用DELAY_KEY_WRITE選項建立資料表的相同方法對所有新打開資料表的進行處理。

如果啟用了DELAY_KEY_WRITE,說明使用該項的資料表的鍵緩衝區在每次更新索引時不被清空,只有關閉資料表時才清空。遮掩蓋可以大大加快鍵的寫操作,但如果您使用該特性,您應用--myisam-recover選項啟動伺服器,為所有MyISAM資料表新增自動檢查(例如,--myisam-recover=BACKUP,FORCE)。參見5.3.1節,「mysqld命令行選項」15.1.1節,「MyISAM啟動選項」

請注意--external-locking不為使用延遲鍵寫入的資料表提供索引破壞保護。

·         delayed_insert_limit

插入delayed_insert_limit 延遲行後,INSERT DELAYED 處理器線程檢查是否有掛起的SELECT語句。如果有,在繼續插入延遲的行之前,允許它們先執行。

·         delayed_insert_timeout

INSERT DELAYED處理器線程終止前應等待INSERT語句的時間。

·         delayed_queue_size

這是各個資料表中處理INSERT DELAYED語句時隊列中行的數量限制。如果隊列滿了,執行INSERT DELAYED語句的客戶端應等待直到隊列內再有空間。

·         div_precision_increment

該變數說明用/操作符執行除操作的結果可增加的精確度的位數。 預設值是4。最小和最大值分別為030。下面的示範說明了增加 預設值的結果。

mysql> SELECT 1/7;
+--------+
| 1/7    |
+--------+
| 0.1429 |
+--------+
mysql> SET div_precision_increment = 12;
mysql> SELECT 1/7;
+----------------+
| 1/7            |
+----------------+
| 0.142857142857 |
+----------------+

·         engine_condition_pushdown

該變數適用於NDB。預設值為0(OFF):如果您執行類似查詢SELECT * FROM t WHERE mycol = 42,其中mycol為沒有索引的列,當滿了的資料表掃瞄每個NDB節點時,執行該查詢。每個節點使用WHERE條件將每一行發送給MySQL伺服器。如果engine_condition_pushdown被設置為1(ON),該條件「pushed down」給儲存引擎並發送給NDB節點。每個節點都執行掃瞄,並只向MySQL伺服器發送回匹配條件的行。

·         expire_logs_days

二進制日誌自動刪除的天數。預設值為0,資料表示「沒有自動刪除」。啟動時和二進制日誌循環時可能刪除。

·         flush

如果用--flush選項啟動mysqld該值為ON

·         flush_time

如果設為非零值,每隔flush_time秒則關閉所有資料表以釋放硬盤資源並同步未清空的數據。我們建議只在Windows 9xMe,或有最小資源的系統中使用該選項。

·         ft_boolean_syntax

使用IN BOOLEAN MODE執行的布爾全文搜索支援的操作符系列。參見12.7.1節,「布爾全文搜索」

預設變數值為 '+ -><()~*:""&|'。更改這些值的規則是:

o        操作符函數由其在字串內的位置決定。

o        替換值必須是14個字元。

o        每個字元必須為ASCII碼非文字數字字元。

o        1個或第2個字元必須為空格。

o        除非語句在第11個字元和第12個字元處引用了操作符,否則不允許複製。這兩個字元可以不相同,但這是唯一可能的兩個。

o        位置101314(預設設置為『:』、『&』和『|)保留用於將來延伸。

·         ft_max_word_len

FULLTEXT索引中所包含的字的最大長度。

釋:更改該變數後必須重建FULLTEXT索引。應使用REPAIR TABLE tbl_name QUICK

·         ft_min_word_len

FULLTEXT索引中所包含的字的最小長度。

釋:更改該變數後必須重建FULLTEXT索引。應使用REPAIR TABLE tbl_name QUICK

·         ft_query_expansion_limit

使用WITH QUERY EXPANSION進行全文搜索的最大匹配數。

·         ft_stopword_file

用於讀取全文搜索的停止字清單的檔案。該檔案中的所有字都會用到;註釋不重要。預設情況下,使用內嵌式停止字清單(myisam/ft_static.c檔案中所定義)。將該變數設置為空字串('')則禁用停止字過濾。

釋:更改該變數或停止字檔案的內容後必須重建FULLTEXT索引。應使用REPAIR TABLE tbl_name QUICK

·         group_concat_max_len

允許的GROUP_CONCAT()函數結果的最大長度。

·         have_archive

如果mysqld支援ARCHIVE資料表則為YES,否則為NO

·         have_bdb

如果mysqld支援BDB資料表則為YES。如果使用--skip-bdb則為DISABLED

·         have_blackhole_engine

如果mysqld支援BLACKHOLE資料表則為YES,否則為NO

·         have_compress

是否zlib壓縮庫適合該伺服器。如果不適合,不能使用COMPRESS()UNCOMPRESS()函數。

·         have_crypt

是否crypt()系統使用適合該伺服器。如果不適合,不能使用CRYPT()函數。

·         have_csv

如果mysqld支援ARCHIVE資料表則為YES,否則為NO

·         have_example_engine

如果mysqld支援EXAMPLE資料表則為YES,否則為NO

have_federated_engine

如果mysqld支援FEDERATED資料表則為YES,否則為NO

·         have_geometry

是否伺服器支援空間數據類型。

·         have_innodb

如果mysqld支援InnoDB資料表則為YES。如果使用--skip-innodb則為DISABLED

·         have_isam

MySQL 5.1,只是為了向後兼容顯示該值,並且總是NO,因為不再支援ISAM資料表。

·         have_ndbcluster

如果mysqld支援NDB CLUSTER資料表則為YES。如果使用了--skip-ndbcluster則為DISABLED

·         have_partition_engine

如果mysqld支援分區則為YES。在MySQL 5.1.1中加入。

·         have_openssl

如果mysqld支援客戶端/伺服器協議的SSL(加密)則為YES

·         have_query_cache

如果mysqld支援查詢緩存則為YES

·         have_raid

如果mysqld支援RAID選項則為YES

·         have_rtree_keys

RTREE索引是否可用。(用於MyISAM資料表的空間索引)

·         have_symlink

是否啟用符號連結支援。在Unix中需要用於支援DATA DIRECTORYINDEX DIRECTORY資料表選項。

·         init_connect

伺服器為每個連接的客戶端執行的字串。字串由一個或多個SQL語句組成。要想指定多個語句,用分號間隔開。例如,每個客戶端開始時預設啟用autocommit模式。沒有全局伺服器變數可以規定autocommit預設情況下應禁用,但可以用init_connect來獲得相同的效果:

SET GLOBAL init_connect='SET AUTOCOMMIT=0';

還可以在命令行或選項檔案中設置該變數。要想使用選項檔案設置變數,應包括下述行:

[mysqld]
init_connect='SET AUTOCOMMIT=0'

請注意init_connect的內容並不為擁有SUPER權限的用戶執行;實際是內容設置錯誤(包含錯誤查詢,例如語法錯誤),這樣使所有連接失敗。不為SUPER用戶執行,使SUPER用戶可以打開連接並固定init_connect

·         init_file

啟動伺服器時用--init-file選項指定的檔案名。檔案中包含伺服器啟動時要執行的SQL語句。每個語句必須在同一行中並且不能包括註釋。

·         init_slave

該變數類似init_connect,但是每次SQL線程啟動時從伺服器應執行該字串。該字串的格式與init_connect變數相同。

·         innodb_xxx

InnoDB系統變數列入15.2.4節,「InnoDB啟動選項」

·         interactive_timeout

伺服器關閉交互式連接前等待活動的秒數。交互式客戶端定義為在mysql_real_connect()中使用CLIENT_INTERACTIVE選項的客戶端。又見wait_timeout

·         join_buffer_size

用於完全聯接的緩衝區的大小(當不使用索引的時候使用聯接操作)。一般情況獲得快速聯接的最好方法是新增索引。當增加索引時不可能通過增加join_buffer_size值來獲得快速完全聯接。將為兩個資料表之間的每個完全聯接分配聯接緩衝區。對於多個資料表之間不使用索引的複雜聯接,需要多聯接緩衝區。

·         key_buffer_size

MyISAM資料表的索引塊分配了緩衝區,由所有線程共享。key_buffer_size是索引塊緩衝區的大小。鍵值緩衝區即為鍵值緩存。

key_buffer_size的最大允許設定值為4GB。有效最大值可以更小,取決於可用物理RAM和作業系統或硬件平台強加的每個程序的RAM限制。

增加該值,達到您可以提供的更好的索引處理(所有讀和多個寫操作)。通常為主要運行MySQL的機器內存的25%。但是,如果您將該值設得過大(例如,大於總內存的50%),系統將轉換為頁並變得極慢。MySQL依賴作業系統來執行數據讀取時的檔案系統緩存,因此您必須為檔案系統緩存留一些空間。

同時寫多行時要想速度更快,應使用LOCK TABLES。參見13.4.5節,「LOCK TABLES和UNLOCK TABLES語法」

您可以通過執行SHOW STATUS語句並檢查Key_read_requestsKey_readsKey_write_requestsKey_writes狀態變數來檢查鍵值緩衝區的性能。參見13.5.4節,「SHOW語法」

Key_reads/Key_read_requests比例一般應小於0.01。如果您使用更新和刪除,Key_writes/Key_write_requests比例通常接近1,但如果您更新時會同時影響到多行或如果您正使用DELAY_KEY_WRITE資料表選項,可能小得多。

key_buffer_size結合Key_blocks_unused狀態變數和緩衝區塊大小,可以確定使用的鍵值緩衝區的比例。從key_cache_block_size伺服器變數可以獲得緩衝區塊大小。使用的緩衝區的比例為:

1 - ((Key_blocks_unused * key_cache_block_size) / key_buffer_size)

該值為約數,因為鍵值緩衝區的部分空間被分配用作內部管理結構。

可以建立多個MyISAM鍵值緩存。4GB限制可以適合每個緩存,而不是一個組。參見7.4.6節,「MyISAM鍵高速緩衝」

·         key_cache_age_threshold

該值控制將緩衝區從鍵值緩存熱子鏈(sub-chain)降級到溫子鏈(sub-chain)。如果值更低,則降級更快。最小值為100。 預設值是300。參見7.4.6節,「MyISAM鍵高速緩衝」

·         key_cache_block_size

鍵值緩存內塊的字節大小。預設值是1024。參見7.4.6節,「MyISAM鍵高速緩衝」

·         key_cache_division_limit

鍵值緩存緩衝區鏈熱子鏈和溫子鏈的劃分點。該值為緩衝區鏈用於溫子鏈的百分比。允許的值的範圍為1100。 預設值是100。參見7.4.6節,「MyISAM鍵高速緩衝」

·         language

錯誤消息所用語言。

·          large_file_support

mysqld編譯時是否使用了大檔案支援選項。

·         large_pages

說明是否啟用了大頁面支援。

·         license

伺服器的授權類型。

·         local_infile

是否LOCAL支援LOAD DATA INFILE語句。

·         locked_in_memory

是否用memlockmysqld鎖在內存中。

·         log

是否啟用將所有查詢記錄到常規查詢日誌中。參見5.11.2節,「通用查詢日誌」

·         log_bin

是否啟用二進制日誌。參見5.11.3節,「二進制日誌」

·         log_bin_trust_routine_creators

若啟用了二進制記錄,則該變數適用。它控制是否可以信任保存的程式的作者不會建立向二進制日誌寫入不安全事件的程式。如果設置為0(預設情況),不允許用戶建立或修改保存的程式,除非他們不僅擁有CREATE ROUTINEALTER ROUTINE權限還擁有SUPER權限。

設置為0還強制限制,程式必須用DETERMINISTIC 特徵或用READS SQL DATANO SQL特徵聲明。如果變數設置為1,MySQL不對保存程式的建立強加限制。

參見20.4節,「儲存子程式和觸發程式的二進制日誌功能」

·         log_error

錯誤日誌的位置。

·         log_slave_updates

是否從伺服器從主伺服器收到的更新應記入從伺服器自己的二進制日誌。要想生效,必須啟用從伺服器的二進制記錄。參見6.8節,「複製啟動選項」

·         log_slow_queries

是否記錄慢查詢。用long_query_time變數的值來確定「慢查詢」。參見5.11.4節,「慢速查詢日誌」

·         log_warnings

是否產生其它警告消息。預設情況下啟用。放棄的連接不記入錯誤日誌,除非值大於1

·         long_query_time

如果查詢時間超過該值,則增加Slow_queries狀態變數。如果您正使用--log-slow-queries選項,則查詢記入慢查詢日誌檔案。用實際時間測量該值,而不是CPU時間,因此低於輕負載系統閾值的查詢可能超過重負載系統的閾值。參見5.11.4節,「慢速查詢日誌」

·         low_priority_updates

如果設置為1,所有INSERTUPDATEDELETELOCK TABLE WRITE語句將等待直到受影響的資料表沒有掛起的SELECTLOCK TABLE READ。該變數以前叫做sql_low_priority_updates

·         lower_case_file_system

該變數說明是否數據目錄所在的檔案系統對檔案名的大小寫敏感。ON說明對檔案名的大小寫不敏感,OFF資料表示敏感。

·           lower_case_table_names

如果設置為1,資料表名用小寫保存到硬盤上,並且資料表名比較時不對大小寫敏感。如果設置為2,按照指定的保存資料表名,但按照小寫來比較。該選項還適合資料庫名和資料表的別名。參見9.2.2節,「識別符大小寫敏感性」

如果您正使用InnoDB資料表,您應在所有平台上將該變數設置為1,強制將名字轉換為小寫。

如果運行MySQL的系統對檔案名的大小寫不敏感(例如WindowsMac OS X),您不應將該變數設置為0。如果啟動時沒有設置該變數,並且數據目錄所在檔案系統對檔案名的大小寫不敏感,MySQL自動將lower_case_table_names設置為2

·         max_allowed_packet

包或任何生成的/中間字串的最大大小。

包消息緩衝區初始化為net_buffer_length字節,但需要時可以增長到max_allowed_packet字節。該值預設很小,以捕獲大的(可能是錯誤的)數據包。

如果您使用大的BLOB 列或長字串,您必須增加該值。應同您想要使用的最大的BLOB一樣大。max_allowed_packet的協議限制為1GB

·         max_binlog_cache_size

如果多語句事務需要更大的內存,您會得到錯誤Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage

·         max_binlog_size

如果二進制日誌寫入的內容超出給定值,日誌就會發生滾動。您不能將該變數設置為大於1GB或小於4096字節。 預設值是1GB

請注意如果您正使用事務:事務以一個塊寫入二進制日誌,因此不不能被幾個二進制日誌拆分。因此,如果您有大的事務,二進制日誌可能會大於max_binlog_size

如果max_relay_log_size0, max_binlog_size的值也適用於中繼日誌

·         max_connect_errors

如果中斷的與主機的連接超過該數目,該主機則阻塞後面的連接。您可以用 FLUSH HOSTS語句解鎖鎖定的主機。

·         max_connections

允許的並行客戶端連接數目。增大該值則增加mysqld 需要的檔案描述符的數量。關於檔案描述符限制的註釋參見7.4.9節,「MySQL如何打開和關閉資料表」。還可參見A.2.6節,「連接數過多」

·         max_delayed_threads

不要啟動大於該數目的線程來處理INSERT DELAYED語句。如果所有INSERT DELAYED線程已經在使用,您想在新資料表中插入數據,行 插入時好像未指定DELAYED屬性。如果您將該值設置為0,MySQL不會建立線程來處理DELAYED行;其結果是完全禁用了DELAYED

·         max_error_count

保存由SHOW ERRORSSHOW WARNINGS顯示的錯誤、警告和註解的最大數目。

·         max_heap_table_size

該變數設置MEMORY (HEAP)資料表可以增長到的最大空間大小。該變數用來計算MEMORY資料表的MAX_ROWS值。在已有的MEMORY資料表上設置該變數沒有效果,除非用CREATE TABLETRUNCATE TABLE等語句重新建立資料表。

·         max_insert_delayed_threads

該變數為max_delayed_threads的同義詞。

·         max_join_size

不允授權能需要檢查多於max_join_size(為單個資料表語句)或行組合(為多個資料表語句)或可能執行大於max_join_size次硬盤查詢的SELECT語句。通過設置該值,您可以捕獲鍵使用不正確並可能花很長時間的SELECT語句。如果用戶想要執行沒有WHERE子句的花較長時間或返回數百萬行的聯接,則設置它。

將該變數設置為DEFAULT之外的值,將SQL_BIG_SELECTS的值重設為0如果您重新設置SQL_BIG_SELECTS值,max_join_size變數被忽略。

如果查詢結果位於查詢緩存中,則不檢查結果大小,因為前面已經計算了結果,不會要求伺服器將它發送給客戶端。

該變數以前叫做sql_max_join_size

·         max_length_for_sort_data

確定使用的filesort算法的索引值大小的限值。參見7.2.12節,「MySQL如何最佳化ORDER BY

·         max_relay_log_size

如果複製從伺服器寫入中繼日誌時超出給定值,則滾動中繼日誌。通過該變數您可以對中繼日誌和二進制日誌設置不同的限制。但是,將該變數設置為0MySQL可以對二進制日誌和中繼日誌使用max_binlog_sizemax_relay_log_size必須設置在4096字節和1GB(包括)之間,或為0。 預設值是0。參見6.3節,「複製實施細節」

·         max_seeks_for_key

限制根據鍵值尋找行時的最大搜索數。MySQL最佳化器假定當用掃瞄鍵在資料表內搜索匹配的行時,不需要超過該數量的鍵值搜索,而不管鍵的實際基數是什麼(參見13.5.4.11節,「SHOW INDEX語法」)。將該值設置為較低的值(100?),您可以強制MySQL選擇鍵值而不選擇資料表掃瞄。

·         max_sort_length

當排序BLOBTEXT值時使用的字節數。只使用每個值的前max_sort_length字節;其它的被忽略。

·         max_tmp_tables

客戶端可以同時打開的臨時資料表的最大數。(但該選項還未生效)

·         max_user_connections

任何給定的MySQL帳號允許的最大同時連接數。0值資料表示「沒有限制」。

該變數具有全局範圍和(只讀)會話範圍。會話變數的的值與全局變數的值相同,除非當前帳號具有非零MAX_USER_CONNECTIONS資源限制。在這種情況下,會話值反應了帳號限制。

·         max_write_lock_count

超過寫鎖定限制後,允許部分讀鎖定。

·         myisam_data_pointer_size

預設指針大小,單位是字節,當未指定MAX_ROWS選項時,CREATE TABLE使用該變數建立MyISAM資料表。該變數不能小於2或大於7。 預設值是6。參見A.2.11節,「資料表已滿」

·         (DEPRECATED) myisam_max_extra_sort_file_size

釋:MySQL 5.1不支援該變數。詳細訊息參見MySQL 5.0 參考手冊

·         myisam_max_sort_file_size

重建MyISAM索引(REPAIR TABLEALTER TABLELOAD DATA INFILE過程中)時,允許MySQL使用的臨時檔案的最大空間大小。如果檔案的大小超過該值,則使用鍵值緩存建立索引,要慢得多。該值的單位為字節。

·         myisam_recover_options

--myisam-recover選項的值。

·         myisam_repair_threads

如果該值大於1,在Repair by sorting過程中並行建立MyISAM資料表索引(每個索引在自己的線程內)。 預設值是1釋:多線程維護仍然是alpha 編碼。

·         myisam_sort_buffer_size

當在REPAIR TABLE或用CREATE INDEX建立索引或ALTER TABLE過程中排序 MyISAM索引分配的緩衝區。

·         myisam_stats_method

當為MyISAM資料表搜集關於索引值分發的統計訊息時伺服器如何處理NULL值。該變數有兩個可能的值,nulls_equalnulls_unequal。對於nulls_equal,認為所有NULL索引值時相等的,並形成一個數值組,其空間大小等於NULL值的數。對於nulls_unequalNULL值認為是不相等的,每個NULL形成一個數值組,大小為1

方法用於生成資料表統計訊息,影響最佳化器如何選擇索引來執行查詢,詳細描述見7.4.7節,「MyISAM索引統計集合」

·         multi_read_range

指定範圍選擇過程中發送到儲存引擎的範圍的最大值。預設值是256。向引擎發送多個範圍可以大大改進某些選擇的性能,特別是對NDBCLUSTER。該引擎需要向所有節點發送範圍請求,同時發送許多請求可以大大降低通信成本。

·         named_pipe

(只適用Windows)說明伺服器是否支援命名管道連接。

·         net_buffer_length

在查詢之間將通信緩衝區重設為該值。一般情況不應改變,但如果內存很小,可以將它設置為期望的客戶端發送的SQL語句的長度。如果語句超出該長度,緩衝區自動擴大,直到max_allowed_packet字節。

·         net_read_timeout

中斷讀前等待連接的其它數據的秒數。當伺服器從客戶端讀數時,net_read_timeout指控制何時中斷的超時值。當伺服器向客戶端寫時,net_write_timeout指控制何時中斷的超時值。又見slave_net_timeout

·         net_retry_count

如果某個通信端口的讀操作中斷了,在放棄前重試多次。在FreeBSD中該值應設得很高,因為內部中斷將發送至所有線程。

·         net_write_timeout

中斷寫之前等待塊寫入連接的秒數。又見net_read_timeout

·         new

MySQL 4.0中使用該變數來打開4.1中的一些行為,並用於向後相容性。在MySQL 5.1,它的值一直是OFF.

·         old_passwords

是否伺服器應為MySQL用戶帳號使用pre-4.1-style密碼。參見A.2.3節,「客戶端不支援鑒定協議」

·         one_shot

這不是一個變數,但當設置變數是可以使用它。其描述見13.5.3節,「SET語法」

·         one_shot

這不是一個變數,但當設置變數是可以使用它。其描述見13.5.3節,「SET語法」

·         open_files_limit

作業系統允許mysqld打開的檔案的數量。這是系統允許的實際值,可能與您在啟動選項中賦給mysqld的值不同。若在系統中MySQL不能更改打開的檔案的數量,則該值為0

·         optimizer_prune_level

在查詢最佳化從最佳化器搜索空間裁減低希望局部計劃中使用的控制方法。0值禁用該方法,以便最佳化器進行窮舉搜索。值為1使最佳化器根據中間方案中得出的行數來裁減方案。

·         optimizer_search_depth

查詢最佳化器進行的搜索的最大深度。如果值大於查詢中的關係數則查詢方案比較佳,但生成查詢執行方案需要的時間更長。值大於查詢中的關係數則返回的執行方案更快,但方案遠沒有最佳化。如果設置為0, 系統自動選擇合理的值。如果設置為查詢中使用的資料表的最大數加2,最佳化器轉換為MySQL 5.0.0(和以前的版本)中使用的算法並搜索。

·         pid_file

程序ID (PID)檔案的路徑名。可以用--pid-file選項設置該變數。

·         plugin_dir

插件目錄的路徑。在MySQL 5.1.2中加入了該變數。

·         port

伺服器幀聽TCP/IP連接所用端口。可以用--port選項設置該變數。

·         preload_buffer_size

重載索引時分配的緩衝區大小。

·         protocol_version

MySQL伺服器使用的客戶端/伺服器協議的版本。

·         query_alloc_block_size

為查詢分析和執行過程中建立的對象分配的內存塊大小。如果內存分段過程中遇到問題,將該變數增加一位會有幫助。

·         query_cache_limit

不要緩存大於該值的結果。預設值是1048576(1MB)

·         query_cache_min_res_unit

查詢緩存分配的最小塊的大小(字節)。 預設值是4096(4KB)。關於該變數的調節訊息參見5.13.3節,「查詢高速緩衝配置」

·         query_cache_size

為緩存查詢結果分配的內存的數量。預設值是0,即禁用查詢緩存。請注意即使query_cache_type設置為0也將分配此數量的內存。詳細訊息參見5.13.3節,「查詢高速緩衝配置」

·         query_cache_type

設置查詢緩存類型。設置GLOBAL值可以設置後面的所有客戶端連接的類型。客戶端可以設置SESSION值以影響他們自己對查詢緩存的使用。下面的資料表顯示了可能的值:

選項

描述

0OFF

不要緩存或查詢結果。請注意這樣不會取消分配的查詢緩存區。要想取消,您應將query_cache_size設置為0

1ON

緩存除了以SELECT SQL_NO_CACHE開頭的所有查詢結果。

2DEMAND

只緩存以SELECT SQL_NO_CACHE開頭的查詢結果。

該變數預設設為ON

·         query_cache_wlock_invalidate

一般情況,當客戶端對MyISAM資料表進行WRITE鎖定時,如果查詢結果位於查詢緩存中,則其它客戶端未被鎖定,可以對該資料表進行查詢。將該變數設置為1,則可以對資料表進行WRITE鎖定,使查詢緩存內所有對該資料表進行的查詢變得非法。這樣當鎖定生效時,可以強制其它試圖訪問資料表的客戶端來等待。

·         query_prealloc_size

用於查詢分析和執行的固定緩衝區的大小。在查詢之間該緩衝區不釋放。如果您執行複雜查詢,分配更大的query_prealloc_size值可以幫助提高性能,因為它可以降低查詢過程中伺服器分配內存的需求。

·         range_alloc_block_size

範圍最佳化時分配的塊的大小。

·         read_buffer_size

每個線程連續掃瞄時為掃瞄的每個資料表分配的緩衝區的大小(字節)。如果進行多次連續掃瞄,可能需要增加該值, 預設值為131072

·         read_only

當變數對複製從伺服器設置為ON時,從伺服器不允許更新,除非通過從伺服器的線程或用戶擁有SUPER權限。可以確保從伺服器不接受客戶端的更新命令。

·         relay_log_purge

當不再需要中繼日誌時禁用或啟用自動清空中繼日誌。預設值是1(啟用)

·         read_rnd_buffer_size

當排序後按排序後的順序讀取行時,則通過該緩衝區讀取行,避免搜索硬盤。將該變數設置為較大的值可以大大改進ORDER BY的性能。但是,這是為每個客戶端分配的緩衝區,因此您不應將全局變數設置為較大的值。相反,只為需要運行大查詢的客戶端更改會話變數。

·         secure_auth

如果用--secure-auth選項啟動了MySQL伺服器,它將阻塞有舊格式(4.1之前)密碼的所有帳號所發起的連接。在這種情況下,該變數的值為ON,否則為OFF

如果您想要防止使用舊格式的密碼(致使網絡通信不安全),您應啟用該選項。

如果啟用該選項並且授權資料表為pre-4.1格式,伺服器啟動失敗並且會出現錯誤。參見A.2.3節,「客戶端不支援鑒定協議」

當用於客戶端選項時,如果伺服器需要該客戶端帳號的舊格式的密碼,則客戶端拒絕連接該伺服器。

·         server_id

--server-id選項的值。用於主複製伺服器和從複製伺服器。

·         shared_memory

(只用於Windows)伺服器是否允許共享內存連接。

·         shared_memory_base_name

(只用於Windows)說明伺服器是否允許共享內存連接,並為共享內存設置識別符。當在單台機器上運行多個MySQL實例時很有用。

·         skip_external_locking

如果mysqld使用外部鎖定,該值為OFF

·         skip_networking

如果伺服器只允許本地(TCP/IP)連接,該值為ON。在Unix中,本地連接使用Unix套接字檔案。在Windows中,本地連接使用命名管道或共享內存。在NetWare中,只支援TCP/IP連接,因此不要將該變數設置為ON

·         skip_show_database

防止不具有SHOW DATABASES權限的人們使用SHOW DATABASES語句。如果您擔心用戶能夠看見屬於其它用戶的資料庫,這樣設置可以提高安全性。其效果取決於SHOW DATABASES權限:如果變數值為ON,只允許具有SHOW DATABASES權限的人們使用SHOW DATABASES 語句,並且該語句將顯示所有資料庫名。如果值為OFF,允許所有用戶執行SHOW DATABASES,但只顯示用戶具有SHOW DATABASES或其它權限的資料庫的名稱。

·         slave_compressed_protocol

如果主、從伺服器均支援,確定是否使用從/主壓縮協議。

·         slave_load_tmpdir

從伺服器為複製LOAD DATA INFILE語句建立臨時檔案的目錄名。

·         slave_net_timeout

放棄讀操作前等待主/從連接的更多數據的等待秒數。

·         slave_skip_errors

從伺服器應跳過(忽視)的複製錯誤。

·         slave_transaction_retries

如果由於ofInnoDB死鎖或超過InnoDBinnodb_lock_wait_timeoutNDBCLUSTERTransactionDeadlockDetectionTimeoutTransactionInactiveTimeout複製從伺服器SQL線程未能執行事務,在提示錯誤並停止前它自動重複slave_transaction_retries次。 預設值是10

·         slow_launch_time

如果建立線程的時間超過該秒數,伺服器增加Slow_launch_threads狀態變數。

·         socket

Unix平台:用於本地客戶端連接的套接字檔案。預設為/var/lib/mysql/mysql.sock

Windows:用於本地客戶端連接的命名管道名。預設為mysql

·         sort_buffer_size

每個排序線程分配的緩衝區的大小。增加該值可以加快ORDER BYGROUP BY操作。參見A.4.4節,「MySQL將臨時檔案儲存在哪裡」

·         sql_mode

當前的伺服器SQL模式,可以動態設置。參見5.3.2節,「SQL伺服器模式」

·         sql_slave_skip_counter

從伺服器應跳過的來自主伺服器的事件數。

·         storage_engine

該變數是table_typeis的同義詞。在MySQL 5.1,首選storage_engine

·         sync_binlog

如果為正,當每個sync_binlog'th寫入該二進制日誌後,MySQL伺服器將它的二進制日誌同步到硬盤上(fdatasync())。請注意如果在autocommit模式,每執行一個語句向二進制日誌寫入一次,否則每個事務寫入一次。 預設值是0,不與硬盤同步。值為1是最安全的選擇,因為崩潰時,您最多丟掉二進制日誌中的一個語句/事務;但是,這是最慢的選擇(除非硬盤有電池備份緩存,從而使同步工作較快)

·         sync_frm

如果該變數設為1,當建立非臨時資料表時它的.frm檔案被同步到硬盤上(fdatasync());這樣較慢但出現崩潰時較安全。 預設值為1

·         system_time_zone

伺服器系統時區。當 伺服器開始執行時,它繼承機器預設時區設置值,可以由運行伺服器的帳號或在啟動指令中進行修改。該值用來設置system_time_zone。典型情況用TZ環境變數來指定時區。還可以用mysqld_safe指令的--timez選項來指定。

·         table_cache

所有線程打開的資料表的數目。增大該值可以增加mysqld需要的檔案描述符的數量。您可以檢查Opened_tables狀態變數來檢查您是否需要增加資料表緩存。參見5.3.4節,「伺服器狀態變數」。如果Opened_tables值較大,並且多次執行FLUSH TABLES(只是強制關閉所有資料表並重新),則應增加table_cache變數的值。

關於資料表緩存的詳細訊息,參見7.4.9節,「MySQL如何打開和關閉資料表」

·         table_type

預設資料表類型(儲存引擎)。要想在伺服器啟動時設置資料表類型,使用--default-table-type選項。參見5.3.1節,「mysqld命令行選項」

·         thread_cache_size

伺服器應緩存多少線程以便重新使用。當客戶端中斷連接時,如果線程少於thread_cache_size,則客戶端的線程被放入緩存。當請求線程時如果允授權以從緩存中重新利用線程,並且只有當緩存空了時才會建立新線程。如果新連接很多,可以增加該變數以提高性能。(一般情況,如果線程執行得很好,性能提高不明顯)。檢查ConnectionsThreads_created狀態變數的差(詳見5.3.4節,「伺服器狀態變數」),您可以看見線程緩存的效率。

·         thread_concurrency

Solaris中,mysqld用該值使用thr_setconcurrency()。該函數使應用程式向線程系統提供需要同時運行的期望的線程數目的提示。

·         thread_stack

每個線程的堆棧大小。用crash-me測試檢測出的許多限制取決於該值。 預設值足夠大,可以滿足普通操作。參見7.1.4節,「MySQL基準套件」

·         time_format

該變數為使用。

·         time_zone

當前的時區。初使值是'SYSTEM'(使用system_time_zone的值),但可以用--default-time-zone選項在伺服器啟動時顯式指定。

·         tmp_table_size

如果內存內的臨時資料表超過該值,MySQL自動將它轉換為硬盤上的MyISAM資料表。如果您執行許多高級GROUP BY查詢並且有大量內存,則可以增加tmp_table_size的值。

·         tmpdir

保存臨時檔案和臨時資料表的目錄。該變數可以設置為幾個路徑,按round-robin模式使用。在Unix中應該用冒號(:)間隔開路徑,在WindowsNetWareOS/2中用分號()

用來將負荷分散到幾個物理硬盤上。如果MySQL伺服器為複製從伺服器,您不應將tmpdir設置為指向基於內存的檔案系統上的目錄或當伺服器主機重啟時聲明的目錄。複製從伺服器需要部分臨時檔案來在機器重啟後仍可用,以便它可以複製臨時資料表或執行LOAD DATA INFILE操作。如果伺服器重啟時臨時檔案夾中的檔案丟失了,則複製失敗。但是,如果您使用MySQL 4.0.0或更新版本,您可以使用 slave_load_tmpdir變數設置從伺服器的臨時目錄。在這種情況下,從伺服器不再使用常規tmpdir,說明您可以將tmpdir設置到一個非固定位置。

·         transaction_alloc_block_size

為保存將保存到二進制日誌中的事務的查詢而分配的內存塊的大小(字節)

·         transaction_prealloc_size

transaction_alloc_blocks分配的固定緩衝區的大小(字節),在兩次查詢之間不會釋放。使該值足夠大,將所有查詢固定到一個事務中,可以避免多次malloc()使用。

·         tx_isolation

預設事務隔離級別。預設值為REPEATABLE-READ

·         updatable_views_with_limit

該變數控制如果更新包含LIMIT子句,是否可以在當前資料表中使用不包含主關鍵字的視圖進行更新。(通常用GUI工具生成這類更新)。更新指UPDATEDELETE語句。這兒主關鍵字指PRIMARY KEY,或一個UNIQUE索引,其中任何列不可以包含NULL

該變數有兩個值:

o        1YES:只發出警告(沒有錯誤消息)。這是 預設值。

o        0NO:禁止更新。

·         version

伺服器版本號。

·         version_bdb

BDB儲存引擎版本。

·         version_comment

configure指令有一個--with-comment選項,當構建MySQL時可以進行註釋。該變數包含註釋值。

·         version_compile_machine

MySQL構建的機器或架構的類型。

·         version_compile_os

MySQL構建的作業系統的類型。

·         wait_timeout

伺服器關閉非交互連接之前等待活動的秒數。

線上程啟動時,根據全局wait_timeout值或全局interactive_timeout值初始化會話wait_timeout值,取決於客戶端類型(mysql_real_connect()的連接選項CLIENT_INTERACTIVE定義)。又見interactive_timeout

5.3.3.1. 動態系統變數

許多伺服器系統變數是動態的,可以使用SET GLOBALSET SESSION在運行時設置。您還可以使用SELECT獲得它們的值。參見9.4節,「系統變數」

下面的資料表列出了所有動態系統變數。最後1列說明每個變數是否適用GLOBALSESSION(或二者)

變數名

值類型

類型

autocommit

boolean

SESSION

big_tables

boolean

SESSION

binlog_cache_size

numeric

GLOBAL

bulk_insert_buffer_size

numeric

GLOBAL | SESSION

character_set_client

string

GLOBAL | SESSION

character_set_connection

string

GLOBAL | SESSION

character_set_results

string

GLOBAL | SESSION

character_set_server

string

GLOBAL | SESSION

collation_connection

string

GLOBAL | SESSION

collation_server

string

GLOBAL | SESSION

completion_type

numeric

GLOBAL | SESSION

concurrent_insert

boolean

GLOBAL

connect_timeout

numeric

GLOBAL

convert_character_set

string

GLOBAL | SESSION

default_week_format

numeric

GLOBAL | SESSION

delay_key_write

OFF | ON | ALL

GLOBAL

delayed_insert_limit

numeric

GLOBAL

delayed_insert_timeout

numeric

GLOBAL

delayed_queue_size

numeric

GLOBAL

div_precision_increment

numeric

GLOBAL | SESSION

engine_condition_pushdown

boolean

GLOBAL | SESSION

error_count

numeric

SESSION

expire_logs_days

numeric

GLOBAL

flush

boolean

GLOBAL

flush_time

numeric

GLOBAL

foreign_key_checks

boolean

SESSION

ft_boolean_syntax

numeric

GLOBAL

group_concat_max_len

numeric

GLOBAL | SESSION

identity

numeric

SESSION

innodb_autoextend_increment

numeric

GLOBAL

innodb_concurrency_tickets

numeric

GLOBAL

innodb_max_dirty_pages_pct

numeric

GLOBAL

innodb_max_purge_lag

numeric

GLOBAL

innodb_support_xa

boolean

GLOBAL | SESSION

innodb_sync_spin_loops

numeric

GLOBAL

innodb_table_locks

boolean

GLOBAL | SESSION

innodb_thread_concurrency

numeric GLOBAL

 

innodb_thread_sleep_delay

numeric GLOBAL

 

insert_id

boolean

SESSION

interactive_timeout

numeric

GLOBAL | SESSION

join_buffer_size

numeric

GLOBAL | SESSION

key_buffer_size

numeric

GLOBAL

last_insert_id

numeric

SESSION

local_infile

boolean

GLOBAL

log_warnings

numeric

GLOBAL

long_query_time

numeric

GLOBAL | SESSION

low_priority_updates

boolean

GLOBAL | SESSION

max_allowed_packet

numeric

GLOBAL | SESSION

max_binlog_cache_size

numeric

GLOBAL

max_binlog_size

numeric

GLOBAL

max_connect_errors

numeric

GLOBAL

max_connections

numeric

GLOBAL

max_delayed_threads

numeric

GLOBAL

max_error_count

numeric

GLOBAL | SESSION

max_heap_table_size

numeric

GLOBAL | SESSION

max_insert_delayed_threads

numeric

GLOBAL

max_join_size

numeric

GLOBAL | SESSION

max_relay_log_size

numeric

GLOBAL

max_seeks_for_key

numeric

GLOBAL | SESSION

max_sort_length

numeric

GLOBAL | SESSION

max_tmp_tables

numeric

GLOBAL | SESSION

max_user_connections

numeric

GLOBAL

max_write_lock_count

numeric

GLOBAL

myisam_stats_method

enum

GLOBAL | SESSION

multi_read_range

numeric

GLOBAL | SESSION

myisam_data_pointer_size

numeric

GLOBAL

log_bin_trust_routine_creators

boolean

GLOBAL

myisam_max_sort_file_size

numeric

GLOBAL | SESSION

myisam_repair_threads

numeric

GLOBAL | SESSION

myisam_sort_buffer_size

numeric

GLOBAL | SESSION

net_buffer_length

numeric

GLOBAL | SESSION

net_read_timeout

numeric

GLOBAL | SESSION

net_retry_count

numeric

GLOBAL | SESSION

net_write_timeout

numeric

GLOBAL | SESSION

old_passwords

numeric

GLOBAL | SESSION

optimizer_prune_level

numeric

GLOBAL | SESSION

optimizer_search_depth

numeric

GLOBAL | SESSION

preload_buffer_size

numeric

GLOBAL | SESSION

query_alloc_block_size

numeric

GLOBAL | SESSION

query_cache_limit

numeric

GLOBAL

query_cache_size

numeric

GLOBAL

query_cache_type

enumeration

GLOBAL | SESSION

query_cache_wlock_invalidate

boolean

GLOBAL | SESSION

query_prealloc_size

numeric

GLOBAL | SESSION

range_alloc_block_size

numeric

GLOBAL | SESSION

read_buffer_size

numeric

GLOBAL | SESSION

read_only

numeric

GLOBAL

read_rnd_buffer_size

numeric

GLOBAL | SESSION

rpl_recovery_rank

numeric

GLOBAL

safe_show_database

boolean

GLOBAL

secure_auth

boolean

GLOBAL

server_id

numeric

GLOBAL

slave_compressed_protocol

boolean

GLOBAL

slave_net_timeout

numeric

GLOBAL

slave_transaction_retries

numeric

GLOBAL

slow_launch_time

numeric

GLOBAL

sort_buffer_size

numeric

GLOBAL | SESSION

sql_auto_is_null

boolean

SESSION

sql_big_selects

boolean

SESSION

sql_big_tables

boolean

SESSION

sql_buffer_result

boolean

SESSION

sql_log_bin

boolean

SESSION

sql_log_off

boolean

SESSION

sql_log_update

boolean

SESSION

sql_low_priority_updates

boolean

GLOBAL | SESSION

sql_max_join_size

numeric

GLOBAL | SESSION

sql_mode

enumeration

GLOBAL | SESSION

sql_notes

boolean

SESSION

sql_quote_show_create

boolean

SESSION

sql_safe_updates

boolean

SESSION

sql_select_limit

numeric

SESSION

sql_slave_skip_counter

numeric

GLOBAL

updatable_views_with_limit

enumeration

GLOBAL | SESSION

sql_warnings

boolean

SESSION

sync_binlog

numeric

GLOBAL

sync_frm

boolean

GLOBAL

storage_engine

enumeration

GLOBAL | SESSION

table_cache

numeric

GLOBAL

table_type

enumeration

GLOBAL | SESSION

thread_cache_size

numeric

GLOBAL

time_zone

string

GLOBAL | SESSION

timestamp

boolean

SESSION

tmp_table_size

enumeration

GLOBAL | SESSION

transaction_alloc_block_size

numeric

GLOBAL | SESSION

transaction_prealloc_size

numeric

GLOBAL | SESSION

tx_isolation

enumeration

GLOBAL | SESSION

unique_checks

boolean

SESSION

wait_timeout

numeric

GLOBAL | SESSION

warning_count

numeric

SESSION

標記為string的變數採用字串值。標記為numeric的變數採用數字值。標記為boolean的變數可以設置為01ONOFF。標記為enumeration的變數一般情況應設置為該變數的某個可用值,但還可以設置為對應期望的枚舉值的數字。對於枚舉系統變數,第1個枚舉值應對應0。這不同於ENUM列,第1個枚舉值對應1

5.3.4. 伺服器狀態變數

伺服器維護許多提供操作相關訊息的狀態變數。您可以通過SHOW STATUS語句查看這些變數和它們的值:

mysql> SHOW STATUS;
+-----------------------------------+------------+
| Variable_name                     | Value      |
+-----------------------------------+------------+
| Aborted_clients                   | 0          |
| Aborted_connects                  | 0          |
| Bytes_received                    | 155372598  |
| Bytes_sent                        | 1176560426 |
 
 
| Connections                       | 30023      |
| Created_tmp_disk_tables           | 0          |
| Created_tmp_files                 | 3          |
| Created_tmp_tables                | 2          |
 
 
| Threads_created                   | 217        |
| Threads_running                   | 88         |
| Uptime                            | 1389872    |
+-----------------------------------+------------+
 

FLUSH STATUS語句可以將許多狀態變數重設為0

狀態變數有以下含義。沒有指示版本的變數在MySQL 5.1之前已經出現。關於它們的使用歷史,參見MySQL 5.0參考手冊

·         Aborted_clients

由於客戶端沒有正確關閉連接導致客戶端終止而中斷的連接數。參見A.2.10節,「通信錯誤和失效連接」

·         Aborted_connects

試圖連接到MySQL伺服器而失敗的連接數。參見A.2.10節,「通信錯誤和失效連接」

·         Binlog_cache_disk_use

使用臨時二進制日誌緩存但超過binlog_cache_size值並使用臨時檔案來保存事務中的語句的事務數量。

·         Binlog_cache_use

使用臨時二進制日誌緩存的事務數量。

·         Bytes_received

從所有客戶端接收到的字節數。

·         Bytes_sent

發送給所有客戶端的字節數。

·         Com_xxx

Com_xxx 語句計數變數資料表示每個xxx 語句執行的次數。每類語句有一個狀態變數。例如,Com_deleteCom_insert分別統計DELETE INSERT語句執行的次數。

Com_stmt_xxx狀態變數為:

o        Com_stmt_prepare

o        Com_stmt_execute

o        Com_stmt_fetch

o        Com_stmt_send_long_data

o        Com_stmt_reset

o        Com_stmt_close

這些變數代資料表準備好的語句命令。它們的名字對應網絡層使用的COM_xxx 命令系列;換句話說:當準備好的語句API使用如mysql_stmt_prepare()mysql_stmt_執行()並執行時,它們的值增加。但是,當執行下面的SQL語句時,Com_stmt_prepare, Com_stmt_executeCom_stmt_close也增加:PREPAREEXECUTEDEALLOCATE PREPARE。此外,舊(MySQL 4.1.3起可用)語句計數變數Com_prepare_sqlCom_execute_sqlCom_dealloc_sql的值也隨PREPAREEXECUTEDEALLOCATE PREPARE語句增加。Com_stmt_fetch代資料表通過光標獲取的網絡round-trips的總數量。

所有Com_stmt_xxx變數將增加,即使語句參數未知或執行過程中出現錯誤。換句話說,它們的值對應發出的請求數,而不是成功完成的請求數。

·         Connections

試圖連接到(不管是否成功)MySQL伺服器的連接數。

·         Created_tmp_disk_tables

伺服器執行語句時在硬盤上自動建立的臨時資料表的數量。

·         Created_tmp_files

mysqld已經建立的臨時檔案的數量。

·         Created_tmp_files

伺服器執行語句時自動建立的內存中的臨時資料表的數量。如果Created_tmp_disk_tables較大,您可能要增加tmp_table_size值使臨時 資料表基於內存而不基於硬盤。

·         Delayed_errors

INSERT DELAYED寫的出現錯誤的行數(可能為duplicate key)

·         Delayed_insert_threads

使用的INSERT DELAYED處理器線程數。

·         Delayed_writes

寫入的INSERT DELAYED行數。

·         Flush_commands

執行的FLUSH語句數。

·         Handler_commit

內部提交語句數。

·         Handler_discover

MySQL伺服器可以問NDB CLUSTER儲存引擎是否知道某一名字的資料表。這被稱作發現。Handler_discover說明通過該方法發現的次數。

·         Handler_delete

行從資料表中刪除的次數。

·         Handler_read_first

索引中第一條被讀的次數。如果較高,它建議伺服器正執行大量全索引掃瞄;例如,SELECT col1 FROM foo,假定col1有索引。

·         Handler_read_key

根據鍵讀一行的請求數。如果較高,說明查詢和資料表的索引正確。

·         Handler_read_next

按照鍵順序讀下一行的請求數。如果您用範圍約束或如果執行索引掃瞄來查詢索引列,該值增加。

·         Handler_read_prev

按照鍵順序讀前一行的請求數。該讀方法主要用於最佳化ORDER BY ... DESC

·         Handler_read_rnd

根據固定位置讀一行的請求數。如果您正執行大量查詢並需要對結果進行排序該值較高。您可能使用了大量需要MySQL掃瞄整個資料表的查詢或您的連接沒有正確使用鍵。

·         Handler_read_rnd_next

在數據檔案中讀下一行的請求數。如果您正進行大量的資料表掃瞄,該值較高。通常說明您的資料表索引不正確或寫入的查詢沒有利用索引。

·         Handler_rollback

內部ROLLBACK語句的數量。

·         Handler_update

在資料表內更新一行的請求數。

·         Handler_write

在資料表內插入一行的請求數。

·         Innodb_buffer_pool_pages_data

包含數據的頁數(髒或乾淨)

·         Innodb_buffer_pool_pages_dirty

當前的髒頁數。

·         Innodb_buffer_pool_pages_flushed

要求清空的緩衝池頁數。

·         Innodb_buffer_pool_pages_free

空頁數。

·         Innodb_buffer_pool_pages_latched

InnoDB緩衝池中鎖定的頁數。這是當前正讀或寫或由於其它原因不能清空或刪除的頁數。

·           Innodb_buffer_pool_pages_misc

忙的頁數,因為它們已經被分配優先用作管理,例如行鎖定或適用的哈希索引。該值還可以計算為Innodb_buffer_pool_pages_total - Innodb_buffer_pool_pages_free - Innodb_buffer_pool_pages_data

·         Innodb_buffer_pool_pages_total

緩衝池總大小(頁數)。

·         Innodb_buffer_pool_read_ahead_rnd

InnoDB初始化的「隨機read-aheads數。當查詢以隨機順序掃瞄資料表的一大部分時發生。

·         Innodb_buffer_pool_read_ahead_seq

InnoDB初始化的順序read-aheads數。當InnoDB執行順序全資料表掃瞄時發生。

·         Innodb_buffer_pool_read_requests

InnoDB已經完成的邏輯讀請求數。

·         Innodb_buffer_pool_reads

不能滿足InnoDB必須單頁讀取的緩衝池中的邏輯讀數量。

·         Innodb_buffer_pool_wait_free

一般情況,通過後台向InnoDB緩衝池寫。但是,如果需要讀或建立頁,並且沒有乾淨的頁可用,則它還需要先等待頁面清空。該計數器對等待實例進行記數。如果已經適當設置緩衝池大小,該值應小。

·         Innodb_buffer_pool_write_requests

InnoDB緩衝池的寫數量。

·         Innodb_data_fsyncs

fsync()操作數。

·         Innodb_data_pending_fsyncs

當前掛起的fsync()操作數。

·         Innodb_data_pending_reads

當前掛起的讀數。

·         Innodb_data_pending_writes

當前掛起的寫數。

·         Innodb_data_read

至此已經讀取的數據數量(字節)。

·         Innodb_data_reads

數據讀總數量。

·         Innodb_data_writes

數據寫總數量。

·         Innodb_data_written

至此已經寫入的數據量(字節)。

·         Innodb_dblwr_writes, Innodb_dblwr_pages_written

已經執行的雙寫操作數量和為此目的已經寫好的頁數。參見15.2.14.1節,「磁盤I/O」

·         Innodb_log_waits

我們必須等待的時間,因為日誌緩衝區太小,我們在繼續前必須先等待對它清空。

·         Innodb_log_write_requests

日誌寫請求數。

·         Innodb_log_writes

向日誌檔案的物理寫數量。

·         Innodb_os_log_fsyncs

向日誌檔案完成的fsync()寫數量。

·         Innodb_os_log_pending_fsyncs

掛起的日誌檔案fsync()操作數量。

·         Innodb_os_log_pending_writes

掛起的日誌檔案寫操作。

·         Innodb_os_log_written

寫入日誌檔案的字節數。

·         Innodb_page_size

編譯的InnoDB頁大小(預設16KB)。許多值用頁來記數;頁的大小很容易轉換為字節。

·         Innodb_pages_created

建立的頁數。

·         Innodb_pages_read

讀取的頁數。

·         Innodb_pages_written

寫入的頁數。

·         Innodb_row_lock_current_waits

當前等待的待鎖定的行數。

·         Innodb_row_lock_time

行鎖定花費的總時間,單位毫秒。

·         Innodb_row_lock_time_avg

行鎖定的平均時間,單位毫秒。

·         Innodb_row_lock_time_max

行鎖定的最長時間,單位毫秒。

·         Innodb_row_lock_waits

一行鎖定必須等待的時間數。

·         Innodb_rows_deleted

InnoDB資料表刪除的行數。

·         Innodb_rows_inserted

插入到InnoDB資料表的行數。

·         Innodb_rows_read

InnoDB資料表讀取的行數。

·         Innodb_rows_updated

InnoDB資料表內更新的行數。

·         Key_blocks_not_flushed

鍵緩存內已經更改但還沒有清空到硬盤上的鍵的數據塊數量。

·         Key_blocks_unused

鍵緩存內未使用的塊數量。您可以使用該值來確定使用了多少鍵緩存;參見5.3.3節,「伺服器系統變數」Key_buffer_size的討論。

·         Key_blocks_used

鍵緩存內使用的塊數量。該值為高水平線標記,說明已經同時最多使用了多少塊。

·         Key_read_requests

從緩存讀鍵的數據塊的請求數。

·         Key_reads

從硬盤讀取鍵的數據塊的次數。如果Key_reads較大,則Key_buffer_size值可能太小。可以用Key_reads/Key_read_requests計算緩存損失率。

·         Key_write_requests

將鍵的數據塊寫入緩存的請求數。

·         Key_writes

向硬盤寫入將鍵的數據塊的物理寫操作的次數。

·         Last_query_cost

用查詢最佳化器計算的最後編譯的查詢的總成本。用於對比同一查詢的不同查詢方案的成本。預設值0資料表示還沒有編譯查詢。 預設值是0Last_query_cost具有會話範圍。

·         Max_used_connections

伺服器啟動後已經同時使用的連接的最大數量。

·         Not_flushed_delayed_rows

等待寫入INSERT DELAY隊列的行數。

·         Open_files

打開的檔案的數目。

·         Open_streams

打開的流的數量(主要用於記錄)

·         Open_tables

當前打開的資料表的數量。

·         Opened_tables

已經打開的資料表的數量。如果Opened_tables較大,table_cache 值可能太小。

·         QCACHE_free_blocks

查詢緩存內自由內存塊的數量。

·         QCACHE_free_memory

用於查詢緩存的自由內存的數量。

·         QCACHE_hits

查詢緩存被訪問的次數。

·         QCACHE_inserts

加入到緩存的查詢數量。

·         QCACHE_lowmem_prunes

由於內存較少從緩存刪除的查詢數量。

·         QCACHE_not_cached

非緩存查詢數(不可緩存,或由於query_cache_type設定值未緩存)

·         Qcache_queries_in_cache

登記到緩存內的查詢的數量。

·         Qcache_total_blocks

查詢緩存內的總塊數。

·         Questions

已經發送給伺服器的查詢的個數。

·         Rpl_status

失敗安全複製狀態(還未使用)

·         Select_full_join

沒有使用索引的聯接的數量。如果該值不為0,您應仔細檢查資料表的索引。

·         Select_full_range_join

在引用的資料表中使用範圍搜索的聯接的數量。

·         Select_range

在第一個資料表中使用範圍的聯接的數量。一般情況不是關鍵問題,即使該值相當大。

·         Select_range_check

在每一行數據後對鍵值進行檢查的不帶鍵值的聯接的數量。如果不為0,您應仔細檢查資料表的索引。

·         Select_scan

對第一個資料表進行完全掃瞄的聯接的數量。

·         Slave_open_temp_tables

當前由從SQL線程打開的臨時資料表的數量。

·         Slave_running

如果該伺服器是連接到主伺服器的從伺服器,則該值為ON

·         Slave_retried_transactions

啟動後複製從伺服器SQL線程嘗試事務的總次數。

·         Slow_launch_threads

建立時間超過slow_launch_time秒的線程數。

·         Slow_queries

查詢時間超過long_query_time秒的查詢的個數。參見5.11.4節,「慢速查詢日誌」

·         Sort_merge_passes

排序算法已經執行的合併的數量。如果這個變數值較大,應考慮增加sort_buffer_size系統變數的值。

·         Sort_range

在範圍內執行的排序的數量。

·         Sort_rows

已經排序的行數。

·         Sort_scan

通過掃瞄資料表完成的排序的數量。

·         Ssl_xxx

用於SSL連接的變數。

·         Table_locks_immediate

立即獲得的資料表的鎖的次數。

·         Table_locks_waited

不能立即獲得的資料表的鎖的次數。如果該值較高,並且有性能問題,您應首先最佳化查詢,然後拆分資料表或使用複製。

·         Threads_cached

線程緩存內的線程的數量。

·         Threads_connected

當前打開的連接的數量。

·         Threads_created

建立用來處理連接的線程數。如果Threads_created較大,您可能要增加thread_cache_size值。緩存訪問率的計算方法Threads_created/Connections

·           Threads_running

激活的(非睡眠狀態)線程數。

·         Uptime

伺服器已經運行的時間(以秒為單位)。

5.4. mysql_fix_privilege_tables:升級MySQL系統資料表

一些MySQL發佈對mysql資料庫中的系統資料表的結構進行了更改,新增了新權限或特性。當您更新到新版本MySQL,您應同時更新系統資料表,以確保它們的結構最新。首先備份mysql資料庫,然後按照下面的程式操作。

UnixUnix類系統中,運行mysql_fix_privilege_tables指令來更新系統資料表:

shell> mysql_fix_privilege_tables

您必須在伺服器運行時執行該指令。它試圖連接本機上用root運行的伺服器。如果root帳號需要密碼,在命令行中按下述方法給出密碼:

shell> mysql_fix_privilege_tables--password=root_password

mysql_fix_privilege_tables指令可以執行將系統資料表轉換為當前格式的任何動作。運行時您可能會看見一些Duplicate column name警告;您可以忽略它們。

運行完指令後,停止伺服器並重啟。

Windows系統中,MySQL分發包括mysql_fix_privilege_tables.sql SQL指令,您可以用mysql客戶端來運行。例如,如果MySQL安裝到C:\Program Files\MySQL\MySQL Server 5.1,命令應為:

C:\> C:\Program Files\MySQL\MySQL Server 5.1\bin\mysql -u root -p mysql
mysql> SOURCE C:/Program Files/MySQL/MySQL Server 5.1/scripts/mysql_fix_privilege_tables.sql

如果安裝到其它目錄,相應地更改路徑名。

mysql命令將提示輸入root密碼;按照提示輸入密碼。

Unix中,當mysql處理mysql_fix_privilege_tables.sql script指令中的語句時,您可能會看見一些Duplicate column name警告;您可以忽略它們。

運行完指令後,停止伺服器並重啟。

5.5. MySQL伺服器關機程序

  1.  伺服器關閉程序可以概括為:

    1.    啟動關閉程序

    2.    伺服器根據需要建立關閉線程

    3.    伺服器停止接收新連接

    4.    伺服器終止當前的活動

    5.    儲存引擎被停掉或關閉

    6.    伺服器退出

    下面是更詳細的描述:

    1.    啟動關閉程序。

    可以用多種方法啟動伺服器的關閉。例如,擁有SHUTDOWN權限的用戶可以執行mysqladmin shutdown命令。mysqladmin可以用於所有支援MySQL的平台上。其它作業系統相關的關閉開始方法還可能有:在Unix中,當接收到SIGTERM信號後,伺服器關閉。對於在Windows中作為服務運行的伺服器,當服務管理器讓它關閉時,則關閉。

    2.    伺服器根據需要建立關閉線程。

    根據開始關閉的方式,伺服器可以建立線程來處理關閉程序。如果客戶端需要關閉,則建立關閉線程。如果收到SIGTERM信號後關閉,信號線程可以自己關閉,或者建立單獨的線程來完成。如果伺服器嘗試建立關閉線程而不能建立(例如,如果內存被耗盡),它在錯誤日誌中給出診斷消息:

    Error: Can't create thread to kill server

    3.    伺服器停止接收新連接。

    在關閉過程中要想防止啟動新活動,伺服器停止接收新的客戶端連接。它將關閉它幀聽的網絡連接:TCP/IP端口、Unix套接字檔案、Windows命名管道和在Windows中的共享內存。

    4.    伺服器終止當前的活動。

    對於每個與客戶端連接相關的線程,與客戶端的連接被中斷,線程被標記為「殺掉的」。當線程注意到此類標記後則線程終止。空閒連接的線程很快終止。當前正處理查詢的線程定期檢查它們的狀態,終止的時間較長。關於線程終止的詳細訊息,參見13.5.5.3節,「KILL語法」,特別是關於對MyISAM資料表的殺掉的REPAIR TABLEOPTIMIZE TABLE操作。

    對於有打開事務的線程,事務被回滾。請注意如果某個線程正在更新非事務資料表,多行UPDATEINSERT等操作會使資料表部分更新,因為操作在完成前會終止。

    如果伺服器是主複製伺服器,與當前連接的從伺服器相關的線程的處理方式同其它客戶端線程。即每個線程被標記為殺掉的,在下次檢查他的狀態後會退出。

    如果伺服器是從複製伺服器,在客戶端線程標記為殺掉的之前,激活的I/OSQL線程被停止。SQL線程允許先結束它當前的語句(以避免造成複製問題)然後停止。如果此時SQL線程正位於事務中部,事務則 回滾。

    5.    儲存引擎被停掉或關閉。

    在該階段,資料表緩存被清空,所有打開的資料表被關閉。

    每個儲存引擎執行它管理的資料表需要的任何動作。例如,MyISAM清空任何掛起的資料表索引寫操作。InnoDB將它的緩衝池清空到硬盤上(除非innodb_fast_shutdown2),將當前的LSN寫入資料表內,並終止自己的內部線程。

    6.    伺服器退出。

5.6. 一般安全問題

本節描述一些常見的需要注意的安全問題,以及一些可以使您的MySQL安裝更加安全以防止黑客和誤用的措施。關於MySQL用於設置用戶帳號並檢查資料庫訪問的訪問控制系統的具體訊息,參見5.7節,「MySQL訪問權限系統」

5.6.1. 通用安全指南

任何在與Internet聯網的計算機上使用MySQL的用戶都應仔細閱讀本節,以避免最常見的安全問題。

討論安全時,我們強調必須完全保護整個伺服器主機的安全(而不只是MySQL伺服器)防範各種類型的可能的攻擊:偷聽、修改、重放和拒絕服務。我們在這裡不能覆蓋各方面的內容和措施。

MySQL根據訪問控制列資料表(ACL)對所有連接、查詢和其它用戶嘗試執行的操作進行安全管理。MySQL客戶端和伺服器之間還支援SSL-加密連接。這兒討論的許多概念並不是MySQL專有的;該思想幾乎同樣適合所有應用程式。

運行MySQL時,應盡量遵從下面的指導:

·         不要讓任何人(除了MySQL root帳號)訪問mysql資料庫中的user資料表!這很關鍵。加密的密碼才是MySQL中的真正的密碼。知道user資料表中所列的密碼並且能訪問該帳號客訪問的主機的人可以很容易地用該用戶登錄

·         學習MySQL訪問權限系統。用GRANTREVOKE語句來控制對MySQL的訪問。不要授予超過需求的權限。決不能為所有主機授權。

檢查清單:

o        試試mysql -u root。如果您能夠成功連接伺服器而沒有要任何密碼,則說明有問題。任何人可以作為MySQLroot用戶用它的全部權限來連接MySQL伺服器!查閱MySQL安裝說明,應特別注意關於設置root密碼的訊息。參見2.9.3節,「使初始MySQL帳號安全」

o        通過SHOW GRANTS語句檢查查看誰已經訪問了什麼。然後使用REVOKE語句刪除不再需要的權限。

·         不要將純文本密碼保存到資料庫中。如果您的計算機有安全危險,入侵者可以獲得所有的密碼並使用它們。相反,應使用MD5()SHA1()或單向哈希函數。

·         不要從詞典中選擇密碼。有專門的程式可以破解它們。即使象「xfish98」這樣的密碼也很差。而「duag98」要好得多,雖然包含了相同的字「fish」,但從標準QWERTY鍵盤向左輸入。另一種方法是使用「Mhall」,來自句子「Mary had a little lamb.」中每個字的第一個字元。這樣很容易記住並輸入,但是不知道的人很難猜出來。

·         購買防火牆。這樣可以保護您防範各種軟件中至少50%的各種類型的攻擊。把MySQL放到防火牆後或隔離區(DMZ)

檢查清單:

o        試試從Internet使用nmap工具掃瞄端口。MySQL預設使用端口3306。不應從不可信任主機訪問該端口。另一種檢查是否MySQL端口打開的簡單方式是從遠程機器試試下面的命令,其中server_hostMySQL伺服器運行的主機:

o                     shell> telnet server_host 3306

如果得到連接並得到一些垃圾字元,則端口打開著,則應從防火牆或路由器上關閉,除非您有合理的理由讓它開著。如果telnet掛起或連接被拒絕,則端口被阻塞,這是您所希望的。

不要信任應用程式的用戶輸入的任何數據。它們可以用Web形式、URL或構建的應用程式輸入特殊或逃溢字元序列來嘗試欺騙您的代碼。如果某個用戶輸入「; DROP DATABASE mysql;」等內容,應確保您的應用程式保持安全。這是特例,但當黑客使用類似技術時,如果您沒有做好準備,結果可能會出現大的安全漏洞和數據丟失。

一個常見的錯誤是只保護字串數據值。一定要記住還應檢查數字數據。如果當用戶輸入值234時,應用程式生成查詢SELECT * FROM table WHERE ID=234用戶可以輸入值234 OR 1=1使應用程式生成查詢SELECT * FROM table WHERE ID=234 OR 1=1。結果是伺服器搜尋資料表內的每個記錄。這樣會暴露每個記錄並造成過多的伺服器負載。保護防範這類攻擊的最簡單的方法是使用單引號將數字常量引起來:SELECT * FROM table WHERE ID='234'。如果用戶輸入其它訊息,均變為字串的一部分。在數字部分,MySQL自動將字串轉換為數字並剝離字串包含的附加的非數字字元。

有時候人們會認為如果資料庫只包含供公共使用的數據,則不需要保護。這是不正確的。即使允許顯示資料庫中的任何記錄,您仍然應保護防範拒絕服務攻擊(例如,基於前面段落中所述的技術的攻擊,會使伺服器浪費資源)。否則,您的伺服器不再響應合法用戶。

檢查清單:

o        試試用Web形式輸入單引號和雙引號('』和『")。如果得到任何形式的MySQL錯誤,立即分析原因。

o        試試修改動態URL,可以在其中新增%22(")%23(#)%27(')

o        試試在動態URL中修改數據類型,使用前面示範中的字元,包括數字和字元類型。您的應用程式應足夠安全,可以防範此類修改和類似攻擊。

o        試試輸入字元、空格和特殊符號,不要輸入數值字段的數字。您的應用程式應在將它們傳遞到MySQL之前將它們刪除或生成錯誤。將未經過檢查的值傳遞給MySQL是很危險的!

o        將數據傳給MySQL之前先檢查其大小。

o        用管理帳號之外的帳號將應用程式連接到資料庫。不要給應用程式任何不需要的訪問權限。

·         許多應用程式編程接口提供了措施逃逸數據值中的特殊字元。如果使用正確,可以防止應用程式用戶輸入使應用程式生成不期望的效果的語句的數值:

o        MySQL C API:使用mysql_real_escape_string() API使用。

o        MySQL++:查詢流使用escapequote修訂符。

o        PHP:使用mysql_escape_string()函數基於MySQL C API中的同名函數。(PHP 4.0.3之前,使用addslashes()PHP 5,可以使用mysqli延伸名,它支援改進的MySQL鑒定協議和密碼,以及用佔位符編寫的語句。

o        Perl DBI:使用quote()方法或使用佔位符。

o        Java JDBC:使用一個PreparedStatement對像和佔位符。

其它編程接口有類似的功能。

·         不要通過Internet傳送明文(未加密的)數據。該訊息可以被有足夠時間和能力來截取它並用於個人目的的任何人訪問。相反,應使用加密協議,例如SSLSSHMySQL支援內部SSL連接,例如版本 4.0.0。可以使用SSH端口映射為通信建立加密(並壓縮)的隧道。

·         學會使用tcpdumpstrings工具。在大多數情況下,您可以使用下面的命令檢查是否MySQL數據流未加密:

·                shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings

(該命令在Linux中可以工作,在其它系統中經過小小的修改後應可以工作)警告:如果您沒有看見明文數據,並不一定說明訊息實際上被加密了。如果您需要較高級別的安全,您應咨詢安全專家。

5.6.2. 使MySQL在攻擊者面前保持安全

當您連接到MySQL伺服器時,您應使用一個密碼。密碼不以明文在上傳輸。客戶端連接序列中的密碼處理在MySQL 4.1.1中已經升級,很安全。如果您仍然使用pre-4.1.1-風格的密碼,加密算法不如新算法強;通過一些工作,可以竊取客戶端和伺服器之間的通信的聰明的攻擊者可以破解密碼。(關於不同的密碼處理方法的討論參見5.7.9節,「MySQL 4.1中的密碼哈希處理」 如果客戶端和伺服器之間的連接通過不可信任網絡,您應使用SSH隧道來加密通信。

所有其它訊息以文本傳送,可以被可以看到連接的任何人讀取。如果您擔心這個,您可以使用壓縮協議來使通信更難以解密。要想使連接更加安全,您應使用SSH來獲得加密的MySQL伺服器和MySQL客戶端之間的TCP/IP連接。您可以從http://www.openssh.org/找到開放原始碼SSH 客戶端,並可以從http://www.ssh.com/獲得商業SSH客戶端。

您還可以使用MySQL內部OpenSSL支援。參見5.8.7節,「使用安全連接」

為了使MySQL系統安全,強烈要求您考慮下列建議:

·         對所有MySQL用戶使用密碼。客戶端程式不需要知道運行它的人員的身份。對於客戶端/伺服器應用程式,用戶可以指定客戶端程式的帳號。例如,如果other_user沒有密碼,任何人可以簡單地用mysql -u other_user db_name冒充他人使用mysql程式進行連接。如果所有用戶有密碼,使用其它用戶的帳號進行連接要困難得多。

要想更改用戶的密碼,應使用SET PASSWORD語句。還可以直接更新mysql資料庫中的user資料表。例如,要更改所有root用戶的MySQL帳號的密碼,應:

shell> mysql -u root
mysql> UPDATE mysql.user SET Password=PASSWORD('newpwd')
    -> WHERE User='root';
mysql> FLUSH PRIVILEGES;

·         絕對不要作為Unixroot用戶運行MySQL伺服器。這樣做非常危險,因為任何具有FILE權限的用戶能夠用root建立檔案(例如,~root/.bashrc)。為了防止,mysqld拒絕用root運行,除非使用--user=root選項明顯指定。

應可以(並且應該)用普通非特權用戶運行mysqld。您可以建立獨立的Unix中的mysql帳號來以便使所有內容更加安全。該帳號只用於管理MySQL。要想用其它Unix用戶啟動mysqld,增加user選項指定/etc/my.cnf選項檔案或伺服器數據目錄的my.cnf選項檔案中的[mysqld]組的帳號。例如:

[mysqld]
user=mysql

該命令使伺服器用指定的用戶來啟動,無論您手動啟動或通過mysqld_safemysql.server啟動。詳細訊息參見A.3.2節,「如何以普通用戶身份運行MySQL」

作為其它Unix用戶而不用root運行mysqld,您不需要更改user資料表中的root帳號,因為MySQL帳號的帳號與Unix帳號的帳號無關。

·         不要允許使用資料表的符號連結。(可以用--skip-symbolic-links選項禁用)如果您用root運行mysqld則特別重要,因為任何對伺服器的數據目錄有寫訪問權限的人則能夠刪除系統中的任何檔案!參見7.6.1.2節,「在Unix平台上使用資料表的符號連結」。

·         確保mysqld運行時,只使用對資料庫目錄具有讀或寫權限的Unix用戶來運行。

·         不要將PROCESSSUPER權限授給非管理用戶。mysqladmin processlist的輸出顯示出當前執行的查詢正文,如果另外的用戶發出一個UPDATE user SET password=PASSWORD('not_secure')查詢,被允許執行那個命令的任何用戶可能看得到。

mysqld為有SUPER權限的用戶專門保留一個額外的連接,因此即使所有普通連接被佔用,MySQL root用戶仍可以登錄並檢查伺服器的活動。

可以使用SUPER權限來終止客戶端連接,通過更改系統變數的值更改服務的器操作,並控制複製伺服器。

·         不要向非管理用戶授予FILE權限。有這權限的任何用戶能在擁有mysqld守護程序權限的檔案系統那裡寫一個檔案!為了更加安全,由SELECT ... INTO OUTFILE生成的所有檔案對每個人是可寫的,並且您不能覆蓋已經存在的檔案。

file權限也可以被用來讀取任何作為運行伺服器的Unix用戶可讀取或訪問的檔案。使用該權限,您可以將任何檔案讀入資料庫資料表。這可能被濫用,例如,通過使用LOAD DATA裝載/etc/passwd進一個資料庫資料表,然後能用SELECT顯示它

·         如果您不信任您的DNS,您應該在授權資料表中使用IP數字而不是主機名。在任何情況下,您應該非常小心地使用包含通配符的主機名來建立 授權資料表條目!

·         如果您想要限制單個帳號允許的連接數量,您可以設置mysqld中的max_user_connections變數來完成。GRANT語句也可以支援 資源控制選項來限制伺服器對一個帳號允許的使用範圍。參見13.5.1.3節,「GRANT和REVOKE語法」

5.6.3. Mysqld安全相關啟動選項

下列mysqld選項影響安全:

·         --allow-suspicious-udfs

該選項控制是否可以載入主函數只有xxx符的用戶定義函數。預設情況下,該選項被關閉,並且只能載入至少有輔助符的UDF。這樣可以防止從未包含合法UDF的共享對像檔案載入函數。參見27.2.3.6節,「用戶定義函數安全注意事項」

·         --local-infile[={0|1}]

如果用--local-infile=0啟動伺服器則客戶端不能使用LOCAL in LOAD DATA語句。參見5.6.4節,「LOAD DATA LOCAL安全問題

·         --old-passwords

強制伺服器為新密碼生成短(pre-4.1)密碼哈希。當伺服器必須支援舊版本客戶端程式時,為了保證相容性這很有用。參見5.7.9節,「MySQL 4.1中的密碼哈希處理」

·         (OBSOLETE) --safe-show-database

在以前版本的MySQL中,該選項使SHOW DATABASES語句只顯示用戶具有部分權限的資料庫名。在MySQL 5.1中,該選項不再作為現在的 預設行為使用,有一個SHOW DATABASES權限可以用來控制每個帳號對資料庫名的訪問。參見13.5.1.3節,「GRANT和REVOKE語法」

·         --safe-user-create

如果啟用,用戶不能用GRANT語句建立新用戶,除非用戶有mysql.user資料表的INSERT權限。如果您想讓用戶具有授權權限來建立新用戶,您應給用戶授予下面的權限:

mysql> GRANT INSERT(user) ON mysql.user TO 'user_name'@'host_name';

這樣確保用戶不能直接更改權限列,必須使用GRANT語句給其它用戶授予該權限。

·         --secure-auth

不允許鑒定有舊(pre-4.1)密碼的帳號。

·         --skip-grant-tables

這個選項導致伺服器根本不使用權限系統。這給每個人以完全訪問所有的資料庫的權力!(通過執行mysqladmin flush-privilegesmysqladmin reload命令,或執行FLUSH PRIVILEGES語句,您能告訴一個正在運行的伺服器再次開始使用授權資料表。)  

·         --skip-name-resolve

主機名不被解析。所有在授權資料表的Host的列值必須是IP號或localhost

·         --skip-networking

在網絡上不允許TCP/IP連接。所有到mysqld的連接必須經由Unix套接字進行。

·         --skip-show-database

使用該選項,只允許有SHOW DATABASES權限的用戶執行SHOW DATABASES語句,該語句顯示所有資料庫名。不使用該選項,允許所有用戶執行SHOW DATABASES,但只顯示用戶有SHOW DATABASES權限或部分資料庫權限的資料庫名。請注意全局權限指資料庫的權限。

5.6.4. LOAD DATA LOCAL安全問題

LOAD DATA語句可以裝載伺服器主機上的檔案,若指定LOCAL關鍵字,可以裝載客戶端檔案。

支援LOCAL版本的LOAD DATA語句有兩個可能的安全問題:

·         MySQL伺服器啟動檔案從客戶端向伺服器主機的傳輸。理論上,打過補丁的伺服器可以告訴客戶端程式傳輸伺服器選擇的檔案,而不是客戶用LOAD DATA語句指定的檔案。這樣伺服器可以訪問客戶端上客戶有讀訪問權限的任何檔案。

·         Web環境中,客戶從Web伺服器連接,用戶可以使用LOAD DATA LOCAL來讀取Web伺服器程序有讀訪問權限的任何檔案(假定用戶可以運行SQL伺服器的任何命令)。在這種環境中,MySQL伺服器的客戶實際上是Web伺服器,而不是連接Web伺服器的用戶運行的程式。

要處理這些問題,我們更改了MySQL 3.23.49MySQL 4.0.2(Windows中的4.0.13)中的LOAD DATA LOCAL的處理方法:

·         預設情況下,現在所有二進制分中的發MySQL客戶端和庫是用--enable-local-infile選項編譯,以便與MySQL 3.23.48和以前的版本兼容。

·         如果您從原始碼構建MySQL但沒有使用--enable-local-infile選項來進行configure,則客戶不能使用LOAD DATA LOCAL,除非顯式使用mysql_options (...MYSQL_OPT_本地_INFILE0)。參見25.2.3.48節,「mysql_options()」

·         您可以用--local-infile=0選項啟動mysqld從伺服器端禁用所有LOAD DATA LOCAL命令。

·         對於mysql命令行客戶端,可以通過指定--local-infile[=1]選項啟用LOAD DATA LOCAL,或通過--local-infile=0選項禁用。類似地,對於mysqlimport--local or -L選項啟用本地數據檔案裝載。在任何情況下,成功進行本地裝載需要伺服器啟用相關選項。

·         如果您使用LOAD DATA LOCAL Perl指令或其它讀選項檔案中的[client]組的程式,您可以在組內新增local-infile=1選項。但是,為了便面不理解local-infile的程式產生問題,則規定使用loose- prefix

·                [client]
·                loose-local-infile=1

·         如果LOAD DATA LOCAL INFILE在伺服器或客戶端被禁用,試圖執行該語句的客戶端將收到下面的錯誤消息:

ERROR 1148: The used command is not allowed with this MySQL version

5.7. MySQL訪問權限系統

MySQL有先進但非標準的安全/權限系統。本節描述它的工作原理。

5.7.1. 權限系統的作用

MySQL權限系統的主要功能是證實連接到一台給定主機的用戶,並且賦予該用戶在資料庫上的SELECTINSERTUPDATEDELETE權限。

附加的功能包括有匿名的用戶並對於MySQL特定的功能例如LOAD DATA INFILE進行授權及管理操作的能力。

5.7.2. 權限系統工作原理

MySQL權限系統保證所有的用戶只執行允許做的事情。當您連接MySQL伺服器時,您的身份由您從那兒連接的主機您指定的帳號來決定。連接後發出請求後,系統根據您的身份和您想做什麼來授予權限。

MySQL在認定身份中考慮您的主機名和帳號字,是因為幾乎沒有原因假定一個給定的用戶在因特網上屬於同一個人。例如,從office.com連接的用戶joe不一定和從elsewhere.com連接的joe是同一個人。MySQL通過允許您區分在不同的主機上碰巧有同樣名字的用戶來處理它:您可以對joeoffice.com進行的連接授與一個權限集,而為joeelsewhere.com的連接授予一個不同的權限集。

MySQL存取控制包含2個階段:

  • 階段1:伺服器檢查是否允許您連接。
  • 階段2:假定您能連接,伺服器檢查您發出的每個請求。看您是否有足夠的權限實施它。例如,如果您從資料庫資料表中選擇(select)行或從資料庫刪除資料表,伺服器確定您對資料表有SELECT權限或對資料庫有DROP權限。

如果連接時您的權限被更改了(通過您和其它人),這些更改不一定立即對您發出的下一個語句生效。詳情參見5.7.7節,「權限更改何時生效」

伺服器在mysql資料庫的 授權資料表中保存權限訊息(即在mysql資料庫中)。當MySQL伺服器啟動時將這些資料表的內容讀入內存,在5.7.7節,「權限更改何時生效」的環境下重新讀取它們。訪問控制決策取決於內存中的 授權資料表的份數。

一般情況,您通過GRANTREVOKE語句間接來操作 授權資料表的內容,設置帳號並控制個人的權限。參見13.5.1.3節,「GRANT和REVOKE語法」。下面討論了 授權資料表的結構以及伺服器與客戶端交互操作時如何使用其內容。

伺服器在存取控制的兩個階段使用mysql資料庫中的userdbhost資料表,這些授權資料表中的列如下:

資料表名

user

db

host

列範圍

Host

Host

Host

 

User

Db

Db

 

Password

User

 

權限列

Select_priv

Select_priv

Select_priv

 

Insert_priv

Insert_priv

Insert_priv

 

Update_priv

Update_priv

Update_priv

 

Delete_priv

Delete_priv

Delete_priv

 

Index_priv

Index_priv

Index_priv

 

Alter_priv

Alter_priv

Alter_priv

 

Create_priv

Create_priv

Create_priv

 

Drop_priv

Drop_priv

Drop_priv

 

Grant_priv

Grant_priv

Grant_priv

 

Create_view_priv

Create_view_priv

Create_view_priv

 

Show_view_priv

Show_view_priv

Show_view_priv

 

Create_routine_priv

Create_routine_priv

 

 

Alter_routine_priv

Alter_routine_priv

 

 

References_priv

References_priv

References_priv

 

Reload_priv

 

 

 

Shutdown_priv

 

 

 

Process_priv

 

 

 

File_priv

 

 

 

Show_db_priv

 

 

 

Super_priv

 

 

 

Create_tmp_table_priv

Create_tmp_table_priv

Create_tmp_table_priv

 

Lock_tables_priv

Lock_tables_priv

Lock_tables_priv

 

Execute_priv

 

 

 

Repl_slave_priv

 

 

 

Repl_client_priv

 

 

安全列

ssl_type

 

 

 

ssl_cipher

 

 

 

x509_issuer

 

 

 

x509_subject

 

 

資源控制列

max_questions

 

 

 

max_updates

 

 

 

max_connections

 

 

 

max_user_connections

 

 

對存取控制的第二階段(請求證實),伺服器執行請求驗證以確保每個客戶端有充分的權限滿足各需求。除了userdbhost授權資料表,如果請求涉及資料表,伺服器可以另外參考tables_privcolumns_priv資料表。tables_privcolumns_priv資料表可以對資料表和列提供更精確的權限控制。這些資料表的列如下:

資料表名

tables_priv

columns_priv

範圍列

Host

Host

 

Db

Db

 

User

User

 

Table_name

Table_name

 

 

Column_name

權限列

Table_priv

Column_priv

 

Column_priv

 

其它列

Timestamp

Timestamp

 

Grantor

 

TimestampGrantor列當前還未使用,這兒不再進一步討論。

為了對涉及保存程式的請求進行驗證,伺服器將查閱procs_priv資料表。該資料表具有以下列:

資料表名

procs_priv

範圍列

Host

 

Db

 

User

 

Routine_name

 

Routine_type

權限列

Proc_priv

其它列

Timestamp

 

Grantor

Routine_type列為ENUM列,值為'FUNCTION''PROCEDURE',資料表示行所指的程式類型。該列允許為同名函數和程式單獨授權。

TimestampGrantor列當前還未使用,這兒不再進一步討論。

每個授權資料表包含範圍列和權限列:

l        範圍列決定資料表中每個條目(行)的範圍,即,行適用的上下文。例如, 一個user資料表行的HostUser值為'thomas.loc.gov''bob'將被用於證實來自主機thomas.loc.govbob對伺服器的連接。同樣,一個db資料表行的HostUserDb列的值是'thomas.loc.gov''bob''reports'將用在bob從主機thomas.loc.gov聯接訪問reports資料庫的時候。tables_privcolumns_priv資料表包含範圍列,指出每個行適用的資料表或資料表/列的組合。procs_priv範圍列指出每個行適用的保存程式。

對於檢查存取的用途,比較Host值是忽略大小寫的。UserPasswordDbTable_name值是區分大小寫的。Column_name值在MySQL3.22.12或以後版本是忽略大小寫的。

l        權限列指出由一個資料表行授予的權限,即,可實施什麼操作。伺服器組合各種的授權資料表的訊息形成一個用戶權限的完整描述。為此使用的規則在5.7.6節,「訪問控制, 階段2:請求核實」描述。

範圍列包含字串,如下所述;每個列的預設值是空字串:

列名

類型

Host

CHAR(60)

User

CHAR(16)

Password

CHAR(16)

Db

CHAR(64)

Table_name

CHAR(64)

Column_name

CHAR(64)

Routine_name

CHAR(64)

為了訪問檢查目的,Host值的比較對大小寫不敏感。UserPasswordDbTable_name值對大小寫敏感。Column_name值對大小寫不敏感。

userdbhost資料表中,所有權限列於單獨的列內,被聲明為ENUM('N','Y') DEFAULT 'N'換句話說每一個權限都可以被禁用和啟用,並且 預設是禁用

tables_privcolumns_privprocs_priv資料表中,權限列被聲明為SET列。這些列的值可以包含該資料表控制的權限的組合:

資料表名

列名

可能的設置元素

tables_priv

Table_priv

'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'

tables_priv

Column_priv

'Select', 'Insert', 'Update', 'References'

columns_priv

Column_priv

'Select', 'Insert', 'Update', 'References'

procs_priv

Proc_priv

'Execute', 'Alter Routine', 'Grant'

簡單地說,伺服器使用這樣的授權資料表:

·         user表範圍列決定是否允許或拒絕到來的連接。對於允許的連接,user資料表授予的權限指出用戶的全局(超級用戶)權限。這些權限適用於伺服器上的all資料庫。

·         db表範圍列決定用戶能從哪個主機存取哪個資料庫。權限列決定允許哪個操作。授予的資料庫級別的權限適用於資料庫和它的資料表。

·         當您想要一個給定的db資料表行應用於若干主機時,dbhost資料表一起使用。例如,如果您想要一個用戶能在您的網絡從若干主機使用一個資料庫,在用戶的db資料表行的Host值設為空值,然後將那些主機的每一個移入host資料表。這個機制詳細描述在5.7.6節,「訪問控制, 階段2:請求核實」

釋:host資料表不受GRANTREVOKE語句的影響。大多數MySQL安裝根本不需要使用該資料表。

·         tables_privcolumns_priv資料表類似於db資料表,但是更精緻:它們在資料表和列級應用而非在資料庫級。授予資料表級別的權限適用於資料表和所有它的列。授予列級別的權限只適用於專用列。

·         procs_priv資料表適用於保存的程式。授予程式級別的權限只適用於單個程式。

管理權限(例如RELOADSHUTDOWN等等)僅在user資料表中被指定。這是因為管理性操作是伺服器本身的操作並且不是特定資料庫,因此沒有理由在其他授權資料表中列出這樣的權限。事實上,只需要查詢user資料表來決定您是否執行一個管理操作。

FILE權限也僅在user資料表中指定。它不是管理性權限,但您在伺服器主機上讀或寫檔案的能力與您正在存取的資料庫無關。

mysqld伺服器啟動時,將授權資料表的內容讀入到內存中。您可以通過FLUSH PRIVILEGES語句或執行mysqladmin flush-privilegesmysqladmin reload命令讓它重新讀取資料表。對授權資料表的更改生效在5.7.7節,「權限更改何時生效」描述。

當您修改授權資料表的內容時,確保您按您想要的方式更改權限設置是一個好主意。要檢查給定帳號的權限,使用SHOW GRANTS語句。例如,要檢查HostUser值分別為pc84.example.combob的帳號所授予的權限,應通過語句:

 

mysql> SHOW GRANTS FOR 'bob'@'pc84.example.com';

一個有用的診斷工具是mysqlaccess指令,由Carlier Yves 提供給MySQL分發。使用--help選項使用mysqlaccess查明它怎樣工作。注意:mysqlaccess僅用userdbhost資料表檢查存取。它不檢查tables_privcolumns_privprocs_priv資料表中指定的資料表、列和程式級權限。

對於診斷權限相關的問題的其它幫助,參見5.7.8節,「拒絕訪問錯誤的原因。對於安全問題常規建議,參見5.6節,「一般安全問題」

5.7.3. MySQL提供的權限

帳號權限訊息被儲存在mysql資料庫的userdbhosttables_privcolumns_privprocs_priv資料表中。在MySQL啟動時並在5.7.7節,「權限更改何時生效」所說的情況時,伺服器將這些資料庫資料表內容讀入內存。

GRANTREVOKE語句所用的涉及權限的名稱顯示在下資料表,還有在授權資料表中每個權限的資料表列名稱和每個權限有關的上下文。關於每個權限的含義相關的詳細訊息參見13.5.1.3節,「GRANT和REVOKE語法」

權限

上下文

CREATE

Create_priv

資料庫、資料表或索引

DROP

Drop_priv

資料庫或資料表

GRANT OPTION

Grant_priv

資料庫、資料表或保存的程式

REFERENCES

References_priv

資料庫或資料表

ALTER

Alter_priv

資料表

DELETE

Delete_priv

資料表

INDEX

Index_priv

資料表

INSERT

Insert_priv

資料表

SELECT

Select_priv

資料表

UPDATE

Update_priv

資料表

CREATE VIEW

Create_view_priv

視圖

SHOW VIEW

Show_view_priv

視圖

ALTER ROUTINE

Alter_routine_priv

保存的程式

CREATE ROUTINE

Create_routine_priv

保存的程式

EXECUTE

Execute_priv

保存的程式

FILE

File_priv

伺服器主機上的檔案訪問

CREATE TEMPORARY TABLES

Create_tmp_table_priv

伺服器管理

LOCK TABLES

Lock_tables_priv

伺服器管理

CREATE USER

Create_user_priv

伺服器管理

PROCESS

Process_priv

伺服器管理

RELOAD

Reload_priv

伺服器管理

REPLICATION CLIENT

Repl_client_priv

伺服器管理

REPLICATION SLAVE

Repl_slave_priv

伺服器管理

SHOW DATABASES

Show_db_priv

伺服器管理

SHUTDOWN

Shutdown_priv

伺服器管理

SUPER

Super_priv

伺服器管理

當從早期的沒有CREATE VIEWSHOW VIEWCREATE ROUTINEALTER ROUTINEEXECUTE權限的版本的MySQL中升級時,要想使用這些權限,您必須使用MySQL分發提供的mysql_fix_privilege_tables指令升級 授權資料表。參見2.10.2節,「升級授權資料表」

如果啟用了二進制記錄,要想建立或修改保存的程式,您還需要SUPER權限,詳細描述見20.4節,「儲存子程式和觸發程式的二進制日誌功能」

通過CREATEDROP權限,您可以建立新資料庫和資料表,或刪除(移掉)已有資料庫和資料表。如果您將mysql資料庫中的DROP權限授予某用戶,用戶可以刪掉MySQL訪問權限保存的資料庫。

SELECTINSERTUPDATEDELETE權限允許您在一個資料庫現有的資料表上實施操作。

SELECT語句只有在他們真正從一個資料表中檢索行時才需要SELECT權限。一些SELECT語句不訪問資料表,甚至沒有任何到伺服器上的資料庫裡的存取任何東西的授權。例如,您可使用mysql客戶端作為一個簡單的計算器來評估未引用資料表的資料表達式:

mysql> SELECT 1+1;
mysql> SELECT PI()*2;

INDEX權限允許您建立或刪除索引。INDEX適用已有資料表如果您具有某個資料表的CREATE權限,您可以在CREATE TABLE語句中包括索引定義。

通過ALTER權限,您可以使用ALTER TABLE來更改資料表的結構和重新命名資料表

需要CREATE ROUTINE權限來建立保存的程式(函數和程式),ALTER ROUTINE權限來更改和刪除保存的程式,EXECUTE來執行保存的程式。

GRANT權限允許您把您自己擁有的那些權限授給其他的用戶。可以用於資料庫、資料表和保存的程式。

FILE權限給予您用LOAD DATA INFILESELECT ... INTO OUTFILE語句讀和寫伺服器上的檔案,任何被授予FILE權限的用戶都能讀或寫MySQL伺服器能讀或寫的任何檔案。(說明用戶可以讀任何資料庫目錄下的檔案,因為伺服器可以訪問這些檔案)FILE權限允許用戶在MySQL伺服器具有寫權限的目錄下建立新檔案。不能覆蓋已有檔案。

其餘的權限用於管理性操作,它使用mysqladmin程式或SQL語句實施。下資料表顯示每個管理性權限允許您執行的mysqladmin命令:

權限

權限擁有者允許執行的命令

RELOAD

flush-hosts, flush-logs, flush-privileges, flush-status, flush-tables, flush-threads, refresh, reload

SHUTDOWN

shutdown

PROCESS

processlist

SUPER

kill

reload命令告訴伺服器將授權資料表重新讀入內存。flush-privilegesreload的同義詞,refresh命令清空所有資料表並打開並關閉記錄檔案,其它flush-xxx命令執行類似refresh的功能,但是範圍更有限,並且在某些情況下可能更好用。例如,如果您只是想清空記錄檔案,flush-logsrefresh是更好的選擇。

shutdown命令關掉伺服器。只能從mysqladmin發出命令。沒有相應的SQL語句。

processlist命令顯示在伺服器內執行的線程的訊息(即其它帳號相關的客戶端執行的語句)。kill命令殺死伺服器線程。您總是能顯示或殺死您自己的線程,但是您需要PROCESS權限來顯示或殺死其他用戶和SUPER權限啟動的線程。參見13.5.5.3節,「KILL語法」

擁有CREATE TEMPORARY TABLES權限便可以使用CREATE TABLE語句中的關鍵字TEMPORARY

擁有LOCK TABLES權限便可以直接使用LOCK TABLES語句來鎖定您擁有SELECT權限的資料表。包括使用寫鎖定,可以防止他人讀鎖定的資料表。

擁有REPLICATION CLIENT權限便可以使用SHOW MASTER STATUSSHOW SLAVE STATUS

REPLICATION SLAVE權限應授予從伺服器所使用的將當前伺服器連接為主伺服器的帳號。沒有這個權限,從伺服器不能發出對主伺服器上的資料庫所發出的更新請求。

擁有SHOW DATABASES權限便允許帳號使用SHOW DATABASE語句來查看資料庫名。沒有該權限的帳號只能看到他們具有部分權限的資料庫, 如果資料庫用--skip-show-database選項啟動,則根本不能使用這些語句。請注意全局權限指資料庫的權限。

總的說來,只授予權限給需要他們的那些用戶是好主意,但是您應該在授予FILE和管理權限時試驗特定的警告:

  • FILE權限可以被濫用於將伺服器主機上MySQL能讀取的任何檔案讀入到資料庫資料表中。包括任何人可讀的檔案和伺服器數據目錄中的檔案。可以使用SELECT訪問資料庫資料表,然後將其內容傳輸到客戶端上。
  • GRANT權限允許用戶將他們的權限給其他用戶。有不同的權限並有GRANT權限的2個用戶可以合併權限。
  • ALTER權限可以用於通過重新命名資料表來推翻權限系統。
  • SHUTDOWN權限通過終止伺服器可以被濫用完全拒絕為其他用戶服務。
  • PROCESS權限能被用來察看當前執行的查詢的明文文本,包括設定或改變密碼的查詢。
  • SUPER權限能用來終止其它用戶或更改伺服器的操作方式。
  • 授給mysql資料庫本身的權限能用來改變密碼和其他訪問權限訊息。密碼被加密儲存,所以惡意的用戶不能簡單地讀取他們以知道明文密碼。然而,具有user資料表Password列寫訪問權限的用戶可以更改帳號的密碼,並可以用該帳號連接MySQL伺服器。

有一些事情您不能用MySQL權限系統做到:

  • 您不能明顯地指定某個給定的用戶應該被拒絕訪問。即,您不能明顯地匹配用戶然後拒絕連接。
  • 您不能指定用戶有權建立立或刪除資料庫中的資料表,但不能建立或刪除資料庫本身。

5.7.4. 與MySQL伺服器連接

當您想要訪問MySQL伺服器時,MySQL客戶端程式一般要求您指定參數:

·         MySQL伺服器運行的主機名

·         姓名

·         密碼

例如,可以從命令行按照下述提示啟動MySQL客戶端(shell>資料表示)

shell> MySQL -h host_name -u user_name -pyour_pass

-h, -u-p選項還可以採用形式--host=host_name--user=user_name--password=your_pass。請注意在-p--password=和後面的密碼之間沒有空格

如果您使用-p--password選項但沒有指定密碼值,客戶端程式提示您輸入密碼。當您輸入密碼時並不顯示密碼。這比在在命令行輸入密碼要安全得多。系統上的任何用戶可以通過命令ps auxww在命令行中指定密碼。參見5.8.6節,「使您的密碼安全」

如果沒有指定連接參數,MySQL客戶端程式使用預設值:

  • 預設主機名是localhost
  • 預設帳號在Windows中是ODBC,在Unix中是您的Unix登錄名。

·         如果沒有-p,則不提供密碼。

這樣, Unix用戶joe,下列命令是等價的:

shell> MySQL -h localhost -u joe
shell> MySQL -h localhost
shell> MySQL -u joe
shell> MySQL

其它MySQL客戶端程式類似。

當進行連接時,您可以指定要使用的不同的預設值,這樣不必每次在您使用客戶端程式是在命令行上輸入它們。這可以有很多方法做到:

  • 您可以在選項檔案的[client]小節裡指定連接參數。檔案的相關小節看上去可能像這樣:
·                [client]
·                host=host_name
·                user=user_name
·                password=your_pass

4.3.2節,「使用選項檔案」中詳細討論了選項檔案。

5.7.5. 訪問控制, 階段1:連接核實

當您試圖連接MySQL伺服器時,伺服器基於您的身份以及您是否能通過供應正確的密碼驗證身份來接受或拒絕連接。如果不是,伺服器完全拒絕您的訪問,否則,伺服器接受連接,然後進入階段2並且等待請求。

您的身份基於2個訊息:

  • 您從那個主機連接
  • 您的MySQL帳號

身份檢查使用3user資料表(Host, UserPassword)範圍列執行。伺服器只有在user資料表記錄的HostUser列匹配客戶端主機名和帳號並且提供了正確的密碼時才接受連接。

user資料表Host值的指定方法:

  • Host值可以是主機名或IP號,或'localhost'指出本地主機。
  • 您可以在Host列值使用通配符字元%_
  • Host'%'匹配任何主機名,空Host值等價於'%'。它們的含義與LIKE操作符的模式匹配操作相同。例如,'%'Host值與所有主機名匹配,而'%.mysql.com'匹配mysql.com域的所有主機。

·         對於指定為IP號的Host值,您可以指定一個網絡掩碼,說明使用多少位地址位來評比網絡號。例如:

·                mysql> GRANT ALL PRIVILEGES ON db.*
·                    -> -> TO david@'192.58.197.0/255.255.255.0';

允許david從任何客戶端用IPclient_ip來連接,下面的條件為真:

client_ip & netmask = host_ip

That is, for the GRANT statement just shown:

client_ip & 255.255.255.0 = 192.58.197.0

滿足該條件並可以連接MySQL伺服器的IP號的範圍為192.58.197.0192.58.197.255

·         註釋:網絡掩碼只用來告訴伺服器使用8162432位地址,例如:

·                192.0.0.0/255.0.0.0(192 A類網絡的任何地址)
·                192.168.0.0/255.255.0.0(192.168 A類網絡的任何地址)
·                192.168.1.0/255.255.255.0(192.168.1 C類網絡的任何地址)
·                192.168.1.1(只有該IP)

下面的網絡掩碼(28 )無效:

192.168.0.1/255.255.255.240

·         db資料表記錄中的空Host值資料表示它的權限應結合匹配客戶端名的host資料表中的行使用。通過AND(相與)而不是或(聯合)操作將權限組合到一起。您可以從5.7.6節,「訪問控制, 階段2:請求核實」找到關於host資料表的詳細訊息。

其它grant資料表的空Host值與'%'相同。

既然您能在Host字段使用IP通配符值(例如,'144.155.166.%'匹配在一個子網上的每台主機),有可能某人可能企圖探究這種能力,通過命名一台主機為144.155.166.somewhere.com。為了阻止這樣的企圖,MySQL不允許匹配以數字和一個點起始的主機名,這樣,如果您用一個命名為類似1.2.foo.com的主機,它的名字決不會匹配授權資料表中的Host列。只有一個IP數字能匹配IP通配符值。

通配符字元在User列中不允許,但是您能指定空的值,它匹配任何名字。如果user資料表匹配的連接有一個空帳號,用戶被認為是匿名用戶(沒有名字的用戶),而非客戶端實際指定的名字。這意味著一個空的帳號被用於在連接期間的進一步的訪問檢查(即,在階段2期間)

Password列可以是空的。這不是通配符,也不意味著匹配任何密碼,它意味著用戶必須不指定一個密碼進行連接。

user資料表中的非空Password值代資料表加密的密碼。MySQL不以任何人可以看的明文文本格式儲存密碼,相反,正在試圖聯接的用戶提供的密碼被加密(使用PASSWORD( )函數),在連接過程中使用加密的密碼檢查密碼是否正確。(加密後的密碼未通過連接即可實現)MySQL角度,加密的密碼是實際密碼,因此您不應讓其它人訪問它!特別是,絕對不要讓非管理用戶讀mysql資料庫中的資料表!

MySQL 5.1使用強鑒定方法(最先在MySQL 4.1中適用)在前面的版本中在連接程序中的密碼保護較好。即使TCP/IP包被截取或mysql資料庫 被捕獲也很安全。5.7.9節,「MySQL 4.1中的密碼哈希處理」中詳細討論了密碼加密。

下面的例子顯示出各種user資料表中HostUser值的組合如何應用於到來的連接:

Host

User

被條目匹配的連接

'thomas.loc.gov'

'fred'

fred, thomas.loc.gov 連接

'thomas.loc.gov'

''

任何用戶, thomas.loc.gov連接

'%'

'fred'

fred, 從任何主機連接

'%'

''

任何用戶, 從任何主機連接

'%.loc.gov'

'fred'

fred, 從在loc.gov域的任何主機連接

'x.y.%'

'fred'

fred, x.y.netx.y.com,x.y.edu等聯接。(這或許無用)

'144.155.166.177'

'fred'

fred, 從有144.155.166.177 IP地址的主機連接

'144.155.166.%'

'fred'

fred, 144.155.166 C類子網的任何主機連接

到來的連接中的客戶端名和帳號可能與user資料表中的多行匹配。例如,由fredthomas.loc.gov的連接匹配多個條目如上所述。

如果有多個匹配,伺服器必須選擇使用哪個條目。按照下述方法解決問題:

l        伺服器在啟動時讀入user資料表後進行排序。

l        然後當用戶試圖連接時,以排序的順序瀏覽條目

l        伺服器使用與客戶端和帳號匹配的第一行。

user資料表排序工作如下,假定user資料表看起來像這樣:

+-----------+----------+-
| Host      | User     | 
+-----------+----------+-
| %         | root     | 
| %         | jeffrey  | 
| localhost | root     | 
| localhost |          | 
+-----------+----------+-

當伺服器讀取資料表時,它首先以最具體的Host值排序。主機名和IP號是最具體的。'%'意味著「任何主機」並且是最不特定的。有相同Host值的條目首先以最具體的User值排序(User值意味著「任何用戶」並且是最不特定的)。最終排序的user資料表看起來像這樣:

+-----------+----------+-
| Host      | User     | 
+-----------+----------+-
| localhost | root     |  ...
| localhost |          |  ...
| %         | jeffrey  |  ...
| %         | root     |  ...
+-----------+----------+-

當客戶端試圖連接時,伺服器瀏覽排序的條目並使用找到的第一匹配。對於由jeffreylocalhost的連接,資料表內有兩個條目匹配:HostUser值為'localhost'''的條目,和值為'%''jeffrey'的條目。'localhost'條目首先匹配,伺服器可以使用。

還有一個例子。假定user資料表看起來像這樣:

+----------------+----------+-
| Host           | User     | 
+----------------+----------+-
| %              | jeffrey  | 
| thomas.loc.gov |          | 
+----------------+----------+-

排序後的資料表看起來像這樣:

+----------------+----------+-
| Host           | User     | 
+----------------+----------+-
| thomas.loc.gov |          | 
| %              | jeffrey  | 
+----------------+----------+-

jeffreythomas.loc.gov的連接與第一行匹配,而由jeffreywhitehouse.gov的連接被第二個匹配。

普遍的誤解是認為,對給定的帳號,當伺服器試圖對連接尋找匹配時,明確命名那個用戶的所有條目將首先被使用。這明顯不符合事實。先前的例子說明了這點,在那裡由jeffreythomas.loc.gov的連接沒被包含'jeffrey'作為User列值的行匹配,但是由沒有帳號的題目匹配!結果是,jeffrey被鑒定為匿名用戶,即使他連接時指定了帳號。

如果您能夠連接伺服器,但您的權限不是您期望的,您可能被鑒定為其它帳號。要想找出伺服器用來鑒定您的帳號,使用CURRENT_USER()函數。它返回user_name@host_name格式的值,說明UserHost 值匹配user資料表記錄。假定jeffrey連接並發出下面的查詢:

mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost     |
+----------------+

這兒顯示的結果說明user資料表行有空的User列值。換句話說,伺服器將jeffrey視為匿名用戶。

診斷鑒定問題的另一個方法是打印出user資料表並且手動排序它看看第一個匹配在哪兒進行。又見12.9.3節,「訊息函數」

5.7.6. 訪問控制, 階段2:請求核實

一旦您建立了連接,伺服器進入訪問控制的階段2。對在此連接上進來的每個請求,伺服器檢查您想執行什麼操作,然後檢查是否有足夠的權限來執行它。這正是在授權資料表中的權限列發揮作用的地方。這些權限可以來自userdbhosttables_privcolumns_priv資料表。(您會發現參考5.7.2節,「權限系統工作原理」很有幫助,它列出了每個 授權資料表中呈現的列。)

user資料表在全局基礎上授予賦予您的權限,該權限不管當前的資料庫是什麼均適用。例如,如果user資料表授予您DELETE權限, 您可以刪除在伺服器主機上從任何資料庫刪除行!換句話說,user資料表權限是超級用戶權限。只把user資料表的權限授予超級用戶如伺服器或資料庫主管是明智的。對其他用戶,您應該把在user資料表中的權限設成'N'並且僅在特定資料庫的基礎上授權。您可以為特定的資料庫、資料表或列授權。

dbhost資料表授予資料庫特定的權限。在這些資料表中的範圍列的值可以採用以下方式:

  • 通配符字元%_可用於兩個資料表的HostDb列。它們與用LIKE操作符執行的模式匹配操作具有相同的含義。如果授權時您想使用某個字元,必須使用反斜現引用。例如,要想在資料庫名中包括下劃線(_),在GRANT語句中用\_來指定
  • db資料表的'%'Host值意味著「任何主機」,在db資料表中空Host值意味著「對進一步的訊息咨詢host資料表」(本節後面將描述的一個過程)。
  • host資料表的'%'或空Host值意味著「任何主機」。
  • 在兩個資料表中的'%'或空Db值意味著「任何資料庫」。
  • 在兩個資料表中的空User值匹配匿名用戶。

dbhost資料表在伺服器啟動時被讀取並排序(同時它讀user資料表)db資料表在HostDbUser範圍列上排序,並且host資料表在HostDb範圍列上排序。對於user資料表,首先根據最具體的值最後根據最不具體的值排序,並且當伺服器尋找匹配條目時,它使用它找到的第一匹配。

tables_privcolumns_priv資料表授予資料表和列特定的權限。這些資料表的範圍列的值可以如下被指定:

  • 通配符%_可用在使用在兩個資料表的Host列。
  • 在兩個資料表中的'%'或空Host意味著「任何主機」。
  • 在兩個資料表中的DbTable_nameColumn_name列不能包含通配符或空。

tables_privcolumns_priv資料表根據HostDbUser列被排序。這類似於db資料表的排序,因為只有Host列可以包含通配符,排序更簡單。

請求證實程序在下面描述。(如果您熟悉訪問檢查的原始碼,您會注意到這裡的描述與在代碼使用的算法略有不同。描述等價於代碼實際做的東西;不同處只是使解釋更簡單。)

對需要管理權限的請求(SHUTDOWNRELOAD等等),伺服器僅檢查user資料表條目,因為那是唯一指定管理權限的資料表。如果行授權請求的操作,訪問被授權,否則拒絕。例如,如果您想要執行mysqladmin shutdown,但是由於user資料表行沒有為您授予HUTDOWN權限,甚至不用檢查dbhost資料表就拒絕您的訪問。(因為它們不包含hutdown_priv行列,沒有這樣做的必要。)

對資料庫有關的請求(INSERTUPDATE等等),伺服器首先通過搜尋user資料表行來檢查用戶的全局(超級用戶)權限。如果行允許請求的操作,訪問被授權。如果在user資料表中全局權限不夠,伺服器通過檢查dbhost資料表確定特定的用戶資料庫權限:

  1. 伺服器在db資料表的HostDbUser列上搜尋匹配。HostUser對應連接用戶的主機名和MySQL帳號。Db列對應用戶想要訪問的資料庫。如果沒有HostUser的行,訪問被拒絕。
  2. 如果db資料表中有匹配的行而且它的Host列不是空的,該行定義用戶的資料庫特定的權限。
  3. 如果匹配的db資料表的行的Host列是空的,它資料表示host資料表列舉被允許訪問資料庫的主機。在這種情況下,在host資料表中作進一步搜尋以發現HostDb列上的匹配。如果沒有host資料表行匹配,訪問被拒絕。如果有匹配,用戶資料庫特定的權限以在dbhost資料表的行的權限,即在兩個行都是'Y'的權限的交集(而不是並集!)計算。(這樣您可以授予在db資料表行中的一般權限,然後用host資料表行按主機主機為基礎有選擇地限制它們。)

在確定了由dbhost資料表行授予的資料庫特定的權限後,伺服器把他們加到由user資料表授予的全局權限中。如果結果允許請求的操作,訪問被授權。否則,伺服器檢查在tables_privcolumns_priv資料表中的用戶的資料表和列權限並把它們加到用戶權限中。基於此結果允許或拒絕訪問。

用布爾術語資料表示,前面關於用戶權限如何計算的描述可以這樣總結:

global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges

它可能不明顯,為什麼呢,如果全局user行的權限最初發現對請求的操作不夠,伺服器以後把這些權限加到資料庫、資料表並列的特定權限。原因是請求可能要求超過一種類型的權限。例如,如果您執行INSERT INTO ... SELECT語句,您就需要INSERTSELECT權限。您的權限必須是user資料表行授予一個權限而db資料表行授予另一個權限。在這種情況下,您有必要的權限執行請求,但是伺服器不能自己把兩個資料表區別開來;兩個行授予的權限必須組合起來。

host資料表不受GRANTREVOKE語句的影響,因此在大多數MySQL安裝中沒有使用。如果您直接修改它,您可以用於某種專門目的,例如用來維護安全伺服器列資料表。例如,在TcXhost資料表包含在本地網絡上所有的機器的資料表。這些資料表被授予所有的權限。

您也可以使用host資料表指定安全的主機。假定您有一台機器public.your.domain,它位於您認為不安全的公共區域,您可以用下列的host資料表條目允許除了那台機器外的網絡上所有主機的訪問:

+--------------------+----+-
| Host               | Db | ...
+--------------------+----+-
| public.your.domain | %  | ... (all privileges set to 'N')
| %.your.domain      | %  | ... (all privileges set to 'Y')
+--------------------+----+-

當然,一定要測試授權資料表中的行(例如,使用SHOW GRANTSmysqlaccess),確保您的訪問權限實際按您期望的方式被設置。

5.7.7. 權限更改何時生效

mysqld啟動時,所有授權資料表的內容被讀進內存並且從此時生效。

當伺服器注意到授權資料表被改變了時,現存的客戶端連接有如下影響:

  • 資料表和列權限在客戶端的下一次請求時生效。
  • 資料庫權限改變在下一個USE db_name命令生效。

·         全局權限的改變和密碼改變在下一次客戶端連接時生效。

如果用GRANTREVOKESET PASSWORD對授權資料表進行修改,伺服器會注意到並立即重新將授權資料表載入內存。

如果您手動地修改授權資料表(使用INSERTUPDATEDELETE等等),您應該執行mysqladmin flush-privilegesmysqladmin reload告訴伺服器再裝載授權資料表,否則您的更改將不會生效,除非您重啟伺服器。

如果您直接更改了授權資料表但忘記重載,重啟伺服器後您的更改方生效。這樣可能讓您迷惑為什麼您的更改沒有什麼變化!

5.7.8. 拒絕訪問錯誤的原因

當您試著聯接MySQL伺服器時,如果碰到問題,下面各項可以幫助您糾正問題:

·         確保伺服器在運行。如果伺服器沒有運行,則您不能連接伺服器。如果您視圖連接伺服器並看到下述消息,可能是伺服器沒有運行:

·                shell> mysql
·                ERROR 2003: Can't connect to MySQL server on 'host_name' (111)
·                shell> mysql
·                ERROR 2002: Can't connect to local MySQL server through socket
·                '/tmp/mysql.sock' (111)

也可能伺服器正在運行,但您可能使用與伺服器上偵聽的不一樣的TCP/IP端口、命名管道或Unix套接字檔案。您可以使用客戶端程式,指定端口選項來指示正確的端口或套接字選項來指示正確的命名管道或Unix套接字檔案。要找出套接字檔案的地點,應:

shell> netstat -ln | grep mysql
  • 必須正確設置授權資料表,以便伺服器可以使用它們進行訪問控制。對於某些分發版類型(例如Windows中的二進制分發版或Linux中的RPM分發版),安裝過程初始化包含 授權資料表的mysql資料庫。如果分發版沒有這樣做,您必須運行mysql_install_db指令來手動初始化授權資料表。詳細內容參見2.9.2節,「Unix下安裝後的過程」

確定是否要初始化授權資料表的一個方法是尋找數據目錄下的mysql目錄數據目錄名通常為datavar,位於MySQL安裝目錄下。應保證MySQL資料庫目錄有檔案user.MYD。否則,執行mysql_install_db指令。運行並重啟伺服器後,執行該命令來測試初始權限:

shell> mysql -u root test

伺服器應該讓您無誤地連接。

  • 在新的安裝以後,您應該連接伺服器並且設置您的用戶及其訪問授權:
·                shell> mysql -u root mysql

伺服器應該讓您連接,因為MySQL root用戶初始時沒有密碼。那也是安全風險,當您正在設置其他MySQL用戶時,也應設定root密碼是一件重要的事請。關於設置初始密碼的說明,參見2.9.3節,「使初始MySQL帳號安全」

  • 如果您將一個現存的MySQL安裝升級到較新的版本,運行了mysql_fix_privilege_tables指令嗎?如果沒有,運行它。增加新功能後,授權資料表的結構可能會改變,因此更新後應確保資料表的結構隨之更新。相關說明參見2.10.2節,「升級授權資料表」

·         如果客戶端程式試圖連接時收到以下錯誤訊息,說明伺服器需要新格式的密碼,而客戶端不能生成:

·                shell> mysql
·                Client does not support authentication protocol requested
·                by server; consider upgrading MySQL client

關於如何處理的詳細訊息,參見5.7.9節,「MySQL 4.1中的密碼哈希處理」A.2.3節,「客戶端不支援鑒定協議」

  • 如果您作為root試試連接並且得到這個錯誤,這意味著,您沒有行在user資料表中的User列值為'root'並且mysqld不能為您的客戶端解析主機名:
  • Access denied for user ''@'unknown' to database mysql

在這種情況下,您必須用--skip-grant-tables選項重啟伺服器並且編輯/etc/hosts\windows\hosts檔案為您的主機增加行。

  • 如果您從3.22.11以前的版本更新現存的MySQL安裝到3.22.11版或以後版本,您運行了mysql_fix_privilege_tables指令嗎?如果沒有,運行它。在GRANT語句變得能工作時,授權資料表的結構用MySQL 3.22.11修改 。

·         記住客戶端程式使用選項檔案或環境變數中指定的連接參數。如果客戶端程式發送不正確的預設連接參數,而您沒有在命令行中指定,檢查環境變數和適用的選項檔案。例如,當您不用任何選項運行客戶端程式,得到Access denied錯誤,確保您沒有在選項檔案中指定舊密碼!

您可以通過使用--no-defaults選項使用客戶端程式來禁用選項檔案。例如:

shell> mysqladmin --no-defaults -u root version

客戶端使用的選項檔案見4.3.2節,「使用選項檔案」。環境變數列於附錄F:環境變數

·         如果遇到下述錯誤,說明root密碼錯誤:

·                shell> mysqladmin -u root -pxxxx ver
·                Access denied for user 'root'@'localhost' (using password: YES)

如果您未指定密碼時出現前面的錯誤,說明某個選項檔案中的密碼不正確。試試前面所說的--no-defaults選項。

關於密碼更改的訊息參見5.8.5節,「設置帳號密碼」

如果您丟失或忘記root密碼,您可以用--skip-grant-tables重啟 mysqld來更改密碼。參見A.4.1節,「如何復位根用戶密碼」.

·         如果您使用SET PASSWORDINSERTUPDATE更改密碼,您必須使用  PASSWORD()函數加密密碼。如果您不使用PASSWORD()函數,密碼不工作。例如,下面的語句設置密碼,但沒能加密,因此用戶後面不能連接:

·                mysql> SET PASSWORD FOR 'abe'@'host_name' = 'eagle';

相反,應這樣設置密碼:

mysql> SET PASSWORD FOR 'abe'@'host_name' = PASSWORD('eagle');

當您使用GRANTCREATE USER語句或mysqladmin password命令指定密碼時,不需要PASSWORD()函數,它們會自動使用PASSWORD()來加密密碼。參見5.8.5節,「設置帳號密碼」13.5.1.1節,「CREATE USER語法」

·         localhost是您本地主機名的一個同義詞,並且也是如果您不明確地指定主機而客戶端嘗試連接的預設主機。

要想在這種系統上避免該問題,您可以使用--host=127.0.0.1選項來明確命名伺服器主機。這樣將通過TCP/IP協議來連接本地mysqld伺服器。您還可以指定--host選項使用TCP/IP,使用實際的本機主機名。在這種情況下,主機名必須指定為伺服器主機上的user資料表行,即使您在伺服器上運行客戶端程式。

·         當嘗試用mysql -u user_name與資料庫連接時,如果您得到一個Access denied錯誤,可能會遇到與user資料表有關的問題,通過執行mysql -u root mysql並且執行下面的SQL語句進行檢查:

·                mysql> SELECT * FROM user;

結果應該包含一個有HostUser列的行匹配您的計算機主機名和您的MySQL帳號。

  • Access denied錯誤消息將告訴您,您正在用哪個用戶嘗試登錄,您正在試圖連接哪個主機,是否使用了密碼。通常,您應該在user資料表中有一行,正確地匹配在錯誤消息給出的主機名和帳號。例如,如果遇到包含using password: NO的錯誤訊息,說明您登錄時沒有密碼。

·         如果當您試著從一個不是MySQL伺服器正在運行的主機上連接時,遇到下列錯誤,那麼在user資料表中沒有匹配那台主機的行:

·                Host ... is not allowed to connect to this MySQL server

可以通過組合您正在試圖連接的用戶/主機名設置一個帳號來修正它。如果您不知道正連接的機器的IP號或主機名,應該把一個'%'行作為Host列值放在user資料表中。在試圖從客戶端器連接以後,通過SELECT USER()查詢顯示您如何真正進行連接。(然後用在日誌檔案上面顯示出的實際的主機名代替user資料表中的'%'行。否則,您將得到一個不安全的系統,因為它允許從任何主機上以任何帳號連接。)

Linux中,發生該錯誤的另一個原因可能是您正使用於您所使用版本的glibc庫不同版本的庫編譯的二進制MySQL版本。在這種情況下,您應升級作業系統或glibc,或下載MySQL版本的原始碼分發版並自己編譯。原始碼RPM一般很容易編譯並安裝,因此不是大問題。

·         如果您連接時指定主機名,但得到錯誤消息主機名未顯示或為IP號,資料表示當MySQL伺服器將IP號解析為客戶端來名時遇到錯誤:

·                shell> mysqladmin -u root -pxxxx -h some-hostname ver
·                Access denied for user 'root'@'' (using password: YES)

這資料表示DNS問題。要想修復,執行mysqladmin flush-hosts來重設內部 DNS主機名緩存。參見7.5.6節,「MySQL如何使用DNS」

一些常用的解決方案包括:

o        試試找出DNS伺服器的錯誤並修復。

o        MySQL授權資料表中指定IP號而不是主機名。

o        /etc/hosts中放入客戶端名。

o        --skip-name-resolve選項啟動mysqld

o        --skip-host-cache選項啟動mysqld

o        Unix中,如果您在同一台機器上運行伺服器和客戶端,連接到localhost。連接到的localhostUnix連接使用Unix套接字檔案而不是TCP/IP

o        Windows中,您在同一台機器上運行伺服器和客戶端並且伺服器支援命名管道連接,連接主機名(週期)。連接使用命名管道而不是TCP/IP

  • 如果mysql -u root test工作但是mysql -h your_hostname -u root test導致Access deniedyour_hostname是本地機的實際主機名,那麼在user資料表中可能沒有您的主機的正確名字。這裡的一個普遍的問題是在user資料表行中的Host值指定一個唯一的主機名,但是您系統的名字解析例程返回一個完全正規的域名(或相反)。例如,如果您在user資料表中有一個主機是'tcx'的行,但是您的DNS告訴MySQL您的主機名是'tcx.subnet.se',行將不工作。嘗試把一個行加到user資料表中,它包含您主機的IP號作為Host列的值。(另外,您可以把一個行加到user資料表中,它有包含一個通配符如'tcx.%'Host值。然而,使用以%結尾的主機名是不安全的並且推薦!)
  • 如果mysql -u user_name test工作但是mysql -u user_name other_db_name不工作,您沒有為給定的用戶授予other_db_name資料庫的訪問權限。
  • 當在伺服器上執行mysql -u user_name時,它工作,但是在其它遠程客戶端上執mysql -h host_name -u user_name時,它卻不工作,您沒有為給定的用戶授予從遠程主機訪問伺服器的權限。
  • 如果您不能弄明白您為什麼得到Access denied,從user資料表中刪除所有Host包含通配符值的行(包含%_的條目)。一個很普遍的錯誤是用Host='%'User='some_user'插入一個新行,認為這將允許您指定localhost從同一台機器進行連接。它不工作的原因是 預設權限包括一個有Host='localhost'User=''的行,因為那個行的Host'localhost''%'更具體,當從localhost連接時,它用於指向新行!正確的步驟是插入Host='localhost'User='some_user'的第2個行,或刪除Host='localhost'User=''行。刪除條目後,記住用FLUSH PRIVILEGES語句重載授權資料表。

·         如果您得到下列錯誤,可以與dbhost資料表有關:

·                Access to database denied

如果從db資料表中選擇了在Host列有空值的條目,保證在host資料表中有一個或多個相應的條目,指定db資料表中的條目適用哪些主機。

·         如果您能夠連接MySQL伺服器,但如果在使用命令SELECT ... INTO OUTFILELOAD DATA INFILE語句時,您得到Access denied錯誤,在user資料表中的條目可能沒有啟用FILE權限。

·         如果您直接更改授權資料表(例如,使用INSERTUPDATEDELETE語句)並且您的更改好像被忽略了,記住您必須執行FLUSH PRIVILEGES語句或mysqladmin flush-privileges命令讓伺服器來重讀授權資料表。否則,直到伺服器下次重啟,您的更改方有效。記住用UPDATE命令更改root密碼後,在清空權限前,您不需要指定新密碼,因為伺服器還不知道您已經更改了密碼!

·         如果您的權限似乎在一個會話過程中改變了,可能是一個超級用戶改變了他們。再次裝入授權資料表會影響新客戶端連接,但是它也影響現存的連接,如5.7.7節,「權限更改何時生效」小節所述。

·         如果您有PerlPythonODBC程式的存取問題,試著用mysql -u user_name db_namemysql -u user_name -pyour_pass db_name與伺服器連接。如果您能用mysql客戶端進行連接,這是程式的一個問題而不是訪問權限的問題。(注意在-p和密碼之間沒有空格;也可以使用--password=your_pass語法指定密碼。如果使用-p選項MySQL提示您輸入密碼。)

·         為了測試,用--skip-grant-tables選項啟動mysqld守護程序,然後您可以改變MySQL授權資料表並且使用mysqlaccess指令檢查您的修改是否有如期的效果。當您對您的改變滿意時,執行mysqladmin flush-privileges告訴mysqld伺服器開始使用新的 授權資料表。(再次裝入授權資料表覆蓋了--skip-grant-tables選項。這允許您告訴伺服器開始使用授權資料表,而不用停掉並重啟它)。

·         如果任何其它事情失敗,用調試選項(例如,--debug=d,general,query)啟動mysqld伺服器。這將打印有關嘗試連接的主機和用戶訊息,和發出的每個命令的訊息。請參見E.1.2節,「建立跟蹤檔案」

·         如果您有任何與MySQL授權資料表的其它問題,而且覺得您必須將這個問題發送到郵件資料表,一定要提供一個MySQL授權資料表的傾倒副本(dump)。您可用mysqldump mysql命令複製資料庫資料表。像平時一樣,用mysqlbug指令郵寄您的問題。參見1.7.1.3節,「如何通報問題和問題」。在一些情況下可以用--skip-grant-tables重啟mysqld以便能運行mysqldump


 

5.7.9. MySQL 4.1中的密碼哈希處理

MySQL用戶帳號列於mysql資料庫中的user資料表內。每個MySQL帳號指定一個密碼,儘管保存在user資料表Password列的密碼不是明文,但哈希值是從資料表中的記錄計算的。用PASSWORD()函數來計算密碼的哈希值。

MySQL在客戶端/伺服器通信的兩個階段使用密碼:

·         如果客戶端試圖連接伺服器,有一個初始鑒定步驟,客戶必須提供一個密碼,並且必須與客戶想要使用的帳號在user資料表保存的哈希值匹配。

·         客戶端連接後,它可以(如果有充分的權限) 設置或更改user資料表內所列的帳號的密碼哈希值值。客戶端可以通過PASSWORD()函數來生成密碼哈希值,或使用GRANTSET PASSWORD語句。

換句話說,當客戶端首次試圖連接時,伺服器使用哈希值進行鑒定。如果連接的客戶端使用PASSWORD()函數或使用GRANTSET語句來設置或更改密碼,則伺服器產生哈希值。

MySQL 4.1中密碼哈希算法已經更新,提供了更好的安全性並降低了密碼被截取的風險。但是,該新機制只能在MySQL 4.1(和更新版本的)伺服器和客戶端中使用,會產生一些相容性問題。4.1或新客戶端可以連接4.1之前的伺服器,因為客戶端可以同時理解舊的和新的密碼哈希機制。但是,4.1之前的客戶端試圖連接4.1版或更新版的伺服器時會遇到困難。例如,3.23mysql客戶端試圖連接5.1伺服器時會失敗並出現下面的錯誤消息:

shell> mysql -h localhost -u root
Client does not support authentication protocol requested
by server; consider upgrading MySQL client

出現該問題的另一個普通例子是在升級到MySQL 4.1或更新版後,試圖使用舊版本的PHP mysql延伸名。(參見25.3.1節,「使用MySQL和PHP的常見問題」

下面討論了新、舊密碼機制之間的差別,以及如果您升級了伺服器但需要為4.1版以前的客戶端保持向後相容性該怎樣做。A.2.3節,「客戶端不支援鑒定協議」中有更詳細的訊息。該訊息將MySQL資料庫從4.0版本或更低版升級到4.1版或更高版的PHP編程人員特別重要。

釋:該討論對比了4.1版的行為和4.1前的行為,這兒描述的4.1中的行為實際上從4.1.1開始。MySQL 4.1.0是一個「舊」的發佈,因為它的實施機制與4.1.1版和更新版中的稍有不同。在MySQL 5.0 參考手冊中詳細描述了4.1.0和最新版之間的差別。

MySQL 4.1之前,PASSWORD()函數計算的密碼哈希值有16個字節長。應為:

mysql> SELECT PASSWORD('mypass');
+--------------------+
| PASSWORD('mypass') |
+--------------------+
| 6f8c114b58f2ce9e   |
+--------------------+

MySQL 4.1之前,user資料表的Password(保存了哈希值)也是16字節長。

MySQL 4.1,已經對PASSWORD()函數進行了修改,可以生成41字節的哈希值:

mysql> SELECT PASSWORD('mypass');
+-------------------------------------------+
| PASSWORD('mypass')                        |
+-------------------------------------------+
| *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
+-------------------------------------------+

同樣,user資料表的Password列必須有41字節長來保存這些值:

·         如果您新安裝MySQL 5.1, Password列自動為41字節長。

·         MySQL 4.1(4.1.14.1系列的更新版)升級到MySQL 5.1,應不會出現相關問題,因為兩個版本使用相同的密碼哈希機制。如果您想要將更早版本的MySQL升級到MySQL5.1,您應先升級到4.1,然後將4.1升級到5.1

加寬的Password列可以同時保存新、舊格式的密碼哈希值。可以有兩種方式確定任何給定格式的密碼哈希值:

·         明顯的不同之處是長度(16字節和41字節)

·         2個不同之處是新格式的密碼哈希值都以『*』字元開頭,而舊格式的密碼絕對不是。

 長密碼哈希值具有更好的加密屬性,並且客戶端根據長哈希值進行鑒定比舊的短哈希值更加安全。

短密碼哈希值和長密碼哈希值之間的不同之處與伺服器如何使用密碼進行鑒定以及如何為執行密碼更改操作的連接的客戶端生成密碼哈希值都有關。

伺服器使用密碼哈希值進行鑒定的方式受Password列的寬度影響:

·         如果列較短,只用短哈希鑒定。

·         如果列較長,可以有短或長哈希值,並且伺服器可以使用任何一種格式:

o        4.1之前的客戶端可以連接,它們只可以使用舊的哈希機制,它們可以只鑒定有短哈希的帳號。

o        4.1及以後版本的客戶端可以鑒定有短哈希或長哈希的帳號。

對於短哈希帳號的鑒定過程,4.1和以後版本的客戶端比為舊版本的客戶端實際要安全得多。從安全性角度,從最低安全到最安全的梯度為:

·         4.1之前的客戶端用短密碼哈希值進行鑒定

·         4.1或以後版本的客戶端用短密碼哈希值進行鑒定

·         4.1或以後版本的客戶端用長密碼哈希值進行鑒定

伺服器為連接的客戶端生成密碼哈希值的方式受Password列寬度和--old-passwords選項的影響。4.1或更新版本的伺服器只有滿足某個條件才生成長哈希:Password列必須足夠寬以容納長哈希值並且未給定--old-passwords選項。這些條件適合:

·         Password列必須足夠寬以容納長哈希(41字節)值。如果列沒有更新,仍然為4.1之前的16字節寬,當客戶端使用PASSWORD()GRANTSET PASSWORD執行密碼更改操作時,伺服器注意到長哈希不適合,只生成短哈希。如果您已經升級到4.1但還沒有運行 mysql_fix_privilege_tables指令來擴寬Password列時會出現這種行為。

·         如果Password列足夠寬,則可以保存短或長密碼哈希值。在這種情況下,PASSWORD()GRANTSET PASSWORD生成長哈希,除非 用--old-passwords選項啟動伺服器。該選項強制伺服器生成短密碼哈希值。

--old-passwords選項的目的是當伺服器生成長密碼哈希值時,允許您維持同4.1之前的客戶端的向後相容性。該選項不影響鑒定(4.1和以後版本的客戶端仍然可以使用有長密碼哈希值的帳號),但它防止在密碼更改操作中在user資料表中建立長密碼哈希值。在這種情況下,該帳號不能再用於4.1之前的客戶端。沒有--old-passwords選項,可能會出現下面的不期望的情況:

·         舊客戶端連接有短密碼哈希值的帳號。

·         客戶更改自己的密碼。沒有--old-passwords,可以為該帳號生成長密碼哈希值。

·         下次舊客戶試圖連接帳號時不能連接上,因為帳號有長密碼哈希值,需要新的哈希機制進行鑒定。(一旦帳號user資料表中為長密碼哈希值,只有4.1和以後版本的客戶端可以鑒定它,因為4.1之前的客戶端不理解長哈希)

該場景說明,如果您必須支援舊的4.1之前的客戶端,不使用--old-passwords選項運行4.1或更新版本的伺服器很危險。用--old-passwords運行伺服器,密碼更改操作不會生成長密碼哈希值,這樣舊客戶端也可以訪問帳號。(這些客戶端不能意外地因更改了密碼將自己鎖出去,並留下長密碼哈希值)

--old-passwords選項的不利之處是您建立或更改的密碼使用短哈希,甚至對於4.1客戶端也如此。這樣,您丟失了長密碼哈希值提供的安全性。如果您想要建立有長哈希的帳號(例如,為4.1客戶端),您必須不使用--old-passwords來運行伺服器。

下面的場景可用於運行4.1或以後的伺服器,包括MySQL 5.1

場景1user資料表中的短Password列:

·         只有短哈希可以保存到Password列。

·         伺服器只使用短哈希進行客戶端鑒定。

·         對於連接的客戶端,使用PASSWORD()GRANTSET PASSWORD的密碼哈希生成操作專使用短哈希。對帳號的任何更改均會生成短密碼哈希值。

·          --old-passwords選項可以使用但是多餘,因為Password列較短,伺服器只生成短密碼哈希值。

場景2Password列;沒有用--old-passwords選項啟動伺服器:

·         短或長哈希可以保存到Password列。

·         4.1和以後版本的客戶端(包括5.1客戶端)可以鑒定有短或長哈希的帳號。

·         4.1之前的客戶端只能鑒定有短哈希的帳號。

·         對於連接的客戶端,使用PASSWORD()GRANTSET PASSWORD的密碼哈希生成操作專使用短哈希。對帳號的任何更改均會生成短密碼哈希值。

如前面所示,該場景的危險性在於4.1之前的客戶端可能不能訪問有短密碼哈希值的帳號。通過PASSWORD()GRANTSET PASSWORDA對這些帳號密碼的更改會產生長的密碼哈希值。從該點看,4.1之前的客戶端升級到4.1之前不能鑒定該帳號。

要處理該問題,可以用特殊方法更改密碼。例如,一般情況您可以使用SET PASSWORD按照下面的方法更改帳號密碼:

mysql> SET PASSWORD FOR 'some_user'@'some_host' = PASSWORD('mypass');

要想更改密碼但建立短哈希,使用OLD_PASSWORD()函數:

mysql> SET PASSWORD FOR 'some_user'@'some_host' = OLD_PASSWORD('mypass');

當您想明顯生成短哈希時OLD_PASSWORD()很有用。

場景3Password列;用--old-passwords選項啟動4.1或新版本的伺服器:

·         短或長哈希可以保存到Password列。

·         4.1和以後版本的客戶端可以鑒定有短或長哈希的帳號(請注意只有不使用--old-passwords選項啟動伺服器,方可以建立長哈希)

·         4.1之前的客戶端只可以鑒定短哈希帳號。

·         對於連接的客戶端,使用PASSWORD()GRANTSET PASSWORD的密碼哈希生成操作專使用短哈希。對帳號的任何更改均會生成短密碼哈希值。

在該場景中,您不能建立長密碼哈希值的帳號,因為--old-passwords選項防止生成長哈希。並且,如果您在使用--old-passwords選項前建立長哈希帳號,當--old-passwords有時更改帳號密碼,結果會使帳號的密碼為短密碼,安全性較長哈希要降低。

這些場景的不利之處可以概括為:

在場景1,您不能利用長哈希提供更安全的鑒定。

在場景2, 如果您沒有顯式使用OLD_PASSWORD()來更改密碼,則4.1之前的客戶端不能再訪問短哈希帳號。

在場景3,--old-passwords防止短哈希帳號不可訪問,但密碼更改操作使帳號的長哈希轉換為短哈希,當--old-passwords有效時不能將它改回長哈希。

5.7.9.1. 更改應用程式密碼哈希值的含義

升級到MySQL4.1或更新版本後,使用PASSWORD()為自己的目的生成密碼的應用程式會出現相容性問題。應用程式實際不應這樣做,因為PASSWORD()只應用來管理MySQL帳號的密碼。但一些應用程式使用PASSWORD()用於自己的目的。

如果您從MySQL 4.1之前的版本升級到4.1或以後版本,並在生成長密碼哈希值的條件下運行伺服器,應用程式使用PASSWORD()破解自己的密碼。這種情況下推薦的方法是修改應用程式,使用其它函數,例如SHA1()MD5(),來產生哈希值。如果不行,您可以使用OLD_PASSWORD()函數,該函數用來提供舊格式的短哈希。但是,請注意OLD_PASSWORD()可能有一天不再被支援。

如果伺服器運行在生成短哈希的條件下,可以使用 OLD_PASSWORD()但與PASSWORD()等同。

MySQL資料庫從4.0或更低版本移植到4.1或更高版本的PHP編程人員應參閱舊客戶端

5.8. MySQL用戶帳號管理

本節描述如何為MySQL伺服器的客戶端設置帳號。討論了下面的主題:

·         MySQL使用的帳號名和密碼的含義,以及如何比較您的作業系統所使用的帳號名和密碼

·         如何設置新帳號並移除已有帳號

·         如何更改密碼

·         安全使用密碼指導

·         如何使用安全SSL連接

5.8.1. MySQL帳號和密碼

用帳號和客戶端或主機定義MySQL帳號,用戶可以根據這些名稱來連接伺服器。帳號也有密碼。MySQL和作業系統使用帳號和密碼的方式有幾處區別:

·         MySQL用於鑒定目的帳號與WindowsUnix使用的帳號(登錄名)沒有關係。在Unix中,大多數MySQL客戶端預設試圖使用當前Unix的帳號作為MySQL帳號來登錄,但這樣只是為了方便。 預設值可以很容易被覆蓋,因為客戶端程式允許用-u--user選項來指定帳號。因為這資料表示任何人可以試圖使用任何帳號來連接伺服器,除非所有MySQL帳號有密碼,否則您不能使資料庫保持安全。通過為沒有密碼的帳號指定帳號,任何人能夠成功連接伺服器。

·         MySQL帳號最大客達16字元長。這樣可以限制MySQL伺服器和客戶端之間的硬編碼,並且防止通過修改mysql資料庫中資料表的定義來偷竊密碼。

:應絕對不要以任何方式修改mysql資料庫中的任何資料表,只能運行MySQL分發中專為此目的提供的指令。將MySQL系統資料表重新定義為其它方式會導致未定義的(和不支援的!)行為

作業系統帳號與MySQL帳號完全不相關,甚至最大長度可能不同。例如, Unix帳號限制為8個字元。

·         MySQL密碼與登錄到您的作業系統的密碼沒有關係。不需要將您用來登錄WindowsUnix機器的密碼和您用來訪問該機器上的MySQL伺服器的密碼關聯起來。

·         MySQL的加密密碼使用自己的算法。該加密算法不同於Unix登錄過程使用的算法。MySQL密碼加密與PASSWORD()SQL函數的方法相同。Unix密碼加密與ENCRYPT()SQL函數的方法相同。PASSWORD()ENCRYPT()函數的描述參見12.9.2節,「加密函數」。從版本4.1 起,MySQL使用更強的鑒定方法,同以前的版本相比可以在連接過程中提供更好的密碼保護。即使TCP/IP包被截取或mysql資料庫被捕獲也很安全。(在前面的版本中,即使密碼以加密形式保存到user資料表中,仍可以通過加密密碼值來連接MySQL伺服器)

當安裝MySQL時,授權資料表裝載時有一系列初使帳號。這些帳號的名稱和訪問權限見2.9.3節,「使初始MySQL帳號安全」,其中還討論了如何未這些帳號賦予密碼。因此,您一般應使用GRANTREVOKE語句來設置、修改和移除MySQL帳號。參見13.5.1.3節,「GRANT和REVOKE語法」

當用命令行客戶端連接MySQL伺服器時,您應為想要使用的帳號指定帳號和密碼:

shell> mysql --user=monty --password=guess db_name

如果您想用較短的選項,命令應為:

shell> mysql -u monty -pguess db_name

-p選項和後面的密碼值之間絕對不能有空格。參見5.7.4節,「與MySQL伺服器連接」

前面的命令包括命令行中的密碼值,會很危險。參見5.8.6節,「使您的密碼安全」。要想避免,指定--password-p選項後面不跟任何密碼值:

shell> mysql --user=monty --password db_name
shell> mysql -u monty -p db_name

然後客戶端程式輸出提示符並等待您輸入密碼。(在這些示範中,db_name並不為密碼,因為用空格將它同前面的密碼項隔離開了)

在一些系統中,MySQL用來提示輸入密碼的庫使用自動將密碼限制到8個字元。這是系統庫的問題,而不是MySQL的問題。MySQL本身並不限制密碼的長度。要解決該問題,將MySQL密碼改為8個字元和更少字元的值,或將密碼放入選項檔案中。

5.8.2. 向MySQL增加新用戶帳號

可以用兩種方式建立MySQL帳號:

·         使用GRANT語句

·         直接操作MySQL授權資料表

最好的方法是使用GRANT語句,因為這樣更精確,錯誤少。從MySQL 3.22.11起提供了GRANT;其語法見13.5.1.3節,「GRANT和REVOKE語法」

建立帳號的其它方法是使用MySQL帳號管理功能的第三方程式。phpMyAdmin即是一個程式。

下面的示範說明如何使用MySQL客戶端程式來設置新用戶。假定按照2.9.3節,「使初始MySQL帳號安全」描述的 預設值來設置權限。這說明為了更改,您必須以MySQL root用戶連接MySQL伺服器,並且root帳號必須有mysql資料庫的INSERT權限和RELOAD管理權限。

首先,使用MySQL程式以MySQL root用戶來連接伺服器:

shell> MySQL --user=root MySQL

如果您為root帳號指定了密碼,還需要為該MySQL命令和本節中的其它命令提供--password-p選項。

root連接到伺服器上後,可以新增新帳號。下面的語句使用GRANT來設置四個新帳號:

mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'
    ->     IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'
    ->     IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
mysql> GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost';
mysql> GRANT USAGE ON *.* TO 'dummy'@'localhost';

GRANT語句建立的帳號有下面的屬性:

·         其中兩個帳號有相同的帳號monty和密碼some_pass。兩個帳號均為超級用戶帳號,具有完全的權限可以做任何事情。一個帳號 ('monty'@'localhost')只用於從本機連接時。另一個帳號('monty'@'%')可用於從其它主機連接。請注意monty的兩個帳號必須能從任何主機以monty連接。沒有localhost帳號,當monty從本機連接時,mysql_install_db建立的localhost的匿名用戶帳號將佔先。結果是,monty將被視為匿名用戶。原因是匿名用戶帳號的Host列值比'monty'@'%'帳號更具體,這樣在user資料表排序順序中排在前面。(user資料表排序的討論參見5.7.5節,「訪問控制, 階段1:連接核實」

·         一個帳號有帳號admin,沒有密碼。該帳號只用於從本機連接。授予了RELOADPROCESS管理權限。這些權限允許admin用戶執行mysqladmin reloadmysqladmin refreshmysqladmin flush-xxx命令,以及mysqladmin processlist。未授予訪問資料庫的權限。您可以通過GRANT語句新增此類權限。

·         一個帳號有帳號dummy,沒有密碼。該帳號只用於從本機連接。未授予權限。通過GRANT語句中的USAGE權限,您可以建立帳號而不授予任何權限。它可以將所有全局權限設為'N'。假定您將在以後將具體權限授予該帳號。

除了GRANT,您可以直接用INSERT語句建立相同的帳號,然後使用FLUSH PRIVILEGES告訴伺服器重載授權資料表:

shell> mysql --user=root mysql
mysql> INSERT INTO user
    ->     VALUES('localhost','monty',PASSWORD('some_pass'),
    ->     'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user
    ->     VALUES('%','monty',PASSWORD('some_pass'),
    ->     'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user SET Host='localhost',User='admin',
    ->     Reload_priv='Y', Process_priv='Y';
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('localhost','dummy','');
mysql> FLUSH PRIVILEGES;

當您用INSERT建立帳號時使用FLUSH PRIVILEGES的原因是告訴伺服器重讀授權資料表。否則,只有重啟伺服器後更改方會被注意到。使用 GRANT,則不需要使用FLUSH PRIVILEGES

INSERT使用PASSWORD()函數是為了加密密碼。GRANT語句為您加密密碼,因此不需要PASSWORD()

'Y'值啟用帳號權限。對於admin帳號,還可以使用更加可讀的INSERT擴充的語法(使用SET)。

在為dummy帳號的INSERT語句中,只有user資料表中的HostUserPassword列記錄為指定的值。沒有一個權限列為顯式設置,因此MySQL將它們均指定為 預設值'N'。這樣等同於GRANT USAGE的操作。

請注意要設置超級用戶帳號,只需要建立一個權限列設置為'Y'user資料表條目。user資料表權限為全局權限,因此其它 授權資料表不再需要條目。

下面的例子建立3個帳號,允許它們訪問專用資料庫。每個帳號的帳號為custom,密碼為obscure

要想用GRANT建立帳號,使用下面的語句:

shell> MySQL --user=root MySQL
shell> mysql --user=root mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON bankaccount.*
    ->     TO 'custom'@'localhost'
    ->     IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON expenses.*
    ->     TO 'custom'@'whitehouse.gov'
    ->     IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON customer.*
    ->     TO 'custom'@'server.domain'
    ->     IDENTIFIED BY 'obscure';

3個帳號可以用於:

·         1個帳號可以訪問bankaccount資料庫,但只能從本機訪問。

·         2個帳號可以訪問expenses資料庫,但只能從主機whitehouse.gov訪問。

·         3個帳號可以訪問customer資料庫,但只能從主機server.domain訪問。

要想不用GRANT設置custom帳號,使用INSERT語句直接修改 授權資料表:

shell> mysql --user=root mysql
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('localhost','custom',PASSWORD('obscure'));
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('whitehouse.gov','custom',PASSWORD('obscure'));
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('server.domain','custom',PASSWORD('obscure'));
mysql> INSERT INTO db
    ->     (Host,Db,User,Select_priv,Insert_priv,
    ->     Update_priv,Delete_priv,Create_priv,Drop_priv)
    ->     VALUES('localhost','bankaccount','custom',
    ->     'Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
    ->     (Host,Db,User,Select_priv,Insert_priv,
    ->     Update_priv,Delete_priv,Create_priv,Drop_priv)
    ->     VALUES('whitehouse.gov','expenses','custom',
    ->     'Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
    ->     (Host,Db,User,Select_priv,Insert_priv,
    ->     Update_priv,Delete_priv,Create_priv,Drop_priv)
    ->     VALUES('server.domain','customer','custom',
    ->     'Y','Y','Y','Y','Y','Y');
mysql> FLUSH PRIVILEGES;
 

3INSERT語句在user資料表中加入條目,允許用戶custom從各種主機用給定的密碼進行連接,但不授予全局權限(所有權限設置為 預設值'N')。後面3INSERT語句在user資料表中加入條目,為custom授予bankaccountexpensescustomer資料庫權限,但只能從合適的主機訪問。通常若直接修改 授權資料表,則應告訴伺服器用FLUSH PRIVILEGES重載授權資料表,使權限更改生效。

如果您想要讓某個用戶從給定域的所有機器訪問(例如,mydomain.com),您可以在帳號名的主機部分使用含『%』通配符的GRANT語句:

mysql> GRANT ...
    ->     ON *.*
    ->     TO 'myname'@'%.mydomain.com'
    ->     IDENTIFIED BY 'mypass';

要想通過直接修改授權資料表來實現:

mysql> INSERT INTO user (Host,User,Password,...)
    ->     VALUES('%.mydomain.com','myname',PASSWORD('mypass'),...);

mysql> FLUSH PRIVILEGES;

5.8.3. 從MySQL刪除用戶帳號

要想移除帳號,應使用DROP USER語句,請參見13.5.1.2節,「DROP USER語法」

5.8.4. 限制帳號資源

限制MySQL伺服器資源使用的一個方法是將max_user_connections系統變數設置為非零值。但是,該方法嚴格限於全局,不允許管理具體帳號。並且,它只限制使用單一帳號同時連接的數量,而不是客戶端連接後的操作。許多MySQL管理員對兩種類型的控制均感興趣,特別是Internet服務提供者。

MySQL 5.1,您可以為具體帳號限制下面的伺服器資源:

·         帳號每小時可以發出的查詢數

·         帳號每小時可以發出的更新數

·         帳號每小時可以連接伺服器的次數

客戶端可以執行的語句根據查詢限制來記數。只有修改資料庫或資料表的語句根據更新限制來記數。

還可以限制每個帳號的同時連接伺服器的連接數。

本文中的帳號為user資料表中的單個記錄。根據UserHost列值唯一識別每個帳號。

做為使用該特性的先決條件,mysql資料庫的user資料表必須包含資源相關的列。資源限制保存在max_questionsmax_updatesmax_connectionsmax_user_connections列內。如果user資料表沒有這些列,必須對它進行升級;參見2.10.2節,「升級授權資料表」

要想用GRANT語句設置資源限制,使WITH子句來命名每個要限制的資源和根據每小時記數的限制值。例如,要想只以限制方式建立可以訪問customer資料庫的新帳號,執行該語句:

mysql> GRANT ALL ON customer.* TO 'francis'@'localhost'
    ->     IDENTIFIED BY 'frank'
    ->     WITH MAX_QUERIES_PER_HOUR 20
    ->          MAX_UPDATES_PER_HOUR 10
    ->          MAX_CONNECTIONS_PER_HOUR 5
    ->          MAX_USER_CONNECTIONS 2;

限制類型不需要全部在WITH子句中命名,但已經命名的可以按任何順序。每個每小時限制值均應為整數,代資料表每小時的記數。如果GRANT語句沒有WITH子句,則每個限制值設置為 預設值零(即沒有限制)。對於MAX_USER_CONNECTIONS,限制為整數,資料表示帳號一次可以同時連接的最大連接數。如果限制設置為 預設值零,則根據MAX_USER_CONNECTIONS系統變數確定該帳號可以同時連接的數量。

要想設置或更改已有帳號的限制,在全局級別使用GRANT USAGE語句(*.*)。下面的語句可以將francis的查詢限制更改為100

mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'
    ->     WITH MAX_QUERIES_PER_HOUR 100;

該語句沒有改變帳號的已有權限,只修改了指定的限制值。

要想取消已有限制,將該值設置為零。例如,要想取消francis每小時可以連接的次數的限制,使用該語句:

mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'
    ->     WITH MAX_CONNECTIONS_PER_HOUR 0;

當帳號使用資源時如果有非零限制,則對資源使用進行記數。

伺服器運行時,它統計每個帳號使用資源的次數。如果帳號在最後一個小時的連接次數達到限制,該帳號的進一步的連接被拒絕。類似地,如果帳號達到查詢或更新次數的限制,進一步的查詢或更新被拒絕。在這種情況下,會給出相關錯誤消息。

根據每個帳號進行資源計算,而不是根據每個客戶端。例如,如果您的帳號的查詢限制為50,您不能通過兩個客戶端同時連接伺服器將限制增加到100。兩個連接的查詢被計算到一起。

可以為所有帳號從全局重設當前的每小時資源使用記數,或單獨重設給定的帳號:

·         要想將所有帳號當前的記數重設為零,可以執行FLUSH USER_RESOURCES語句。還可以通過重載授權資料表來重設記數(例如,使用FLUSH PRIVILEGES語句或mysqladmin reload命令)

·         將具體帳號的限制重新授予任何值,可以將它設置為零。要想實現,按照前面所述使用GRANT USAGE,並將限制值指定為該帳號當前的限制值。

計數器重設不影響MAX_USER_CONNECTIONS限制。

當伺服器啟動時所有記數從零開始。

5.8.5. 設置帳號密碼

  • 可以用mysqladmin命令在命令行指定密碼:
    shell> mysqladmin -u user_name -h host_name password "newpwd"

    該命令重設密碼的帳號為user資料表內匹配User列的user_nameHost您發起連接的客戶端的記錄。

    為帳號賦予密碼的另一種方法是執行SET PASSWORD語句:

    mysql> SET PASSWORD FOR 'jeffrey'@'%' = PASSWORD('biscuit');

    只有root等可以更新mysql資料庫的用戶可以更改其它用戶的密碼。如果您沒有以匿名用戶連接,省略FOR子句便可以更改自己的密碼:

    mysql> SET PASSWORD = PASSWORD('biscuit');

    您還可以在全局級別使用GRANT USAGE語句(*.*)來指定某個帳號的密碼而不影響帳號當前的權限:

    mysql> GRANT USAGE ON *.* TO 'jeffrey'@'%' IDENTIFIED BY 'biscuit';

    一般情況下最好使用上述方法來指定密碼,您還可以直接修改user資料表:

    ·         要想在建立新帳號時建立密碼,在Password列提供一個值:

    ·                shell> mysql -u root mysql
    ·                mysql> INSERT INTO user (Host,User,Password)
    ·                     -> VALUES('%','jeffrey',PASSWORD('biscuit'));
    ·                mysql> FLUSH PRIVILEGES;
    ·                 

    ·         要想更改已有帳號的密碼,使用UPDATE來設置Password列值:

    ·                shell> mysql -u root mysql
    ·                 mysql> UPDATE user SET Password = PASSWORD('bagel')
    ·                       -> WHERE Host = '%' AND User = 'francis';
    ·                mysql> FLUSH PRIVILEGES;

    當您使用SET PASSWORDINSERTUPDATE指定帳號的密碼時,必須用PASSWORD()函數對它進行加密。(唯一的特例是如果密碼為空,您不需要使用PASSWORD())。需要使用PASSWORD()是因為user資料表以加密方式保存密碼,而不是明文。如果您忘記了,您可能會像這樣設置密碼:

    shell> mysql -u root mysql
    mysql> INSERT INTO user (Host,User,Password)
        -> VALUES('%','jeffrey','biscuit');
    mysql> FLUSH PRIVILEGES;
     

    結果是密碼'biscuit'保存到user資料表後沒有加密。當jeffrey使用該密碼連接伺服器時,值被加密並同保存在user資料表中的進行比較。但是,保存的值為字串'biscuit',因此比較將失敗,伺服器拒絕連接:

    shell> mysql -u jeffrey -pbiscuit test
    Access denied

    如果您使用GRANT ... IDENTIFIED BY語句或mysqladmin password命令設置密碼,它們均會加密密碼。在這種情況下,不需要使用 PASSWORD()函數。

    釋:PASSWORD()加密不同於Unix密碼加密。參見5.8.1節,「MySQL帳號和密碼」

5.8.6. 使您的密碼安全

在管理級別,您決不能將mysql.user資料表的訪問權限授予任何非管理帳號。

當您運行客戶端程式連接MySQL伺服器時,以一種暴露的可被其他用戶發現的方式指定您的密碼是不妥當的。當您運行客戶端程式時,您可以使用下列方法指定您的密碼,還有每個方法的風險評估:

·         使用一個在命令行上-pyour_pass--password=your_pass的選項。例如:

·                shell> mysql -u francis -pfrank db_name

這很方便但是不安全,因為您的密碼對系統狀態程式(例如ps)變得可見,它可以被其他的用戶使用來顯示命令行。一般MySQL客戶在他們的初始化順序期間用零覆蓋命令行參數,但是仍然有一個短暫間隔時間內參數值可見的。

·         使用一個-p--password選項(沒有指定密碼)。在這種情況下,客戶端程式請求來自終端的密碼:

·                shell> mysql -u francis -p db_name
·                Enter password: ********

 *字元指示輸入密碼的地方。輸入密碼時密碼看不見。

因為它對其他用戶不可見,與在命令行上指定它相比,這樣進入您的密碼更安全。然而,這個輸入一個密碼的方法僅僅為您交互式運行程式是合適的。如果您想要從非交互式運行的一個指令使用一個客戶端,就沒有從終端輸入入密碼的機會。在某些系統中,您甚至會發現指令的第一行被(錯誤地)讀並解釋為您的密碼!

·         在一個配置檔案中儲存您的密碼。例如,在Unix中,您可在主目錄的.my.cnf檔案中的[client]節列出您的密碼:

·                [client]
·                password=your_pass

如果您在.my.cnf裡面儲存密碼,除了您本人其它人不能訪問該檔案。保證檔案的訪問模式是400600例如:

shell> chmod 600 .my.cnf

關於選項檔案的詳細討論參見4.3.2節,「使用選項檔案」

·         您可在MYSQL_PWD環境變數中儲存密碼。但是這種指定MySQL密碼的方法是極不安全的,不應該使用。ps的某些版本包括顯示運行程序的環境的選項;如果您設定MYSQL_PWD,您的密碼將被運行ps的所有人看見,甚至在沒有這樣一個版本的ps的系統上,沒有其它方法觀察到程序環境的假設是不明智的。參見附錄F:環境變數

總之,最安全的方法是讓客戶端程式提示輸入密碼或在適當保護的選項檔案中指定密碼。

5.8.7. 使用安全連接

MySQL支援MySQL客戶端和伺服器之間的安全(加密的)連接所使用的安全套接字層(SSL)協議。本節討論如何使用SSL連接。還描述了在Windows中設置SSH的方法。

MySQL的標準配置傾向於盡可能快,因此預設情況不使用加密連接。使用該協議會使客戶端/伺服器協議慢得多。對數據進行加密非常耗CPU,需要計算機多做許多工作,會延遲MySQL的其它任務。對於需要通過加密連接提供安全的應用程式,可以保證額外的計算。

MySQL允許在連接前啟用加密。您可以根據具體應用程式的需求選擇普通未加密連接或安全加密SSL連接。

5.8.7.1. SSL基本概念

要想理解MySQL如何使用SSL,需要解釋一些基本SSLX509概念。熟悉的人們可以跳過該部分。

預設情況下,MySQL在客戶端和伺服器之間使用未加密的連接。這說明可以訪問網絡的部分人可以看到您的通信,並看到發送和接收的數據。他們甚至可以更改在客戶端和伺服器之間傳遞的數據。要想提高安全性,當使用客戶端程式時,您可以通過--compress選項壓縮客戶端/伺服器之間的通信。但是,這樣並不能阻擋住頑固的攻擊者。

當您需要以安全方式在網絡中傳遞訊息時,未加密的連接是不可接受的。加密是使任何數據不可讀的方法。事實上,今天的許多慣例需要加密算法提供更加安全的要素。它們應能抵抗各種已知的攻擊,例如更改加密消息的順序或兩次重放數據。

SSL是一種使用不同的加密算法確保從公用網接收到的數據是可信的協議。它具有檢測數據更改、丟失或重放的機制。SSL還包括使用 X509標準提供身份認證的算法。

使用X509,可以識別Internet上的某些人。通常用於電子商務應用程式中。按照基本概念,應有某種稱之為「認證機構(CA)的機構,可以向請求者分發電子證書。證書依賴非對稱加密算法,有兩個加密密鑰(公共密鑰和私人密鑰)。認證持有者可以向其它方出示證書來證明身份。證書包括持有者的公共密鑰。只能使用對應的私人密鑰對含該公共密鑰的加密數據進行解密,私人密鑰由證書持有者擁有。

如果您需要關於SSLX509、或加密的詳細訊息,使用Internet搜索引擎來搜索您感興趣的關鍵字。

5.8.7.2. 需求(OpenSSL)

要想在MySQL伺服器和客戶端程式之間使用SSL連接,系統必須能夠支援OpenSSL。如果用支援內嵌式yaSSLMySQL版本,不要讀該節,但應閱讀5.8.7.3節,「使用yaSSL」

要想獲得安全的MySQL連接,必須:

1.    安裝OpenSSL庫。我們已經測試了帶OpenSSL 0.9.6MySQL。如果您需要OpenSSL,請訪問http://www.openssl.org

2.    配置MySQL,用--with-vio--with-openssl選項運行configure指令。

3.    確保升級了授權資料表,使mysql.user資料表內包含SSL相關列。如果 授權資料表是從MySQL 4.0.0之前的版本升級,這很重要。升級過程見2.10.2節,「升級授權資料表」

4.    要想檢查是否運行的mysqld伺服器支援OpenSSL,應檢查have_openssl系統變數的值:

5.            mysql> SHOW VARIABLES LIKE 'have_openssl';
6.            +---------------+-------+
7.            | Variable_name | Value |
8.            +---------------+-------+
9.            | have_openssl  | YES   |
10.        +---------------+-------+

如果值為YES,伺服器支援OpenSSL連接。

5.8.7.3. 使用yaSSL

使用MySQL的內嵌式yaSSL支援,可以很容易地使用安全連接。不需要安裝OpenSSL和執行5.8.7.2節,「需求(OpenSSL)」中的步驟。並且,MySQLyaSSL使用相同的授權模型。

當前,在以下平台上支援yaSSL

·         Linux/x86-64 Red Hat Enterprise 3.0

·         Linux RHAS21 Itanium-2,帶gcc,靜態連結

·         Linux Itanium-2,帶gcc

·         Windows

當從原始碼構建MySQL時如果您想要啟用yaSSL,應這樣配置MySQL

./configure --with-yassl=yes

要想啟動MySQL伺服器支援yaSSL,使用支援OpenSSL的相同的選項,並識別建立安全連接需要的證書:

shell> mysqld --ssl-ca=cacert.pem \
       --ssl-cert=server-cert.pem \
       --ssl-key=server-key.pem

·         --ssl-ca識別認證機構證書。

·         --ssl-cert識別伺服器證書。

·         --ssl-key識別客戶證書。

要想用yaSSL支援建立與MySQL伺服器的安全連接,應這樣啟動客戶端:

shell> mysql --ssl-ca=cacert.pem \
       --ssl-cert=server-cert.pem \
       --ssl-key=server-key.pem

換句話說,選項與伺服器的相同,並且認證機構證書必須相同。

要想從應用程式建立安全連接,使用mysql_real_connect()之前,應使用mysql_ssl_set()API函數來設置相應認證選項。參見25.2.3.64節,「mysql_ssl_set()」

5.8.7.4. 為MySQL設置SSL證書

下面是一個為MySQ設置SSL證書的例子:
DIR=`pwd`/openssl
PRIV=$DIR/private
 
mkdir $DIR $PRIV $DIR/newcerts
cp /usr/share/ssl/openssl.cnf $DIR
replace ./demoCA $DIR -- $DIR/openssl.cnf
 
# Create necessary files: $database, $serial and $new_certs_dir
# directory (optional)
 
touch $DIR/index.txt
echo "01" > $DIR/serial
 
#
# Generation of Certificate Authority(CA)
#
 
openssl req -new -x509 -keyout $PRIV/cakey.pem -out $DIR/cacert.pem \
    -config $DIR/openssl.cnf
 
# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ................++++++
# .........++++++
# writing new private key to '/home/monty/openssl/private/cakey.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL admin
# Email Address []:
 
#
# Create server request and key
#
openssl req -new -keyout $DIR/server-key.pem -out \
    $DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf
 
# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ..++++++
# ..........++++++
# writing new private key to '/home/monty/openssl/server-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL server
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:
 
#
# Remove the passphrase from the key (optional)
#
 
openssl rsa -in $DIR/server-key.pem -out $DIR/server-key.pem
 
#
# Sign server cert
#
openssl ca  -policy policy_anything -out $DIR/server-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/server-req.pem
 
# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL admin'
# Certificate is to be certified until Sep 13 14:22:46 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
#
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated
 
#
# Create client request and key
#
openssl req -new -keyout $DIR/client-key.pem -out \
    $DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf
 
# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# .....................................++++++
# .............................................++++++
# writing new private key to '/home/monty/openssl/client-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL user
# Email Address []:
#
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:
 
#
# Remove a passphrase from the key (optional)
#
openssl rsa -in $DIR/client-key.pem -out $DIR/client-key.pem
 
#
# Sign client cert
#
 
openssl ca  -policy policy_anything -out $DIR/client-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/client-req.pem
 
# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL user'
# Certificate is to be certified until Sep 13 16:45:17 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
#
#
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated
 
#
# Create a my.cnf file that you can use to test the certificates
#
 
cnf=""
cnf="$cnf [client]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/client-cert.pem"
cnf="$cnf ssl-key=$DIR/client-key.pem"
cnf="$cnf [mysqld]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/server-cert.pem"
cnf="$cnf ssl-key=$DIR/server-key.pem"
echo $cnf | replace " " '
' > $DIR/my.cnf

 

要想測試SSL連接,按下面方法啟動伺服器,其中$DIR是示範my.cnf選項檔案安裝的路徑名:

shell> MySQLd --defaults-file=$DIR/my.cnf &

然後使用相同的選項檔案使用客戶端程式:

shell> MySQL --defaults-file=$DIR/my.cnf

如果您有MySQL原始碼分發版,還可以修改前面的my.cnf檔案來指向SSL目錄中的示範證書和密鑰檔案來測試您的設置。

5.8.7.5. SSL GRANT 選項

MySQL可以檢查X509證書的屬性和基於帳號和密碼的通用鑒定方法。要想為MySQL帳號指定SSL相關選項,使用GRANT語句的REQUIRE子句。參見13.5.1.3節,「GRANT和REVOKE語法」

有多種可能來限制一個帳號的連接類型:

·         如果帳號沒有SSLX509需求,如果帳號和密碼合法,允許未加密的連接。但是,如果客戶有正確的證書和密鑰檔案,在客戶選項中可以使用加密連接。

·         REQUIRE SSL選項限制伺服器只允許該帳號的SSL加密連接。請注意如果有ACL記錄允許非SSL連接,該選項會被忽略。

·                  mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
·                     -> IDENTIFIED BY 'goodsecret' REQUIRE SSL;

·         REQUIRE X509資料表示客戶必須有合法證書但確切的證書、分發者和主體不重要。唯一的需求是應可以被某個CA認證機構驗證它的簽名。

·                mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
·                    -> IDENTIFIED BY 'goodsecret' REQUIRE X509;

·         REQUIRE ISSUER 'issuer'限制連接企圖,即客戶必須出示CA 'issuer'簽發的合法X509證書。如果客戶出示了一個合法證書,但是是由不同的分發者簽發,伺服器拒絕連接。使用X509證書資料表示要加密,因此不需要SSL選項。

·                mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
·                    -> IDENTIFIED BY 'goodsecret'
·                    -> REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/
·                       O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com';

請注意ISSUER值應做為單一字串輸入。

·         REQUIRE SUBJECT 'subject' 限制連接企圖,即客戶必須出示主題為'subject'的合法X509證書。如果客戶出示了一個合法證書,但是有不同的主題,伺服器拒絕連接。

·                mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
·                    -> IDENTIFIED BY 'goodsecret'
·                    -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
·                       O=MySQL demo client certificate/
       CN=Tonu Samuel/Email=tonu@example.com';

請注意SUBJECT值應做為單一字串輸入。

·         REQUIRE CIPHER 'cipher'用來確保使用足夠強的密碼和密鑰長度。如果使用舊的短加密密鑰算法,SSL本身可能很弱。使用該選項,我們可以索取確切的加密方法來連接。

·                mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
·                    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';

REQUIRE子句中,可以結合使用SUBJECTISSUERCIPHER選項:

mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
       O=MySQL demo client certificate/
       CN=Tonu Samuel/Email=tonu@example.com'
    -> AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/
       O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com'
    -> AND CIPHER 'EDH-RSA-DES-CBC3-SHA';

請注意SUBJECTISSUER值應做為單一字串輸入。

MySQL 5.1,REQUIRE選項之間可以選用AND關鍵字。

選項的順序不重要,但任何選項不能用兩次。

5.8.7.6. SSL命令行選項

下面列出了規定SSL、證書檔案和密鑰檔案使用的選項。它們可以位於命令行中或選項檔案中。

·         --ssl

對於伺服器,該選項規定該伺服器允許SSL連接。對於客戶端程式,它允許客戶使用SSL連接伺服器。單單該選項不足以使用SSL連接。還必須指定--ssl-ca--ssl-cert--ssl-key選項。

通常從反向使用該選項資料表示不應使用SSL。要想實現,將選項指定為--skip-ssl--ssl=0

請注意使用--ssl需要SSL連接。例如,如果編譯的伺服器或客戶不支援SSL,則使用普通的未加密的連接。

確保使用SSL連接的安全方式是使用含REQUIRE SSL子句的GRANT語句在伺服器上建立一個帳號。然後使用該帳號來連接伺服器,伺服器和客戶端均應啟用SSL支援。

·         --ssl-ca=file_name

含可信SSL CA的清單的檔案的路徑。

·         --ssl-capath=directory_name

包含pem格式的可信SSL CA證書的目錄的路徑。

·         --ssl-cert=file_name

SSL證書檔案名,用於建立安全連接。

·         --ssl-cipher=cipher_list

允許的用於SSL加密的密碼的清單。cipher_list的格式與OpenSSL ciphers命令相同。

示範:--ssl-cipher=ALL:-AES:-EXP

·         --ssl-key=file_name

SSL密鑰檔案名,用於建立安全連接。

5.8.7.7. 用SSH以遠程方式從Windows連接到MySQL

本節說明如何用SSH安全連接到遠程MySQL伺服器(David Carlson <dcarlson@mplcommcom>)

1.    Windows主機上安裝SSH客戶端。作為用戶,我所發現的最好的非免費客戶端來自http://www.vandyke.com/SecureCRT。另一個選則是http://www.f-secure.com/f-secure。您還可以從http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows/ Google找到一些免費客戶端。

2.    啟動Windows SSH客戶端。設置Host_Name = yourmysqlserver_URL_or_IP。設置userid=your_userid以便登錄伺服器。此userid值可以與您的MySQL帳號的帳號不相同。

3.    設置端口映射。可以進行遠程映射(設置local_port: 3306, remote_host: yourmysqlservername_or_ip, remote_port: 3306)或本地映射(設置port: 3306, host: localhost, remote port: 3306)

4.    進行保存,否則下次需要重設。

5.    剛建立的SSH會話登錄伺服器。

6.    Windows機器上啟動相應ODBC應用程式(例如Access)

7.    Windows中建立一個新的檔案按照常用方法通過ODBC驅動程式連結MySQL,不同的是要為MySQL伺服器輸入localhost,而不是yourmysqlservername

您應有使用SSH加密的ODBC連接到MySQL

5.9. 備份與恢復

本節討論如何進行資料庫備份(完全備份和增量備份),以及如何執行資料表的維護。本節描述的SQL語句語法參見第5章:資料庫管理。此處提供的大多數訊息主要適合MyISAM資料表。InnoDB備份程式參見15.2.8節,「InnoDB資料庫的備份和恢復

5.9.1. 資料庫備份

因為MySQL資料表保存為檔案方式,很容易備份。要想保持備份的一致性,對相關資料表執行LOCK TABLES操作,然後對資料表執行FLUSH TABLES。參見13.4.5節,「LOCK TABLES和UNLOCK TABLES語法」13.5.5.2節,「FLUSH語法」。您只需要讀鎖定;這樣當您複製資料庫目錄中的檔案時,允許其它客戶繼續查詢資料表。需要FLUSH TABLES語句來確保開始備份前將所有激活的索引頁寫入硬盤。

如果您想要進行SQL級別的資料表備份,您可以使用SELECT INTO ...OUTFILEBACKUP TABLE。對於SELECT INTO ...OUTFILE, 輸出的檔案不能先存在。對於BACKUP TABLE也如此,因為覆蓋完整的檔案會有安全風險。參見13.2.7節,「SELECT語法」13.5.2.2節,「BACKUP TABLE語法」

備份資料庫的另一個技術是使用mysqldump程式或mysqlhotcopy指令。參見8.8節,「mysqldump:資料庫備份程式」8.9節,「mysqlhotcopy:資料庫備份程式」

1.    完全備份資料庫:

2.            shell> mysqldump --tab=/path/to/some/dir --opt db_name

或:

shell> mysqlhotcopy db_name /path/to/some/dir

只要伺服器不再進行更新,還可以只複製所有資料表檔案(*.frm*.MYD*.MYI檔案)mysqlhotcopy指令使用該方法。(但請注意如果資料庫包含InnoDB資料表,這些方法不工作。InnoDB不將資料表的內容保存到資料庫目錄中,mysqlhotcopy只適合MyISAM資料表)

3.    如果mysqld在運行則停止,然後用--log-bin[=file_name]選項來啟動。參見5.11.3節,「二進制日誌」。二進制日誌檔案中提供了  執行mysqldump之後對資料庫的更改進行複製所需要的訊息。

對於InnoDB資料表,可以進行線上備份,不需要對資料表進行鎖定;參見8.8節,「mysqldump:資料庫備份程式」

MySQL支援增量備份:需要用--log-bin選項來啟動伺服器以便啟用二進制日誌;參見5.11.3節,「二進制日誌」。當想要進行增量備份時(包含上一次完全備份或增量備份之後的所有更改),應使用FLUSH LOGS回滾二進制日誌。然後,您需要將從最後的完全或增量備份的某個時刻到最後某個點的所有二進制日誌複製到備份位置。這些二進制日誌為增量備份;恢復時,按照下面的解釋應用。下次進行完全備份時,還應使用FLUSH LOGSmysqlhotcopy --flushlogs回滾二進制日誌。參見8.8節,「mysqldump:資料庫備份程式」8.9節,「mysqlhotcopy:資料庫備份程式」

如果MySQL伺服器為從複製伺服器,則無論選擇什麼備份方法,當備份從機數據時,還應備份master.inforelay-log.info檔案。恢復了從機數據後,需要這些檔案來繼續複製。如果從機執行複製LOAD DATA INFILE命令,您應還備份用--slave-load-tmpdir選項指定的目錄中的SQL_LOAD-*檔案。(如果未指定,該位置預設為tmpdir變數值)從機需要這些檔案來繼續複製中斷的LOAD DATA INFILE操作。

如果必須恢復MyISAM資料表,先使用REPAIR TABLEmyisamchk -r來恢復。99.9%的情況下該方法可以工作。如果myisamchk失敗,試試下面的方法。請注意只有用--log-bin選項啟動了MySQL從而啟用二進制日誌它才工作;參見5.11.3節,「二進制日誌」

1.    恢復原mysqldump備份,或二進制備份。

2.    執行下面的命令重新更新二進制日誌:

3.            shell> mysqlbinlog hostname-bin.[0-9]* | mysql

在某些情況下,您可能只想要從某個位置重新運行某些二進制日誌。(通常您想要從恢復備份的日期重新運行所有二進制日誌,查詢不正確時例外)。關於mysqlbinlog工具和如何使用它的詳細訊息參見8.6節,「mysqlbinlog:用於處理二進制日誌檔案的實用工具」

還可以對具體檔案進行選擇備份:

·         要想複製資料表,使用SELECT * INTO OUTFILE 'file_name' FROM tbl_name

·         要想重載資料表,使用LOAD DATA INFILE 'file_name' REPLACE ...並恢復。要避免複製記錄,資料表必須有PRIMARY KEY或一個UNIQUE索引。當新記錄複製唯一鍵值的舊記錄時,REPLACE關鍵字可以將舊記錄替換為新記錄。

如果備份時遇到伺服器性能問題,可以有幫助的一個策略是在從伺服器而不是主伺服器上建立複製並執行備份。參見6.1節,「複製介紹」

如果使用Veritas檔案系統,可以這樣備份:

1.    從客戶端程式執行FLUSH TABLES WITH READ LOCK

2.    從另一個shell執行mount vxfs snapshot

3.    從第一個客戶端執行UNLOCK TABLES

4.    從快照複製檔案。

5.    卸載快照。

5.9.2. 示範用備份與恢復策略

本節討論進行備份的程式,在出現崩潰後,可以恢復數據:

·         作業系統崩潰

·         電源故障

·         檔案系統崩潰

·         硬件問題(硬盤、母板等等)

該命令不包括mysqldumpmysql程式的--userpassword等選項。應包括必要的選項讓MySQL伺服器允許您連接它。

我們假定數據保存在MySQLInnoDB儲存引擎中,支援事務和自動崩潰恢復。我們假定崩潰時MySQL伺服器帶負載。如果不帶負載,則不需要恢復。

出現作業系統崩潰或電源故障時,我們可以假定重啟後硬盤上的MySQLś數據仍可用。由於崩潰,InnoDB數據檔案中的數據可能不再保持一致性,但InnoDB讀取它的日誌並會查到掛起的提交的和未提交的事務清單,它們沒有清空到數據檔案中。InnoDB自動捲回未提交的事務,並清空到它的數據檔案中。通過MySQL錯誤日誌將該恢復過程相關訊息傳達給用戶。下面的例子為日誌摘錄:

InnoDB: Database was not shut down normally.
InnoDB: Starting recovery from log files...
InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 0 13674004
InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
...
InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
InnoDB: 1 uncommitted transaction(s) which must be rolled back
InnoDB: Starting rollback of uncommitted transactions
InnoDB: Rolling back trx no 16745
InnoDB: Rolling back of trx no 16745 completed
InnoDB: Rollback of uncommitted transactions completed
InnoDB: Starting an apply batch of log records to the database...
InnoDB: Apply batch completed
InnoDB: Started
mysqld: ready for connections

如果檔案系統崩潰或出現硬件問題,我們可以假定重啟後硬盤上的MySQLś數據不可用。這說明MySQL未能成功啟動,因為一些硬盤數據塊不再可讀。在這種情況下,需要重新格式化硬盤,安裝一個新的,或糾正問題。然後需要從備份中恢復MySQL數據,這說明我們必須先做好備份。要想確保,應及時返回並設計備份策略。

5.9.2.1. 備份策略

我們都知道必須按計劃定期進行備份。可以用幾個工具完全備份(在某個時間點的數據快照)MySQL。例如,InnoDB Hot BackupInnoDB數據檔案提供線上非數據塊物理備份,mysqldump提供線上邏輯備份。這裡使用mysqldump

假定我們在星期日下午1點進行了備份,此時負荷較低。下面的命令可以完全備份所有資料庫中的所有InnoDB資料表:

shell> mysqldump --single-transaction --all-databases > backup_sunday_1_PM.sql

這是線上非塊備份,不會干擾對資料表的讀寫。我們以前假定我們的資料表為InnoDB資料表,因此--single-transaction使用一致性地讀,並且保證mysqldump所看見的數據不會更改。(其它客戶端對InnoDB資料表進行的更改不會被mysqldump程序看見)如果我們還有其它類型的資料表,我們必須假定在備份過程中它們不會更改。例如,對於mysql資料庫中的MyISAM資料表,我們必須假定在備份過程中沒有對MySQL帳號進行管理更改。

mysqldump命令產生的.sql檔案包含一系列SQL INSERT語句,可以用來重載轉儲的資料表。

需要進行完全備份,但有時不方便。會產生大的備份檔案並需要花時間來生成。從某個角度,完全備份並不理想,因為每個成功的完全備份包括所有數據,甚至自從上一次完全備份以來沒有更改的部分。完成了初使完全備份後,進行增量備份會更有效。這樣備份檔案要小得多,備份時間也較短。不利之處是,恢復時不能只重載完全備份來恢復數據。還必須要用增量備份來恢復增量更改。

要想進行增量備份,我們需要保存增量更改。應使用--log-bin選項啟動MySQL伺服器,以便更新數據時將這些更改保存到檔案中。該選項啟用二進制日誌,因此伺服器寫將每個更新數據的SQL語句寫入MySQL二進制日誌。讓我們看看用--log-bin選項啟動的已經運行多日的MySQL伺服器的數據目錄。我們找到以下MySQL二進制日誌檔案:

-rw-rw---- 1 guilhem  guilhem   1277324 Nov 10 23:59 gbichot2-bin.000001
-rw-rw---- 1 guilhem  guilhem         4 Nov 10 23:59 gbichot2-bin.000002
-rw-rw---- 1 guilhem  guilhem        79 Nov 11 11:06 gbichot2-bin.000003
-rw-rw---- 1 guilhem  guilhem       508 Nov 11 11:08 gbichot2-bin.000004
-rw-rw---- 1 guilhem  guilhem 220047446 Nov 12 16:47 gbichot2-bin.000005
-rw-rw---- 1 guilhem  guilhem    998412 Nov 14 10:08 gbichot2-bin.000006
-rw-rw---- 1 guilhem  guilhem       361 Nov 14 10:07 gbichot2-bin.index

每次重啟,MySQL伺服器用序列中的下一個編號建立一個新的二進制日誌檔案。當伺服器運行時,您還可以通過執行FLUSH LOGS SQL語句或mysqladmin flush-logs命令,告訴伺服器關閉當前的二進制日誌檔案並建立一個新檔案。mysqldump也有一個選項來清空日誌。數據目錄中的.index檔案包含該目錄下所有MySQL二進制日誌的清單。該檔案用於複製。

恢復時MySQL二進制日誌很重要,因為它們是增量備份。如果進行完全備份時確保清空了日誌,則後面建立的二進制日誌檔案包含了備份後的所有數據更改。讓我們稍稍修改前面的mysqldump命令,讓它在完全備份時能夠清空 MySQL二進制日誌,以便轉儲檔案包含包含新的當前的二進制日誌:

shell> mysqldump --single-transaction --flush-logs --master-data=2
           --all-databases > backup_sunday_1_PM.sql

執行該命令後,數據目錄則包含新的二進制日誌檔案,gbichot2-bin.000007。結果.sql檔案包含下列行:

-- Position to start replication or point-in-time 恢復時y from
-- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',MASTER_LOG_POS=4;

因為mysqldump命令可以執行完全備份,這些行資料表示兩件事情:

·         .sql檔案包含所有寫入gbichot2-bin.000007二進制日誌檔案或最新的檔案之前的更改。

·         備份後所記錄的所有數據更改不出現在.sql中,但出現在gbichot2-bin.000007二進制日誌檔案或最新的檔案中。

在星期一下午1點,我們可以清空日誌開始新的二進制日誌檔案來建立增量備份。例如,執行mysqladmin flush-logs命令建立gbichot2-bin.000008。星期日下午1點的完全備份和星期一下午1點之間的所有更改為檔案gbichot2-bin.000007。該增量備份很重要,因此最好將它複製到安全的地方。(例如,備份到磁帶或DVD上,或複製到另一台機器上)在星期二下午1點,執行另一個mysqladmin flush-logs命令。星期一下午1點和星期二下午1點之間的所有所有更改為檔案gbichot2-bin.000008(也應複製到某個安全的地方)

MySQL二進制日誌佔據硬盤空間。要想釋放空間,應隨時清空。操作方法是刪掉不再使用的二進制日誌,例如進行完全備份時:

shell> mysqldump --single-transaction --flush-logs --master-data=2
           --all-databases --delete-master-logs > backup_sunday_1_PM.sql

釋:如果您的伺服器為複製主伺服器,用mysqldump --delete-master-logs刪掉MySQL二進制日誌很危險,因為從伺服器可能還沒有完全處理該二進制日誌的內容。

PURGE MASTER LOGS語句的描述中解釋了為什麼在刪掉MySQL二進制日誌之前應進行確認。參見13.6.1.1節,「PURGE MASTER LOGS語法」

5.9.2.2. 為恢復進行備份

現在假設在星期三上午8點出現了災難性崩潰,需要使用備份檔案進行恢復。恢復時,我們首先恢復最後的完全備份(從星期日下午1點開始)。完全備份檔案是一系列SQL語句,因此恢復它很容易:

shell> mysql < backup_sunday_1_PM.sql

在該點,數據恢復到星期日下午1點的狀態。要想恢復從那時起的更改,我們必須使用增量備份,也就是,gbichot2-bin.000007gbichot2-bin.000008二進制日誌檔案。根據需要從備份處取過這些檔案,然後按下述方式處理:

shell> mysqlbinlog gbichot2-bin.000007 gbichot2-bin.000008 | mysql

我們現在將數據恢復到星期二下午1點的狀態,但是從該時刻到崩潰之間的數據仍然有丟失。要想恢復,我們需要MySQL伺服器將MySQL二進制日誌保存到安全的位置(RAID disks, SAN, ...),應為與數據檔案的保存位置不同的地方,保證這些日誌不在毀壞的硬盤上。(也就是,我們可以用--log-bin選項啟動伺服器,指定一個其它物理設備上的與數據目錄不同的位置。這樣,即使包含該目錄的設備丟失,日誌也不會丟失)如果我們執行了這些操作,我們手頭上會有gbichot2-bin.000009檔案,我們可以用它來恢復大部分最新的數據更改,而不會丟失到崩潰時的數據。

5.9.2.3. 備份策略摘要

出現作業系統崩潰或電源故障時,InnoDB自己可以完成所有數據恢復工作。但為了確保您可以睡好覺,應遵從下面的指導:

·         一定用--log-bin或甚至--log-bin=log_name選項運行MySQL伺服器,其中日誌檔案名位於某個安全媒介上,不同於數據目錄所在驅動器。如果您有這樣的安全媒介,最好進行硬盤負載均衡(這樣能夠提高性能)

·         定期進行完全備份,使用mysqldump命令進行線上非塊備份。

·         FLUSH LOGSmysqladmin flush-logs清空日誌進行定期增量備份。

5.9.3. 自動恢復

如果MySQL伺服器啟用了二進制日誌,您可以使用mysqlbinlog工具來恢復從指定的時間點開始 (例如,從您最後一次備份)直到現在或另一個指定的時間點的數據。關於啟用二進制日誌的訊息,參見5.11.3節,「二進制日誌」。對於mysqlbinlog的詳細訊息,參見8.6節,「mysqlbinlog:用於處理二進制日誌檔案的實用工具」

要想從二進制日誌恢復數據,您需要知道當前二進制日誌檔案的路徑和檔案名。一般可以從選項檔案(my.cnf or my.ini,取決於您的系統)中找到路徑。如果未包含在選項檔案中,當伺服器啟動時,可以在命令行中以選項的形式給出。啟用二進制日誌的選項為--log-bin。要想確定當前的二進制日誌檔案的檔案名,輸入下面的MySQL語句:

SHOW BINLOG EVENTS \G

您還可以從命令行輸入下面的內容:

mysql --user=root -pmy_pwd -e 'SHOW BINLOG EVENTS \G'

將密碼my_pwd替換為伺服器的root密碼。

5.9.3.1. 指定恢復時間

對於MySQL 4.1.4,可以在mysqlbinlog語句中通過--start-date--stop-date選項指定DATETIME格式的起止時間。舉例說明,假設在今天上午10:00(今天是2005420),執行SQL語句來刪除一個大資料表。要想恢復資料表和數據,您可以恢復前晚上的備份,並輸入:
mysqlbinlog --stop-date="2005-04-20 9:59:59" /var/log/mysql/bin.123456 \
     | mysql -u root -pmypwd

該命令將恢復截止到在--stop-date選項中以DATETIME格式給出的日期和時間的所有數據。如果您沒有檢測到幾個小時後輸入的錯誤的SQL語句,可能您想要恢復後面發生的活動。根據這些,您可以用起使日期和時間再次運行mysqlbinlog

mysqlbinlog --start-date="2005-04-20 10:01:00" /var/log/mysql/bin.123456 \
     | mysql -u root -pmypwd \

在該行中,從上午10:01登錄的SQL語句將運行。組合執行前夜的轉儲檔案和mysqlbinlog的兩行可以將所有數據恢復到上午10:00前一秒鐘。您應檢查日誌以確保時間確切。下一節介紹如何實現。

5.9.3.2. 指定恢復位置

也可以不指定日期和時間,而使用mysqlbinlog的選項--start-position--stop-position來指定日誌位置。它們的作用與起止日選項相同,不同的是給出了從日誌起的位置號。使用日誌位置是更準確的恢復方法,特別是當由於破壞性SQL語句同時發生許多事務的時候。要想確定位置號,可以運行mysqlbinlog尋找執行了不期望的事務的時間範圍,但應將結果重新指向文本檔案以便進行檢查。操作方法為:
mysqlbinlog --start-date="2005-04-20 9:55:00" --stop-date="2005-04-20 10:05:00" \
      /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql

該命令將在/tmp目錄建立小的文本檔案,將顯示執行了錯誤的SQL語句時的SQL語句。您可以用文本編輯器打開該檔案,尋找您不要想重複的語句。如果二進制日誌中的位置號用於停止和繼續恢復操作,應進行註釋。用log_pos加一個數字來標記位置。使用位置號恢復了以前的備份檔案後,您應從命令行輸入下面內容:

mysqlbinlog --stop-position="368312" /var/log/mysql/bin.123456 \
    | mysql -u root -pmypwd 
 
mysqlbinlog --start-position="368315" /var/log/mysql/bin.123456 \
    | mysql -u root -pmypwd \ 

上面的第1行將恢復到停止位置為止的所有事務。下一行將恢復從給定的起始位置直到二進制日誌結束的所有事務。因為mysqlbinlog的輸出包括每個SQL語句記錄之前的SET TIMESTAMP語句,恢復的數據和相關MySQL日誌將反應事務執行的原時間。

5.9.4. 資料表維護和崩潰恢復

後面幾節討論如何使用myisamchk來檢查或維護MyISAM資料表(對應.MYI.MYD檔案的資料表)

您可以使用myisamchk實用程式來獲得有關您的資料庫資料表的訊息或檢查、修復、最佳化他們。下列小節描述如何使用myisamchk(包括它的選項的描述),如何建立資料表的維護計劃,以及如何使用myisamchk執行各種功能。

儘管用myisamchk修復資料表很安全,在修復(或任何可以大量更改資料表的維護操作)之前先進行備份也是很好的習慣

影響索引的myisamchk操作會使ULLTEXT索引用full-text參數重建,不再與MySQL伺服器使用的值兼容。要想避免,請閱讀5.9.5.1節,「用於myisamchk的一般選的說明。

在許多情況下,您會發現使用SQL語句實現MyISAM資料表的維護比執行myisamchk操作要容易地多:

·         要想檢查或維護MyISAM資料表,使用CHECK TABLEREPAIR TABLE

·         要想最佳化MyISAM資料表,使用OPTIMIZE TABLE

·         要想分析MyISAM資料表,使用ANALYZE TABLE

可以直接這些語句,或使用mysqlcheck客戶端程式,可以提供命令行接口。

這些語句比myisamchk有利的地方是伺服器可以做任何工作。使用myisamchk,您必須確保伺服器在同一時間不使用資料表。否則,myisamchk和伺服器之間會出現不期望的相互干涉。

5.9.5. myisamchk:MyISAM資料表維護實用工具

可以使用myisamchk實用程式來獲得有關資料庫資料表的訊息或檢查、修復、最佳化他們。myisamchk適用MyISAM資料表(對應.MYI.MYD檔案的資料表)

使用myisamchk的方法:

shell> myisamchk [options] tbl_name ...

options指定您想讓myisamchk做什麼。在後面描述它們。還可以通過使用myisamchk --help得到選項列資料表。

tbl_name是您想要檢查或修復的資料庫資料表。如果您不在資料庫目錄的某處運行myisamchk,您必須指定資料庫目錄的路徑,因為myisamchk不知道您的資料庫位於哪兒。實際上,myisamchk不在乎您正在操作的檔案是否位於一個資料庫目錄;您可以將對應於資料庫資料表的檔案拷貝到別處並且在那裡執行恢復操作。

如果您願意,可以用myisamchk命令行命名幾個資料表。還可以通過命名索引檔案( .MYI後綴)來指定一個資料表。它允許您通過使用模式*.MYI指定在一個目錄所有的資料表。例如,如果您在資料庫目錄,可以這樣在目錄下檢查所有的MyISAM資料表:

shell> myisamchk *.MYI

如果您不在資料庫目錄下,可通過指定到目錄的路徑檢查所有在那裡的資料表:

shell> myisamchk /path/to/database_dir/*.MYI

您甚至可以通過為MySQL數據目錄的路徑指定一個通配符來檢查所有的資料庫中的所有資料表:

shell> myisamchk /path/to/datadir/*/*.MYI

推薦的快速檢查所有MyISAM資料表的方式是:

shell> myisamchk --silent --fast /path/to/datadir/*/*.MYI

如果您想要檢查所有MyISAM資料表並修復任何破壞的資料表,可以使用下面的命令:

shell> myisamchk --silent --force --fast --update-state \
          -O key_buffer=64M -O sort_buffer=64M \
          -O read_buffer=1M -O write_buffer=1M \
          /path/to/datadir/*/*.MYI

該命令假定您有大於64MB的自由內存。關於用myisamchk分配內存的詳細訊息,參見5.9.5.5節,「myisamchk內存使用」

當您運行myisamchk時,必須確保其它程式不使用資料表。否則,當您運行myisamchk時,會顯示下面的錯誤消息:

warning: clients are using or haven't closed the table properly

這說明您正嘗試檢查正被另一個還沒有關閉檔案或已經終止而沒有正確地關閉檔案的程式(例如mysqld伺服器)更新的資料表。

如果mysqld正在運行,您必須通過FLUSH TABLES強制清空仍然在內存中的任何資料表修改。當您運行myisamchk時,必須確保其它程式不使用資料表。避免該問題的最容易的方法是使用CHECK TABLE而不用myisamchk來檢查資料表。

5.9.5.1. 用於myisamchk的一般選

本節描述的選項可以用於用myisamchk執行的任何類型的資料表維護操作。本節後面的章節中描述的選項只適合具體操作,例如檢查或修復資料表。

·         --help-?

顯示幫助消息並退出。

·         --debug=debug_options, -# debug_options

輸出調試記錄檔案。debug_options字串經常是'd:t:o,filename'

·         --silent-s

沉默模式。僅當發生錯誤時寫輸出。您能使用-s兩次(-ss)使myisamchk沉默。

·         --verbose-v

冗長模式。打印更多的訊息。這能與-d-e一起使用。為了更冗長,使用-v多次(-vv, -vvv)

·         --version, -V

顯示版本訊息並退出。

·         --wait, -w

如果資料表被鎖定,不是提示錯誤終止,而是在繼續前等待到資料表被解鎖。請注意如果用--skip-external-locking選項運行mysqld,只能用另一個myisamchk命令鎖定資料表。

還可以通過--var_name=value選項設置下面的變數:

變數

預設值

decode_bits

9

ft_max_word_len

取決於版本

ft_min_word_len

4

ft_stopword_file

內建列資料表

key_buffer_size

523264

myisam_block_size

1024

read_buffer_size

262136

sort_buffer_size

2097144

sort_key_blocks

16

stats_method

nulls_unequal

write_buffer_size

262136

可以用myisamchk --help檢查myisamchk變數及其 預設值:

當用排序鍵值修復鍵值時使用sort_buffer_size,使用--recover時這是很普通的情況。

當用--extend-check檢查資料表或通過一行一行地將鍵值插入資料表中(如同普通插入)來修改鍵值時使用Key_buffer_size。在以下情況通過鍵值緩衝區進行修復:

·         使用--safe-recover

·         當直接建立鍵值檔案時,需要對鍵值排序的臨時檔案有兩倍大。通常是當CHARVARCHAR、或TEXT列的鍵值較大的情況,因為排序操作在處理過程中需要保存全部鍵值。如果您有大量臨時空間,可以通過排序強制使用myisamchk來修復,可以使用--sort-recover選項。

通過鍵值緩衝區的修復佔用的硬盤空間比使用排序麼少,但是要慢。

如果想要快速修復,將key_buffer_sizesort_buffer_size變數設置到大約可用內存的25%。可以將兩個變數設置為較大的值,因為一個時間只使用一個變數。

myisam_block_size是用於索引塊的內存大小。

stats_method影響當給定--analyze選項時,如何為索引統計搜集處理NULL值。它如同myisam_stats_method系統變數。詳細訊息參見5.3.3節,「伺服器系統變數」7.4.7節,「MyISAM索引統計集合」myisam_stats_method的描述。

ft_min_word_lenft_max_word_len資料表示FULLTEXT索引的最小和最大字長。ft_stopword_file為停止字檔案的檔案名。需要在以下環境中對其進行設置。

如果您使用myisamchk來修改資料表索引(例如修復或分析),使用最小和最大字長和停止字檔案的 預設全文參數值(除非您另外指定)重建FULLTEXT索引。這樣會導致查詢失敗。

出現這些問題是因為只有伺服器知道這些參數。它們沒有保存在MyISAM索引檔案中。如果您修改了伺服器中的最小或最大字長或停止字檔案,要避免該問題,為用於mysqldmyisamchk指定相同的ft_min_word_lenft_max_word_lenft_stopword_file值。例如,如果您將最小字長設置為3,可以這樣使用myisamchk來修復資料表:

shell> myisamchk --recover --ft_min_word_len=3 tbl_name.MYI

要想確保myisamchk和伺服器使用相同的全文參數值,可以將它們放入選項檔案的[mysqld][myisamchk]小節:

[mysqld]
ft_min_word_len=3
 
[myisamchk]
ft_min_word_len=3

除了myisamchk,還可以使用REPAIR TABLEANALYZE TABLEOPTIMIZE TABLEALTER TABLE。這些語句由伺服器執行,知道要使用的正確的全文參數值。

5.9.5.2. 用於myisamchk的檢查選項

myisamchk支援下面的資料表檢查操作選項:

·         --check, -c

檢查資料表的錯誤。如果您不明確指定操作類型選項,這就是預設操作。

·         --check-only-changed, -C

只檢查上次檢查後有變更的資料表。

·         --extend-check, -e

非常仔細地檢查資料表。如果資料表有許多索引將會相當慢。該選項只能用於極端情況。一般情況下,可以使用myisamchkmyisamchk --medium-check來確定資料表內是否有錯誤。

如果您使用了--extend-check並且有充分的內存,將key_buffer_size變數設置為較大的值可以使修復操作運行得更快。

·         --fast-F

只檢查沒有正確關閉的資料表。

·         --force, -f

如果myisamchk發現資料表內有任何錯誤,則自動進行修復。維護類型與--repair-r選項指定的相同。

·         --information, -i

打印所檢查資料表的統計訊息。

·         --medium-check, -m

--extend-check更快速地進行檢查。只能發現99.99%的錯誤,在大多數情況下就足夠了。

·         --read-only, -T

不要將資料表標記為已經檢查。如果您使用myisamchk來檢查正被其它應用程式使用而沒有鎖定的資料表很有用,例如當用--skip-external-locking選項運行時運行mysqld

·         --update-state, -U

將訊息保存在.MYI檔案中,來資料表示資料表檢查的時間以及是否資料表崩潰了。該選項用來充分利用--check-only-changed選項,但如果mysqld伺服器正使用資料表並且正用--skip-external-locking選項運行時不應使用該選項。

5.9.5.3. myisamchk的修復選項

myisamchk支援下面的資料表修復操作的選項:

·         --backup, -B

.MYD檔案備份為file_name-time.BAK

·         --character-sets-dir=path

字元編碼安裝目錄。參見5.10.1節,「數據和排序用字元編碼」

·         --correct-checksum

糾正資料表的校驗和訊息。

·         --data-file-length=len, -D len

數據檔案的最大長度(當重建數據檔案且為「滿」時)

·         --extend-check-e

進行修復,試圖從數據檔案恢復每一行。一般情況會發現大量的垃圾行。不要使用該選項,除非您不顧後果。

·         --force, -f

覆蓋舊的中間檔案(檔案名類似tbl_name.TMD),而不是中斷。

·         --keys-used=val, -k val

對於myisamchk,該選項值為位值,說明要更新的索引。選項值的每一個二進制位對應資料表的一個索引,其中第一個索引對應位0。選項值0禁用對所有索引的更新,可以保證快速插入。通過myisamchk -r可以重新激活被禁用的索引。

·         --no-symlinks, -l

不跟隨符號連接。通常myisamchk修復一個符號連接所指的資料表。在MySQL 4.0中該選項不存在,因為從4.0開始的版本在修復過程中不移除符號連結。

·         --parallel-recover, -p

-r-n的用法相同,但使用不同的線程並行建立所有鍵。這是alpha代碼。自己承擔風險!

·         --quick-q

不修改數據檔案,快速進行修復。出現複製鍵時,您可以兩次指定該項以強制myisamchk修改原數據檔案。

·         --recover, -r

可以修復幾乎所有一切問題,除非唯一的鍵不唯一時(對於MyISAM資料表,這是非常不可能的情況)。如果您想要恢復資料表,這是首先要嘗試的選項。如果myisamchk報告資料表不能用-r恢復,則只能嘗試-o。在不太可能的情況下-r失敗,數據檔案保持完好)

如果您有大量內存,您應增加sort_buffer_size的值

·         --safe-recover, -o

使用一個老的恢復方法讀取,按順序讀取所有行,並根據找到的行更新所有索引樹。這比-r慢些,但是能處理-r不能處理的情況。該恢復方法使用的硬盤空間比-r少。一般情況,您應首先用-r維修,如果-r失敗則用-o

如果您有大量內存,您應增加sort_buffer_size的值

·         (OBSOLETE) --set-character-set=name

MySQL 5.1中不使用。參見--set-collation

·         --set-collation=name

更改用來排序資料表索引的校對規則。校對規則名的第一部分包含字元編碼名。

·         --sort-recover, -n

強制myisamchk通過排序來解析鍵值,即使臨時檔案將可能很大。

·         --tmpdir=path, -t path

用於保存臨時檔案的目錄的路徑。如果未設置,myisamchk使用TMPDIR環境變數的值。tmpdir可以設置為一系列目錄路徑,用於成功地以round-robin模式建立臨時檔案。在Unix中,目錄名之間的間隔字元為冒號(:),在WindowsNetWareOS/2中為分號 ()

·         --unpack-u

將用myisampack打包的資料表解包。

5.9.5.4. 用於myisamchk的其它選項

myisamchk支援以下資料表檢查和修復之外的其它操作的選項:

·         --analyze-a

分析鍵值的分佈。這通過讓聯結最佳化器更好地選擇資料表應該以什麼次序聯結和應該使用哪個鍵來改進聯結性能。要想獲取分佈相關訊息,使用myisamchk --description --verbose tbl_name命令或SHOW KEYS FROM tbl_name語句。

·         --description, -d

打印出關於資料表的描述性訊息。

·         --set-auto-increment[=value], -A[value]

強制從給定值開始的新記錄使用AUTO_INCREMENT編號(或如果已經有AUTO_INCREMENT值大小的記錄,應使用更高值)。如果未指定value,新記錄的AUTO_INCREMENT編號應使用當前資料表的最大值加上1

·         --sort-index, -S

以從高到低的順序排序索引樹塊。這將最佳化搜尋並且將使按鍵值的資料表掃瞄更快。

·         --sort-records=N, -R N

根據一個具體索引排序記錄。這使您的數據更局部化並且可以加快在該鍵上的SELECTORDER BY的範圍搜索。(第一次做排序可能很慢!)為了找出一張資料表的索引編號,使用SHOW INDEX,它以myisamchk看見他們的相同順序顯示一張資料表的索引。索引從1開始編號。

如果鍵沒有打包(PACK_KEYS=0),它們的長度相同,因此當myisamchk 排序並移動記錄時,只覆蓋索引中的記錄偏移量。如果鍵已經打包(PACK_KEYS=1)myisamchk必須先解開打包的鍵塊,然後重新建立索引並再次將鍵塊打包。(在這種情況下,重新建立索引比更新每個索引的偏移量要快)

5.9.5.5. myisamchk內存使用

當您運行myisamchk時內存分配重要.MYIsamchk使用的內存大小不能超過用-O選項指定的。如果您想對每一個大資料表使用myisamchk,您必須首先確定您想使用多少內存。修復時可以使用的 預設值只有3MB。使用更大的內存,可以讓myisamchk工作得更快一些。例如,如果有大於32MBRAM,可以使用如下所示選項(除了您可以指定的其它選項)

shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...

對於大多數情況,使用-O sort=16M應該足夠了。

應記住myisamchk使用TMPDIR中的臨時檔案。如果TMPDIR指向內存檔案系統,您可能很容易得到內存溢出的錯誤。如果發生,設定TMPDIR指向有更多空間的檔案系統目錄並且重啟myisamchk

修復時myisamchk也需要大量硬盤空間:

·         將數據檔案大小擴大一倍(原檔案和複製檔案)。如果您用--quick修復則不需要該空間;在這種情況下,只重新建立了索引檔案。在檔案系統上需要的空間與原數據檔案相同!(建立的複製檔案位於原檔案所在目錄)

·         代替舊索引檔案的新索引檔案所佔空間。修復工作一開始,就對舊索引檔案進行了刪減,因此您通常會忽略該空間。在檔案系統上需要的該空間與原數據檔案相同!

·         當使用--recover---sort-recover(但不使用--safe-recover)時,需要排序緩衝區空間。需要的空間為:

·                (largest_key + row_pointer_length) * number_of_rows * 2

可以用myisamchk -dv tbl_name檢查鍵值和row_pointer_length的長度。在臨時目錄分配該空間(TMPDIR--tmpdir=path指定)

如果在修復過程中出現硬盤空間問題,可以試試用--safe-recover代替--recover

5.9.5.6. 將myisamchk用於崩潰恢

如果用--skip-external-locking運行mysqld(在某些系統上為 預設設置,例如Linux),當mysqld使用某個資料表時,您不能可靠地使用myisamchk來檢查相同的資料表。當您運行myisamchk時如果可以確保沒有人在通過mysqld訪問資料表,在開始檢查資料表前,您只需要運行mysqladmin flush-tables。如果您不能保證,則您檢查資料表時您必須停止mysqld。如果mysqld更新資料表時運行myisamchk,您可能會獲得資料表被破壞的警告,即使事實並非如此。

如果不使用--skip-external-locking,可以隨時使用myisamchk來檢查資料表。當檢查資料表時,所有嘗試更新資料表的客戶端將等待,直到myisamchk準備好可以繼續。

如果使用myisamchk來修復或最佳化資料表,必須確保mysqld伺服器沒有在使用該資料表(如果您正使用--skip-external-locking選項也適用)。如果不關閉mysqld,在運行myisamchk之前至少應執行mysqladmin flush-tables。如果伺服器和myisamchk同時訪問資料表,資料表可能會被破壞

本節描述如何檢查和處理MySQL資料庫中的數據破壞。如果資料表經常被破壞,您應盡力找到原因。參見A.4.2節,「如果MySQL依然崩潰,應作些什麼」

關於MyISAM資料表怎樣會被破壞的解釋,參見15.1.4節,「MyISAM資料表方面的問題」

在執行崩潰恢復時,理解在一個資料庫中的每一個MyISAM資料表tbl_name對應的在資料庫目錄中的3個檔案是很重要的:

檔案

目的

tbl_name.frm

定義(格式)檔案

tbl_name.MYD

數據檔案

tbl_name.MYI

索引檔案

3類檔案的每一類都可能遭受不同形式的損壞,但是問題最常發生在數據檔案和索引檔案。

myisamchk通過一行一行地建立一個.MYD數據檔案的副本來工作,它通過刪除舊的.MYD 檔案並且重命名新檔案到原來的檔案名結束修復階段。如果您使用--quickmyisamchk不建立一個臨時.MYD檔案,只是假定.MYD檔案是正確的並且僅建立一個新的索引檔案,不接觸.MYD檔案,這是安全的,因為myisamchk自動檢測.MYD檔案是否損壞並且在這種情況下,放棄修復。您也可以給myisamchk兩個--quick選項。在這種情況下,myisamchk不會在一些錯誤上(象重複鍵)放棄,相反試圖通過修改.MYD檔案解決它們。通常,只有在太少的空閒磁盤空間上實施正常修復,使用兩個--quick選項時才有用。在這種情況下,您至少應該在運行myisamchk前做進行備份。

5.9.5.7. 如何檢查MyISAM資料表的錯誤

要想檢查MyISAM資料表,應使用下面的命令:

·         myisamchk tbl_name

這樣能找出99.99%的錯誤。它不能找出的是僅僅涉及數據檔案的損壞(這很不常見)。如果想要檢查一張資料表,通常應該沒有選項地運行myisamchk或用-s--silent選項的任何一個。

·         myisamchk -m tbl_name

這樣能找出99.99%的錯誤。它首先檢查所有索引條目的錯誤並通讀所有行。它還計算行內所有鍵值的校驗和,並確認校驗和與索引樹內鍵的校驗和相匹配。

·         myisamchk -e tbl_name

可以完全徹底地檢查數據(-e意思是「延伸檢查」)。它對每一行做每個鍵的讀檢查以證實它們確實指向正確的行。這在一個有很多鍵的大資料表上可能花很長時間。myisamchk通常將在它發現第一個錯誤以後停止。如果您想要獲得更多的訊息,可以增加--verbose(-v)選項。這使得myisamchk繼續一直到最多20個錯誤。

·         myisamchk -e -i tbl_name

象前面的命令一樣,但是-i選項告訴myisamchk還打印出一些統計訊息。

在一般使用中,一個簡單的myisamchk(沒有除資料表名以外的參數)就足夠檢查資料表了。

5.9.5.8. 如何修復資料表

本節描述如何對MyISAM資料表使用myisamchk(延伸名.MYI.MYD)

您還可以(並且應該,如果可能)使用CHECK TABLEREPAIR TABLE語句來檢查和修復MyISAM資料表。參見13.5.2.3節,「CHECK TABLE語法」13.5.2.6節,「REPAIR TABLE語法」

一張損壞的資料表的症狀通常是查詢意外中斷並且能看到下述錯誤:

  • tbl_name.frm被鎖定不能更改。
  • 不能找到檔案tbl_name.MYIErrcodennn)。
  • 檔案意外結束。
  • 記錄檔案被毀壞。
  • 從資料表處理器得到錯誤nnn

要想得到錯誤相關的詳細訊息,您可以運行perror nnn,其中nnn為錯誤編號。下面的示範顯示了如何使用perror來找到最常用錯誤編號(用資料表的方式指出問題)的含義:

shell> perror 126 127 132 134 135 136 141 144 145
126 = Index file is crashed / Wrong file format
127 = Record-file is crashed
132 = Old database file
134 = Record was already deleted (or record file crashed)
135 = No more room in record file
136 = No more room in index file
141 = Duplicate unique key or constraint on write or update
144 = Table is crashed and last repair failed

145 = Table was marked as crashed and should be repaired

請注意錯誤135(記錄檔案中沒有更多的空間)和錯誤136(索引檔案中沒有更多的空間)不是可以通過簡單修復可以修復的錯誤。在這種情況下,必須使用ALTER TABLE來增加MAX_ROWSAVG_ROW_LENGTH資料表選項值:

ALTER TABLE tbl_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;

如果您不知道當前的資料表的選項值,使用SHOW CREATE TABLEDESCRIBE來查詢

對於其它的錯誤,您必須修復資料表。myisamchk通常可以檢測和修復大多數問題。

修復過程包括四個階段,此處將進行描述。開始修復前,應進入資料庫目錄並檢查資料表檔案的授權。在Unix中,確保它們對於運行mysqld用戶可讀(您也應可讀,因為您需要訪問檢查的檔案)。如果您需要修改檔案,您還必須擁有寫訪問權限。

myisamchk修復資料表的選項的描述參見5.9.5節,「myisamchk:MyISAM資料表維護實用工具」的前幾節。

下面幾節列出了上述命令失敗或您想要使用myisamchk提供的延伸特性等情況的例子。

如果您要通過命令行來修復資料表,必須首先停止mysqld伺服器。請注意當您在遠程伺服器上運行mysqladmin shutdown時,mysqladmin返回後,mysqld伺服器將仍然運行一會兒,直到停止所有查詢並將所有鍵清空到硬盤上。

階段1:檢查您的資料表

如果您有很多時間,運行myisamchk *.MYImyisamchk -e *.MYI。使用-s(沉默)選項禁止不必要的訊息。

如果mysqld伺服器處於宕機狀態,應使用--update-state選項來告訴myisamchk將資料表標記為'檢查過的'

您必須只修復那些myisamchk報告有錯誤的資料表。對這樣的資料表,繼續到階段2

如果在檢查時,您得到奇怪的錯誤(例如out of memory錯誤),或如果myisamchk崩潰,到階段3

階段2:簡單安全的修復

註釋:如果想更快地進行修復,當運行myisamchk時,您應將sort_buffer_sizeKey_buffer_size變數的值設置為可用內存的大約25%

首先,試試myisamchk -r -q tbl_name(-r -q意味著「快速恢復模式」)。這將試圖不接觸數據檔案來修復索引檔案。如果數據檔案包含它應有的一切內容和指向數據檔案內正確地點的刪除連接,這應該管用並且資料表可被修復。開始修復下一張資料表。否則,執行下列過程:

  1. 在繼續前對數據檔案進行備份。
  2. 使用myisamchk -r tbl_name(-r意味著「恢復模式」)。這將從數據檔案中刪除不正確的記錄和已被刪除的記錄並重建索引檔案。
  3. 如果前面的步驟失敗,使用myisamchk --safe-recover tbl_name。安全恢復模式使用一個老的恢復方法,處理常規恢復模式不行的少數情況(但是更慢)

如果在修復時,您得到奇怪的錯誤(例如out of memory錯誤),或如果myisamchk崩潰,到階段3

階段3:困難的修復

只有在索引檔案的第一個16K塊被破壞,或包含不正確的訊息,或如果索引檔案丟失,您才應該到這個階段。在這種情況下,需要建立一個新的索引檔案。按如下步驟操做:

  1. 把數據檔案移到安全的地方。
  2. 使用資料表描述檔案建立新的()數據檔案和索引檔案:
  3. shell> mysql db_name
  4. mysql> SET AUTOCOMMIT=1;
  5. mysql> TRUNCATE TABLE tbl_name;
  6. mysql> quit

如果您的MySQL版本沒有TRUNCATE TABLE,則使用DELETE FROM tbl_name

  1. 將老的數據檔案拷貝到新建立的數據檔案之中。(不要只是將老檔案移回新檔案之中;您要保留一個副本以防某些東西出錯。)

回到階段2。現在myisamchk -r -q應該工作了。(這不應該是一個無限循環)。

您還可以使用REPAIR TABLE tbl_name USE_FRM,將自動執行整個程式。

階段4:非常困難的修復

只有.frm描述檔案也破壞了,您才應該到達這個階段。這應該從未發生過,因為在資料表被建立以後,描述檔案就不再改變了。

  1. 從一個備份恢復描述檔案然後回到階段3。您也可以恢復索引檔案然後回到階段2。對後者,您應該用myisamchk -r啟動。
  2. 如果您沒有進行備份但是確切地知道資料表是怎樣建立的,在另一個資料庫中建立資料表的一個拷貝。刪除新的數據檔案,然後從其他資料庫將描述檔案和索引檔案移到破壞的資料庫中。這樣提供了新的描述和索引檔案,但是讓.MYD數據檔案獨自留下來了。回到階段2並且嘗試重建索引檔案。

5.9.5.9. 資料表最佳化

為了組合碎片記錄並且消除由於刪除或更新記錄而浪費的空間,以恢復模式運行myisamchk

shell> myisamchk -r tbl_name

您可以用SQLOPTIMIZE TABLE語句使用的相同方式來最佳化資料表,OPTIMIZE TABLE可以修復資料表並對鍵值進行分析,並且可以對索引樹進行排序以便更快地搜尋鍵值。實用程式和伺服器之間不可能交互操作,因為當您使用OPTIMIZE TABLE時,伺服器做所有的工作。參見13.5.2.5節,「OPTIMIZE TABLE語法」

myisamchk還有很多其它可用來提高資料表的性能的選項:

·         -S, --sort-index

·         -R index_num, --sort-records=index_num

·         -a, --analyze

關於這些選項的完整的描述,參見5.9.5節,「myisamchk:MyISAM資料表維護實用工具」

5.9.6. 建立資料表維護計劃

定期對資料表進行檢查而非等到問題出現後再檢查資料庫資料表是一個好主意。檢查和修復MyISAM資料表的一個方式是使用CHECK TABLEREPAIR TABLE語句。參見13.5.2.3節,「CHECK TABLE語法」13.5.2.6節,「REPAIR TABLE語法」

檢查資料表的另一個方法是使用myisamchk。為維護目的,可以使用myisamchk -s檢查資料表。-s選項(簡稱--silent)使myisamchk以沉默模式運行,只有當錯誤出現時才打印消息。

在伺服器啟動時檢查資料表是一個好主意。例如,無論何時機器在更新當中重新啟動了,您通常需要檢查所有可能受影響的資料表。(即「預期的破壞了的資料表」)。要想自動檢查MyISAM資料表,用--myisam-recover選項啟動伺服器。

一個更好的測試將是檢查最後修改時間比.pid檔案新的資料表。

您還應該在正常系統操作期間定期檢查資料表。在MySQL AB,我們運行一個cron任務,每週一次檢查所有重要的資料表,使用crontab檔案中這樣的行:

35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI

可以打印損壞的資料表的訊息,以便我們在需要時能夠檢驗並且修復它們。

多年了我們還沒有發現(的確是真的)都沒有任何意外損壞的資料表時(由於除硬件故障外的其它原因造成損壞的資料表),每週一次對我們是足夠了。

我們建議現在開始,您對所有最後24小時內被更新了的資料表每晚都執行myisamchk -s,直到您變得像我們那樣信任MySQL

一般情況,MySQL資料表很少需要維護。如果您用動態大小的行更改MyISAM資料表(VARCHARBLOBTEXT列的資料表)或有刪除了許多行的資料表,您可能想要不時地(每月一次)整理/組合資料表的空間。

可以對有問題的資料表執行OPTIMIZE TABLE來最佳化。或者是,如果可以停一會mysqld伺服器,進入數據目錄,當伺服器停止時使用該命令:

shell> myisamchk -r -s --sort-index -O sort_buffer_size=16M */*.MYI

5.9.7. 獲取關於資料表的訊息

為了獲得關於一個資料表的描述或統計,使用下面的命令:

·         myisamchk -d tbl_name

以「描述模式」運行myisamchk,生成資料表的描述。如果用--skip-external-locking選項啟動MySQL伺服器,myisamchk可以報告運行的資料表被更新的錯誤。然而,既然在描述模式中myisamchk不更改資料表,沒有任何破壞數據的風險。

·         myisamchk -d -v tbl_name

為了生成更多關於myisamchk正在做什麼的訊息,加上-v告訴它以冗長模式運行。

·         myisamchk -eis tbl_name

僅顯示資料表的最重要的訊息。因為必須讀取整個資料表,該操作很慢。

·         myisamchk -eiv tbl_name

這類似 -eis,只是告訴您正在做什麼。

下面為這些命令的輸出示範。它們基於含這些數據和索引檔案大小的資料表:

-rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.MYD
-rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 company.MYM

myisamchk -d輸出示範:

MyISAM file:     company.MYI
Record format:   Fixed length
Data records:    1403698  Deleted blocks:         0
Recordlength:    226
 
table description:
Key Start Len Index   Type
1   2     8   unique  double
2   15    10  multip. text packed stripped
3   219   8   multip. double
4   63    10  multip. text packed stripped
5   167   2   multip. unsigned short
6   177   4   multip. unsigned long
7   155   4   multip. text
8   138   4   multip. unsigned long
9   177   4   multip. unsigned long
    193   1           text

myisamchk -d -v 輸出示範:

MyISAM file:         company
Record format:       Fixed length
File-version:        1
Creation time:       1999-10-30 12:12:51
Recover time:        1999-10-31 19:13:01
Status:              checked
Data records:            1403698  Deleted blocks:              0
Datafile parts:          1403698  Deleted data:                0
Datafile pointer (bytes):      3  Keyfile pointer (bytes):     3
Max datafile length:  3791650815  Max keyfile length: 4294967294
Recordlength:                226
 
table description:
Key Start Len Index   Type                  Rec/key     Root Blocksize
1   2     8   unique  double                      1 15845376      1024
2   15    10  multip. text packed stripped        2 25062400      1024
3   219   8   multip. double                     73 40907776      1024
4   63    10  multip. text packed stripped        5 48097280      1024
5   167   2   multip. unsigned short           4840 55200768      1024
6   177   4   multip. unsigned long            1346 65145856      1024
7   155   4   multip. text                     4995 75090944      1024
8   138   4   multip. unsigned long              87 85036032      1024
9   177   4   multip. unsigned long             178 96481280      1024
    193   1           text

myisamchk -eis 輸出示範:

Checking MyISAM file: company
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:  98%  Packed:   17%
 
Records:          1403698    M.recordlength:     226
Packed:             0%
Recordspace used:     100%   Empty space:          0%
Blocks/Record:   1.00
Record blocks:    1403698    Delete blocks:        0
Recorddata:     317235748    Deleted data:         0
Lost space:             0    Linkdata:             0
 
User time 1626.51, System time 232.36
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 639, Involuntary context switches 28966

myisamchk -eiv 輸出示範:

Checking MyISAM file: company
Data records: 1403698   Deleted blocks:       0
- check file-size
- check delete-chain
block_size 1024:
index  1:
index  2:
index  3:
index  4:
index  5:
index  6:
index  7:
index  8:
index  9:
No recordlinks
- check index reference
- check data record references index: 1
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 2
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
- check data record references index: 3
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
- check data record references index: 5
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 6
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 7
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 8
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 9
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:   9%  Packed:   17%
 
- check records and index references
[LOTS OF ROW NUMBERS DELETED]
 
Records:         1403698   M.recordlength:   226   Packed:           0%
Recordspace used:    100%  Empty space:        0%  Blocks/Record: 1.00
Record blocks:   1403698   Delete blocks:      0
Recorddata:    317235748   Deleted data:       0
Lost space:            0   Linkdata:           0
 
User time 1639.63, System time 251.61
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
Blocks in 4 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 10604, Involuntary context switches 122798

下面解釋myisamchk產生的訊息的類型。「keyfile」是索引檔案。「記錄」和「行」是同義詞。

·         MyISAM file

ISAM(索引)檔案名。

·         File-version

ISAM格式的版本。當前總是2

·         Creation time

數據檔案建立的時間。

·         Recover time

索引/數據檔案上次被重建的時間。

·         Data records

在資料表中有多少記錄。

·         Deleted blocks

有多少刪除的塊仍然保留著空間。您可以最佳化資料表以使這個空間減到最小。參見第7章:最佳化

·         Datafile parts

對動態記錄格式,這指出有多少數據塊。對於一個沒有碎片的最佳化過的資料表,這與Data records相同。

·         Deleted data

不能回收的刪除數據有多少字節。您可以最佳化資料表以使這個空間減到最小。參見第7章:最佳化

·         Datafile pointer

數據檔案指針的大小,以字節計。它通常是2345個字節。大多數資料表用2個字節管理,但是目前這還不能從MySQL控制。對固定資料表,這是一個記錄地址。對動態資料表,這是一個字節地址。

·         Keyfile pointer

索引檔案指針的大小,以字節計。它通常是123個字節。大多數資料表用 2 個字節管理,但是它自動由MySQL計算。它總是一個塊地址。

·         Max datafile length

資料表的數據檔案(.MYD檔案)能夠有多長,以字節計。

·         Max keyfile length

資料表的鍵值檔案(.MYI檔案)能夠有多長,以字節計。

·           Recordlength

每個記錄佔多少空間,以字節計。

·         Record format

用於儲存資料表行的格式。上面的例子使用Fixed length其他可能的值是CompressedPacked

·         table description

在資料表中所有鍵值的列資料表。對每個鍵,給出一些底層的訊息:

o        Key

該鍵的編號。

o        Start

該索引部分從記錄的哪裡開始。

o        Len

該索引部分是多長。對於緊湊的數字,這應該總是列的全長。對字串,它可以比索引的列的全長短些,因為您可能會索引到字串列的前綴。

o        Index

uniquemultipmultiple)。表明一個值是否能在該索引中存在多次。

o        Type

該索引部分有什麼數據類型。這是一個packedstrippedempty選項的ISAM數據類型。

o        Root

根索引塊的地址。

o        Blocksize

每個索引塊的大小。預設是1024,但是從原始碼構建MySQL時,該值可以在編譯時改變。

o        Rec/key

這是由最佳化器使用的統計值。它告訴對該鍵的每個值有多少條記錄。唯一鍵總是有一個1值。在一個資料表被裝載後(或變更很大),可以用myisamchk -a更新。如果根本沒被更新,給定一個30的預設值。

在上面例子的資料表中,第9個鍵有兩個table description行。者說明它是有2個部分的多部鍵。

·         Keyblocks used

鍵塊使用的百分比是什麼。當在例子中使用的資料表剛剛用myisamchk重新組織時,該值非常高(很接近理論上的最大值)

·         Packed

MySQL試圖用一個通用後綴壓縮鍵。這只能被用於CHAR/VARCHAR/DECIMAL列的鍵。對於左部分類似的長字串,能顯著地減少使用空間。在上面的第3個例子中,第4個鍵是10個字元長,可以減少60%的空間。

·         Max levels

對於該鍵的B樹有多深。有長鍵的大資料表有較高的值。

·         Records

資料表中有多少行。

·         M.recordlength

平均記錄長度。對於有定長記錄的資料表,這是準確的記錄長度,因為所有記錄的長度相同。

·         Packed

MySQL從字串的結尾去掉空格。Packed值表明這樣做達到的節約的百分比。

·         Recordspace used

數據檔案被使用的百分比。

·         Empty space

數據檔案未被使用的百分比。

·         Blocks/Record

每個記錄的平均塊數(即,一個碎片記錄由多少個連接組成)。對固定格式資料表,這總是1。該值應該盡可能保持接近1.0。如果它變得太大,您可以重新組織資料表。參見第7章:最佳化

·         Recordblocks

多少塊(連結)被使用。對固定格式,它與記錄的個數相同。

·         Deleteblocks

多少塊(連結)被刪除。

·         Recorddata

在數據檔案中使用了多少字節。

·         Deleted data

在數據檔案中多少字節被刪除(未使用)

·         Lost space

如果一個記錄被更新為更短的長度,就損失了一些空間。這是所有這樣的損失之和,以字節計。

·         Linkdata

當使用動態資料表格式,記錄碎片用指針連接(每個4 7字節)Linkdata指這樣的指針使用的內存量之和。

如果一張資料表已經用myisampack壓縮了,myisamchk -d打印每個資料表列的附加訊息。對於它的一個例子及其含義的描述,參見8.2節,「myisampack:生成壓縮、只讀MyISAM資料表」

5.10. MySQL本地化和國際應用

本節描述如何配置伺服器來使用不同的字元編碼。還討論如何設置伺服器的時區並啟用各個連接的時區支援。

5.10.1. 數據和排序用字元編碼

預設情況下,MySQL使用cp1252(Latin1)字元編碼根據Swedish/Finnish規則進行排序。這些 預設值適合美國和西歐大部分國家。

所有MySQL二進制分發版用--with-extra-charsets=complex編譯而成。可以在所有標準程式中新增代碼,使它們可以處理latin1和所有多字節二進制字元編碼。其它字元編碼根據需要從字元編碼定義檔案載入。

字元編碼確定在名稱中使用什麼字元。它還確定如何用SELECT語句的ORDER BYGROUP BY子句對字串進行排序。

還可以在啟動伺服器時用--default-character-set選項更改字元編碼。字元編碼可以用--with-charset=charset--with-extra-charsets=list-of-charsets | complex | all | none選項來configure,字元編碼配置檔案列於SHAREDIR/charsets/Index。參見2.8.2節,「典型配置選項

還可以在您啟動伺服器時用--default-collation選項更改字元編碼 校對規則。校對規則必須是預設字元編碼的合法校對規則。(使用SHOW COLLATION語句來確定每個字元編碼使用哪個校對規則) 參見2.8.2節,「典型配置選項

如果在運行MySQL時更改字元編碼,還會更改排序順序。結果是您必須對所有資料表運行myisamchk -r -q --set-character-set=charset ,或正確地對索引進行排序。

當客戶端連接MySQL伺服器時,伺服器告訴客戶端伺服器的預設字元編碼是什麼。客戶端切換到該字元編碼進行連接。

當轉義SQL查詢的字串時,您應使用mysql_real_escape_string()mysql_real_escape_string()等價於舊的mysql_escape_string()函數,不同的是它使用MYSQL連接句柄作為第一個參數,以便轉義字元時可以使用相應的字元編碼。

如果客戶端的編譯路徑不是伺服器的安裝目錄,並且配置MySQL時沒有包括MySQL二進制中的所有字元編碼,如果伺服器運行時需要使用客戶端設置的字元編碼之外的其它字元編碼,您必須告訴客戶端從哪裡找到更多的字元編碼。

可以指定--character-sets-dir選項來資料表示動態MySQL字元編碼所保存目錄的路徑。例如,可以將下面的行放入選項檔案中:

[client]
character-sets-dir=/usr/local/mysql/share/mysql/charsets

您可以強制客戶端使用專用字元編碼:

[client]
default-character-set=charset

但是一般情況不需要。

5.10.1.1. 使用德國字元編碼

MySQL 5.1,分別指定字元編碼和 校對規則。這說明如果您想使用German排序順序,您應選擇latin1 字元編碼和latin1_german1_cilatin1_german2_ci校對規則。例如,要用latin1_german1_ci校對規則啟動伺服器,應使用--character-set-server=latin1--collation-server=latin1_german1_ci選項。

關於這兩種校對規則的不同之處,參見10.10.2節,「西歐字元編碼」

5.10.2. 設置錯誤消息語言

預設情況下,mysqld用英語給出錯誤消息,但也可以用以下語言顯示:CzechDanishDutchEstonianFrenchGermanGreekHungarianItalianJapaneseKoreanNorwegianNorwegian-nyPolishPortugueseRomanianRussianSlovakSpanish Swedish

要想在啟動mysqld後用具體語言顯示錯誤消息,使用--language-L選項。選項值可以為語言名稱或錯誤消息檔案的全路徑。例如:

shell> mysqld --language=swedish

或:

shell> mysqld --language=/usr/local/share/swedish

語言名應為小寫。

語言檔案位於(預設情況下)MySQL基本目錄的share/LANGUAGE目錄下。

要想更改錯誤消息檔案,應編輯errmsg.txt檔案,然後執行下面的命令以生成errmsg.sys檔案:

shell> comp_err errmsg.txt errmsg.sys

如果您升級到新版本的MySQL,記住使用新的errmsg.txt檔案來重新更改。

5.10.3. 新增新的字元編碼

本節討論在MySQL中新增新字元編碼的程式。您必須有一個MySQL原始碼分發版。

要選擇正確的程式,先確定字元編碼是簡單字元編碼還是複雜字元編碼:

·         如果字元編碼不需要使用特殊字串校對規則程式進行排序,並且不需要多字節字元支援,則為簡單字元編碼。

·         如果需要上述某個特性,則為複雜字元編碼。

例如,latin1danish為簡單字元編碼,而big5czech為複雜字元編碼。

在下面的程式中,字元編碼名用MYSET資料表示。

對於簡單字元編碼,應:

1.    sql/share/charsets/Index檔案最後新增MYSET。並指定唯一的編號。

2.    建立檔案sql/share/charsets/MYSET.conf(您可以使用sql/share/charsets/latin1.conf的備份檔案作為該檔案的基礎)

檔案的語法很簡單:

·         註釋從『#』字元開始,一直到該行末尾。

·         各字之間用任意數量的空格間隔開。

·         定義字元編碼時,每個字必須為十六進制格式的數字。

·         ctype數組佔據前257個字。to_lower[]to_upper[]sort_order[]數組依次佔據256個字。

參見5.10.4節,「字元定義數組」

3.    將字元編碼名新增到configurE.inCHARSETS_AVAILABLECOMPILED_CHARSETS列。

4.    重新配置、編譯並測試。

對於複雜字元編碼,應:

1.    MySQL原始碼分發版中建立檔案strings/ctype-MYSET.c

2.    sql/share/charsets/Index檔案最後新增MYSET。並指定唯一的編號。

3.    看看已有的ctype-*.c檔案(例如strings/ctype-big5.c),看看需要定義什麼。請注意檔案中的數組名必須為ctype_MYSETto_lower_MYSET等等。對應簡單字元編碼的數組。參見5.10.4節,「字元定義數組」

4.    在檔案頂部,新增註釋:

5.            /*
6.            * This comment is parsed by configure to create ctype.c,
7.            * so don't change it unless you know what you are doing.
8.            *
9.            * .configure. number_MYSET=MYNUMBER
10.        * .configure. strxfrm_multiply_MYSET=N
11.        * .configure. mbmaxlen_MYSET=N
12.        */

configure程式使用該註釋自動將字元編碼包括進MySQL庫中。

在下面章節中解釋strxfrm_multiplymbmaxlen 行。只有需要字串比較函數或多字節字元編碼函數時,才需要單獨將它們包括進來。

13.然後您應建立下面的函數:

    • my_strncoll_MYSET()
    • my_strcoll_MYSET()
    • my_strxfrm_MYSET()
    • my_like_range_MYSET()

參見5.10.5節,「字串比較支援」

14.將字元編碼名新增到configurE.inCHARSETS_AVAILABLECOMPILED_CHARSETS列。

15.重新配置、編譯並測試。

sql/share/charsets/README檔案中包括詳細的說明。

如果您想要MySQL分發中的字元編碼,請向MySQL內部郵件系統發郵件。參見1.7.1.1節,「The MySQL郵件列資料表」

5.10.4. 字元定義數組

to_lower[]to_upper[]是簡單數組,含有小寫和大寫字元,對應字元編碼的每個成員。例如:

to_lower['A'] should contain 'a'
to_upper['a'] should contain 'A'

sort_order[]是一個映射,資料表示如何排列字元的順序,以便進行比較和排序。通常(但非對於所有字元編碼)to_upper[]相同,說明排序對大小寫敏感。MySQL排序字元基於sort_order[]元素的值。對於更加複雜的排序規則,參見5.10.5節,「字串比較支援」的字串 校對規則討論。

ctype[]是一個位數組,每個字元為一個元素。(請注意字元值索引to_lower[]to_upper[]sort_order[],但用字元值+ 1索引ctype[]。這是傳統的轉換方法,能夠處理EOF

m_ctype.h中有下面的位掩碼定義:

#define _U      01      /* Uppercase */
#define _L      02      /* Lowercase */
#define _N      04      /* Numeral (digit) */
#define _S      010     /* Spacing character */
#define _P      020     /* Punctuation */
#define _C      040     /* Control character */
#define _B      0100    /* Blank */
#define _X      0200    /* heXadecimal digit */

每個字元的ctype[]條目應為相應的描述字元的位掩碼值的聯合。例如,'A'是大寫字元(_U)以及十六進制整數(_X),因此ctype['A'+1]應包含 值:

_U + _X = 01 + 0200 = 0201

5.10.5. 字串比較支援

如果語言的排序規則比較複雜,不能用簡單sort_order[]資料表來處理,需要使用字串比較函數。

最好的文檔是已有字元編碼。以big5czechgbksjistis160字元編碼作為例子。

您必須在檔案頂部的特殊註釋處指定strxfrm_multiply_MYSET=N值。N應設置為字串在my_strxfrm_MYSET過程中可能增長的最大比例(必須為正整數)

5.10.6. 多字節字元支援

如果您想要新增包括多字節字元的新字元編碼支援,需要使用多字節字元函數。

最好的文檔是已有字元編碼。以euc_krgb2312,gbksjisujis字元編碼作為例子。這些字元編碼位於strings目錄的ctype-charset.c檔案中。

必須在檔案頂部的特殊註釋處指定mbmaxlen_MYSET=N值。N應設置為字元編碼內最長字元的字節數。

5.10.7. 字元編碼問題

如果您想要使用沒有編譯為二進制的字元編碼,可能會遇到下面的問題:

·         您的程式的字元編碼保存路徑不正確。(預設為/usr/local/mysql/share/mysql/charsets)。可以在運行有問題的程式時通過--character-sets-dir選項來修復。

·         字元編碼為多字節字元編碼,不能動態載入。在這種情況下,您必須重新編譯程式,以支援字元編碼。

·         字元編碼為動態字元編碼,但您沒有對應的配置檔案。在這種情況下,您應從新MySQL分發安裝該字元編碼的配置檔案。

·         如果Index檔案沒有包含字元編碼名,程式將顯示下面的錯誤消息:

·                ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf'
·                not found (Errcode2)

在這種情況下,您應獲得新Index檔案或在當前檔案中手動新增字元編碼。

對於MyISAM資料表,可以用myisamchk -dvv tbl_name檢查資料表的字元編碼名和編號。

5.10.8. MySQL伺服器時區支援

 MySQL伺服器有幾個時區設置:

·         系統時區。伺服器啟動時便試圖確定主機的時區,用它來設置system_time_zone系統變數。

·         伺服器當前的時區。全局系統變數time_zone資料表示伺服器當前使用的時區。初使值為'SYSTEM',說明伺服器時區與系統時區相同。可以用--default-time-zone=timez選項顯式指定初使值。如果您有SUPER 權限,可以用下面的語句在運行時設置全局變數值:

·                mysql> SET GLOBAL time_zone = timezone;

·         每個連接的時區。每個客戶端連接有自己的時區設置,用會話time_zone變數給出。其初使值與全局變數time_zone相同,但可以用下面的語句重設:

·                mysql> SET time_zone = timezone;

可以用下面的方法查詢當前的全局變數值和每個連接的時區:

mysql> SELECT @@global.time_zone, @@session.time_zone;

timezone值為字串,資料表示UTC的偏移量,例如'+10:00''-6:00'。如果已經建立並裝入mysql資料庫中的時區相關資料表,您還可以使用命名的時區,例如'Europe/Helsinki''US/Eastern''MET'。值'SYSTEM'說明該時區應與系統時區相同。時區名對大小寫不敏感。

MySQL安裝程式在mysql資料庫中建立時區資料表,但不裝載。您必須手動裝載。(如果您正從以前的版本升級到MySQL 4.1.3或更新版本,您應通過升級mysql資料庫來建立資料表。參見2.10.2節,「升級授權資料表」中的說明)

如果您的系統有自己的時區訊息資料庫(描述時區的一系列檔案),應使用mysql_tzinfo_to_sql程式來填充時區資料表。示範系統如LinuxFreeBSDSun SolarisMac OS X。這些檔案的可能位置為/usr/share/zoneinfo目錄。如果您的系統沒有時區訊息資料庫,可以使用本節後面描述的下載的軟件包。

mysql_tzinfo_to_sql程式用來裝載時區資料表。在命令行中,將時區訊息目錄路徑名傳遞到mysql_tzinfo_to_sql並輸出發送到mysql程式。例如:

shell> mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

mysql_tzinfo_to_sql讀取系統時區檔案並生成SQL語句。mysql處理這些語句並裝載時區資料表。

mysql_tzinfo_to_sql還可以用來裝載單個時區檔案,並生成閏秒訊息。

要想裝載對應時區tz_name的單個時區檔案tz_file,應這樣使用mysql_tzinfo_to_sql

shell> mysql_tzinfo_to_sql tz_file tz_name | mysql -u root mysql

如果您的時區需要計算閏秒,按下面方法初使化閏秒訊息,其中tz_file是時區檔案名:

shell> mysql_tzinfo_to_sql --leap tz_file | mysql -u root mysql

如果您的系統沒有時區訊息資料庫 (例如,WindowsHP-UX),您可以從http://dev.mysql.com/downloads/timezones.html下載預構建時區資料表軟件包。該軟件包包含MyISAM時區資料表所用的.frm.MYD.MYI檔案。這些資料表應屬於mysql資料庫,因此應將這些檔案放到MySQL伺服器數據目錄的mysql子目錄。操作時應關閉伺服器。

警告!如果您的系統有時區訊息資料庫,請不要使用下載的軟件包。而應使用mysql_tzinfo_to_sql實用工具!否則,MySQL和系統上其它應用程式處理日期時間的方法會有所不同。

關於在複製時時區設置相關請查閱6.7節,「複製特性和已知問題」

5.11. MySQL日誌檔案

MySQL有幾個不同的日誌檔案,可以幫助您找出mysqld內部發生的事情:

日誌檔案

記入檔案中的訊息類型

錯誤日誌

記錄啟動、運行或停止mysqld時出現的問題。

查詢日誌

記錄建立的客戶端連接和執行的語句。

更新日誌

記錄更改數據的語句。不贊成使用該日誌。

二進制日誌

記錄所有更改數據的語句。還用於複製。

慢日誌

記錄所有執行時間超過long_query_time秒的所有查詢或不使用索引的查詢。

預設情況下,所有日誌建立於mysqld數據目錄中。通過刷新日誌,您可以強制 mysqld來關閉和重新打開日誌檔案(或者在某些情況下切換到一個新的日誌)。當您執行一個FLUSH LOGS語句或執行mysqladmin flush-logsmysqladmin refresh時,出現日誌刷新。參見13.5.5.2節,「FLUSH語法」

如果您正使用MySQL複製功能,從複製伺服器將維護更多日誌檔案,被稱為接替日誌。相關討論參見第6章:MySQL中的複製

5.11.1. 錯誤日誌

錯誤日誌檔案包含了當mysqld啟動和停止時,以及伺服器在運行過程中發生任何嚴重錯誤時的相關訊息。

如果mysqld莫名其妙地死掉並且mysqld_safe需要重新啟動它,mysqld_safe在錯誤日誌中寫入一條restarted mysqld消息。如果mysqld注意到需要自動檢查或著修復一個資料表,則錯誤日誌中寫入一條消息。

在一些作業系統中,如果mysqld死掉,錯誤日誌包含堆棧跟蹤訊息。跟蹤訊息可以用來確定mysqld死掉的地方。參見E.1.4節,「使用堆棧跟蹤」

可以用--log-error[=file_name]選項來指定mysqld保存錯誤日誌檔案的位置。如果沒有給定file_name值,mysqld使用錯誤日誌名host_name.err 並在數據目錄中寫入日誌檔案。如果您執行FLUSH LOGS,錯誤日誌用-old重新命名後綴並且mysqld建立一個新的空日誌檔案。(如果未給出--log-error選項,則不會重新命名)

如果不指定--log-error,或者(Windows)如果您使用--console選項,錯誤被寫入標準錯誤輸出stderr。通常標準輸出為您的終端。

Windows中,如果未給出--console選項,錯誤輸出總是寫入.err檔案。

5.11.2. 通用查詢日誌

如果您想要知道mysqld內部發生了什麼,您應該用--log[=file_name]-l [file_name]選項啟動它。如果沒有給定file_name的值, 預設名是host_name.log所有連接和語句被記錄到日誌檔案。當您懷疑在客戶端發生了錯誤並想確切地知道該客戶端發送給mysqld的語句時,該日誌可能非常有用

mysqld按照它接收的順序記錄語句到查詢日誌。這可能與執行的順序不同。這與更新日誌和二進制日誌不同,它們在查詢執行後,但是任何一個鎖釋放之前記錄日誌。(查詢日誌還包含所有語句,而二進制日誌不包含只查詢數據的語句)

伺服器重新啟動和日誌刷新不會產生新的一般查詢日誌檔案(儘管刷新關閉並重新打開一般查詢日誌檔案)。在Unix中,您可以通過下面的命令重新命名檔案並建立一個新檔案:

shell> mv hostname.log hostname-old.log
shell> mysqladmin flush-logs
shell> cp hostname-old.log to-backup-directory
shell> rm hostname-old.log

Windows中,伺服器打開日誌檔案期間您不能重新命名日誌檔案。您必須先停止伺服器然後重新命名日誌檔案。然後,重啟伺服器來建立新的日誌檔案。

5.11.3. 二進制日誌

二進制日誌以一種更有效的格式,並且是事務安全的方式包含更新日誌中可用的所有訊息。

二進制日誌包含了所有更新了數據或者已經潛在更新了數據(例如,沒有匹配任何行的一個DELETE)的所有語句。語句以「事件」的形式保存,它描述數據更改。

釋:二進制日誌已經代替了老的更新日誌,更新日誌在MySQL 5.1中不再使用。

二進制日誌還包含關於每個更新資料庫的語句的執行時間訊息。它不包含沒有修改任何數據的語句。如果您想要記錄所有語句(例如,為了識別有問題的查詢),您應使用一般查詢日誌。參見5.11.2節,「通用查詢日誌」

二進制日誌的主要目的是在恢復使能夠最大可能地更新資料庫,因為二進制日誌包含備份後進行的所有更新。

二進制日誌還用於在主複製伺服器上記錄所有將發送給從伺服器的語句。參見第6章:MySQL中的複製

運行伺服器時若啟用二進制日誌則性能大約慢1%。但是,二進制日誌的好處,即用於恢復並允許設置複製超過了這個小小的性能損失。

當用--log-bin[=file_name]選項啟動時,mysqld寫入包含所有更新數據的SQL命令的日誌檔案。如果未給出file_name值, 預設名為-bin後面所跟的主機名。如果給出了檔案名,但沒有包含路徑,則檔案被寫入數據目錄。建議指定一個檔案名,原因參見A.8.1節,「MySQL中的打開事宜」

如果您在日誌名中提供了延伸名(例如,--log-bin=file_name.extension),則延伸名被悄悄除掉並忽略。

mysqld在每個二進制日誌名後面新增一個數字延伸名。每次您啟動伺服器或刷新日誌時該數字則增加。如果當前的日誌大小達到max_binlog_size,還會自動建立新的二進制日誌。如果您正使用大的事務,二進制日誌還會超過max_binlog_size:事務全寫入一個二進制日誌中,絕對不要寫入不同的二進制日誌中。

為了能夠知道還使用了哪個不同的二進制日誌檔案,mysqld還建立一個二進制日誌索引檔案,包含所有使用的二進制日誌檔案的檔案名。預設情況下與二進制日誌檔案的檔案名相同,延伸名為'.index'。您可以用--log-bin-index[=file_name]選項更改二進制日誌索引檔案的檔案名。當mysqld在運行時,不應手動編輯該檔案;如果這樣做將會使mysqld變得混亂。

可以用RESET MASTER語句刪除所有二進制日誌檔案,或用PURGE MASTER LOGS只刪除部分二進制檔案。參見13.5.5.5節,「RESET語法」13.6.1節,「用於控制主伺服器的SQL語句」

二進制日誌格式有一些已知限制,會影響從備份恢復。參見6.7節,「複製特性和已知問題」

保存程式和觸發器的二進制日誌的描述參見20.4節,「儲存子程式和觸發程式的二進制日誌功能」

可以使用下面的mysqld選項來影響記錄到二進制日誌知的內容。又見選項後面的討論。

·         --binlog-do-db=db_name

告訴主伺服器,如果當前的資料庫(USE選定的資料庫)db_name,應將更新記錄到二進制日誌中。其它所有沒有明顯指定的資料庫  被忽略。如果使用該選項,您應確保只對當前的資料庫進行更新。

對於CREATE DATABASEALTER DATABASEDROP DATABASE語句,有一個例外,即通過操作的資料庫來決定是否應記錄語句,而不是用當前的資料庫。

一個不能按照期望執行的例子:如果用binlog-do-db=sales啟動伺服器,並且執行USE prices; UPDATE sales.january SET amount=amount+1000,該語句不寫入二進制日誌。

·         --binlog-ignore-db=db_name

告訴主伺服器,如果當前的資料庫(USE選定的資料庫)db_name,不應將更新保存到二進制日誌中。如果您使用該選項,您應確保只對當前的資料庫進行更新。

一個不能按照您期望的執行的例子:如果伺服器用binlog-ignore-db=sales啟動,並且執行USE prices; UPDATE sales.january SET amount=amount+1000,該語句不寫入二進制日誌。

類似於--binlog-do-db,對於CREATE DATABASEALTER DATABASEDROP DATABASE語句,有一個例外,即通過操作的資料庫來決定是否應記錄語句,而不是用當前的資料庫。

要想記錄或忽視多個資料庫,使用多個選項,為每個資料庫指定相應的選項。

伺服器根據下面的規則對選項進行評估,以便將更新記錄到二進制日誌中或忽視。請注意對於CREATE/ALTER/DROP DATABASE語句有一個例外。在這些情況下,根據以下規則,所建立、修改或刪除的資料庫將代替當前的資料庫。

1.    是否有binlog-do-dbbinlog-ignore-db規則?

·         沒有:將語句寫入二進制日誌並退出。

·         有:執行下一步。

2.    有一些規則(binlog-do-dbbinlog-ignore-db或二者都有)。當前有一個資料庫(USE是否選擇了資料庫?)?

·         沒有:不要寫入語句,並退出。

·         有:執行下一步。

3.    有當前的資料庫。是否有binlog-do-db規則?

·         有:當前的資料庫是否匹配binlog-do-db規則?

o        有:寫入語句並退出。

o        沒有:不要寫入語句,退出。

·         No:執行下一步。

4.    有一些binlog-ignore-db規則。當前的資料庫是否匹配binlog-ignore-db規則?

·         有:不要寫入語句,並退出。

·         沒有:寫入查詢並退出。

例如,只用binlog-do-db=sales運行的伺服器不將當前資料庫不為sales的語句寫入二進制日誌(換句話說,binlog-do-db有時可以資料表示「忽視其它資料庫)

如果您正進行複製,應確保沒有從伺服器在使用舊的二進制日誌檔案,方可刪除它們。一種方法是每天一次執行mysqladmin flush-logs並刪除三天前的所有日誌。可以手動刪除,或最好使用PURGE MASTER LOGS(參見13.6.1節,「用於控制主伺服器的SQL語句」),該語句還會安全地更新二進制日誌索引檔案(可以採用日期參數)

具有SUPER權限的客戶端可以通過SET SQL_LOG_BIN=0語句禁止將自己的語句記入二進制記錄。參見13.5.3節,「SET語法」

您可以用mysqlbinlog實用工具檢查二進制日誌檔案。如果您想要重新處理日誌止的語句,這很有用。例如,可以從二進制日誌更新MySQL伺服器,方法如下:

shell> mysqlbinlog log-file | mysql -h server_name

關於mysqlbinlog實用工具的詳細訊息以及如何使用它,參見8.6節,「mysqlbinlog:用於處理二進制日誌檔案的實用工具」

如果您正使用事務,必須使用MySQL二進制日誌進行備份,而不能使用舊的更新日誌。

查詢結束後、鎖定被釋放前或提交完成後則立即記入二進制日誌。這樣可以確保按執行順序記入日誌。

對非事務資料表的更新執行完畢後立即保存到二進制日誌中。對於事務資料表,例如BDBInnoDB資料表,所有更改資料表的更新(UPDATEDELETEINSERT) 被緩存起來,直到伺服器接收到COMMIT語句。在該點,執行完COMMIT之前,mysqld將整個事務寫入二進制日誌。當處理事務的線程啟動時,它為緩衝查詢分配binlog_cache_size大小的內存。如果語句大於該值,線程則打開臨時檔案來保存事務。線程結束後臨時檔案被刪除。

Binlog_cache_use狀態變數顯示了使用該緩衝區(也可能是臨時檔案)保存語句的事務的數量。Binlog_cache_disk_use狀態變數顯示了這些事務中實際上有多少必須使用臨時檔案。這兩個變數可以用於將binlog_cache_size調節到足夠大的值,以避免使用臨時檔案。

max_binlog_cache_size(預設4GB)可以用來限制用來緩存多語句事務的緩衝區總大小。如果某個事務大於該值,將會失敗並 回滾。

如果您正使用更新日誌或二進制日誌,當使用CREATE ... SELECT or INSERT ... SELECT時,並行插入被轉換為普通插入。這樣通過在備份時使用日誌可以確保重新建立資料表的備份。

請注意MySQL 5.1值的二進制日誌格式與以前版本的MySQL不同,因為複製改進了。參見6.5節,「不同MySQL版本之間的複製相容性」

預設情況下,並不是每次寫入時都將二進制日誌與硬盤同步。因此如果作業系統或機器(不僅僅是MySQL伺服器)崩潰,有可能二進制日誌中最後的語句丟失了。要想防止這種情況,您可以使用sync_binlog全局變數(1是最安全的值,但也是最慢的),使二進制日誌在每N次二進制日誌寫入後與硬盤同步。參見5.3.3節,「伺服器系統變數」。即使sync_binlog設置為1,出現崩潰時,也有可能資料表內容和二進制日誌內容之間存在不一致性。例如,如果使用InnoDB資料表,MySQL伺服器處理COMMIT語句,它將整個事務寫入二進制日誌並將事務提交到InnoDB如果在兩次操作之間出現崩潰,重啟時,事務被InnoDB回滾,但仍然存在二進制日誌中。可以用--innodb-safe-binlog選項解決該問題,可以增加InnoDB資料表內容和二進制日誌之間的一致性。(註釋:在MySQL 5.1中不需要--innodb-safe-binlog;由於引入了XA事務支援,該選項作廢了)

該選項可以提供更大程度的安全,還應對MySQL伺服器進行配置,使每個事務的二進制日誌(sync_binlog =1)(預設情況為真)InnoDB日誌與硬盤同步。該選項的效果是崩潰後重啟時,在滾回事務後,MySQL伺服器從二進制日誌剪切 回滾的InnoDB事務。這樣可以確保二進制日誌反饋InnoDB資料表的確切數據等,並使從伺服器保持與主伺服器保持同步(不接收 回滾的語句)

請注意即使MySQL伺服器更新其它儲存引擎而不是InnoDB,也可以使用--innodb-safe-binlog。在InnoDB崩潰恢復時,只從二進制日誌中刪除影響InnoDB資料表的語句/事務。如果崩潰恢復時MySQL伺服器發現二進制日誌變短了(即至少缺少一個成功提交的InnoDB事務),如果sync_binlog =1並且硬盤/檔案系統的確能根據需要進行同步(有些不需要)則不會發生,則輸出錯誤消息 ("二進制日誌<>比期望的要小")。在這種情況下,二進制日誌不準確,複製應從主伺服器的數據快照開始。

寫入二進制日誌檔案和二進制日誌索引檔案的方法與寫入MyISAM資料表相同。參見A.4.3節,「MySQL處理磁盤滿的方式」

5.11.4. 慢速查詢日誌

--log-slow-queries[=file_name]選項啟動時,mysqld寫一個包含所有執行時間超過long_query_time秒的SQL語句的日誌檔案。獲得初使資料表鎖定的時間不算作執行時間。

如果沒有給出file_name值, 預設未主機名,後綴為-slow.log。如果給出了檔案名,但不是絕對路徑名,檔案則寫入數據目錄。

語句執行完並且所有鎖釋放後記入慢查詢日誌。記錄順序可以與執行順序不相同。

慢查詢日誌可以用來找到執行時間長的查詢,可以用於最佳化。但是,檢查又長又慢的查詢日誌會很困難。要想容易些,您可以使用mysqldumpslow命令獲得日誌中顯示的查詢摘要來處理慢查詢日誌。

MySQL 5.1的慢查詢日誌中,不使用索引的慢查詢同使用索引的查詢一樣記錄。要想防止不使用索引的慢查詢記入慢查詢日誌,使用--log-short-format選項。參見5.3.1節,「mysqld命令行選項」

MySQL 5.1,通過--log-slow-admin-statements伺服器選項,您可以請求將慢管理語句,例如OPTIMIZE TABLEANALYZE TABLE ALTER TABLE寫入慢查詢日誌。

用查詢緩存處理的查詢不加到慢查詢日誌中,因為資料表有零行或一行而不能從索引中受益的查詢也不寫入慢查詢日誌。

5.11.5. 日誌檔案維護

MySQL伺服器可以建立各種不同的日誌檔案,從而可以很容易地看見所進行的操作。參見5.11節,「MySQL日誌檔案」。但是,您必須定期清理這些檔案,確保日誌不會佔用太多的硬盤空間。

當啟用日誌使用MySQL時,您可能想要不時地備份並刪除舊的日誌檔案,並告訴MySQL開始記入新檔案。參見5.9.1節,「資料庫備份」

Linux (Redhat)的安裝上,您可為此使用mysql-log-rotate指令。如果您從RPM分發安裝MySQL,指令應該自動被安裝了。

在其它系統上,您必須自己安裝短指令,您可從cron等入手處理日誌檔案。

您可以通過mysqladmin flush-logsSQL語句FLUSH LOGS來強制MySQL開始使用新的日誌檔案。

日誌清空操作做下列事情:

  • 如果使用標準日誌(--log)或慢查詢日誌(--log-slow-queries),關閉並重新打開日誌檔案。(預設為mysql.log`hostname`-slow.log)
  • 如果使用更新日誌(--log-update)或二進制日誌(--log-bin),關閉日誌並且打開有更高序列號的新日誌檔案。

如果您只使用更新日誌,您只需要重新命名日誌檔案,然後在備份前清空日誌。例如,您可以這樣做:

shell> cd mysql-data-directory
shell> mv mysql.log mysql.old
shell> mysqladmin flush-logs

然後做備份並刪除mysql.old

5.12. 在同一台機器上運行多個MySQL伺服器

在一些情況下,您可能想要在同一台機器上運行多個mysqld伺服器。您可能想要測試一個新的MySQL發佈,同時不影響現有產品的設置。或者,您可能想使不同的用戶訪問來訪問不同的mysqld伺服器以便他們自己來管理。(例如,您可能是一個Internet服務提供商,希望為不同的客戶來提供獨立的MySQL安裝)

要想在一個單獨的機器上運行多個伺服器,每個伺服器必須有唯一的各運行參數值。這些值可以在命令行中設置或在選項檔案中設置。參見4.3節,「指定程式選項」

至少下面的選項對每個伺服器必須是不同的:

·         --port=port_num

--port控制著TCP/IP連接的端口號。

·         --socket=path

--socket控制Unix中的Unix套接字檔案路徑和在Windows中的命名管道名稱。在Windows中,只有支援命名管道連接的伺服器才需要明確指定管道名稱。

·         --shared-memory-base-name=name

該選項當前只在Windows中使用。它指定Windows伺服器使用的、允許客戶端通過共享內存來連接的共享內存名。

·         --pid-file=path

該選項只在Unix中使用。它指出伺服器在其中寫入程序ID的檔案名。

如果您使用下面的日誌檔案選項,對於每個伺服器來說,它們必須是不同的:

·           --log=path

·         --log-bin=path

·         --log-update=path

·         --log-error=path

·         --bdb-logdir=path

日誌檔案選項的描述參見5.11.5節,「日誌檔案維護」

為了提高性能,您可以為每個伺服器指定下面選項的不同的值,以便在物理磁盤之間平均分配負荷:

·         --tmpdir=path

·         --bdb-tmpdir=path

還推薦使用不同的臨時目錄,以便容易地確定哪個MySQL伺服器建立了給定的臨時檔案。

一般情況,每個伺服器應還使用不同的數據目錄,可以通過--datadir=path選項來指定。

警告:一般情況,您決不要讓兩個伺服器更新相同資料庫中的數據。否則,如果您的作業系統不支援故障排除系統鎖定,該可能會導致非常奇怪的結果。如果(不理會該警告)運行的多個伺服器使用相同的數據目錄並且啟用了日誌記錄,您必須使用適當的選項來為每個伺服器指定唯一的日誌檔案名。否則,伺服器嘗試用相同的檔案來記錄日誌。請注意這種類型的設置只能在MyISAMMERGE資料表上工作,對其它任何儲存引擎不起作用。

多個伺服器共享一個數據目錄的警告也適用於NFS環境。允許多個MySQL伺服器通過NFS訪問一個共同的數據目錄是一個非常不好的主義

·         主要問題是NFS存在速度瓶頸。它不是用於這種用途。

·         NFS的另一個冒險是您必須提出一個方法來確保兩個或多個伺服器不會相互干擾。NFS檔案的鎖定通常由lockd後台程式處理,但是目前,沒有一個運行平台能夠在每種情況下100%可靠地進行鎖定。

使您更加容易:忘記在伺服器之間通過NFS共享數據目錄。一個較好的解決方案是使用包含幾個CPU並且和使用有效處理多線程的作業系統的機器。

如果在不同的位置有多個MySQL的安裝,一般情況可以用--basedir=path選項為每個伺服器指定基本安裝目錄,使每個伺服器使用不同的數據目錄、日誌檔案和PID檔案。(所有這些值的 預設值相對於根目錄來確定)。那樣的話, 您唯一需要指定的其它選項是--socket--port選項。例如,假如使用tar檔案二進制分發版安裝不同的MySQL版本。這些安裝在不同的位置,因此可以使用各個安裝伺服器相應的根目錄中的bin/mysqld_safe命令啟動伺服器。mysqld_safe確定正確的--basedir選項傳遞給mysqld,您僅需要為mysqld_safe指定--socket--port選項。

正如下面幾節所討論的那樣,可以通過設置環境變數或用指定的命令行選項來啟動更多的伺服器。但是,如果您需要在一個更穩定的基礎上運行多個伺服器,一個更方便的方法是使用選項檔案來為每個伺服器指定那些選項值,它對每個伺服器必須是唯一的。

5.12.1. 在Windows下運行多個伺服器

Windows中,可以從命令行手動啟動來運行多個伺服器,每個伺服器使用合適的操作參數。在基於Windows NT的系統中,安裝幾個伺服器時,您還有將多個伺服器安裝為Windows服務並運行的選項。關於從命令行運行MySQL伺服器或作為服務運行的一般說明在 2.3節,「在Windows上安裝MySQL」中給出。本節描述怎樣確保您用不同的啟動選項值(對於每個伺服器必須是唯一的,例如數據目錄)啟動各個伺服器。這些選項的描述見5.12節,「在同一台機器上運行多個MySQL伺服器」

5.12.1.1. 在命令行中啟動多個Windows伺服器

為了從命令行手動啟動多個伺服器,可以在命令行中或在選項檔案中指定適當的選項。把選項放在選項檔案中比較方便,但是需要確保每個伺服器可以獲得自己的選項。為了實現,為每個建立一個選項檔案,並且運行服務時通過--defaults-file選項告訴伺服器選項檔案名。

假設您想要在端口3307使用數據目錄C:\mydata1運行mysqld,並且想在端口3308使用數據目錄C:\mydata1運行mysqld-max(要想這樣做,啟動伺服器之前要確保,每個數據目錄存在並且有自己的mysql資料庫拷貝,它包含 授權資料表)

然後建立兩個選項檔案。例如,建立一個檔案名為C:\my-opts1.cnf的配置檔案,它看起來像這個樣子:

[mysqld]
datadir = C:/mydata1
port = 3307

建立第二個檔案名為C:\my-opts1.cnf的配置檔案,它看起來像這個樣子:

mysqld]
datadir = C:/mydata2
port = 3308

然後,用它們自己的選項檔案啟動每個伺服器:

C:\> C:\mysql\bin\mysqld --defaults-file=C:\my-opts1.cnf
C:\> C:\mysql\bin\mysqld-max --defaults-file=C:\my-opts2.cnf

NT中,每個伺服器在前台啟動(伺服器退出前,不會顯示新的提示符);需要在兩個控制台窗口中執行這兩個命令。

要想關閉伺服器,必須連接到相應的端口號:

C:\> C:\mysql\bin\mysqladmin --port=3307 shutdown

C:\> C:\mysql\bin\mysqladmin --port=3308 shutdown

如剛才所討論的,伺服器配置允許客戶端通過TCP/IP來連接。如果您的Windows版本支援命名管道並且您想允許命名管道連接,使用mysqld-ntmysqld-max-nt伺服器並指定啟用命名管道並且指定管道名的選項。支援命名管道連接的每個伺服器必須使用一個唯一的管道名。例如,C:\my-opts1.cnf檔案可能像這樣來書寫:

[mysqld]
datadir = C:/mydata1
port = 3307
enable-named-pipe
socket = mypipe1

然後,這樣啟動伺服器:

C:\> C:\mysql\bin\mysqld-nt --defaults-file=C:\my-opts1.cnf

同樣修改第2個伺服器使用的C:\my-opts2.cnf檔案。

5.12.1.2. 做為服務啟動多個Windows伺服器

在基於NT的系統中,MySQL伺服器可以以Windows服務的方式來運行。安裝、控制和刪除單個MySQL服務的過程描述見2.3.12節,「以Windows服務方式啟動MySQL」

您還可以以服務的方式安裝多個MySQL伺服器。此時,除了所有參數對每個伺服器必須是唯一的,您還必須確保每個伺服器使用不同的服務名。

在下面的說明中,假設您想要運行mysqld-nt伺服器的兩個不同的版本,它們分別安裝在C:\mysql-4.1.8C:\mysql-5.1.2-alpha目錄中。(可能存在這種情況,如果您正在運行版本4.1.8作為您的產品伺服器,還想使用5.1.2-alpha版本來進行測試)

當用--install--install-manual選項安裝一個MySQL服務時,應遵從以下原則:

·         如果您沒有指定服務名,伺服器使用預設的MySQL服務名,從標準選項檔案的[mysqld]組中讀取選項。

·         如果您在--install選項後指定了服務名,伺服器忽略[mysqld]選項組,從具有相同名的組中讀取選項作為服務名。伺服器從標準選項檔案中讀取選項。

·         如果您在服務名後面指定一個--defaults-file選項,伺服器忽略標準選項檔案,只從命名的檔案的[mysqld]組讀取選項。

釋:MySQL 4.0.17之前,只有使用預設服務名(MySQL安裝的一個伺服器或使用服務名mysqld顯式安裝的一個伺服器從標準選項檔案讀[mysqld]組。到4.0.17時,如果伺服器讀標準選項檔案,則它們均讀[mysqld]組,即使它們安裝時使用了另一個服務名。這樣允許您為選項使用[mysqld]組,用於所有MySQL伺服器,並將根據每個伺服器命名的選項組用於該伺服器,即使用那個服務名安裝的伺服器。

根據前面敘述,您可以通過幾個方法來設置多個伺服器。下面的說明描述了一些示範。在嘗試之前,應確保您首先關閉並且卸載了所有已有的MySQL伺服器。

·         方法1在一個標準選項檔案中指定所有伺服器選項。要想這樣做,為每個伺服器使用不同的服務名。假設您想使用服務名mysqld1運行4.1.8版的mysqld-nt使用服務名mysqld2運行5.1.2-alpha版的mysqld-nt。在這種情況下,您可以為4.1.8使用[mysqld1]組,為5.1.2-alpha使用[mysqld2]組。例如,您可以像這樣建立 C:\my.cnf檔案:

·                # options for mysqld1 service
·                [mysqld1]
·                basedir = C:/mysql-4.1.8
·                port = 3307
·                enable-named-pipe
·                socket = mypipe1
·                 
·                # options for mysqld2 service
·                [mysqld2]
·                basedir = C:/mysql-5.1.2-alpha
·                port = 3308
·                enable-named-pipe
·                socket = mypipe2

如下面所示安裝伺服器,使用伺服器的全路徑名來確保Windows為每個服務註冊正確的可執行程式:

C:\> C:\mysql-4.1.8\bin\mysqld-nt --install mysqld1
C:\> C:\mysql-5.1.2-alpha\bin\mysqld-nt --install mysqld2

為了啟動伺服器,使用服務管理器,或用帶有適當的服務名的NET START

C:\> NET START mysqld1

C:\> NET START mysqld2

要想停止服務,使用服務管理器,或用帶有適當的服務名的NET STOP

C:\> NET STOP mysqld1
C:\> NET STOP mysqld2

·         方法2為每個伺服器用不同的檔案指定選項,當您安裝服務時使用--defaults-file告訴每個伺服器使用什麼檔案。此時,每個檔案應用一個[mysqld]組列出選項。

使用這種方法為4.1.8版本的mysqld-nt指定選項,應像這樣建立一個C:\my-opts1.cnf檔案:

[mysqld]
basedir = C:/mysql-4.1.8
port = 3307
enable-named-pipe
socket = mypipe1

對於5.1.2-alpha版的mysqld-nt,像這樣建立一個C:\my-opts2.cnf檔案:

[mysqld]
basedir = C:/mysql-5.1.2-alpha port = 3308
enable-named-pipe
socket = mypipe2

安裝服務如下(在一個單一行中輸入每個命令):

C:\> C:\mysql-4.1.8\bin\mysqld-nt -- installmysqld1
           --defaults-file=C:\my-opts1.cnf
C:\> C:\mysql-5.1.2-alpha\bin\mysqld-nt -- installmysqld2
           --defaults-file=C:\my-opts2.cnf

當您作為服務安裝一個MySQL伺服器時,要想使用--defaults-file選項,您必須在此選項之前加服務名。

安裝服務後,按照與前面的示範相同的方法啟動和停止。

要想卸載多個服務,對每個服務使用mysqld --remove,在--remove選項後指定服務名。如果服務名是 預設的(MySQL),您可以不指定。

5.12.2. 在Unix中運行多個伺服器

Unix中運行多個伺服器最容易的方法是使用不同的TCP/IP端口sUnix套接字檔案編譯,因此每個實例在不同的網絡接口偵聽。另外,每個安裝應在不同的基礎目錄中編譯,那將自動為您的每個伺服器產生使用不同的編譯進來的數據目錄、日誌檔案和PID檔案位置。

假設一個現有的4.1.8版本伺服器配置為預設TCP/IP端口號(3306)Unix套接字檔案(/tmp/mysql.sock)。要想配置一個新的5.1.2-alpha版的伺服器來使用不同的操作參數,使用一個configure命令,大概像這樣使用:

shell> ./configure --with-tcp-port=port_number \
             --with-unix-socket-path=file_name \
             --prefix=/usr/local/mysql-5.1.2-alpha

這裡,port_numberfile_name必須不同於預設TCP/IP端口號和Unix套接字檔案路徑名,並且--prefix值應指定一個不同於現有MySQL安裝目錄的安裝目錄。

如果您有一個MySQL伺服器正偵聽一個給定的端口號,您可以使用下面的命令來找出針對一些重要配置變數它使用了那些操作參數,包括基礎目錄和Unix套接字檔案名:

shell> mysqladmin --host=host_name --port=port_number variables

通過該命令顯示的訊息,當配置其它伺服器時,您可以告訴伺服器該選項沒有使用的值。

請注意,如果您指定localhost作為一個主機名,mysqladmin預設使用Unix套接字檔案連接,而不是TCP/IP。從 MySQL 4.1開始,通過--protocol= TCP | SOCKET | PIPE | MEMORY}選項,您可以顯示地指定連接協議。

如果只是用一個不同的Unix套接字檔案和TCP/IP端口號啟動,不必編譯新的MySQL伺服器。還可以在運行時指定這些值。這樣做的一個方法是使用命令行選項:

shell> mysqld_safe --socket=file_name --port=port_number

要啟動第二個伺服器,提供不同的--socket--port選項值,並且傳遞一個--datadir=path選項給mysqld_safe,以便伺服器使用一個不同的數據目錄。

達到相似效果的另一個方法是使用環境變數來設置 Unix套接字檔案名和TCP/IP端口號:

shell> MYSQL_UNIX_PORT=/tmp/mysqld-new.sock
shell> MYSQL_TCP_PORT=3307
shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT
shell> mysql_install_db --user=mysql
shell> mysqld_safe --datadir=/path/to/datadir &

這是一個快速啟動第二個伺服器以用於測試的方法。該方法的最大好處是環境變數設定值適用於您從相同的shell使用的任何客戶端程式。因而,那些客戶端連接自動指向第二個伺服器!

附錄F:環境變數包括您可以使用的影響mysqld的其它環境變數列資料表

對於自動伺服器啟動,對於每個伺服器,機器引導時執行的啟動指令應執行下面的命令,每個命令用一個相應的選項檔案路徑:

mysqld_safe --defaults-file=path

每個選項檔案應包含一個給定伺服器特定的選項值。

Unix中,mysqld_multi指令是啟動多個伺服器的另一個方法。參見5.1.5節,「mysqld_multi:管理多個MySQL伺服器的程式」

5.12.3. 在多伺服器環境中使用客戶端程式

當您想要用一個客戶端程式連接一個MySQL伺服器時,該伺服器偵聽不同的網絡接口,而不是編譯到您的客戶端的網絡接口,您可以使用下面的方法:

·         啟動客戶端,用--host=host_name --port=port_number通過TCP/IP來連接一個遠程伺服器,用--host=127.0.0.1 --port=port_number通過TCP/IP來連接一個本地伺服器,或者用--host=localhost --socket=file_name通過一個Unix套接字檔案或一個Windows命名管道來連接一個本地伺服器。

·         MySQL 4.1起,啟動客戶端時用--protocol=tcp通過TCP/IP來連接,用--protocol=socket通過一個Unix套接字檔案來連接,用--protocol=pipe通過一個命名管道來連接,或用--protocol=memory通過共享內存來連接。對於TCP/IP連接,您可能還需要指定--host--port選項。對於其它類型的連接,您可能需要指定一個--socket選項來指定一個Unix套接字檔案或命名管道名,或者一個--shared-memory-base-name選項來指定共享內存名。共享內存連接僅在Windows中支援。

·         Unix中,在您啟動客戶端之前,設置MYSQL_UNIX_PORTMYSQL_TCP_PORT環境變數來指定Unix套接字檔案和TCP/IP端口號。如果您經常使用具體的套接字檔案或端口號,您可以在.login檔案中放置命令來設置環境變數以便您每次登錄時該命令起作用。參見附錄F:環境變數

·         在一個選項檔案的[client]組中指定預設Unix套接字檔案和TCP/IP端口號。例如,您可以在Windows中使用C:\my.cnf檔案,或在Unix中主目錄內使用.my.cnf檔案。參見4.3.2節,「使用選項檔案」

·         C程式中,在mysql_real_connect()使用時,您可以指定套接字檔案或端口號參數。通過使用mysql_options()您還可以有程式讀選項檔案。參見25.2.3節,「C API函數描述」

·         如果您正在使用Perl DBD::mysql模塊,您可以從MySQL選項檔案中讀取選項。例如:

·                $dsn = "DBI:mysql:test;mysql_read_default_group=client;"
·                        . "mysql_read_default_file=/usr/local/mysql/data/my.cnf";
·                    $dbh = DBI->connect($dsn, $user, $password);

參見25.4節,「MySQL Perl API」

其它程式接口可以為讀選項檔案提供相似的功能。

5.13. MySQL查詢高速緩衝

查詢緩存儲存SELECT查詢的文本以及發送給客戶端的相應結果。如果隨後收到一個相同的查詢,伺服器從查詢緩存中重新得到查詢結果,而不再需要解析和執行查詢。

如果您有一個不經常改變的資料表並且伺服器收到該資料表的大量相同查詢,查詢緩存在這樣的應用環境中十分有用。對於許多Web伺服器來說存在這種典型情況,它根據資料庫內容生成大量的動態頁面。

釋:查詢緩存不返回舊的數據。當資料表更改後,查詢緩存值的相關條目被清空。

釋:如果您有許多mysqld伺服器更新相同的MyISAM資料表,在這種情況下查詢緩存不起作用。

釋:查詢緩存不適用於伺服器方編寫的語句。如果正在使用伺服器方編寫的語句,要考慮到這些語句將不會應用查詢緩存。參見 25.2.4節,「C API預處理語句」

下面是查詢緩存的一些性能數據。這些結果是在Linux Alpha 2 x 500MHz系統(2GB RAM64MB查詢緩存)上運行MySQL基準組件產生的。

·         如果執行的所有查詢是簡單的(如從只有一行數據的資料表中選取一行),但查詢是不同的,查詢不能被緩存,查詢緩存激活率是13%。這可以看作是最壞的情形。在實際應用中,查詢要複雜得多,因此,查詢緩存使用率一般會很低。

·         從只有一行的資料表中搜尋一行數據時,使用查詢緩存比不使用速度快238%。這可以看作查詢使用緩存時速度提高最小的情況。

伺服器啟動時要禁用查詢緩存,設置query_cache_size系統變數為0。禁用查詢緩存代碼後,沒有明顯的速度提高。編譯MySQL時,通過在configure使用--without-query-cache選項,可以從伺服器中徹底去除查詢緩存能力。

5.13.1. 查詢高速緩衝如何工作

本節描述查詢緩存的工作原理。5.13.3節,「查詢高速緩衝配置」描述了怎樣控制是否使用查詢緩存。

查詢解析之前進行比較,因此下面的兩個查詢被查詢緩存認為是不相同的:

SELECT * FROM tbl_name
Select * from tbl_name

查詢必須是完全相同的(逐字節相同)才能夠被認為是相同的。另外,同樣的查詢字串由於其它原因可能認為是不同的。使用不同的資料庫、不同的協議版本或者不同 預設字元編碼的查詢被認為是不同的查詢並且分別進行緩存。

從查詢緩存中提取一個查詢之前,MySQL檢查用戶對所有相關資料庫和資料表的SELECT權限。如果沒有權限,不使用緩存結果。

如果從查詢緩存中返回一個查詢結果,伺服器把Qcache_hits狀態變數的值加一,而不是Com_select變數。參見5.13.4節,「查詢高速緩衝狀態和維護」

如果一個資料表被更改了,那麼使用那個資料表的所有緩衝查詢將不再有效,並且從緩衝區中移出。這包括那些映射到改變了的資料表的使用MERGE資料表的查詢。一個資料表可以被許多類型的語句更改,例如INSERTUPDATEDELETETRUNCATEALTER TABLEDROP TABLEDROP DATABASE

COMMIT執行完後,被更改的事務InnoDB資料表不再有效。

使用InnoDB資料表時,查詢緩存也在事務中工作,使用該資料表的版本號來檢測其內容是否仍舊是當前的。

MySQL 5.1中,視圖產生的查詢被緩存。

SELECT SQL_CALC_FOUND_ROWS ...SELECT FOUND_ROWS() type類型的查詢使用查詢緩存。即使因建立的行數也被保存在緩衝區內,前面的查詢從緩存中提取,FOUND_ROWS()也返回正確的值。

如果一個查詢包含下面函數中的任何一個,它不會被緩存:

BENCHMARK()

CONNECTION_ID()

CURDATE()

CURRENT_DATE()

CURRENT_TIME()

CURRENT_TIMESTAMP()

CURTIME()

DATABASE()

帶一個參數的ENCRYPT()

FOUND_ROWS()

GET_LOCK()

LAST_INSERT_ID()

LOAD_FILE()

MASTER_POS_WAIT()

NOW()

RAND()

RELEASE_LOCK()

SYSDATE()

不帶參數的UNIX_TIMESTAMP()

USER()

 

在下面的這些條件下,查詢也不會被緩存:

·         引用自行定義函數(UDFs)

·         引用自行定義變數。

·         引用mysql系統資料庫中的資料表。

·         下面方式中的任何一種:

SELECT ...IN SHARE MODE
SELECT ...FOR UPDATE
SELECT ...INTO OUTFILE ...
SELECT ...INTO DUMPFILE ...
SELECT * FROM ...WHERE autoincrement_col IS NULL

最後一種方式不能被緩存是因為它被用作為ODBC工作區來獲取最近插入的ID值。參見26.1.14.1節,「如何在ODBC中獲取AUTO_INCREMENT列的值

·          被作為編寫好的語句,即使沒有使用佔位符。例如,下面使用的查詢:

char *my_sql_stmt = "SELECT ab FROM table_c";
   /* ...*/
mysql_stmt_prepare(stmtmy_sql_stmtstrlen(my_sql_stmt));

不被緩存。參見25.2.4節,「C API預處理語句」

·         使用TEMPORARY資料表。

·         不使用任何資料表。

·         用戶有某個資料表的列級權限。

5.13.2. 查詢高速緩衝SELECT選項

可以在SELECT語句中指定查詢緩存相關選項:

·          SQL_CACHE

如果query_cache_type系統變數的值是ONDEMAND查詢結果被緩存。

·          SQL_NO_CACHE

查詢結果不被緩存。

示範:

SELECT SQL_CACHE id, name FROM customer;
SELECT SQL_NO_CACHE id, name FROM customer;

5.13.3. 查詢高速緩衝配置

通過have_query_cache伺服器系統變數指示查詢緩存是否可用:

mysql> SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| have_query_cache | YES   |
+------------------+-------+

即使禁用查詢緩存,當使用標準 MySQL二進制時,這個值總是YES

其它幾個系統變數控制查詢緩存操作。當啟動mysqld時,這些變數可以在選項檔案或者命令行中設置。所有查詢緩存系統變數名以query_cache_ 開頭。它們的詳細描述見5.3.3節,「伺服器系統變數」,還給出了額外的配置訊息。

為了設置查詢緩存大小,設置query_cache_size系統變數。設置為0資料表示禁用查詢緩存。 預設緩存大小設置為0;也就是禁用查詢緩存。

當設置query_cache_size變數為非零值時,應記住查詢緩存至少大約需要40KB來分配其數據結構。(具體大小取決於系統結構)如果您把該值設置的太小,將會得到一個警告,如本例所示:

mysql> SET GLOBAL query_cache_size = 40000;

Query OK, 0 rows affected, 1 warning (0.00 sec)

 

mysql> SHOW WARNINGS\G

*************************** 1. row ***************************

  Level: Warning

   Code: 1282

Message: Query cache failed to set size 39936; new query cache size is 0

 

mysql> SET GLOBAL query_cache_size = 41984;

Query OK, 0 rows affected (0.00 sec)

 

mysql> SHOW VARIABLES LIKE 'query_cache_size';

+------------------+-------+

| Variable_name    | Value |

+------------------+-------+

| query_cache_size | 41984 |

+------------------+-------+

如果查詢緩存大小設置為大於0query_cache_type變數影響其工作方式。這個變數可以設置為下面的值:

·         0OFF將阻止緩存或查詢緩存結果。

·         1ON將允許緩存,以SELECT SQL_NO_CACHE開始的查詢語句除外。

·         2DEMAND,僅對以SELECT SQL_CACHE開始的那些查詢語句啟用緩存。

設置query_cache_type變數的GLOBAL值將決定更改後所有連接客戶端的緩存行為。具體客戶端可以通過設置query_cache_type變數的會話值控制它們本身連接的緩存行為。例如,一個客戶可以禁用自己的查詢緩存,方法如下:

mysql> SET SESSION query_cache_type = OFF;

要控制可以被緩存的具體查詢結果的最大值,應設置query_cache_limit變數。 預設值是1MB

當一個查詢結果(返回給客戶端的數據)從查詢緩衝中提取期間,它在查詢緩存中排序。因此,數據通常不在大的數據塊中處理。查詢緩存根據數據排序要求分配數據塊,因此,當一個數據塊用完後分配一個新的數據塊。因為內存分配操作是昂貴的(費時的),所以通過query_cache_min_res_unit系統變數給查詢緩存分配最小值。當查詢執行時,最新的結果數據塊根據實際數據大小來確定,因此可以釋放不使用的內存。根據您的伺服器執行查詢的類型,您會發現調整query_cache_min_res_unit變數的值是有用的:

·         query_cache_min_res_unit預設值是4KB。這應該適合大部分情況。

·         如果您有大量返回小結果數據的查詢,預設數據塊大小可能會導致內存碎片,顯示為大量空閒內存塊。由於缺少內存,內存碎片會強制查詢緩存從緩存內存中修整(刪除)查詢。這時,您應該減少query_cache_min_res_unit變數的值。空閒塊和由於修整而移出的查詢的數量通過Qcache_free_blocksQcache_lowmem_prunes變數的值給出。

·          如果大量查詢返回大結果(檢查 Qcache_total_blocksQcache_queries_in_cache狀態變數),您可以通過增加query_cache_min_res_unit變數的值來提高性能。但是,注意不要使它變得太大(參見前面的條目)。

5.13.4. 查詢高速緩衝狀態和維護

可以使用下面的語句檢查MySQL伺服器是否提供查詢緩存功能:

mysql> SHOW VARIABLES LIKE 'have_query_cache';

+------------------+-------+

| Variable_name    | Value |

+------------------+-------+

| have_query_cache | YES   |

+------------------+-------+

可以使用FLUSH QUERY CACHE語句來清理查詢緩存碎片以提高內存使用性能。該語句不從緩存中移出任何查詢。

RESET QUERY CACHE語句從查詢緩存中移出所有查詢。FLUSH TABLES語句也執行同樣的工作。

為了監視查詢緩存性能,使用SHOW STATUS查看緩存狀態變數:

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+--------+
|變數名                   | |
+-------------------------+--------+
| Qcache_free_blocks      | 36     |
| Qcache_free_memory      | 138488 |
| Qcache_hits             | 79570  |
| Qcache_inserts          | 27087  |
| Qcache_lowmem_prunes    | 3114   |
| Qcache_not_cached       | 22989  |
| Qcache_queries_in_cache | 415    |
| Qcache_total_blocks     | 912    |
+-------------------------+--------+

這些變數的描述見5.3.4節,「伺服器狀態變數」。這裡描述它們的一些應用。

SELECT查詢的總數量等價於:

Com_select
+ Qcache_hits
+ queries with errors found by parser

Com_select的值等價於:

Qcache_inserts
+ Qcache_not_cached
+ queries with errors found during columns/rights check

查詢緩存使用長度可變塊,因此Qcache_total_blocksQcache_free_blocks可以顯示查詢緩存內存碎片。執行FLUSH QUERY CACHE後,只保留一個空閒塊。

每個緩存查詢至少需要兩個塊(一個塊用於查詢文本,一個或多個塊用於查詢結果)。並且,每一個查詢使用的每個資料表需要一個塊。但是,如果兩個或多個查詢使用相同的資料表,僅需要分配一個塊。

Qcache_lowmem_prunes狀態變數提供的訊息能夠幫助您您調整查詢緩存的大小。它計算為了緩存新的查詢而從查詢緩衝區中移出到自由內存中的查詢的數目。查詢緩衝區使用最近最少使用(LRU)策略來確定哪些查詢從緩衝區中移出。調整訊息在5.13.3節,「查詢高速緩衝配置」中給出。


這是MySQL參考手冊的翻譯版本,關於MySQL參考手冊,請訪問dev.mysql.com。 原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。