第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服務器上allAUTO_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數據庫本身的權限能用來改變密碼和其他訪問權限信息。密碼被加密存儲,所以惡意的用戶不能簡單地讀取他們以知道明文密碼。然而,具有userPassword列寫訪問權限的用戶可以更改賬戶的密碼,并可以用該賬戶連接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列匹配客戶端主機名和用戶名并且提供了正確的密碼時才接受連接。

userHost值的指定方法:

  • Host值可以是主機名或IP號,或'localhost'指出本地主機。
  • 你可以在Host列值使用通配符字符%_
  • Host'%'匹配任何主機名,空Host值等價于'%'。它們的含義與LIKE操作符的模式匹配操作相同。例如,'%'Host值與所有主機名匹配,而'%.mysql.com'匹配mysql.com域的所有主機。

·         對于指定為IP號的Host值,你可以指定一個網絡掩碼,說明使用多少位地址位來評比網絡號。例如:

·                mysql> GRANT ALL PRIVILEGES ON db.*
·                    -> -> TO [email protected]'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賬戶指定一個密碼,盡管保存在userPassword列的密碼不是明文,但哈希值是從表中的記錄計算的。用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 protected]';

請注意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 protected]';

請注意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 protected]'
    -> AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/
       O=MySQL Finland AB/CN=Tonu Samuel/[email protected]'
    -> 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 <[email protected]com>)

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表方面的問題”

在執行崩潰恢復時,理解在一個數據庫中的每一個MyISAMtbl_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。 原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。

广西11选五走势图彩经网