亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄 搜索
目錄 前言 1. 一般信息 1.1. 關(guān)于本手冊 1.2. 本手冊采用的慣例 1.3. MySQL AB概述 1.4. MySQL數(shù)據(jù)庫管理系統(tǒng)概述 1.4.1. MySQL的歷史 1.4.2. MySQL的的主要特性 1.4.3. MySQL穩(wěn)定性 1.4.4. MySQL表最大能達到多少 1.4.5. 2000年兼容性 1.5. MaxDB數(shù)據(jù)庫管理系統(tǒng)概述 1.5.1. 什么是MaxDB? 1.5.2. MaxDB的歷史 1.5.3. MaxDB的特性 1.5.4. 許可和支持 1.5.5. MaxDB和MySQL之間的特性差異 1.5.6. MaxDB和MySQL之間的協(xié)同性 1.5.7. 與MaxDB有關(guān)的鏈接 1.6. MySQL發(fā)展大事記 1.6.1. MySQL 5.1的新特性 1.7. MySQL信息源 1.7.1. MySQL郵件列表 1.7.2. IRC(在線聊天系統(tǒng))上的MySQL社區(qū)支持 1.7.3. MySQL論壇上的MySQL社區(qū)支持 1.8. MySQL標(biāo)準(zhǔn)的兼容性 1.8.1. MySQL遵從的標(biāo)準(zhǔn)是什么 1.8.2. 選擇SQL模式 1.8.3. 在ANSI模式下運行MySQL 1.8.4. MySQL對標(biāo)準(zhǔn)SQL的擴展 1.8.5. MySQL與標(biāo)準(zhǔn)SQL的差別 1.8.6. MySQL處理約束的方式 2. 安裝MySQL 2.1. 一般安裝問題 2.1.1. MySQL支持的操作系統(tǒng) 2.1.2. 選擇要安裝的MySQL分發(fā)版 2.1.3. 怎樣獲得MySQL 2.1.4. 通過MD5校驗和或GnuPG驗證軟件包的完整性 2.1.5. 安裝布局 2.2. 使用二進制分發(fā)版的標(biāo)準(zhǔn)MySQL安裝 2.3. 在Windows上安裝MySQL 2.3.1. Windows系統(tǒng)要求 2.3.2. 選擇安裝軟件包 2.3.3. 用自動安裝器安裝MySQL 2.3.4. 使用MySQL安裝向?qū)?/a> 2.3.5. 使用配置向?qū)?/a> 2.3.6. 通過非安裝Zip文件安裝MySQL 2.3.7. 提取安裝檔案文件 2.3.8. 創(chuàng)建選項文件 2.3.9. 選擇MySQL服務(wù)器類型 2.3.10. 首次啟動服務(wù)器 2.3.11. 從Windows命令行啟動MySQL 2.3.12. 以Windows服務(wù)方式啟動MySQL 2.3.13. 測試MySQL安裝 2.3.14. 在Windows環(huán)境下對MySQL安裝的故障診斷與排除 2.3.15. 在Windows下升級MySQL 2.3.16. Windows版MySQL同Unix版MySQL對比 2.4. 在Linux下安裝MySQL 2.5.在Mac OS X中安裝MySQL 2.6. 在NetWare中安裝MySQL 2.7. 在其它類Unix系統(tǒng)中安裝MySQL 2.8. 使用源碼分發(fā)版安裝MySQL 2.8.1. 源碼安裝概述 2.8.2. 典型配置選項 2.8.3. 從開發(fā)源碼樹安裝 2.8.4. 處理MySQL編譯問題 2.8.5. MIT-pthreads注意事項 2.8.6. 在Windows下從源碼安裝MySQL 2.8.7. 在Windows下編譯MySQL客戶端 2.9. 安裝后的設(shè)置和測試 2.9.1. Windows下安裝后的過程 2.9.2. Unix下安裝后的過程 2.9.3. 使初始MySQL賬戶安全 2.10. 升級MySQL 2.10.1. 從5.0版升級 2.10.2. 升級授權(quán)表 2.10.3. 將MySQL數(shù)據(jù)庫拷貝到另一臺機器 2.11. 降級MySQL 2.12. 具體操作系統(tǒng)相關(guān)的注意事項 2.12.1. Linux注意事項 2.12.2. Mac OS X注意事項 2.12.3. Solaris注意事項 2.12.4. BSD注意事項 2.12.5. 其它Unix注意事項 2.12.6. OS/2注意事項 2.13. Perl安裝注意事項 2.13.1. 在Unix中安裝Perl 2.13.2. 在Windows下安裝ActiveState Perl 2.13.3. 使用Perl DBI/DBD接口的問題 3. 教程 3.1. 連接與斷開服務(wù)器 3.2. 輸入查詢 3.3. 創(chuàng)建并使用數(shù)據(jù)庫 3.3.1. 創(chuàng)建并選擇數(shù)據(jù)庫 3.3.2. 創(chuàng)建表 3.3.3. 將數(shù)據(jù)裝入表中 3.3.4. 從表檢索信息 3.4. 獲得數(shù)據(jù)庫和表的信息 NoName 3.6. 常用查詢的例子 3.6.1. 列的最大值 3.6.2. 擁有某個列的最大值的行 3.6.3. 列的最大值:按組 3.6.4. 擁有某個字段的組間最大值的行 3.6.5. 使用用戶變量 3.6.6. 使用外鍵 3.6.7. 根據(jù)兩個鍵搜索 3.6.8. 根據(jù)天計算訪問量 3.6.9. 使用AUTO_INCREMENT 3.7. 孿生項目的查詢 3.7.1. 查找所有未分發(fā)的孿生項 3.7.2. 顯示孿生對狀態(tài)的表 3.8. 與Apache一起使用MySQL 4. MySQL程序概述 4.1. MySQL程序概述 4.2. 調(diào)用MySQL程序 4.3. 指定程序選項 4.3.1. 在命令行上使用選項 4.3.2. 使用選項文件 4.3.3. 用環(huán)境變量指定選項 4.3.4. 使用選項設(shè)置程序變量 5. 數(shù)據(jù)庫管理 5.1. MySQL服務(wù)器和服務(wù)器啟動腳本 5.1.1. 服務(wù)器端腳本和實用工具概述 5.1.2. mysqld-max擴展MySQL服務(wù)器 5.1.3. mysqld_safe:MySQL服務(wù)器啟動腳本 5.1.4. mysql.server:MySQL服務(wù)器啟動腳本 5.1.5. mysqld_multi:管理多個MySQL服務(wù)器的程序 5.2. mysqlmanager:MySQL實例管理器 5.2.1. 用MySQL實例管理器啟動MySQL服務(wù)器 5.2.2. 連接到MySQL實例管理器并創(chuàng)建用戶賬戶 5.2.3. MySQL實例管理器命令行選項 5.2.4. MySQL實例管理器配置文件 5.2.5. MySQL實例管理器識別的命令 5.3. mysqld:MySQL服務(wù)器 5.3.1. mysqld命令行選項 5.3.2. SQL服務(wù)器模式 5.3.3. 服務(wù)器系統(tǒng)變量 5.3.4. 服務(wù)器狀態(tài)變量 5.4. mysql_fix_privilege_tables:升級MySQL系統(tǒng)表 5.5. MySQL服務(wù)器關(guān)機進程 5.6. 一般安全問題 5.6.1. 通用安全指南 5.6.2. 使MySQL在攻擊者面前保持安全 5.6.3. Mysqld安全相關(guān)啟動選項 5.6.4. LOAD DATA LOCAL安全問題 5.7. MySQL訪問權(quán)限系統(tǒng) 5.7.1. 權(quán)限系統(tǒng)的作用 5.7.2. 權(quán)限系統(tǒng)工作原理 5.7.3. MySQL提供的權(quán)限 5.7.4. 與MySQL服務(wù)器連接 5.7.5. 訪問控制 5.7.6. 訪問控制 5.7.7. 權(quán)限更改何時生效 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. 設(shè)置賬戶密碼 5.8.6. 使你的密碼安全 5.8.7. 使用安全連接 5.9. 備份與恢復(fù) 5.9.1. 數(shù)據(jù)庫備份 5.9.2. 示例用備份與恢復(fù)策略 5.9.3. 自動恢復(fù) 5.9.4. 表維護和崩潰恢復(fù) 5.9.5. myisamchk:MyISAM表維護實用工具 5.9.6. 建立表維護計劃 5.9.7. 獲取關(guān)于表的信息 5.10. MySQL本地化和國際應(yīng)用 5.10.1. 數(shù)據(jù)和排序用字符集 5.10.2. 設(shè)置錯誤消息語言 5.10.3. 添加新的字符集 5.10.4. 字符定義數(shù)組 5.10.5. 字符串比較支持 5.10.6. 多字節(jié)字符支持 5.10.7. 字符集問題 5.10.8. MySQL服務(wù)器時區(qū)支持 5.11. MySQL日志文件 5.11.1. 錯誤日志 5.11.2. 通用查詢?nèi)罩?/a> 5.11.3. 二進制日志 5.11.4. 慢速查詢?nèi)罩?/a> 5.11.5. 日志文件維護 5.12. 在同一臺機器上運行多個MySQL服務(wù)器 5.12.1. 在Windows下運行多個服務(wù)器 5.12.2. 在Unix中運行多個服務(wù)器 5.12.3. 在多服務(wù)器環(huán)境中使用客戶端程序 5.13. MySQL查詢高速緩沖 5.13.1. 查詢高速緩沖如何工作 5.13.2. 查詢高速緩沖SELECT選項 5.13.3. 查詢高速緩沖配置 5.13.4. 查詢高速緩沖狀態(tài)和維護 6. MySQL中的復(fù)制 6.1. 復(fù)制介紹 6.2. 復(fù)制實施概述 6.3. 復(fù)制實施細(xì)節(jié) 6.3.1. 復(fù)制主線程狀態(tài) 6.3.2. 復(fù)制從I/O線程狀態(tài) 6.3.3. 復(fù)制從SQL線程狀態(tài) 6.3.4. 復(fù)制傳遞和狀態(tài)文件 6.4. 如何設(shè)置復(fù)制 6.5. 不同MySQL版本之間的復(fù)制兼容性 6.6. 升級復(fù)制設(shè)置 6.6.1. 將復(fù)制升級到5.0版 6.7. 復(fù)制特性和已知問題 6.8. 復(fù)制啟動選項 6.9. 復(fù)制FAQ 6.10. 復(fù)制故障診斷與排除 6.11. 通報復(fù)制缺陷 6.12. 多服務(wù)器復(fù)制中的Auto-Increment 7. 優(yōu)化 7.1. 優(yōu)化概述 7.1.1. MySQL設(shè)計局限與折衷 7.1.2. 為可移植性設(shè)計應(yīng)用程序 7.1.3. 我們已將MySQL用在何處? 7.1.4. MySQL基準(zhǔn)套件 7.1.5. 使用自己的基準(zhǔn) 7.2. 優(yōu)化SELECT語句和其它查詢 7.2.1. EXPLAIN語法(獲取SELECT相關(guān)信息) 7.2.2. 估計查詢性能 7.2.3. SELECT查詢的速度 7.2.4. MySQL怎樣優(yōu)化WHERE子句 7.2.5. 范圍優(yōu)化 7.2.6. 索引合并優(yōu)化 7.2.7. MySQL如何優(yōu)化IS NULL 7.2.8. MySQL如何優(yōu)化DISTINCT 7.2.9. MySQL如何優(yōu)化LEFT JOIN和RIGHT JOIN 7.2.10. MySQL如何優(yōu)化嵌套Join 7.2.11. MySQL如何簡化外部聯(lián)合 7.2.12. MySQL如何優(yōu)化ORDER BY 7.2.13. MySQL如何優(yōu)化GROUP BY 7.2.14. MySQL如何優(yōu)化LIMIT 7.2.15. 如何避免表掃描 7.2.16. INSERT語句的速度 7.2.17. UPDATE語句的速度 7.2.18. DELETE語句的速度 7.2.19. 其它優(yōu)化技巧 7.3. 鎖定事宜 7.3.1. 鎖定方法 7.3.2. 表鎖定事宜 7.4. 優(yōu)化數(shù)據(jù)庫結(jié)構(gòu) 7.4.1. 設(shè)計選擇 7.4.2. 使你的數(shù)據(jù)盡可能小 7.4.3. 列索引 7.4.4. 多列索引 7.4.5. MySQL如何使用索引 7.4.6. MyISAM鍵高速緩沖 7.4.7. MyISAM索引統(tǒng)計集合 7.4.8. MySQL如何計算打開的表 7.4.9. MySQL如何打開和關(guān)閉表 7.4.10. 在同一個數(shù)據(jù)庫中創(chuàng)建多個表的缺陷 7.5. 優(yōu)化MySQL服務(wù)器 7.5.1. 系統(tǒng)因素和啟動參數(shù)的調(diào)節(jié) 7.5.2. 調(diào)節(jié)服務(wù)器參數(shù) 7.5.3. 控制查詢優(yōu)化器的性能 7.5.4. 編譯和鏈接怎樣影響MySQL的速度 7.5.5. MySQL如何使用內(nèi)存 7.5.6. MySQL如何使用DNS 7.6. 磁盤事宜 7.6.1. 使用符號鏈接 8. 客戶端和實用工具程序 8.1. 客戶端腳本和實用工具概述 8.2. myisampack:生成壓縮、只讀MyISAM表 8.3. mysql:MySQL命令行工具 8.3.1. 選項 8.3.2. mysql命令 8.3.3. 怎樣從文本文件執(zhí)行SQL語句 8.3.4. mysql技巧 8.4. mysqlaccess:用于檢查訪問權(quán)限的客戶端 8.5. mysqladmin:用于管理MySQL服務(wù)器的客戶端 8.6. mysqlbinlog:用于處理二進制日志文件的實用工具 8.7. mysqlcheck:表維護和維修程序 8.8. mysqldump:數(shù)據(jù)庫備份程序 8.9. mysqlhotcopy:數(shù)據(jù)庫備份程序 8.10. mysqlimport:數(shù)據(jù)導(dǎo)入程序 8.11. mysqlshow-顯示數(shù)據(jù)庫、表和列信息 8.12. myisamlog:顯示MyISAM日志文件內(nèi)容 8.13. perror:解釋錯誤代碼 8.14. replace:字符串替換實用工具 8.15. mysql_zap:殺死符合某一模式的進程 9. 語言結(jié)構(gòu) 9.1. 文字值 9.1.1. 字符串 9.1.2. 數(shù)值 9.1.3. 十六進制值 9.1.4. 布爾值 9.1.5. 位字段值 9.1.6. NULL值 9.2. 數(shù)據(jù)庫、表、索引、列和別名 9.2.1. 識別符限制條件 9.2.2. 識別符大小寫敏感性 9.3. 用戶變量 9.4. 系統(tǒng)變量 9.4.1. 結(jié)構(gòu)式系統(tǒng)變量 9.5. 注釋語法 9.6. MySQL中保留字的處理 10. 字符集支持 10.1. 常規(guī)字符集和校對 10.2. MySQL中的字符集和校對 10.3. 確定默認(rèn)字符集和校對 10.3.1. 服務(wù)器字符集和校對 10.3.2. 數(shù)據(jù)庫字符集和校對 10.3.3. 表字符集和校對 10.3.4. 列字符集和校對 10.3.5. 字符集和校對分配示例 10.3.6. 連接字符集和校對 10.3.7. 字符串文字字符集和校對 10.3.8. 在SQL語句中使用COLLATE 10.3.9. COLLATE子句優(yōu)先 10.3.10. BINARY操作符 10.3.11. 校對確定較為復(fù)雜的一些特殊情況 10.3.12. 校對必須適合字符集 10.3.13. 校對效果的示例 10.4. 字符集支持影響到的操作 10.4.1. 結(jié)果字符串 10.4.2. CONVERT() 10.4.3. CAST() 10.4.4. SHOW語句 10.5. Unicode支持 10.6. 用于元數(shù)據(jù)的UTF8 10.7. 與其它DBMS的兼容性 10.8. 新字符集配置文件格式 10.9. 國家特有字符集 10.10. MySQL支持的字符集和校對 10.10.1. Unicode字符集 10.10.2. 西歐字符集 10.10.3. 中歐字符集 10.10.4. 南歐與中東字符集 10.10.5. 波羅的海字符集 10.10.6. 西里爾字符集 10.10.7. 亞洲字符集 11. 列類型 11.1. 列類型概述 11.1.1. 數(shù)值類型概述 11.1.2. 日期和時間類型概述 11.1.3. 字符串類型概述 11.2. 數(shù)值類型 11.3. 日期和時間類型 11.3.1. DATETIME、DATE和TIMESTAMP類型 11.3.2. TIME類型 11.3.3. YEAR類型 11.3.4. Y2K事宜和日期類型 11.4. String類型 11.4.1. CHAR和VARCHAR類型 11.4.2. BINARY和VARBINARY類型 11.4.3. BLOB和TEXT類型 11.4.4. ENUM類型 11.4.5. SET類型 11.5. 列類型存儲需求 11.6. 選擇正確的列類型 11.7. 使用來自其他數(shù)據(jù)庫引擎的列類型 12. 函數(shù)和操作符 12.1. 操作符 12.1.1. 操作符優(yōu)先級 12.1.2. 圓括號 12.1.3. 比較函數(shù)和操作符 12.1.4. 邏輯操作符 12.2. 控制流程函數(shù) 12.3. 字符串函數(shù) 12.3.1. 字符串比較函數(shù) 12.4. 數(shù)值函數(shù) 12.4.1. 算術(shù)操作符 12.4.2. 數(shù)學(xué)函數(shù) 12.5. 日期和時間函數(shù) 12.6. MySQL使用什么日歷? 12.7. 全文搜索功能 12.7.1. 布爾全文搜索 12.7.2. 全文搜索帶查詢擴展 12.7.3. 全文停止字 12.7.4. 全文限定條件 12.7.5. 微調(diào)MySQL全文搜索 12.8. Cast函數(shù)和操作符 12.9. 其他函數(shù) 12.9.1. 位函數(shù) 12.9.2. 加密函數(shù) 12.9.3. 信息函數(shù) 12.9.4. 其他函數(shù) NoName 12.10.1. GROUP BY(聚合)函數(shù) 12.10.2. GROUP BY修改程序 12.10.3. 具有隱含字段的GROUP BY 13. SQL語句語法 13.1. 數(shù)據(jù)定義語句 13.1.1. ALTER DATABASE語法 13.1.2. ALTER TABLE語法 13.1.3. CREATE DATABASE語法 13.1.4. CREATE INDEX語法 13.1.5. CREATE TABLE語法 13.1.6. DROP DATABASE語法 13.1.7. DROP INDEX語法 13.1.8. DROP TABLE語法 13.1.9. RENAME TABLE語法 13.2. 數(shù)據(jù)操作語句 13.2.1. DELETE語法 13.2.2. DO語法 13.2.3. HANDLER語法 13.2.4. INSERT語法 13.2.5. LOAD DATA INFILE語法 13.2.6. REPLACE語法 13.2.7. SELECT語法 13.2.8. Subquery語法 13.2.9. TRUNCATE語法 13.2.10. UPDATE語法 13.3. MySQL實用工具語句 13.3.1. DESCRIBE語法(獲取有關(guān)列的信息) 13.3.2. USE語法 13.4. MySQL事務(wù)處理和鎖定語句 13.4.1. START TRANSACTION 13.4.2. 不能回滾的語句 13.4.3. 會造成隱式提交的語句 13.4.4. SAVEPOINT和ROLLBACK TO SAVEPOINT語法 13.4.5. LOCK TABLES和UNLOCK TABLES語法 13.4.6. SET TRANSACTION語法 13.4.7. XA事務(wù) 13.5. 數(shù)據(jù)庫管理語句 13.5.1. 賬戶管理語句 13.5.2. 表維護語句 13.5.3. SET語法 13.5.4. SHOW語法 13.5.5. 其它管理語句 13.6. 復(fù)制語句 13.6.1. 用于控制主服務(wù)器的SQL語句 13.6.2. 用于控制從服務(wù)器的SQL語句 13.7. 用于預(yù)處理語句的SQL語法 14. 插件式存儲引擎體系結(jié)構(gòu) 14.1. 前言 14.2. 概述 14.3. 公共MySQL數(shù)據(jù)庫服務(wù)器層 14.4. 選擇存儲引擎 14.5. 將存儲引擎指定給表 14.6. 存儲引擎和事務(wù) 14.7. 插入存儲引擎 14.8. 拔出存儲引擎 14.9. 插件式存儲器的安全含義 15. 存儲引擎和表類型 15.1. MyISAM存儲引擎 15.1.1. MyISAM啟動選項 15.1.2. 鍵所需的空間 15.1.3. MyISAM表的存儲格式 15.1.4. MyISAM表方面的問題 15.2. InnoDB存儲引擎 15.2.1. InnoDB概述 15.2.2. InnoDB聯(lián)系信息 15.2.3. InnoDB配置 15.2.4. InnoDB啟動選項 15.2.5. 創(chuàng)建InnoDB表空間 15.2.6. 創(chuàng)建InnoDB表 15.2.7. 添加和刪除InnoDB數(shù)據(jù)和日志文件 15.2.8. InnoDB數(shù)據(jù)庫的備份和恢復(fù) 15.2.9. 將InnoDB數(shù)據(jù)庫移到另一臺機器上 15.2.10. InnoDB事務(wù)模型和鎖定 15.2.11. InnoDB性能調(diào)節(jié)提示 15.2.12. 多版本的實施 15.2.13. 表和索引結(jié)構(gòu) 15.2.14. 文件空間管理和磁盤I/O 15.2.15. InnoDB錯誤處理 15.2.16. 對InnoDB表的限制 15.2.17. InnoDB故障診斷與排除 15.3. MERGE存儲引擎 15.3.1. MERGE表方面的問題 15.4. MEMORY (HEAP)存儲引擎 15.5. BDB (BerkeleyDB)存儲引擎 15.5.1. BDB支持的操作系統(tǒng) 15.5.2. 安裝BDB 15.5.3. BDB啟動選項 15.5.4. BDB表的特性 15.5.5. 修改BDB所需的事宜 15.5.6. 對BDB表的限制 15.5.7. 使用BDB表時可能出現(xiàn)的錯誤 15.6. EXAMPLE存儲引擎 15.7. FEDERATED存儲引擎 15.7.1. 安裝FEDERATED存儲引擎 15.7.2. FEDERATED存儲引擎介紹 15.7.3. 如何使用FEDERATED表 15.7.4. FEDERATED存儲引擎的局限性 15.8. ARCHIVE存儲引擎 15.9. CSV存儲引擎 15.10. BLACKHOLE存儲引擎 16. 編寫自定義存儲引擎 16.1. 前言 16.2. 概述 16.3. 創(chuàng)建存儲引擎源文件 NoName 16.5. 對處理程序進行實例化處理 16.6. 定義表擴展 16.7. 創(chuàng)建表 16.8. 打開表 16.9. 實施基本的表掃描功能 16.9.1. 實施store_lock()函數(shù) 16.9.2. 實施external_lock()函數(shù) 16.9.3. 實施rnd_init()函數(shù) 16.9.4. 實施info()函數(shù) 16.9.5. 實施extra()函數(shù) 16.9.6. 實施rnd_next()函數(shù) 16.10. 關(guān)閉表 NoName NoName NoName 16.14. API引用 16.14.1. bas_ext 16.14.2. close 16.14.3. create 16.14.4. delete_row 16.14.5. delete_table 16.14.6. external_lock 16.14.7. extra 16.14.8. info 16.14.9. open 16.14.10. rnd_init 16.14.11. rnd_next 16.14.12. store_lock 16.14.13. update_row 16.14.14. write_row 17. MySQL簇 17.1. MySQL簇概述 17.2. MySQL簇的基本概念 17.3. 多計算機的簡單基礎(chǔ)知識 17.3.1. 硬件、軟件和聯(lián)網(wǎng) 17.3.2. 安裝 17.3.3. 配置 17.3.4. 首次啟動 17.3.5. 加載示例數(shù)據(jù)并執(zhí)行查詢 17.3.6. 安全關(guān)閉和重啟 17.4. MySQL簇的配置 17.4.1. 從源碼創(chuàng)建MySQL簇 17.4.2. 安裝軟件 17.4.3. MySQL簇的快速測試設(shè)置 17.4.4. 配置文件 17.5. MySQL簇中的進程管理 17.5.1. 用于MySQL簇的MySQL服務(wù)器進程使用 17.5.2. ndbd,存儲引擎節(jié)點進程 17.5.3. ndb_mgmd,“管理服務(wù)器”進程 17.5.4. ndb_mgm,“管理客戶端”進程 17.5.5. 用于MySQL簇進程的命令選項 17.6. MySQL簇的管理 17.6.1. MySQL簇的啟動階段 17.6.2. “管理客戶端”中的命令 17.6.3. MySQL簇中生成的事件報告 17.6.4. 單用戶模式 17.6.5. MySQL簇的聯(lián)機備份 17.7. 使用與MySQL簇的高速互連 17.7.1. 配置MySQL簇以使用SCI套接字 17.7.2. 理解簇互連的影響 17.8. MySQL簇的已知限制 17.9. MySQL簇發(fā)展的重要歷程 17.9.1. MySQL 5.0中的MySQL簇變化 17.9.2. 關(guān)于MySQL簇的MySQL 5.1發(fā)展歷程 17.10. MySQL簇常見問題解答 17.11. MySQL簇術(shù)語表 18. 分區(qū) 18.1. MySQL中的分區(qū)概述 18.2. 分區(qū)類型 18.2.1. RANGE分區(qū) 18.2.2. LIST分區(qū) 18.2.3. HASH分區(qū) 18.2.4. KEY分區(qū) 18.2.5. 子分區(qū) 18.2.6. MySQL分區(qū)處理NULL值的方式 18.3. 分區(qū)管理 18.3.1. RANGE和LIST分區(qū)的管理 18.3.2. HASH和KEY分區(qū)的管理 18.3.3. 分區(qū)維護 18.3.4. 獲取關(guān)于分區(qū)的信息 19. MySQL中的空間擴展 19.1. 前言 19.2. OpenGIS幾何模型 19.2.1. Geometry類的層次 19.2.2. 類Geometry 19.2.3. 類Point 19.2.4. 類Curve 19.2.5. 類LineString 19.2.6. 類Surface 19.2.7. 類Polygon 19.2.8. 類GeometryCollection 19.2.9. 類MultiPoint 19.2.10. 類MultiCurve 19.2.11. 類MultiLineString 19.2.12. 類MultiSurface 19.2.13. 類MultiPolygon 19.3. 支持的空間數(shù)據(jù)格式 19.3.1. 著名的文本(WKT)格式 19.3.2. 著名的二進制(WKB)格式 19.4. 創(chuàng)建具備空間功能的MySQL數(shù)據(jù)庫 19.4.1. MySQL空間數(shù)據(jù)類型 19.4.2. 創(chuàng)建空間值 19.4.3. 創(chuàng)建空間列 19.4.4. 填充空間列 19.4.5. 獲取空間數(shù)據(jù) 19.5. 分析空間信息 19.5.1. Geometry格式轉(zhuǎn)換函數(shù) 19.5.2. Geometry函數(shù) 19.5.3. 從已有Geometry創(chuàng)建新Geometry的函數(shù) 19.5.4. 測試幾何對象間空間關(guān)系的函數(shù) 19.5.5. 關(guān)于幾何最小邊界矩形(MBR)的關(guān)系 19.5.6. 測試幾何類之間空間關(guān)系的函數(shù) 19.6. 優(yōu)化空間分析 19.6.1. 創(chuàng)建空間索引 19.6.2. 使用空間索引 19.7. MySQL的一致性和兼容性 19.7.1. 尚未實施的GIS特性 20. 存儲程序和函數(shù) 20.1. 存儲程序和授權(quán)表 20.2. 存儲程序的語法 20.2.1. CREATE PROCEDURE和CREATE FUNCTION 20.2.2. ALTER PROCEDURE和ALTER FUNCTION 20.2.3. DROP PROCEDURE和DROP FUNCTION 20.2.4.SHOW CREATE PROCEDURE和SHOW CREATE FUNCTION 20.2.5.SHOW PROCEDURE STATUS和SHOW FUNCTION STATUS 20.2.6. CALL語句 20.2.7. BEGIN ... END復(fù)合語句 20.2.8. DECLARE語句 20.2.9. 存儲程序中的變量 20.2.10. 條件和處理程序 20.2.11. 光標(biāo) 20.2.12. 流程控制構(gòu)造 20.3. 存儲程序、函數(shù)、觸發(fā)程序和復(fù)制:常見問題 20.4. 存儲子程序和觸發(fā)程序的二進制日志功能 21. 觸發(fā)程序 21.1. CREATE TRIGGER語法 21.2. DROP TRIGGER語法 21.3. 使用觸發(fā)程序 22. 視圖 22.1. ALTER VIEW語法 22.2. CREATE VIEW語法 22.3. DROP VIEW語法 22.4. SHOW CREATE VIEW語法 23. INFORMATION_SCHEMA信息數(shù)據(jù)庫 23.1. INFORMATION_SCHEMA表 23.1.1. INFORMATION_SCHEMA SCHEMATA表 23.1.2. INFORMATION_SCHEMA TABLES表 23.1.3. INFORMATION_SCHEMA COLUMNS表 23.1.4. INFORMATION_SCHEMA STATISTICS表 23.1.5. INFORMATION_SCHEMA USER_PRIVILEGES表 23.1.6. INFORMATION_SCHEMA SCHEMA_PRIVILEGES表 23.1.7. INFORMATION_SCHEMA TABLE_PRIVILEGES表 23.1.8. INFORMATION_SCHEMA COLUMN_PRIVILEGES表 23.1.9. INFORMATION_SCHEMA CHARACTER_SETS表 23.1.10. INFORMATION_SCHEMA COLLATIONS表 23.1.11. INFORMATION_SCHEMA COLLATION_CHARACTER_SET_APPLICABILITY表 23.1.12. INFORMATION_SCHEMA TABLE_CONSTRAINTS表 23.1.13. INFORMATION_SCHEMA KEY_COLUMN_USAGE表 23.1.14. INFORMATION_SCHEMA ROUTINES表 23.1.15. INFORMATION_SCHEMA VIEWS表 23.1.16. INFORMATION_SCHEMA TRIGGERS表 23.1.17. 其他INFORMATION_SCHEMA表 NoName 24. 精度數(shù)學(xué) 24.1. 數(shù)值的類型 24.2. DECIMAL數(shù)據(jù)類型更改 24.3. 表達式處理 24.4. 四舍五入 24.5. 精度數(shù)學(xué)示例 25. API和庫 25.1. libmysqld,嵌入式MySQL服務(wù)器庫 25.1.1. 嵌入式MySQL服務(wù)器庫概述 25.1.2. 使用libmysqld編譯程序 25.1.3. 使用嵌入式MySQL服務(wù)器時的限制 25.1.4. 與嵌入式服務(wù)器一起使用的選項 25.1.5. 嵌入式服務(wù)器中尚需完成的事項(TODO) 25.1.6. 嵌入式服務(wù)器示例 25.1.7. 嵌入式服務(wù)器的許可 25.2. MySQL C API 25.2.1. C API數(shù)據(jù)類型 25.2.2. C API函數(shù)概述 25.2.3. C API函數(shù)描述 25.2.4. C API預(yù)處理語句 25.2.5. C API預(yù)處理語句的數(shù)據(jù)類型 25.2.6. C API預(yù)處理語句函數(shù)概述 25.2.7. C API預(yù)處理語句函數(shù)描述 25.2.8. C API預(yù)處理語句方面的問題 25.2.9. 多查詢執(zhí)行的C API處理 25.2.10. 日期和時間值的C API處理 25.2.11. C API線程函數(shù)介紹 25.2.12. C API嵌入式服務(wù)器函數(shù)介紹 25.2.13. 使用C API時的常見問題 25.2.14. 創(chuàng)建客戶端程序 25.2.15. 如何生成線程式客戶端 25.3. MySQL PHP API 25.3.1. 使用MySQL和PHP的常見問題 25.4. MySQL Perl API 25.5. MySQL C++ API 25.5.1. Borland C++ 25.6. MySQL Python API 25.7. MySQL Tcl API 25.8. MySQL Eiffel Wrapper 25.9. MySQL程序開發(fā)實用工具 25.9.1. msql2mysql:轉(zhuǎn)換mSQL程序以用于MySQL 25.9.2. mysql_config:獲取編譯客戶端的編譯選項 26. 連接器 26.1. MySQL Connector/ODBC 26.1.1. MyODBC介紹 26.1.2. 關(guān)于ODBC和MyODBC的一般信息 26.1.3. 如何安裝MyODBC 26.1.4. 在Windows平臺上從二進制版本安裝MyODBC 26.1.5. I在Unix平臺上從二進制版本安裝MyODBC 26.1.6. 在Windows平臺上從源碼版本安裝MyODBC 26.1.7. 在Unix平臺上從源碼版本安裝MyODBC 26.1.8. 從BitKeeper開發(fā)源碼樹安裝MyODBC 26.1.9. MyODBC配置 26.1.10. 與MyODBC連接相關(guān)的事宜 26.1.11. MyODBC和Microsoft Access 26.1.12. MyODBC和Microsoft VBA及ASP 26.1.13. MyODBC和第三方ODBC工具 26.1.14. MyODBC通用功能 26.1.15. 基本的MyODBC應(yīng)用步驟 26.1.16. MyODBC API引用 26.1.17. MyODBC數(shù)據(jù)類型 26.1.18. MyODBC錯誤代碼 26.1.19. MyODBC與VB:ADO、DAO和RDO 26.1.20. MyODBC與Microsoft.NET 26.1.21. 感謝 26.2. MySQL Connector/NET 26.2.1. 前言 26.2.2. 下載并安裝MySQL Connector/NET 26.2.3. Connector/NET體系結(jié)構(gòu) 26.2.4. 使用MySQL Connector/NET 26.2.5. MySQL Connector/NET變更史 26.3. MySQL Connector/J 26.3.1. 基本的JDBC概念 26.3.2. 安裝 Connector/J 26.3.3. JDBC引用 26.3.4. 與J2EE和其他Java框架一起使用 Connector/J 26.3.5. 診斷 Connector/J方面的問題 26.3.6. Changelog 26.4. MySQL Connector/MXJ 26.4.1. 前言 26.4.2. 支持平臺: 26.4.3. Junit測試要求 26.4.4. 運行Junit測試 26.4.5. 作為JDBC驅(qū)動程序的一部分運行 26.4.6. 在Java對象中運行 26.4.7. MysqldResource API 26.4.8. 在JMX代理(custom)中運行 26.4.9. 部署在標(biāo)準(zhǔn)的JMX代理環(huán)境下 (JBoss) 26.4.10. 安裝 27. 擴展MySQL 27.1. MySQL內(nèi)部控件 27.1.1. MySQL線程 27.1.2. MySQL測試套件 27.2. 為MySQL添加新函數(shù) 27.2.1. 自定義函數(shù)接口的特性 27.2.2. CREATE FUNCTION/DROP FUNCTION語法 27.2.3. 添加新的自定義函數(shù) 27.2.4. 添加新的固有函數(shù) 27.3. 為MySQL添加新步驟 27.3.1. 步驟分析 27.3.2. 編寫步驟 A. 問題和常見錯誤 A.1. 如何確定導(dǎo)致問題的原因 A.2. 使用MySQL程序時的常見錯誤 A.2.1. 拒絕訪問 A.2.2. 無法連接到[local] MySQL服務(wù)器 A.2.3. 客戶端不支持鑒定協(xié)議 A.2.4. 輸入密碼時出現(xiàn)密碼錯誤 NoName A.2.6. 連接數(shù)過多 A.2.7. 內(nèi)存溢出 A.2.8. MySQL服務(wù)器不可用 A.2.9. 信息包過大 A.2.10. 通信錯誤和失效連接 A.2.11. 表已滿 A.2.12. 無法創(chuàng)建文件/寫入文件 A.2.13. 命令不同步 A.2.14. 忽略用戶 A.2.15. 表tbl_name不存在 A.2.16. 無法初始化字符集 A.2.17. 文件未找到 A.3. 與安裝有關(guān)的事宜 A.3.1. 與MySQL客戶端庫的鏈接問題 A.3.2. 如何以普通用戶身份運行MySQL A.3.3. 與文件許可有關(guān)的問題 A.4. 與管理有關(guān)的事宜 A.4.1. 如何復(fù)位根用戶密碼 A.4.2. 如果MySQL依然崩潰,應(yīng)作些什么 A.4.3. MySQL處理磁盤滿的方式 A.4.4. MySQL將臨時文件儲存在哪里 A.4.5. 如何保護或更改MySQL套接字文件/tmp/mysql.sock A.4.6. 時區(qū)問題 A.5. 與查詢有關(guān)的事宜 A.5.1. 搜索中的大小寫敏感性 A.5.2. 使用DATE列方面的問題 A.5.3. 與NULL值有關(guān)的問題 A.5.4. 與列別名有關(guān)的問題 A.5.5. 非事務(wù)表回滾失敗 A.5.6. 從相關(guān)表刪除行 A.5.7. 解決與不匹配行有關(guān)的問題 A.5.8. 與浮點比較有關(guān)的問題 A.6. 與優(yōu)化器有關(guān)的事宜 A.7. 與表定義有關(guān)的事宜 A.7.1. 與ALTER TABLE有關(guān)的問題 A.7.2. 如何更改表中的列順序 A.7.3. TEMPORARY TABLE問題 A.8. MySQL中的已知事宜 A.8.1. MySQL中的打開事宜 B. 錯誤代碼和消息 B.1. 服務(wù)器錯誤代碼和消息 B.2. 客戶端錯誤代碼和消息 C. 感謝 C.1. MySQL AB處的開發(fā)人 C.2. MySQL貢獻人 C.3. 資料員和譯員 C.4. MySQL使用和包含的庫 C.5. 支持MySQL的軟件包 C.6. 用于創(chuàng)建MySQL的工具 C.7. MySQL支持人員 D. MySQL變更史 D.1. 5.1.x版中的變更情況(開發(fā)) D.1.1. 5.1.2版中的變更情況(尚未發(fā)布) D.1.2. 5.1.1版中的變更情況(尚未發(fā)布) D.2. MyODBC的變更情況 D.2.1. MyODBC 3.51.12的變更情況 D.2.2. MyODBC 3.51.11的變更情況 E. 移植到其他系統(tǒng) E.1. 調(diào)試MySQL服務(wù)器 E.1.1. 針對調(diào)試編譯MySQL E.1.2. 創(chuàng)建跟蹤文件 E.1.3. 在gdb環(huán)境下調(diào)試mysqld E.1.4. 使用堆棧跟蹤 E.1.5. 使用日志文件找出mysqld中的錯誤原因 E.1.6. 如果出現(xiàn)表崩潰,請生成測試案例 E.2. 調(diào)試MySQL客戶端 E.3. DBUG軟件包 E.4. 關(guān)于RTS線程的注釋 E.5. 線程軟件包之間的差異 F. 環(huán)境變量 G. MySQL正則表達式 H. MySQL中的限制 H.1. 聯(lián)合的限制 I. 特性限制 I.1. 對存儲子程序和觸發(fā)程序的限制 I.2. 對服務(wù)器端光標(biāo)的限制 I.3. 對子查詢的限制 I.4. 對視圖的限制 I.5. 對XA事務(wù)的限制 J. GNU通用公共許可 K. MySQL FLOSS許可例外 索引
文字

第16章:編寫自定義存儲引擎

目錄

16.1. 前言
16.2. 概述
16.3. 創(chuàng)建存儲引擎源文件
16.4. 創(chuàng)建handlerton
16.5. 對處理程序進行實例化處理
16.6. 定義表擴展
16.7. 創(chuàng)建表
16.8. 打開表
16.9. 實施基本的表掃描功能
16.9.1. 實施store_lock()函數(shù)
16.9.2. 實施external_lock()函數(shù)
16.9.3. 實施rnd_init()函數(shù)
16.9.4. 實施info()函數(shù)
16.9.5. 實施extra()函數(shù)
16.9.6. 實施rnd_next()函數(shù)
16.10. 關(guān)閉表
16.11. 為存儲引擎添加對INSERT的支持
16.12. 為存儲引擎添加對UPDATE的支持
16.13. 為存儲引擎添加對DELETE的支持
16.14. API引用
16.14.1. bas_ext
16.14.2. close
16.14.3. create
16.14.4. delete_row
16.14.5. delete_table
16.14.6. external_lock
16.14.7. extra
16.14.8. info
16.14.9. open
16.14.10. rnd_init
16.14.11. rnd_next
16.14.12. store_lock
16.14.13. update_row
16.14.14. write_row

16.1.?前言

對于MySQL 5.1,MySQL AB公司引入了插件式存儲引擎體系結(jié)構(gòu),這樣,就能創(chuàng)建新的存儲引擎,并將它們添加到正在運行的MySQL服務(wù)器上,而不必重新編譯服務(wù)器本身。

該體系結(jié)構(gòu)簡化了新存儲引擎的開發(fā)和部署。

本章的意圖是作為指南,用于幫助你為新的插件式存儲引擎體系結(jié)構(gòu)開發(fā)存儲引擎。

關(guān)于MySQL插件式存儲引擎體系結(jié)構(gòu)的更多信息,請參見第14章:插件式存儲引擎體系結(jié)構(gòu)。

16.2.?概述

MySQL服務(wù)器采用了模塊化風(fēng)格。

圖16.1:MySQL體系結(jié)構(gòu)

MySQL architecture
存儲引擎負(fù)責(zé)管理數(shù)據(jù)存儲,以及MySQL的索引管理。通過定義的APIMySQL服務(wù)器能夠與存儲引擎進行通信。

每個存儲引擎均是1個繼承類,每個類實例作為處理程序而被引用。

針對需要與特殊表一起工作的每個線程,處理程序是在1個處理程序的基礎(chǔ)上實例化的。例如,如果3個連接全都在相同的表上工作,需要創(chuàng)建3個處理程序?qū)嵗?/p>

一旦創(chuàng)建了處理程序?qū)嵗?span>MySQL服務(wù)器將向處理程序發(fā)送命令,以便執(zhí)行數(shù)據(jù)存儲和檢索任務(wù),如打開表、操縱行和管理索引等。

能夠以累進方式創(chuàng)建定制存儲引擎:開發(fā)人員能夠以只讀存儲引擎啟動,隨后添加對INSERT、UPDATEDELETE操作的支持,甚至能夠增加對索引功能、事務(wù)和其他高級操作的支持。

16.3.?創(chuàng)建存儲引擎源文件

實施新存儲引擎的最簡單方法是,通過拷貝和更改EXAMPLE存儲引擎開始。在MySQL 5.1源碼樹的sql/examples/目錄下可找到文件ha_example.ccha_example.h。關(guān)于如何獲得5.1源碼樹的說明,請參見2.8.3節(jié),“從開發(fā)源碼樹安裝”。

復(fù)制文件時,將名稱從ha_example.ccha_example.h更改為與存儲引擎相適應(yīng)的名稱,如ha_foo.ccha_foo.h

拷貝并重命名了這些文件后,必須更換所有的EXAMPLE示例,以及具有存儲引擎名稱的示例。如果你熟悉sed,也能自動完成這些步驟:

sed s/EXAMPLE/FOO/g ha_example.h | sed s/example/foo/g ha_foo.h
sed s/EXAMPLE/FOO/g ha_example.cc | sed s/example/foo/g ha_foo.cc

16.4.?創(chuàng)建handlerton

handlerton(“單個處理程序”的簡稱定義了存儲引擎,并包含指向函數(shù)的函數(shù)指針,它以整體方式作用在引擎上,而函數(shù)工作在單獨的處理程序?qū)嵗?。在這類函數(shù)的一些示例中,包含用于處理注釋和回滾的事務(wù)函數(shù)。

下面給出了一個來自EXAMPLE存儲引擎的示例:

handlerton example_hton= {
? "EXAMPLE",
? SHOW_OPTION_YES,
? "Example storage engine", 
??DB_TYPE_EXAMPLE_DB,
? NULL,??? 
? 0,?????? 
? 0,?????? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? example_create_handler,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? NULL,??? 
? HTON_CAN_RECREATE
};

下面給出了來自handler.hhandlerton定義:

typedef struct
? {
??? const char *name;
??? SHOW_COMP_OPTION state;
??? const char *comment;
??? enum db_type db_type;
??? bool (*init)();
??? uint slot;
??? uint savepoint_offset;
??? int? (*close_connection)(THD *thd);
??? int? (*savepoint_set)(THD *thd, void *sv);
??? int? (*savepoint_rollback)(THD *thd, void *sv);
??? int? (*savepoint_release)(THD *thd, void *sv);
??? int? (*commit)(THD *thd, bool all);
?? ?int? (*rollback)(THD *thd, bool all);
??? int? (*prepare)(THD *thd, bool all);
??? int? (*recover)(XID *xid_list, uint len);
??? int? (*commit_by_xid)(XID *xid);
??? int? (*rollback_by_xid)(XID *xid);
??? void *(*create_cursor_read_view)();
??? void (*set_cursor_read_view)(void *);
??? void (*close_cursor_read_view)(void *);
??? handler *(*create)(TABLE *table);
??? void (*drop_database)(char* path);
??? int (*panic)(enum ha_panic_function flag);
??? int (*release_temporary_latches)(THD *thd);
??? int (*update_statistics)();
??? int (*start_consistent_snapshot)(THD *thd);
??? bool (*flush_logs)();
??? bool (*show_status)(THD *thd, stat_print_fn *print, enum ha_stat_type stat);
??? int (*repl_report_sent_binlog)(THD *thd, char *log_file_name, my_off_t end_offset);
??? uint32 flags;??????????????????????????????? 
??} handlerton;? 

共有30handlerton元素,但只有少量元素是強制性的(明確地講是前4個元素和第21個元素)。

1.??? 存儲引擎的名稱。這是創(chuàng)建表時將使用的名稱(CREATE TABLE ... ENGINE = FOO;)。

2.??? 確定使用SHOW STORAGE ENGINES命令時是否列出存儲引擎。

3.??? 存儲引擎注釋,對使用SHOW STORAGE ENGINES命令時顯示的存儲引擎的描述。

4.??? MySQL服務(wù)器內(nèi)唯一識別存儲引擎的整數(shù)。內(nèi)置存儲引擎使用的常數(shù)定義在handler.h文件中。作為創(chuàng)建常數(shù)的可選方法,可使用大于25的整數(shù)。

5.??? 指向存儲引擎初始化程序的指針。僅當(dāng)啟動服務(wù)器時才調(diào)用該函數(shù),以便在實例化處理程序之前,存儲引擎類能執(zhí)行必要的內(nèi)務(wù)操作。

6.??? 插槽。保存每連接的信息時,每個存儲引擎在thd中有自己的內(nèi)存區(qū)域(實際上為指針)。它是作為thd->ha_data[foo_hton.slot]訪問的。插槽編號在調(diào)用foo_init()MySQL初始化。

7.??? 保存點偏移。為了保存每個savepoint數(shù)據(jù),為存儲引擎提供了請求的大?。ǖ湫颓闆r下為0)。

必須以靜態(tài)方式初始化savepoint偏移,使其具有所有的內(nèi)存大小,以便保存每個savepoint的信息。在foo_init之后,它被更改為savepoint存儲區(qū)域的偏移,存儲引擎不需要使用它。

8.??? 由事務(wù)性存儲引擎使用,清理其存儲段內(nèi)分配的內(nèi)存,和/或回滾任何未完成的事務(wù)。

9.??? 由事務(wù)性存儲引擎選擇性使用,創(chuàng)建savepoint(保存點),并將其保存到提供的內(nèi)存中。

10.指向處理程序rollback_to_savepoint()函數(shù)的函數(shù)指針。它用于在事務(wù)期間返回savepoint。僅對支持保存點的存儲引擎才會填充它。

11.指向處理程序release_savepoint()函數(shù)的函數(shù)指針。它用于在事務(wù)期間釋放保存點的資源。僅對支持保存點的存儲引擎才會填充它。

12.指向處理程序commit()函數(shù)的函數(shù)指針。它用于提交事務(wù)。僅對支持事務(wù)的存儲引擎才會填充它。

13.指向處理程序rollback()函數(shù)的函數(shù)指針。它用于回滾交易。僅對支持事務(wù)的存儲引擎才會填充它。

14.XA事務(wù)性存儲引擎所需。為提交操作準(zhǔn)備事務(wù)。將XID與事務(wù)關(guān)聯(lián)起來。

15.XA事務(wù)性存儲引擎所需?;謴?fù)由XID標(biāo)識的事務(wù)。

16.XA事務(wù)性存儲引擎所需。提交由XID標(biāo)識的事務(wù)。

17.XA事務(wù)性存儲引擎所需。回滾由XID標(biāo)識的事務(wù)。

18.與服務(wù)器端光標(biāo)一起使用,尚未實施。

19.與服務(wù)器端光標(biāo)一起使用,尚未實施。

20.與服務(wù)器端光標(biāo)一起使用,尚未實施。

21.MANDATORY:構(gòu)造并返回處理程序?qū)嵗?/p>

22.撤銷方案時,如果存儲引擎需要執(zhí)行特殊步驟時使用(如在使用表空間的存儲引擎中使用)。

23.清理在服務(wù)器關(guān)閉和崩潰時調(diào)用的函數(shù)。

24.InnoDB特殊函數(shù)。

25.在啟動SHOW STATUS時調(diào)用InnoDB特殊函數(shù)

26.調(diào)用InnoDB特殊函數(shù)以開始連續(xù)讀取。

27.調(diào)用它,指明應(yīng)將日志刷新為可靠的存儲。

28.在存儲引擎上提供可被人員讀取的狀態(tài)信息。

29.InnoDB特殊函數(shù)用于復(fù)制。

30.Handlerton標(biāo)志,通常與ALTER TABLE相關(guān)。可能的值定義于sql/handler.h文件中,并在此列出;

31.?????? #define HTON_NO_FLAGS???????????????? 0
32.?????? #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
33.?????? #define HTON_ALTER_NOT_SUPPORTED ????(1 << 1)
34.?????? #define HTON_CAN_RECREATE??????????? (1 << 2)
35.?????? #define HTON_FLUSH_AFTER_RENAME????? (1 << 3)
36.?????? #define HTON_NOT_USER_SELECTABLE???? (1 << 4)

HTON_ALTER_NOT_SUPPORTEDFEDERATED存儲引擎使用,用以指明存儲引擎不接受AFTER TABLE語句。

HTON_FLUSH_AFTER_RENAME指明,重命名表后 ,必須調(diào)用FLUSH LOGS。

HTON_NOT_USER_SELECTABLE指明存儲引擎不能由用戶選擇,而是用作系統(tǒng)存儲引擎,如用于二進制日志的偽存儲引擎。

16.5.?對處理程序進行實例化處理

調(diào)用存儲引擎的第1個方法是調(diào)用新的處理程序?qū)嵗?/p>

在存儲引擎源文件中定義handlerton之前,必須定義用于函數(shù)實例化的函數(shù)題頭。下面給出了1個來自CSV引擎的示例:

static handler* tina_create_handler(TABLE *table);

正如你所見到的那樣,函數(shù)接受指向處理程序準(zhǔn)備管理的表的指針,并返回處理程序?qū)ο蟆?/p>

定義了函數(shù)題頭后,用第21handlerton元素中的函數(shù)指針命名函數(shù),指明函數(shù)負(fù)責(zé)生成新的處理程序?qū)嵗?/p>

下面給出了MyISAM存儲引擎的實例化函數(shù)示例:

static handler *myisam_create_handler(TABLE *table)
? {
? ??return new ha_myisam(table);
? }

該調(diào)用隨后與存儲引擎的構(gòu)造程序一起工作。下面給出了來自FEDERATED存儲引擎的1個示例:

ha_federated::ha_federated(TABLE *table_arg)
? :handler(&federated_hton, table_arg),
? mysql(0), stored_result(0), scan_flag(0),
? ref_length(sizeof(MYSQL_ROW_OFFSET)), current_position(0)
? {}

下面給出了來自EXAMPLE存儲引擎的另一個示例:

ha_example::ha_example(TABLE *table_arg)
? :handler(&example_hton, table_arg)
? {}? 

FEDERATED示例中的附加元素是處理程序的額外初始化要素。所要求的最低實施是EXAMPLE示例中顯示的handler()初始化。

16.6.?定義表擴展

就給定的表、數(shù)據(jù)和索引,要求存儲引擎為MySQL服務(wù)器提供存儲引擎所使用的擴展列表。

擴展應(yīng)采用以Null終結(jié)的字符串?dāng)?shù)組形式。下面給出了CSV引擎使用的數(shù)組:

static const char *ha_tina_exts[] = {
? ".CSV",
? NullS
};

調(diào)用bas_ext()函數(shù)時返回該數(shù)組。

const char **ha_tina::bas_ext() const
{
? return ha_tina_exts;
}

通過提供擴展信息,你還能忽略DROP TABLE功能的實施,這是因為,通過關(guān)閉表并用你指定的擴展刪除所有文件,MySQL服務(wù)器能實現(xiàn)該功能。

16.7.?創(chuàng)建表

一旦實例化了處理程序,所需的第1個操作很可能是創(chuàng)建表。

你的存儲引擎必須實現(xiàn)create()虛擬函數(shù):

virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;

該函數(shù)應(yīng)創(chuàng)建所有必須的文件,然后關(guān)閉表。MySQL服務(wù)器將調(diào)用隨后需打開的表。

*name參數(shù)是表的名稱。*form參數(shù)是st_table結(jié)構(gòu),該結(jié)構(gòu)定義了表并與MySQL服務(wù)器已創(chuàng)建的tablename.frm文件的內(nèi)容匹配。在大多數(shù)情況下,存儲引擎不需要更改tablename.frm文件,也沒有支持該操作的預(yù)置功能。

*info參數(shù)是包含CREATE TABLE語句用于創(chuàng)建表所需信息的結(jié)構(gòu)。該結(jié)構(gòu)定義于handler.h文件中,并為了便于參考列于下面:

typedef struct st_ha_create_information
? {
??? CHARSET_INFO *table_charset, *default_table_charset;
??? LEX_STRING connect_string;
??? const char *comment,*password;
??? const char *data_file_name, *index_file_name;
??? const char *alias;
??? ulonglong max_rows,min_rows;
??? ulonglong auto_increment_value;
??? ulong table_options;
??? ulong avg_row_length;
??? ulong raid_chunksize;
??? ulong used_fields;
??? SQL_LIST merge_list;
??? enum db_type db_type;
??? enum row_type row_type;
??? uint null_bits;?????????????????????? 
??? uint options;???????????????????????????? ????????????????? 
??? uint raid_type,raid_chunks;
??? uint merge_insert_method;
??? uint extra_size;????????????????????? 
??? bool table_existed;?????????????????????? ????????????? 
??? bool frm_only;??????????????????????? 
??? bool varchar;???????????????????????? 
? } HA_CREATE_INFO;

基本的存儲引擎能忽略*form*info的內(nèi)容,這是因為,真正所需的是創(chuàng)建存儲引擎所使用的數(shù)據(jù)文件,以及對數(shù)據(jù)文件的可能初始化操作(假定存儲文件是基于文件的)。

下面給出了來自CSV存儲引擎的實施示例:

int ha_tina::create(const char *name, TABLE *table_arg,
? HA_CREATE_INFO *create_info)
? {
??? char name_buff[FN_REFLEN];
??? File create_file;
??? DBUG_ENTER("ha_tina::create");
? 
????if ((create_file= my_create(fn_format(name_buff, name, "", ".CSV",
????????? MY_REPLACE_EXT|MY_UNPACK_FILENAME),0,
????????? O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
??? DBUG_RETURN(-1);
? 
????my_close(create_file,MYF(0));
 
????DBUG_RETURN(0);
? }

在前面的例子中,CSV引擎未引用*table_arg*create_info參數(shù),而是簡單地創(chuàng)建了所需的數(shù)據(jù)文件,關(guān)閉它們,并返回。

my_createmy_close函數(shù)是定義于src/include/my_sys.h文件中的助手函數(shù)。

16.8.?打開表

在表上執(zhí)行任何讀或?qū)懖僮髦埃?span>MySQL服務(wù)器將調(diào)用open()方法打開表數(shù)據(jù)和索引文件(如果存在的話)。

int open(const char *name, int mode, int test_if_locked);

1個參數(shù)是要打開的表的名稱。第2個參數(shù)確定了要打開的文件或準(zhǔn)備執(zhí)行的操作。它們的值定義于handler.h中,并為了方便起見列在下面

#define HA_OPEN_KEYFILE?????????????? ? 1
#define HA_OPEN_RNDFILE?????????????? ? 2
#define HA_GET_INDEX?????????? ??? 4
#define HA_GET_INFO??????????? ????? 8 ??? 
#define HA_READ_ONLY?????????? ??? 16? ? 
#define HA_TRY_READ_ONLY?????? ? 32??? 
#define HA_WAIT_IF_LOCKED????? ? 64??? ? 
#define HA_ABORT_IF_LOCKED???? 128???? ? 
#define HA_BLOCK_LOCK????????? ??? 256 ? 
#define HA_OPEN_TEMPORARY????? ? 512

最后一個選項規(guī)定了是否要在打開表之前檢查表上的鎖定。

在典型情況下,存儲引擎需要實施某種形式的共享訪問控制,以防止在多線程環(huán)境下的文件損壞。關(guān)于如何實施文件鎖定的示例,請參見sql/examples/ha_tina.ccget_share()free_share()方法。

16.9.?實施基本的表掃描功能

16.9.1. 實施store_lock()函數(shù)
16.9.2. 實施external_lock()函數(shù)
16.9.3. 實施rnd_init()函數(shù)
16.9.4. 實施info()函數(shù)
16.9.5. 實施extra()函數(shù)
16.9.6. 實施rnd_next()函數(shù)

最基本的存儲引擎能實現(xiàn)只讀表掃描功能。這類引擎可用于支持SQL日志查詢、以及在MySQL之外填充的其他數(shù)據(jù)文件。

本節(jié)介紹的方法實施提供了創(chuàng)建更高級存儲引擎的基礎(chǔ)。

下面給出了在CSV引擎的9行表掃描過程中進行的方法調(diào)用:

ha_tina::store_lock
ha_tina::external_lock
ha_tina::info
ha_tina::rnd_init
ha_tina::extra - ENUM HA_EXTRA_CACHE   Cache record in HA_rrnd()
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::rnd_next
ha_tina::extra - ENUM HA_EXTRA_NO_CACHE   End cacheing of records (def)
ha_tina::external_lock
ha_tina::extra - ENUM HA_EXTRA_RESET   Reset database to after open

16.9.1.?實施store_lock()函數(shù)

在執(zhí)行任何讀取或?qū)懖僮髦?,調(diào)用store_lock()函數(shù)。

將鎖定添加到表鎖定處理程序之前(請參見thr_lock.c),mysqld將用請求的鎖調(diào)用存儲鎖定。目前,存儲鎖定能將寫鎖定更改為讀鎖定(或其他鎖定),忽略鎖定(如果不打算使用MySQL鎖定的話),或為很多表添加鎖定(就像使用MERGE處理程序時作的那樣)。

例如,Berkeley DB能將所有的WRITE鎖定更改為TL_WRITE_ALLOW_WRITE(表示我們正在執(zhí)行WRITES,但我們?nèi)栽试S其他人員進行操作)。

釋放鎖定時,也將調(diào)用store_lock(),在這種情況下,通常不需做任何事。

在某些特殊情況下,MySQL可能會發(fā)送對TL_IGNORE的請求。這意味著我們正在請求與上次相同的鎖定,這也應(yīng)被忽略(當(dāng)我們打開了表的某一部分時,如果其他人執(zhí)行了表刷新操作,就會出現(xiàn)該情況,此時,mysqld將關(guān)閉并再次打開表,然后獲取與上次相同的鎖定)。我們打算在將來刪除該特性。

可能的鎖定類型定義于includes/thr_lock.h中,并列在下面:

enum thr_lock_type
{
???????? TL_IGNORE=-1,
 ????????????? ?????TL_UNLOCK,??????????????? ???????????? 
 ????????????? ?????TL_READ,????????????????? ?????????????? 
 ????????????? ?????TL_READ_WITH_SHARED_LOCKS,? 
?????????TL_READ_HIGH_PRIORITY,????? 
???????? TL_READ_NO_INSERT, ????????? ?????
???????? TL_WRITE_ALLOW_WRITE, ?????????????? ???
???????? TL_WRITE_ALLOW_READ,? ??????
???????? TL_WRITE_CONCURRENT_INSERT, 
???????? TL_WRITE_DELAYED,? ????????? ?????
???????? TL_WRITE_LOW_PRIORITY,?????? ???? 
???????? TL_WRITE,????????? ????????? ?????
???????? TL_WRITE_ONLY?????????????? 
};? 

實際的鎖定處理因鎖定實施的不同而不同,你可以選擇某些請求的鎖定類型或不選擇任何鎖定類型,并根據(jù)情況恰當(dāng)?shù)卮肽阕约旱姆椒?。下面給出了1CSV存儲引擎實施示例:

THR_LOCK_DATA **ha_tina::store_lock(THD *thd,
???????????????????????????????????? THR_LOCK_DATA **to,
???????????????????????????????????? enum thr_lock_type lock_type)
 {
?? if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
???? lock.type=lock_type;
?? *to++= &lock;
?? return to;
 }? 

16.9.2.?實施external_lock()函數(shù)

external_lock() 函數(shù)是在事務(wù)開始時調(diào)用的,或發(fā)出LOCK TABLES語句時調(diào)用的,用于事務(wù)性存儲引擎。

sql/ha_innodb.ccsql/ha_berkeley.cc文件中,可找到使用external_lock()的示例,但大多數(shù)存儲引擎簡單地返回0,就像EXAMPLE存儲引擎那樣:

int ha_example::external_lock(THD *thd, int lock_type)
 {
?? DBUG_ENTER("ha_example::external_lock");
?? DBUG_RETURN(0);
 }

16.9.3.?實施rnd_init()函數(shù)

在任何表掃描之前調(diào)用的函數(shù)是rnd_init()函數(shù)。函數(shù)rnd_init()用于為表掃描作準(zhǔn)備,將計數(shù)器和指針復(fù)位為表的開始狀態(tài)。

下述示例來自CSV存儲引擎:

  int ha_tina::rnd_init(bool scan)
    {
      DBUG_ENTER("ha_tina::rnd_init");
 
      current_position= next_position= 0;
      records= 0;
      chain_ptr= chain;
 
      DBUG_RETURN(0);
    }  

16.9.4.?實施info()函數(shù)

執(zhí)行表掃描操作之前,將調(diào)用info()函數(shù),以便為優(yōu)化程序提供額外信息。

優(yōu)化程序所需的信息不是通過返回值給定的,你需填充存儲引擎類的特定屬性,當(dāng)info()調(diào)用返回后,優(yōu)化程序?qū)⒆x取存儲引擎類。

除了供優(yōu)化程序使用外,在調(diào)用info()函數(shù)期間,很多值集合還將用于SHOW TABLE STATUS語句。

sql/handler.h中列出了完整的公共屬性,下面給出了一些常見的屬性:

ulonglong data_file_length;?????????? 
ulonglong max_data_file_length;?????? 
ulonglong index_file_length;
ulonglong max_index_file_length;
ulonglong delete_length;????????????? 
ulonglong auto_increment_value;
ha_rows records;????????????????????? 
ha_rows deleted;????????????????????? 
ulong raid_chunksize;
ulong mean_rec_length;???????? 
time_t create_time;?????????????????? 
time_t check_time;
time_t update_time;? 

對于表掃描,最重要的屬性是“records”,它指明了表中的記錄數(shù)。當(dāng)存儲引擎指明表中有01行時,或有2行以上時,在這兩種情況下,優(yōu)化程序的執(zhí)行方式不同。因此,當(dāng)你在執(zhí)行表掃描之前不清楚表中有多少行時,應(yīng)返回大于等于2的值,這很重要(例如,數(shù)據(jù)是在外部填充的)。

16.9.5.?實施extra()函數(shù)

執(zhí)行某些操作之前,應(yīng)調(diào)用extra()函數(shù),以便為存儲引擎就如何執(zhí)行特定操作予以提示。

額外調(diào)用中的提示實施不是強制性的,大多數(shù)存儲引擎均返回0

int ha_tina::extra(enum ha_extra_function operation)
 {
   DBUG_ENTER("ha_tina::extra");
   DBUG_RETURN(0);
 }

16.9.6.?實施rnd_next()函數(shù)

完成表的初始化操作后,MySQL服務(wù)器將調(diào)用處理程序的rnd_next()函數(shù),每兩個掃描行調(diào)用1次,直至滿足了服務(wù)器的搜索條件或到達文件結(jié)尾為止,在后一種情況下,處理程序?qū)⒎祷?span>HA_ERR_END_OF_FILE。

rnd_next()函數(shù)有一個名為*buf的單字節(jié)數(shù)組參數(shù)。對于*buf參數(shù),必須按內(nèi)部MySQL格式用表行的內(nèi)容填充它。

服務(wù)器采用了三種數(shù)據(jù)格式:固定長度行,可變長度行,以及具有BLOB指針的可變長度行。對于每種格式,各列將按照它們由CREATE TABLE語句定義的順序顯示(表定義保存在.frm文件中,優(yōu)化程序和處理程序均能從相同的源,即TABLE結(jié)構(gòu),訪問表的元數(shù)據(jù))。

每種格式以每列1比特的"NULL bitmap"開始。對于含6個列的表,其bitmap1字節(jié),對于含916列的表,其bitmap2字節(jié),依此類推。要想指明特定的值是NULL,應(yīng)將該列NULL位設(shè)置為1

當(dāng)NULL bitmap逐個進入列后,每列將具有MySQL手冊的“MySQL數(shù)據(jù)類型”一節(jié)中指定的大小。在服務(wù)器中,列的數(shù)據(jù)類型定義在sql/field.cc文件中。對于固定長度行格式,列將簡單地逐個放置。對于可變長度行,VARCHAR列將被編碼為1字節(jié)長,后跟字符串。對于具有BLOB列的可變長度行,每個blob由兩部分表示:首先是表示BLOB實際大小的整數(shù),然后是指向內(nèi)存中BLOB的指針。

在任何表處理程序中從rnd_next()開始,可找到行轉(zhuǎn)換(或“包裝”)的示例。例如,在ha_tina.cc中,find_current_row()內(nèi)的代碼給出了使用TABLE結(jié)構(gòu)(由表指向的)和字符串對象(命名緩沖)包裝字符數(shù)據(jù)(來自CSV文件)的方法。將行寫回磁盤需要反向轉(zhuǎn)換,從內(nèi)部格式解包。

下述示例來自CSV存儲引擎:

int ha_tina::rnd_next(byte *buf)
 {
? ?DBUG_ENTER("ha_tina::rnd_next");
 
???statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status);
 
???current_position= next_position;
?? if (!share->mapped_file)
???? DBUG_RETURN(HA_ERR_END_OF_FILE);
?? if (HA_ERR_END_OF_FILE == find_current_row(buf) )
???? DBUG_RETURN(HA_ERR_END_OF_FILE);
 
???records++;
?? DBUG_RETURN(0);
 }? 

對于從內(nèi)部行格式到CSV行格式的轉(zhuǎn)換,它是在find_current_row()函數(shù)中執(zhí)行的。

int ha_tina::find_current_row(byte *buf)
 {
?? byte *mapped_ptr= (byte *)share->mapped_file + current_position;
?? byte *end_ptr;
?? DBUG_ENTER("ha_tina::find_current_row");
 
???
?? if ((end_ptr=? find_eoln(share->mapped_file, current_position,
??????????????????????????? share->file_stat.st_size)) == 0)
???? DBUG_RETURN(HA_ERR_END_OF_FILE);
 
???for (Field **field=table->field ; *field ; field++)
?? {
???? buffer.length(0);
???? mapped_ptr++; // Increment past the first quote
???? for(;mapped_ptr != end_ptr; mapped_ptr++)
???? {
?????? // Need to convert line feeds!
?????? if (*mapped_ptr == '"' &&
?????????? (((mapped_ptr[1] == ',') && (mapped_ptr[2] == '"')) ||
??????????? (mapped_ptr == end_ptr -1 )))
?????? {
???????? mapped_ptr += 2; // Move past the , and the "
???????? break;
??? ???}
?????? if (*mapped_ptr == '\\' && mapped_ptr != (end_ptr - 1))
?????? {
???????? mapped_ptr++;
???????? if (*mapped_ptr == 'r')
?????????? buffer.append('\r');
???????? else if (*mapped_ptr == 'n' )
?????????? buffer.append('\n');
???????? else if ((*mapped_ptr == '\\') || (*mapped_ptr == '"'))
?????????? buffer.append(*mapped_ptr);
???????? else? 
???????? {
?????????? buffer.append('\\');
?????????? buffer.append(*mapped_ptr);
???????? }
?? ????}
?????? else
???????? buffer.append(*mapped_ptr);
???? }
???? (*field)->store(buffer.ptr(), buffer.length(), system_charset_info);
?? }
?? next_position= (end_ptr - share->mapped_file)+1;
?? 
?? memset(buf, 0, table->s->null_bytes); 
 
???DBUG_RETURN(0);
 }? 

16.10.?關(guān)閉表

當(dāng)MySQL服務(wù)器完成表操作時,它將調(diào)用close()方法關(guān)閉文件指針并釋放任何其他資源。

對于使用共享訪問方法的存儲引擎(如CSV引擎和其他示例引擎中顯示的方法),必須將它們自己從共享結(jié)構(gòu)中刪除:

int ha_tina::close(void)
 {
?? DBUG_ENTER("ha_tina::close");
?? DBUG_RETURN(free_share(share));
 }? 

對于使用其自己共享管理系統(tǒng)的存儲引擎,應(yīng)使用任何所需的方法,在它們的處理程序中,從已打開表的共享區(qū)刪除處理程序?qū)嵗?/p>

16.11.?為存儲引擎添加對INSERT的支持

一旦在你的存儲引擎中有了讀支持,下一個需要實施的特性是對INSERT語句的支持。有了INSERT支持,存儲引擎就能處理WORM(寫一次,讀多次)應(yīng)用程序,如用于以后分析的日志和歸檔應(yīng)用等。

所有的INSERT操作均是通過write_row()函數(shù)予以處理的:

int ha_foo::write_row(byte *buf)? 

*buf參數(shù)包含將要插入的行,采用內(nèi)部MySQL格式。基本的存儲引擎將簡單地前進到數(shù)據(jù)文件末尾,并直接在末尾處添加緩沖的內(nèi)容,這樣就能使行讀取變得簡單,這是因為,你可以讀取行并將其直接傳遞到rnd_next()函數(shù)的緩沖參數(shù)中。

寫入行的進程與讀取行的進程相反:從MySQL內(nèi)部行格式獲取數(shù)據(jù),并將其寫入數(shù)據(jù)文件。下述示例來自CSV存儲引擎:

int ha_tina::write_row(byte * buf)
 {
?? int size;
?? DBUG_ENTER("ha_tina::write_row");
 
???statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status);
 
???if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
???? table->timestamp_field->set_time();
 
???size= encode_quote(buf);
 
???if (my_write(share->data_file, buffer.ptr(), size, MYF(MY_WME | MY_NABP)))
???? DBUG_RETURN(-1);
?
?? if (get_mmap(share, 0) > 0)
???? DBUG_RETURN(-1);
?? DBUG_RETURN(0);
 }

前述示例中的兩條注釋包括,更新關(guān)于寫入操作的表統(tǒng)計,以及在寫入行之前設(shè)置時間戳。

16.12.?為存儲引擎添加對UPDATE的支持

通過執(zhí)行表掃描操作,在找到與UPDATE語句的WHERE子句匹配的行后,MySQL服務(wù)器將執(zhí)行UPDATE語句,然后調(diào)用update_row()函數(shù):

int ha_foo::update_row(const byte *old_data, byte *new_data)

*old_data參數(shù)包含更新前位于行中的數(shù)據(jù),*new_data參數(shù)包含行的新內(nèi)容(采用MySQL內(nèi)部行格式)。

更新的執(zhí)行取決于行格式和存儲實施方式。某些存儲引擎將替換恰當(dāng)位置的數(shù)據(jù),而其他實施方案則會刪除已有的行,并在數(shù)據(jù)文件末尾添加新行。

非事務(wù)性存儲引擎通常會忽略*old_data參數(shù)的內(nèi)容,僅處理*new_data緩沖。事務(wù)性存儲引擎可能需要比較緩沖,以確定在上次回滾中出現(xiàn)了什么變化。

如果正在更新的表中包含時間戳列,對時間戳的更新將由update_row()調(diào)用管理。下述示例來自CSV引擎:

int ha_tina::update_row(const byte * old_data, byte * new_data)
 {
?? int size;
?? DBUG_ENTER("ha_tina::update_row");
 
???statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
 ????????????? ??????&LOCK_status);
 
???if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
???? table->timestamp_field->set_time();
 
???size= encode_quote(new_data);
 
???if (chain_append())
???? DBUG_RETURN(-1);
 
???if (my_write(share->data_file, buffer.ptr(), size, MYF(MY_WME | MY_NABP)))
???? DBUG_RETURN(-1);
?? DBUG_RETURN(0);
 }

請注意上例中的時間戳設(shè)置。

16.13.?為存儲引擎添加對DELETE的支持

MySQL服務(wù)器采用了與INSERT語句相同的方法來執(zhí)行DELETE語句:服務(wù)器使用rnd_next()函數(shù)跳到要刪除的行,然后調(diào)用delete_row()函數(shù)刪除行。

int ha_foo::delete_row(const byte *buf)

*buf參數(shù)包含要刪除行的內(nèi)容。對于大多數(shù)存儲引擎,該參數(shù)可被忽略,但事務(wù)性存儲引擎可能需要保存刪除的數(shù)據(jù),以供回滾操作使用。

下述示例來自CSV存儲引擎:

int ha_tina::delete_row(const byte * buf)
 {
?? DBUG_ENTER("ha_tina::delete_row");
?? statistic_increment(table->in_use->status_var.ha_delete_count,
?????????????????????? &LOCK_status);
 
???if (chain_append())
???? DBUG_RETURN(-1);
? 
???--records;
 
???DBUG_RETURN(0);
 }

前述示例的步驟是更新delete_count統(tǒng)計,并記錄計數(shù)。

16.14.?API引用

16.14.1. bas_ext
16.14.2. close
16.14.3. create
16.14.4. delete_row
16.14.5. delete_table
16.14.6. external_lock
16.14.7. extra
16.14.8. info
16.14.9. open
16.14.10. rnd_init
16.14.11. rnd_next
16.14.12. store_lock
16.14.13. update_row
16.14.14. write_row

16.14.1.?bas_ext

目的

定義存儲引擎所使用的文件擴展。

概要

virtual const char ** bas_ext ( ); ?
? ;

描述

這是bas_ext方法。調(diào)用它,可為MySQL服務(wù)器提供存儲引擎所使用的文件擴展列表。該列表將返回以Null終結(jié)的字符串?dāng)?shù)組。

通過提供擴展列表,在很多情況下,存儲引擎能省略delete_table()函數(shù),這是因為MySQL服務(wù)器將關(guān)閉所有對表的引用,并使用指定的擴展刪除所有文件。

參數(shù)

該函數(shù)無參數(shù)。

返回值

  • 返回值是存儲引擎擴展的以Null終結(jié)的字符串?dāng)?shù)組。下面給出了CSV引擎的示例:

    static const char *ha_tina_exts[] =
     {
       ".CSV",
       NullS
     };
    

用法

static const char *ha_tina_exts[] =
 {
   ".CSV",
   NullS
 };
        
const char **ha_tina::bas_ext() const
 {
   return ha_tina_exts;
 }  

默認(rèn)實施

static const char *ha_example_exts[] = {
   NullS
 };
 
const char **ha_example::bas_ext() const
 {
   return ha_example_exts;
 }

16.14.2.?close

目的

關(guān)閉打開的表。

概要

virtual int close ( void); ?
? void ;

描述

這是close方法。

關(guān)閉表。這是釋放任何已分配資源的恰當(dāng)時機。

sql_base.ccsql_select.cctable.cc調(diào)用它。在sql_select.cc中,它僅用于關(guān)閉臨時表,或在將臨時表轉(zhuǎn)換為myisam表的過程中關(guān)閉表。關(guān)于sql_base.cc,請查看close_data_tables()

參數(shù)

  • void

返回值

無返回值。

用法

取自CSV引擎的示例:

int ha_example::close(void)
{
  DBUG_ENTER("ha_example::close");
  DBUG_RETURN(free_share(share));
}

16.14.3.?create

目的

創(chuàng)建新表。

概要

virtual int create ( name, ?
? form, ?
? info); ?
const char *? name ;
TABLE *? form ;
HA_CREATE_INFO *? info ;

描述

這是create方法。

調(diào)用create()以創(chuàng)建表。變量名稱為表的名稱。調(diào)用create()時,不需要打開表。此外,由于已創(chuàng)建了.frm文件,不推薦調(diào)整create_info。

ha_create_table()handle.cc中調(diào)用。

參數(shù)

  • name

  • form

  • info

返回值

無返回值。

用法

CSV搜索引擎示例:

int ha_tina::create(const char *name, TABLE *table_arg,
                    HA_CREATE_INFO *create_info)
{
  char name_buff[FN_REFLEN];
  File create_file;
  DBUG_ENTER("ha_tina::create");

  if ((create_file= my_create(fn_format(name_buff, name, "", ".CSV",
                                        MY_REPLACE_EXT|MY_UNPACK_FILENAME),0,
                              O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
    DBUG_RETURN(-1);

  my_close(create_file,MYF(0));

  DBUG_RETURN(0);
}          

16.14.4.?delete_row

目的

刪除行。

概要

virtual int delete_row ( buf); ?
const byte *? buf ;

描述

這是delete_row方法。

Buf包含刪除行的副本。調(diào)用了當(dāng)前行后,服務(wù)器將立刻調(diào)用它(通過前一個rnd_next()或索引調(diào)用)。如果存在指向上一行的指針,或能夠訪問 主鍵,刪除操作將更為容易。請記住,服務(wù)器不保證連續(xù)刪除。可以使用ORDER BY子句。

sql_acl.ccsql_udf.cc中調(diào)用,以管理內(nèi)部的表信息。sql_delete.ccsql_insert.ccsql_select.cc中調(diào)用。sql_select中,它用于刪除副本,而在插入操作中,它用于REPLACE調(diào)用。

參數(shù)

  • buf

返回值

無返回值。

用法

          
        

默認(rèn)實施

{ return  HA_ERR_WRONG_COMMAND; }

16.14.5.?delete_table

目的

用來自bas_ext()的擴展刪除所有文件。

概要

virtual int delete_table ( name); ?
const char *? name ;

描述

這是delete_table方法。

用于刪除表。調(diào)用delete_table()時,所有已打開的對該表的引用均將被關(guān)閉(并釋放全局共享的引用)。變量名稱為表名。此時,需要刪除任何已創(chuàng)建的文件。

如果未實施它,將從handler.cc調(diào)用默認(rèn)的delete_table(),并用bas_ext()返回的文件擴展刪除所有文件。假定處理程序返回的擴展比文件實際使用的多。

delete_tableha_create_table()handler.cc調(diào)用。如果為存儲引擎指定了table_flag HA_DROP_BEFORE_CREATE,僅在創(chuàng)建過程中使用。

參數(shù)

  • name: 表的基本名稱

返回值

·???????? 如果成功地從base_ext刪除了至少1個文件而且未出現(xiàn)除ENOENT之外的錯誤,返回0

·???????? #: Error

用法

大多數(shù)存儲引擎均會忽略該函數(shù)的實施。

16.14.6.?external_lock

目的

為事務(wù)處理表鎖定。

概要

virtual int external_lock ( thd, ?
? lock_type); ?
THD *? thd ;
int? lock_type ;

描述

這是external_lock方法。

lock.cc用于mysql的鎖定函數(shù)一節(jié),給出了關(guān)于該議題的額外注釋,值的一讀。

在表上創(chuàng)建鎖定。如果實施了能處理事務(wù)的存儲引擎,請查看ha_berkely.cc,以了解如何執(zhí)行該操作的方法。否則,應(yīng)考慮在此調(diào)用flock()。

lock_external()unlock_external()lock.cc中調(diào)用。也能由copy_data_between_tables()sql_table.cc中調(diào)用。

參數(shù)

  • thd

  • lock_type

返回值

無返回值。

默認(rèn)實施

{ return 0; }

16.14.7.?extra

目的

將提示從服務(wù)器傳遞給存儲引擎。

概要

virtual int extra ( operation); ?
enum ha_extra_function? operation ;

描述

這是extra方法。

無論何時,當(dāng)服務(wù)器希望將提示發(fā)送到存儲引擎時,將調(diào)用extra()。MyISAM引擎實現(xiàn)了大多數(shù)提示。ha_innodb.cc給出了最詳盡的提示列表。

參數(shù)

  • operation

返回值

無返回值。

用法

          
        

默認(rèn)實施

默認(rèn)情況下,存儲引擎傾向于不實施任何提示。

{ return 0; }

16.14.8.?info

目的

提示存儲引擎通報統(tǒng)計信息。

概要

virtual void info ( uint); ?
? uint ;

描述

這是info方法。

::info()用于將信息返回給優(yōu)化程序。目前,該表處理程序未實施實際需要的大多數(shù)字段。SHOW也能利用該數(shù)據(jù)。注意,或許你打算在你的代碼中包含下述內(nèi)容“if (records > 2) records = 2”。原因在于,服務(wù)器僅優(yōu)化具有一條記錄的情形。如果在表掃描過程中,你不清楚記錄的數(shù)目,最好將記錄數(shù)設(shè)為2,以便能夠返回盡可能多的所需記錄。除了記錄外,你或許還希望設(shè)置其他變量,包括:刪除的記錄,data_file_length,index_file_lengthdelete_length,check_time。更多信息,請參見handler.h中的公共變量。

在下述文件中調(diào)用:filesort.cc ha_heap.cc item_sum.cc opt_sum.cc sql_delete.cc sql_delete.cc sql_derived.cc sql_select.cc sql_select.cc sql_select.cc sql_select.cc sql_select.cc sql_show.cc sql_show.cc sql_show.cc sql_show.cc sql_table.cc sql_union.cc sql_update.cc

參數(shù)

  • uint

返回值

無返回值。

用法

該示例取自CSV存儲引擎:

void ha_tina::info(uint flag)
{
  DBUG_ENTER("ha_tina::info");
  
  if (records < 2)
    records= 2;
  DBUG_VOID_RETURN;
}          

16.14.9.?open

目的

打開表。

概要

virtual int open ( name, ?
? mode, ?
? test_if_locked); ?
const char *? name ;
int? mode ;
uint? test_if_locked ;

描述

這是open方法。

用于打開表。名稱是文件的名稱。在需要打開表時打開它。例如,當(dāng)請求在表上執(zhí)行選擇操作時(對于每一請求,表未打開并被關(guān)閉,對其進行高速緩沖處理)。

handler::ha_open()handler.cc中調(diào)用。通過調(diào)用ha_open(),然后調(diào)用處理程序相關(guān)的open(),服務(wù)器打開所有表。

對于處理程序?qū)ο?,將作為初始化的一部分并在將其用于正常查詢之前打開它(并非總在元數(shù)據(jù)變化之前)。如果打開了對象,在刪除之前還將關(guān)閉它。

這是open方法。調(diào)用open以打開數(shù)據(jù)庫表。

1個參數(shù)是要打開的表的名稱。第2個參數(shù)決定了要打開的文件或?qū)⒁獔?zhí)行的操作。這類值定義于handler.h中,為了方便起見在此列出:

??????? #define HA_OPEN_KEYFILE?????????????? ? 1
??????? #define HA_OPEN_RNDFILE?????????????? ? 2
??????? #define HA_GET_INDEX????????? ??? 4
??????? #define HA_GET_INFO?????????? ????? 8 ??? 
??????? #define HA_READ_ONLY????????? ??? 16? ? 
??????? #define HA_TRY_READ_ONLY????? ? 32??? 
??????? #define HA_WAIT_IF_LOCKED???? ? 64??? ? 
??????? #define HA_ABORT_IF_LOCKED??? 128???? ? 
??????? #define HA_BLOCK_LOCK???????? ??? 256 ? 
??????? #define HA_OPEN_TEMPORARY???? ? 512
????? 

最后的選項規(guī)定了在打開表之前是否應(yīng)檢查表上的鎖定。

典型情況下,存儲引擎需要實現(xiàn)某種形式的共享訪問控制,以防止多線程環(huán)境下的文件損壞。關(guān)于如何實現(xiàn)文件鎖定的示例,請參見sql/examples/ha_tina.ccget_share()free_share()方法。

參數(shù)

  • name

  • mode

  • test_if_locked

返回值

無返回值。

用法

該示例取自CSV存儲引擎:

        int ha_tina::open(const char *name, int mode, uint test_if_locked)
        {
        DBUG_ENTER("ha_tina::open");
        
        if (!(share= get_share(name, table)))
        DBUG_RETURN(1);
        thr_lock_data_init(&share->lock,&lock,NULL);
        ref_length=sizeof(off_t);
        
        DBUG_RETURN(0);
        }          
      

16.14.10.?rnd_init

目的

為表掃描功能初始化處理程序。

概要

virtual int rnd_init ( scan); ?
bool? scan ;

描述

這是rnd_init方法。

當(dāng)系統(tǒng)希望存儲引擎執(zhí)行表掃描時,將調(diào)用rnd_init()。

index_init()不同,rnd_init()可以調(diào)用兩次,兩次調(diào)用之間不使用rnd_end()(僅當(dāng)scan=1時才有意義)。隨后,第2次調(diào)用應(yīng)準(zhǔn)備好新的表掃描。例如,如果rnd_init分配了光標(biāo),第2次調(diào)用應(yīng)將光標(biāo)定位于表的開始部分,不需要撤銷分配并再次分配。

從下述文件調(diào)用:filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc, sql_update.cc。

參數(shù)

  • scan

返回值

無返回值。

用法

該示例取自CSV存儲引擎:

int ha_tina::rnd_init(bool scan)
{
  DBUG_ENTER("ha_tina::rnd_init");

  current_position= next_position= 0;
  records= 0;
  chain_ptr= chain;
  DBUG_RETURN(0);
}          

16.14.11.?rnd_next

目的

從表中讀取下一行,并將其返回服務(wù)器。

概要

virtual int rnd_next ( buf); ?
byte *? buf ;

描述

這是rnd_next方法。

對于表掃描的每一行調(diào)用它。耗盡記錄時,應(yīng)返回HA_ERR_END_OF_FILE。用行信息填充buff。表的字段結(jié)構(gòu)是以服務(wù)器能理解的方式將數(shù)據(jù)保存到buf中的鍵。

從下述文件調(diào)用:filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc, sql_update.cc。

參數(shù)

  • buf

返回值

無返回值。

用法

下述示例取自ARCHIVE存儲引擎:

int ha_archive::rnd_next(byte *buf)
{
  int rc;
  DBUG_ENTER("ha_archive::rnd_next");

  if (share->crashed)
      DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
 
  if (!scan_rows)
    DBUG_RETURN(HA_ERR_END_OF_FILE);
  scan_rows--;

  statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
		      &LOCK_status);
    current_position= gztell(archive);
  rc= get_row(archive, buf);
 
  if (rc != HA_ERR_END_OF_FILE)
    records++;

  DBUG_RETURN(rc);
}          

16.14.12.?store_lock

目的

創(chuàng)建和釋放表鎖定。

概要

virtual THR_LOCK_DATA ** store_lock ( thd, ?
? to, ?
? lock_type); ?
THD *? thd ;
THR_LOCK_DATA **? to ;
enum thr_lock_type? lock_type ;

描述

這是store_lock方法。

下面介紹了關(guān)于handler::store_lock()的概念:

該語句決定了在表上需要何種鎖定。對于updates/deletes/inserts,我們得到WRITE鎖定;對于SELECT...,我們得到讀鎖定。

將鎖定添加到表鎖定處理程序之前(請參見thr_lock.c),mysqld將用請求的鎖定調(diào)用存儲鎖定。目前,存儲鎖定能將寫鎖定更改為讀鎖定(或某些其他鎖定),忽略鎖定(如果不打算使用MySQL表鎖定),或為很多表添加鎖定(就像使用MERGE處理程序時那樣)。

例如,Berkeley DB能夠?qū)⑺械?span>WRITE鎖定更改為TL_WRITE_ALLOW_WRITE(表明正在執(zhí)行WRITES操作,但我們?nèi)栽试S其他人執(zhí)行操作)。

釋放鎖定時,也將調(diào)用store_lock()。在這種情況下,通常不需要作任何事。

在某些特殊情況下,MySQL可能會發(fā)送對TL_IGNORE的請求。這意味著我們正在請求與上次相同的鎖定,這也應(yīng)被忽略(當(dāng)我們打開了表的某一部分時,如果其他人執(zhí)行了表刷新操作,就會出現(xiàn)該情況,此時,mysqld將關(guān)閉并再次打開表,然后獲取與上次相同的鎖定)。我們打算在將來刪除該特性。

get_lock_data()lock.cc中調(diào)用。

參數(shù)

  • thd

  • to

  • lock_type

返回值

無返回值。

用法

下述示例取自ARCHIVE存儲引擎:

THR_LOCK_DATA **ha_archive::store_lock(THD *thd,
                                       THR_LOCK_DATA **to,
                                       enum thr_lock_type lock_type)
{
  if (lock_type == TL_WRITE_DELAYED)
    delayed_insert= TRUE;
  else
    delayed_insert= FALSE;

  if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) 
  {
    

    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
         lock_type <= TL_WRITE) && !thd->in_lock_tables
        && !thd->tablespace_op)
      lock_type = TL_WRITE_ALLOW_WRITE;

    

    if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) 
      lock_type = TL_READ;

    lock.type=lock_type;
  }

  *to++= &lock;
 
  return to;
}          

16.14.13.?update_row

目的

更新已有行的內(nèi)容。

概要

virtual int update_row ( old_data, ?
? new_data); ?
const byte *? old_data ;
byte *? new_data ;

描述

這是update_row方法。

old_data將保存前一行的記錄,而new_data將保存最新的數(shù)據(jù)。

如果使用了ORDER BY子句,服務(wù)器能夠根據(jù)排序執(zhí)行更新操作。不保證連續(xù)排序。

目前,new_data不會擁有已更新的auto_increament記錄,或已更新的時間戳字段。你可以通過下述方式(例如)完成該操作:if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); if (table->next_number_field && record == table->record[0]) update_auto_increment();

sql_select.cc, sql_acl.cc, sql_update.ccsql_insert.cc調(diào)用。

參數(shù)

  • old_data

  • new_data

返回值

無返回值。

用法

          
        

默認(rèn)實施

           { return  HA_ERR_WRONG_COMMAND; }
        

16.14.14.?write_row

目的

為表添加新行。

概要

virtual int write_row ( buf); ?
byte *? buf ;

描述

這是write_row方法。

write_row()用于插入行。目前,如果出現(xiàn)大量加載,不會給出任何extra()提示。buf是數(shù)據(jù)的字節(jié)數(shù)組,大小為table->s->reclength

可以使用字段信息從本地字節(jié)數(shù)組類型提取數(shù)據(jù)。例如:

for (Field **field=table->field ; *field ; field++) { ... }

BLOB必須特殊處理:

??? 
for (ptr= table->s->blob_field, end= ptr + table->s->blob_fields ; ptr != end ; ptr++) 
??{ 
????????char *data_ptr; 
????????uint32 size= ((Field_blob*)table->field[*ptr])->get_length();
??????? ((Field_blob*)table->field[*ptr])->get_ptr(&data_ptr); 
????????... 
??}

關(guān)于以字符串形式提取所有數(shù)據(jù)的示例,請參見ha_tina.cc。在ha_berkeley.cc中,對于ha_berkeley自己的本地存儲類型,給出了一個通過“包裝功能”完整保存它的例子。

請參見update_row()關(guān)于auto_increments和時間戳的注釋。該情形也適用于write_row()。

item_sum.cc、item_sum.cc、sql_acl.cc、sql_insert.ccsql_insert.cc、sql_select.cc、sql_table.cc、sql_udf.cc、以及sql_update.cc調(diào)用。

參數(shù)

  • 數(shù)據(jù)的buf字節(jié)數(shù)組

返回值

無返回值。

用法

          
        

默認(rèn)實施

           { return  HA_ERR_WRONG_COMMAND; }
        

這是MySQL參考手冊的翻譯版本,關(guān)于MySQL參考手冊,請訪問dev.mysql.com。 原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。

上一篇: 下一篇: