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

Verzeichnis suchen
目錄 前言 1. 一般信息 1.1. 關于本手冊 1.2. 本手冊采用的慣例 1.3. MySQL AB概述 1.4. MySQL數據庫管理系統(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數據庫管理系統(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有關的鏈接 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標準的兼容性 1.8.1. MySQL遵從的標準是什么 1.8.2. 選擇SQL模式 1.8.3. 在ANSI模式下運行MySQL 1.8.4. MySQL對標準SQL的擴展 1.8.5. MySQL與標準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ā)版的標準MySQL安裝 2.3. 在Windows上安裝MySQL 2.3.1. Windows系統(tǒng)要求 2.3.2. 選擇安裝軟件包 2.3.3. 用自動安裝器安裝MySQL 2.3.4. 使用MySQL安裝向導 2.3.5. 使用配置向導 2.3.6. 通過非安裝Zip文件安裝MySQL 2.3.7. 提取安裝檔案文件 2.3.8. 創(chuàng)建選項文件 2.3.9. 選擇MySQL服務器類型 2.3.10. 首次啟動服務器 2.3.11. 從Windows命令行啟動MySQL 2.3.12. 以Windows服務方式啟動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. 安裝后的設置和測試 2.9.1. Windows下安裝后的過程 2.9.2. Unix下安裝后的過程 2.9.3. 使初始MySQL賬戶安全 2.10. 升級MySQL 2.10.1. 從5.0版升級 2.10.2. 升級授權表 2.10.3. 將MySQL數據庫拷貝到另一臺機器 2.11. 降級MySQL 2.12. 具體操作系統(tǒng)相關的注意事項 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. 連接與斷開服務器 3.2. 輸入查詢 3.3. 創(chuàng)建并使用數據庫 3.3.1. 創(chuàng)建并選擇數據庫 3.3.2. 創(chuàng)建表 3.3.3. 將數據裝入表中 3.3.4. 從表檢索信息 3.4. 獲得數據庫和表的信息 NoName 3.6. 常用查詢的例子 3.6.1. 列的最大值 3.6.2. 擁有某個列的最大值的行 3.6.3. 列的最大值:按組 3.6.4. 擁有某個字段的組間最大值的行 3.6.5. 使用用戶變量 3.6.6. 使用外鍵 3.6.7. 根據兩個鍵搜索 3.6.8. 根據天計算訪問量 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. 調用MySQL程序 4.3. 指定程序選項 4.3.1. 在命令行上使用選項 4.3.2. 使用選項文件 4.3.3. 用環(huán)境變量指定選項 4.3.4. 使用選項設置程序變量 5. 數據庫管理 5.1. MySQL服務器和服務器啟動腳本 5.1.1. 服務器端腳本和實用工具概述 5.1.2. mysqld-max擴展MySQL服務器 5.1.3. mysqld_safe:MySQL服務器啟動腳本 5.1.4. mysql.server:MySQL服務器啟動腳本 5.1.5. mysqld_multi:管理多個MySQL服務器的程序 5.2. mysqlmanager:MySQL實例管理器 5.2.1. 用MySQL實例管理器啟動MySQL服務器 5.2.2. 連接到MySQL實例管理器并創(chuàng)建用戶賬戶 5.2.3. MySQL實例管理器命令行選項 5.2.4. MySQL實例管理器配置文件 5.2.5. MySQL實例管理器識別的命令 5.3. mysqld:MySQL服務器 5.3.1. mysqld命令行選項 5.3.2. SQL服務器模式 5.3.3. 服務器系統(tǒng)變量 5.3.4. 服務器狀態(tài)變量 5.4. mysql_fix_privilege_tables:升級MySQL系統(tǒng)表 5.5. MySQL服務器關機進程 5.6. 一般安全問題 5.6.1. 通用安全指南 5.6.2. 使MySQL在攻擊者面前保持安全 5.6.3. Mysqld安全相關啟動選項 5.6.4. LOAD DATA LOCAL安全問題 5.7. MySQL訪問權限系統(tǒng) 5.7.1. 權限系統(tǒng)的作用 5.7.2. 權限系統(tǒng)工作原理 5.7.3. MySQL提供的權限 5.7.4. 與MySQL服務器連接 5.7.5. 訪問控制 5.7.6. 訪問控制 5.7.7. 權限更改何時生效 5.7.8. 拒絕訪問錯誤的原因 5.7.9. MySQL 4.1中的密碼哈希處理 5.8. MySQL用戶賬戶管理 5.8.1. MySQL用戶名和密碼 5.8.2. 向MySQL增加新用戶賬戶 5.8.3. 從MySQL刪除用戶賬戶 5.8.4. 限制賬戶資源 5.8.5. 設置賬戶密碼 5.8.6. 使你的密碼安全 5.8.7. 使用安全連接 5.9. 備份與恢復 5.9.1. 數據庫備份 5.9.2. 示例用備份與恢復策略 5.9.3. 自動恢復 5.9.4. 表維護和崩潰恢復 5.9.5. myisamchk:MyISAM表維護實用工具 5.9.6. 建立表維護計劃 5.9.7. 獲取關于表的信息 5.10. MySQL本地化和國際應用 5.10.1. 數據和排序用字符集 5.10.2. 設置錯誤消息語言 5.10.3. 添加新的字符集 5.10.4. 字符定義數組 5.10.5. 字符串比較支持 5.10.6. 多字節(jié)字符支持 5.10.7. 字符集問題 5.10.8. MySQL服務器時區(qū)支持 5.11. MySQL日志文件 5.11.1. 錯誤日志 5.11.2. 通用查詢日志 5.11.3. 二進制日志 5.11.4. 慢速查詢日志 5.11.5. 日志文件維護 5.12. 在同一臺機器上運行多個MySQL服務器 5.12.1. 在Windows下運行多個服務器 5.12.2. 在Unix中運行多個服務器 5.12.3. 在多服務器環(huán)境中使用客戶端程序 5.13. MySQL查詢高速緩沖 5.13.1. 查詢高速緩沖如何工作 5.13.2. 查詢高速緩沖SELECT選項 5.13.3. 查詢高速緩沖配置 5.13.4. 查詢高速緩沖狀態(tài)和維護 6. MySQL中的復制 6.1. 復制介紹 6.2. 復制實施概述 6.3. 復制實施細節(jié) 6.3.1. 復制主線程狀態(tài) 6.3.2. 復制從I/O線程狀態(tài) 6.3.3. 復制從SQL線程狀態(tài) 6.3.4. 復制傳遞和狀態(tài)文件 6.4. 如何設置復制 6.5. 不同MySQL版本之間的復制兼容性 6.6. 升級復制設置 6.6.1. 將復制升級到5.0版 6.7. 復制特性和已知問題 6.8. 復制啟動選項 6.9. 復制FAQ 6.10. 復制故障診斷與排除 6.11. 通報復制缺陷 6.12. 多服務器復制中的Auto-Increment 7. 優(yōu)化 7.1. 優(yōu)化概述 7.1.1. MySQL設計局限與折衷 7.1.2. 為可移植性設計應用程序 7.1.3. 我們已將MySQL用在何處? 7.1.4. MySQL基準套件 7.1.5. 使用自己的基準 7.2. 優(yōu)化SELECT語句和其它查詢 7.2.1. EXPLAIN語法(獲取SELECT相關信息) 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)化數據庫結構 7.4.1. 設計選擇 7.4.2. 使你的數據盡可能小 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如何打開和關閉表 7.4.10. 在同一個數據庫中創(chuàng)建多個表的缺陷 7.5. 優(yōu)化MySQL服務器 7.5.1. 系統(tǒng)因素和啟動參數的調節(jié) 7.5.2. 調節(jié)服務器參數 7.5.3. 控制查詢優(yōu)化器的性能 7.5.4. 編譯和鏈接怎樣影響MySQL的速度 7.5.5. MySQL如何使用內存 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:用于檢查訪問權限的客戶端 8.5. mysqladmin:用于管理MySQL服務器的客戶端 8.6. mysqlbinlog:用于處理二進制日志文件的實用工具 8.7. mysqlcheck:表維護和維修程序 8.8. mysqldump:數據庫備份程序 8.9. mysqlhotcopy:數據庫備份程序 8.10. mysqlimport:數據導入程序 8.11. mysqlshow-顯示數據庫、表和列信息 8.12. myisamlog:顯示MyISAM日志文件內容 8.13. perror:解釋錯誤代碼 8.14. replace:字符串替換實用工具 8.15. mysql_zap:殺死符合某一模式的進程 9. 語言結構 9.1. 文字值 9.1.1. 字符串 9.1.2. 數值 9.1.3. 十六進制值 9.1.4. 布爾值 9.1.5. 位字段值 9.1.6. NULL值 9.2. 數據庫、表、索引、列和別名 9.2.1. 識別符限制條件 9.2.2. 識別符大小寫敏感性 9.3. 用戶變量 9.4. 系統(tǒng)變量 9.4.1. 結構式系統(tǒng)變量 9.5. 注釋語法 9.6. MySQL中保留字的處理 10. 字符集支持 10.1. 常規(guī)字符集和校對 10.2. MySQL中的字符集和校對 10.3. 確定默認字符集和校對 10.3.1. 服務器字符集和校對 10.3.2. 數據庫字符集和校對 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. 校對確定較為復雜的一些特殊情況 10.3.12. 校對必須適合字符集 10.3.13. 校對效果的示例 10.4. 字符集支持影響到的操作 10.4.1. 結果字符串 10.4.2. CONVERT() 10.4.3. CAST() 10.4.4. SHOW語句 10.5. Unicode支持 10.6. 用于元數據的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. 數值類型概述 11.1.2. 日期和時間類型概述 11.1.3. 字符串類型概述 11.2. 數值類型 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. 使用來自其他數據庫引擎的列類型 12. 函數和操作符 12.1. 操作符 12.1.1. 操作符優(yōu)先級 12.1.2. 圓括號 12.1.3. 比較函數和操作符 12.1.4. 邏輯操作符 12.2. 控制流程函數 12.3. 字符串函數 12.3.1. 字符串比較函數 12.4. 數值函數 12.4.1. 算術操作符 12.4.2. 數學函數 12.5. 日期和時間函數 12.6. MySQL使用什么日歷? 12.7. 全文搜索功能 12.7.1. 布爾全文搜索 12.7.2. 全文搜索帶查詢擴展 12.7.3. 全文停止字 12.7.4. 全文限定條件 12.7.5. 微調MySQL全文搜索 12.8. Cast函數和操作符 12.9. 其他函數 12.9.1. 位函數 12.9.2. 加密函數 12.9.3. 信息函數 12.9.4. 其他函數 NoName 12.10.1. GROUP BY(聚合)函數 12.10.2. GROUP BY修改程序 12.10.3. 具有隱含字段的GROUP BY 13. SQL語句語法 13.1. 數據定義語句 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. 數據操作語句 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語法(獲取有關列的信息) 13.3.2. USE語法 13.4. MySQL事務處理和鎖定語句 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事務 13.5. 數據庫管理語句 13.5.1. 賬戶管理語句 13.5.2. 表維護語句 13.5.3. SET語法 13.5.4. SHOW語法 13.5.5. 其它管理語句 13.6. 復制語句 13.6.1. 用于控制主服務器的SQL語句 13.6.2. 用于控制從服務器的SQL語句 13.7. 用于預處理語句的SQL語法 14. 插件式存儲引擎體系結構 14.1. 前言 14.2. 概述 14.3. 公共MySQL數據庫服務器層 14.4. 選擇存儲引擎 14.5. 將存儲引擎指定給表 14.6. 存儲引擎和事務 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數據和日志文件 15.2.8. InnoDB數據庫的備份和恢復 15.2.9. 將InnoDB數據庫移到另一臺機器上 15.2.10. InnoDB事務模型和鎖定 15.2.11. InnoDB性能調節(jié)提示 15.2.12. 多版本的實施 15.2.13. 表和索引結構 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表時可能出現的錯誤 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()函數 16.9.2. 實施external_lock()函數 16.9.3. 實施rnd_init()函數 16.9.4. 實施info()函數 16.9.5. 實施extra()函數 16.9.6. 實施rnd_next()函數 16.10. 關閉表 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. 多計算機的簡單基礎知識 17.3.1. 硬件、軟件和聯(lián)網 17.3.2. 安裝 17.3.3. 配置 17.3.4. 首次啟動 17.3.5. 加載示例數據并執(zhí)行查詢 17.3.6. 安全關閉和重啟 17.4. MySQL簇的配置 17.4.1. 從源碼創(chuàng)建MySQL簇 17.4.2. 安裝軟件 17.4.3. MySQL簇的快速測試設置 17.4.4. 配置文件 17.5. MySQL簇中的進程管理 17.5.1. 用于MySQL簇的MySQL服務器進程使用 17.5.2. ndbd,存儲引擎節(jié)點進程 17.5.3. ndb_mgmd,“管理服務器”進程 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. 關于MySQL簇的MySQL 5.1發(fā)展歷程 17.10. MySQL簇常見問題解答 17.11. MySQL簇術語表 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. 獲取關于分區(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. 支持的空間數據格式 19.3.1. 著名的文本(WKT)格式 19.3.2. 著名的二進制(WKB)格式 19.4. 創(chuàng)建具備空間功能的MySQL數據庫 19.4.1. MySQL空間數據類型 19.4.2. 創(chuàng)建空間值 19.4.3. 創(chuàng)建空間列 19.4.4. 填充空間列 19.4.5. 獲取空間數據 19.5. 分析空間信息 19.5.1. Geometry格式轉換函數 19.5.2. Geometry函數 19.5.3. 從已有Geometry創(chuàng)建新Geometry的函數 19.5.4. 測試幾何對象間空間關系的函數 19.5.5. 關于幾何最小邊界矩形(MBR)的關系 19.5.6. 測試幾何類之間空間關系的函數 19.6. 優(yōu)化空間分析 19.6.1. 創(chuàng)建空間索引 19.6.2. 使用空間索引 19.7. MySQL的一致性和兼容性 19.7.1. 尚未實施的GIS特性 20. 存儲程序和函數 20.1. 存儲程序和授權表 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復合語句 20.2.8. DECLARE語句 20.2.9. 存儲程序中的變量 20.2.10. 條件和處理程序 20.2.11. 光標 20.2.12. 流程控制構造 20.3. 存儲程序、函數、觸發(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信息數據庫 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. 精度數學 24.1. 數值的類型 24.2. DECIMAL數據類型更改 24.3. 表達式處理 24.4. 四舍五入 24.5. 精度數學示例 25. API和庫 25.1. libmysqld,嵌入式MySQL服務器庫 25.1.1. 嵌入式MySQL服務器庫概述 25.1.2. 使用libmysqld編譯程序 25.1.3. 使用嵌入式MySQL服務器時的限制 25.1.4. 與嵌入式服務器一起使用的選項 25.1.5. 嵌入式服務器中尚需完成的事項(TODO) 25.1.6. 嵌入式服務器示例 25.1.7. 嵌入式服務器的許可 25.2. MySQL C API 25.2.1. C API數據類型 25.2.2. C API函數概述 25.2.3. C API函數描述 25.2.4. C API預處理語句 25.2.5. C API預處理語句的數據類型 25.2.6. C API預處理語句函數概述 25.2.7. C API預處理語句函數描述 25.2.8. C API預處理語句方面的問題 25.2.9. 多查詢執(zhí)行的C API處理 25.2.10. 日期和時間值的C API處理 25.2.11. C API線程函數介紹 25.2.12. C API嵌入式服務器函數介紹 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:轉換mSQL程序以用于MySQL 25.9.2. mysql_config:獲取編譯客戶端的編譯選項 26. 連接器 26.1. MySQL Connector/ODBC 26.1.1. MyODBC介紹 26.1.2. 關于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連接相關的事宜 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應用步驟 26.1.16. MyODBC API引用 26.1.17. MyODBC數據類型 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體系結構 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驅動程序的一部分運行 26.4.6. 在Java對象中運行 26.4.7. MysqldResource API 26.4.8. 在JMX代理(custom)中運行 26.4.9. 部署在標準的JMX代理環(huán)境下 (JBoss) 26.4.10. 安裝 27. 擴展MySQL 27.1. MySQL內部控件 27.1.1. MySQL線程 27.1.2. MySQL測試套件 27.2. 為MySQL添加新函數 27.2.1. 自定義函數接口的特性 27.2.2. CREATE FUNCTION/DROP FUNCTION語法 27.2.3. 添加新的自定義函數 27.2.4. 添加新的固有函數 27.3. 為MySQL添加新步驟 27.3.1. 步驟分析 27.3.2. 編寫步驟 A. 問題和常見錯誤 A.1. 如何確定導致問題的原因 A.2. 使用MySQL程序時的常見錯誤 A.2.1. 拒絕訪問 A.2.2. 無法連接到[local] MySQL服務器 A.2.3. 客戶端不支持鑒定協(xié)議 A.2.4. 輸入密碼時出現密碼錯誤 NoName A.2.6. 連接數過多 A.2.7. 內存溢出 A.2.8. MySQL服務器不可用 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. 與安裝有關的事宜 A.3.1. 與MySQL客戶端庫的鏈接問題 A.3.2. 如何以普通用戶身份運行MySQL A.3.3. 與文件許可有關的問題 A.4. 與管理有關的事宜 A.4.1. 如何復位根用戶密碼 A.4.2. 如果MySQL依然崩潰,應作些什么 A.4.3. MySQL處理磁盤滿的方式 A.4.4. MySQL將臨時文件儲存在哪里 A.4.5. 如何保護或更改MySQL套接字文件/tmp/mysql.sock A.4.6. 時區(qū)問題 A.5. 與查詢有關的事宜 A.5.1. 搜索中的大小寫敏感性 A.5.2. 使用DATE列方面的問題 A.5.3. 與NULL值有關的問題 A.5.4. 與列別名有關的問題 A.5.5. 非事務表回滾失敗 A.5.6. 從相關表刪除行 A.5.7. 解決與不匹配行有關的問題 A.5.8. 與浮點比較有關的問題 A.6. 與優(yōu)化器有關的事宜 A.7. 與表定義有關的事宜 A.7.1. 與ALTER TABLE有關的問題 A.7.2. 如何更改表中的列順序 A.7.3. TEMPORARY TABLE問題 A.8. MySQL中的已知事宜 A.8.1. MySQL中的打開事宜 B. 錯誤代碼和消息 B.1. 服務器錯誤代碼和消息 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. 調試MySQL服務器 E.1.1. 針對調試編譯MySQL E.1.2. 創(chuàng)建跟蹤文件 E.1.3. 在gdb環(huán)境下調試mysqld E.1.4. 使用堆棧跟蹤 E.1.5. 使用日志文件找出mysqld中的錯誤原因 E.1.6. 如果出現表崩潰,請生成測試案例 E.2. 調試MySQL客戶端 E.3. DBUG軟件包 E.4. 關于RTS線程的注釋 E.5. 線程軟件包之間的差異 F. 環(huán)境變量 G. MySQL正則表達式 H. MySQL中的限制 H.1. 聯(lián)合的限制 I. 特性限制 I.1. 對存儲子程序和觸發(fā)程序的限制 I.2. 對服務器端光標的限制 I.3. 對子查詢的限制 I.4. 對視圖的限制 I.5. 對XA事務的限制 J. GNU通用公共許可 K. MySQL FLOSS許可例外 索引
Figuren

第6章:MySQL中的復制

目錄

6.1. 復制介紹
6.2. 復制實施概述
6.3. 復制實施細節(jié)
6.3.1. 復制主線程狀態(tài)
6.3.2. 復制從I/O線程狀態(tài)
6.3.3. 復制從SQL線程狀態(tài)
6.3.4. 復制傳遞和狀態(tài)文件
6.4. 如何設置復制
6.5. 不同MySQL版本之間的復制兼容性
6.6. 升級復制設置
6.6.1. 將復制升級到5.0版
6.7. 復制特性和已知問題
6.8. 復制啟動選項
6.9. 復制FAQ
6.10. 復制故障診斷與排除
6.11. 通報復制缺陷
6.12. 多服務器復制中的Auto-Increment

本章描述了MySQL提供的各種復制特性。引入了復制概念,顯示如何設置復制服務器和服務以指導相應的復制選項。還提供了FAQ(以及答案) 列表,以及解決復制問題的排錯建議。

關于復制相關的SQL語句的語法描述,參見13.6節(jié),“復制語句”。

我們建議你經常訪問我們的網址http://www.mysql.com,并檢查對本章的修改。復制在不斷地得到改進,我們用最新的信息定期更新本手冊。

6.1.?復制介紹

MySQL支持單向、異步復制,復制過程中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。(這與同步復制可以進行對比,同步復制是MySQL簇的一個特征—參見第17章:MySQL簇。主服務器將更新寫入二進制日志文件,并維護文件的一個索引以跟蹤日志循環(huán)。這些日志可以記錄發(fā)送到從服務器的更新。當一個從服務器連接主服務器時,它通知主服務器從服務器在日志中讀取的最后一次成功更新的位置。從服務器接收從那時起發(fā)生的任何更新,然后封鎖并等待主服務器通知新的更新。

如果你想要設置鏈式復制服務器,從服務器本身也可以充當主服務器。

請注意當你進行復制時,所有對復制中的表的更新必須在主服務器上進行。否則,你必須要小心,以避免用戶對主服務器上的表進行的更新與對從服務器上的表所進行的更新之間的沖突。

單向復制有利于健壯性、速度和系統(tǒng)管理:

·???????? 主服務器/從服務器設置增加了健壯性。主服務器出現問題時,你可以切換到從服務器作為備份。

·???????? 通過在主服務器和從服務器之間切分處理客戶查詢的負荷,可以得到更好的客戶響應時間。SELECT查詢可以發(fā)送到從服務器以降低主服務器的查詢處理負荷。但修改數據的語句仍然應發(fā)送到主服務器,以便主服務器和從服務器保持同步。如果非更新查詢?yōu)橹?,該負載均衡策略很有效,但一般是更新查詢。

·???????? 使用復制的另一個好處是可以使用一個從服務器執(zhí)行備份,而不會干擾主服務器。在備份過程中主服務器可以繼續(xù)處理更新。參見5.9.1節(jié),“數據庫備份”。

6.2.?復制實施概述

MySQL復制基于主服務器在二進制日志中跟蹤所有對數據庫的更改(更新、刪除等等)。因此,要進行復制,必須在主服務器上啟用二進制日志。參見5.11.3節(jié),“二進制日志”。

每個從服務器從主服務器接收主服務器已經記錄到其二進制日志的保存的更新,以便從服務器可以對其數據拷貝執(zhí)行相同的更新。

認識到二進制日志只是一個從啟用二進制日志的固定時間點開始的記錄非常重要。任何設置的從服務器需要主服務器上的在主服務器上啟用二進制日志時的數據庫拷貝。如果啟動從服務器時,其數據庫與主服務器上的啟動二進制日志時的狀態(tài)不相同,從服務器很可能失敗。

將主服務器的數據拷貝到從服務器的一個途徑是使用LOAD DATA FROM MASTER語句。請注意LOAD DATA FROM MASTER目前只在所有表使用MyISAM存儲引擎的主服務器上工作。并且,該語句將獲得全局讀鎖定,因此當表正復制到從服務器上時,不可能在主服務器上進行更新。當我們執(zhí)行表的無鎖熱備份時,則不再需要全局讀鎖定。

由于這些限制,我們建議只有主服務器上的數據集相對較小,或者主服務器上延遲讀鎖定已經被接受,才可以使用LOAD DATA FROM MASTER。而LOAD DATA FROM MASTER的實際速度隨系統(tǒng)的不同而不同,對于執(zhí)行時間,最好的規(guī)則是每1MB的數據用1秒鐘。這是一個粗略的估計,但你會發(fā)現如果主服務器和從服務器的性能上等價于700MHz Pentium CPU,通過100Mbps的網絡進行連接,則該估計相當準確。

從服務器設置為復制主服務器的數據后,它連接主服務器并等待更新過程。如果主服務器失敗,或者從服務器失去與主服務器之間的連接,從服務器保持定期嘗試連接,直到它能夠繼續(xù)幀聽更新。由--master-connect-retry選項控制重試間隔。 默認為60秒。

每個從服務器跟蹤復制時間。主服務器不知道有多少個從服務器或在某一時刻有哪些被更新了。

6.3.?復制實施細節(jié)

6.3.1. 復制主線程狀態(tài)
6.3.2. 復制從I/O線程狀態(tài)
6.3.3. 復制從SQL線程狀態(tài)
6.3.4. 復制傳遞和狀態(tài)文件

MySQL使用3個線程來執(zhí)行復制功能(其中1個在主服務器上,另兩個在從服務器上。當發(fā)出START SLAVE時,從服務器創(chuàng)建一個I/O線程,以連接主服務器并讓它發(fā)送記錄在其二進制日志中的語句。主服務器創(chuàng)建一個線程將二進制日志中的內容發(fā)送到從服務器。該線程可以識別為主服務器上SHOW PROCESSLIST的輸出中的Binlog Dump線程。從服務器I/O線程讀取主服務器Binlog Dump線程發(fā)送的內容并將該數據拷貝到從服務器數據目錄中的本地文件中,即中繼日志。第3個線程是SQL線程,是從服務器創(chuàng)建用于讀取中繼日志并執(zhí)行日志中包含的更新。

在前面的描述中,每個從服務器有3個線程。有多個從服務器的主服務器創(chuàng)建為每個當前連接的從服務器創(chuàng)建一個線程;每個從服務器有自己的I/OSQL線程。

這樣讀取和執(zhí)行語句被分成兩個獨立的任務。如果語句執(zhí)行較慢則語句讀取任務沒有慢下來。例如,如果從服務器有一段時間沒有運行了,當從服務器啟動時,其I/O線程可以很快地從主服務器索取所有二進制日志內容,即使SQL線程遠遠滯后。如果從服務器在SQL線程執(zhí)行完所有索取的語句前停止,I/O 線程至少已經索取了所有內容,以便語句的安全拷貝保存到本地從服務器的中繼日志中,供從服務器下次啟動時執(zhí)行。這樣允許清空主服務器上的二進制日志,因為不再需要等候從服務器來索取其內容。

SHOW PROCESSLIST語句可以提供在主服務器上和從服務器上發(fā)生的關于復制的信息。

下面的例子說明了這3個線程在SHOW PROCESSLIST中的顯示。

在主服務器上,SHOW PROCESSLIST的輸出看上去應為:

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
???? Id: 2
? ?User: root
?? Host: localhost:32931
???? db: NULL
Command: Binlog Dump
?? Time: 94
? State: Has sent all binlog to slave; waiting for binlog to
???????? be updated
?? Info: NULL

這兒,線程2是一個連接從服務器的復制線程。該信息表示所有主要更新已經被發(fā)送到從服務器,主服務器正等待更多的更新出現。

在從服務器上,SHOW PROCESSLIST的輸出看上去應為:

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
???? Id: 10
?? User: system user
?? Host:
???? db: NULL
Command: Connect
?? Time: 11
? State: Waiting for master to send event
?? Info: NULL
*************************** 2. row ***************************
???? Id: 11
?? User: system user
?? Host:
???? db: NULL
Command: Connect
?? Time: 11
? State: Has read all relay log; waiting for the slave I/O
???????? thread to update it
?? Info: NULL

該信息表示線程10是同主服務器通信的I/O線程,線程11是處理保存在中繼日志中的更新的SQL線程。SHOW PROCESSLIST運行時,兩個線程均空閑,等待其它更新。

請注意Time列的值可以顯示從服務器比主服務器滯后多長時間。參見6.9節(jié),“復制FAQ”。

6.3.1.?復制主線程狀態(tài)

下面列出了主服務器的Binlog Dump線程的State列的最常見的狀態(tài)。如果你沒有在主服務器上看見任何Binlog Dump線程,這說明復制沒有在運行—即,目前沒有連接任何從服務器。

·???????? Sending binlog event to slave

二進制日志由各種事件組成,一個事件通常為一個更新加一些其它信息。線程已經從二進制日志讀取了一個事件并且正將它發(fā)送到從服務器。

·???????? Finished reading one binlog; switching to next binlog

線程已經讀完二進制日志文件并且正打開下一個要發(fā)送到從服務器的日志文件。

·???????? Has sent all binlog to slave; waiting for binlog to be updated

線程已經從二進制日志讀取所有主要的更新并已經發(fā)送到了從服務器。線程現在正空閑,等待由主服務器上新的更新導致的出現在二進制日志中的新事件。

·???????? Waiting to finalize termination

線程停止時發(fā)生的一個很簡單的狀態(tài)。

6.3.2.?復制從I/O線程狀態(tài)

下面列出了從服務器的I/O線程的State列的最常見的狀態(tài)。該狀態(tài)也出現在Slave_IO_State列,由SHOW SLAVE STATUS顯示。這說明你可以只通過該語句仔細瀏覽所發(fā)生的事情。

·???????? Connecting to master

線程正試圖連接主服務器。

·???????? Checking master version

建立同主服務器之間的連接后立即臨時出現的狀態(tài)。

·???????? Registering slave on master

建立同主服務器之間的連接后立即臨時出現的狀態(tài)。

·???????? Requesting binlog dump

建立同主服務器之間的連接后立即臨時出現的狀態(tài)。線程向主服務器發(fā)送一條請求,索取從請求的二進制日志文件名和位置開始的二進制日志的內容。

·???????? Waiting to reconnect after a failed binlog dump request

如果二進制日志轉儲請求失敗(由于沒有連接),線程進入睡眠狀態(tài),然后定期嘗試重新連接??梢允褂?span>--master-connect-retry選項指定重試之間的間隔。

·???????? Reconnecting after a failed binlog dump request

線程正嘗試重新連接主服務器。

·???????? Waiting for master to send event

線程已經連接上主服務器,正等待二進制日志事件到達。如果主服務器正空閑,會持續(xù)較長的時間。如果等待持續(xù)slave_read_timeout秒,則發(fā)生超時。此時,線程認為連接被中斷并企圖重新連接。

·???????? Queueing master event to the relay log

線程已經讀取一個事件,正將它復制到中繼日志供SQL線程來處理。

·???????? Waiting to reconnect after a failed master event read

讀取時(由于沒有連接)出現錯誤。線程企圖重新連接前將睡眠master-connect-retry秒。

·???????? Reconnecting after a failed master event read

線程正嘗試重新連接主服務器。當連接重新建立后,狀態(tài)變?yōu)?span>Waiting for master to send event。

·???????? Waiting for the slave SQL thread to free enough relay log space

正使用一個非零relay_log_space_limit值,中繼日志已經增長到其組合大小超過該值。I/O線程正等待直到SQL線程處理中繼日志內容并刪除部分中繼日志文件來釋放足夠的空間。

·???????? Waiting for slave mutex on exit

線程停止時發(fā)生的一個很簡單的狀態(tài)。

6.3.3.?復制從SQL線程狀態(tài)

下面列出了從服務器的SQL線程的State列的最常見的狀態(tài)。

·???????? Reading event from the relay log

線程已經從中繼日志讀取一個事件,可以對事件進行處理了。

·???????? Has read all relay log; waiting for the slave I/O thread to update it

線程已經處理了中繼日志文件中的所有事件,現在正等待I/O線程將新事件寫入中繼日志。

·???????? Waiting for slave mutex on exit

線程停止時發(fā)生的一個很簡單的狀態(tài)。

I/O線程的State列也可以顯示語句的文本。這說明線程已經從中繼日志讀取了一個事件,從中提取了語句,并且正在執(zhí)行語句。

6.3.4.?復制傳遞和狀態(tài)文件

默認情況,中繼日志使用host_name-relay-bin.nnnnnn形式的文件名,其中host_name是從服務器主機名,nnnnnn是序列號。用連續(xù)序列號來創(chuàng)建連續(xù)中繼日志文件,從000001開始。從服務器跟蹤索引文件中目前正使用的中繼日志。 默認中繼日志索引文件名為host_name-relay-bin.index。默認情況,在從服務器的數據目錄中創(chuàng)建這些文件??梢杂?span>--relay-log和--relay-log-index服務器選項覆蓋 默認文件名。參見6.8節(jié),“復制啟動選項”。

中繼日志與二進制日志的格式相同,并且可以用mysqlbinlog讀取。SQL線程執(zhí)行完中繼日志中的所有事件并且不再需要之后,立即自動刪除它。沒有直接的刪除中繼日志的機制,因為SQL線程可以負責完成。然而,FLUSH LOGS可以循環(huán)中繼日志,當SQL線程刪除日志時會有影響。

在下面的條件下創(chuàng)建新的中繼日志:

·???????? 每次I/O線程啟動時創(chuàng)建一個新的中繼日志。

·???????? 當日志被刷新時;例如,用FLUSH LOGSmysqladmin flush-logs。

·???????? 當當前的中繼日志文件變得太大時?!?span id="wjcelcm34c" class="quote">太大”含義的確定方法:

o??????? max_relay_log_size,如果max_relay_log_size > 0

o??????? max_binlog_size,如果max_relay_log_size = 0

從屬復制服務器在數據目錄中另外創(chuàng)建兩個小文件。這些狀態(tài)文件默認名為主master.inforelay-log.info。它們包含SHOW SLAVE STATUS語句的輸出所顯示的信息(關于該語句的描述參見13.6.2節(jié),“用于控制從服務器的SQL語句”)。狀態(tài)文件保存在硬盤上,從服務器關閉時不會丟失。下次從服務器啟動時,讀取這些文件以確定它已經從主服務器讀取了多少二進制日志,以及處理自己的中繼日志的程度。

I/O線程更新master.info文件。文件中的行和SHOW SLAVE STATUS顯示的列的對應關系為:

描述

1

文件中的行號

2

Master_Log_File

3

Read_Master_Log_Pos

4

Master_Host

5

Master_User

6

密碼(不由SHOW SLAVE STATUS顯示)

7

Master_Port

8

Connect_Retry

9

Master_SSL_Allowed

10

Master_SSL_CA_File

11

Master_SSL_CA_Path

12

Master_SSL_Cert

13

Master_SSL_Cipher

14

Master_SSL_Key

SQL線程更新relay-log.info文件。文件中的行和SHOW SLAVE STATUS顯示的列的對應關系為:

描述

1

Relay_Log_File

2

Relay_Log_Pos

3

Relay_Master_Log_File

4

Exec_Master_Log_Pos

當備份從服務器的數據時,你還應備份這兩個小文件以及中繼日志文件。它們用來在恢復從服務器的數據后繼續(xù)進行復制。如果丟失了中繼日志但仍然有relay-log.info文件,你可以通過檢查該文件來確定SQL線程已經執(zhí)行的主服務器中二進制日志的程度。然后可以用Master_Log_FileMaster_LOG_POS選項執(zhí)行CHANGE MASTER TO來告訴從服務器重新從該點讀取二進制日志。當然,要求二進制日志仍然在主服務器上。

如果從服務器正復制LOAD DATA INFILE語句,你應也備份該目錄內從服務器用于該目的的任何SQL_LOAD-*文件。從服務器需要這些文件繼續(xù)復制任何中斷的LOAD DATA INFILE操作。用--slave-load-tmpdir選項來指定目錄的位置。如果未指定, 默認值為tmpdir變量的值。

6.4.?如何設置復制

這里簡單描述了如何為你當前的MySQL服務器設置完整的復制。假設你想要復制主服務器上的所有數據庫,并且還沒有配置的復制。你需要關閉主服務器來完成下面所列的步驟。

下面的程序針對設置一個從服務器,你可以用來設置多個從服務器。

雖然該方法是設置從服務器的最直接的途徑,它并不是唯一的一個。例如,如果你有一個主服務器的數據快照,并且主服務器已經設置了服務器ID,啟用了二進制日志,不需要關閉主服務器或停止對它的更新也可以設置從服務器。詳情請參見6.9節(jié),“復制FAQ”。

如果想要管理MySQL復制設置,我們建議你通讀本章,并嘗試13.6.1節(jié),“用于控制主服務器的SQL語句”和13.6.2節(jié),“用于控制從服務器的SQL語句”中的所有語句。還應熟悉6.8節(jié),“復制啟動選項”中描述的復制啟動選項。

注釋:該程序和后面章節(jié)所示的復制SQL語句需要SUPER權限。

1.??? 確保在服務器和從服務器上安裝的MySQL版本與6.5節(jié),“不同MySQL版本之間的復制兼容性”所示的表兼容。理想情況,應在主服務器和從服務器上使用最近版本的MySQL。

請先證實問題不是出現在最新的MySQL版本中再通報bug。

2.??? 在主服務器上為服務器設置一個連接賬戶。該賬戶必須授予REPLICATION SLAVE權限。如果賬戶僅用于復制(推薦這樣做),則不需要再授予任何其它權限。(關于設置用戶 賬戶和權限的信息,參見5.8節(jié),“MySQL用戶賬戶管理”)。

假定你的域為mydomain.com,想要創(chuàng)建用戶名為repl的一個賬戶,從服務器可以使用該賬戶從你的域內的任何主機使用密碼slavepass來訪問主服務器。要創(chuàng)建該 賬戶,可使用GRANT語句:

mysql> GRANT REPLICATION SLAVE ON *.*
??? -> TO 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass';

如果你計劃從從屬服務器主機使用LOAD TABLE FROM MASTERLOAD DATA FROM MASTER語句,你需要授予該賬戶其它權限:

·???????? 授予賬戶SUPERRELOAD全局權限。

·???????? 為所有想要裝載的表授予SELECT權限。任何該 賬戶不能SELECT的主服務器上的表被LOAD DATA FROM MASTER忽略掉。

3.??? 執(zhí)行FLUSH TABLES WITH READ LOCK語句清空所有表和塊寫入語句:

4.??????????? mysql> FLUSH TABLES WITH READ LOCK;

對于InnoDB表,請注意:FLUSH TABLES WITH READ LOCK還鎖定COMMIT操作。當獲得全局讀鎖定后,可以開始InnoDB表的文件系統(tǒng)快照??煺詹荒鼙WC內部(InnoDB存儲引擎內部)一致性(因為InnoDB緩存沒有刷新),但并不需要關心該問題,因為InnoDB可以在啟動時解決該問題并給出一致的結果。這說明InnoDB在啟動快照時可以進行崩潰恢復,而不會破壞。然而,當保證一致的InnoDB表快照時,還沒有途徑來停止MySQL服務器。

讓客戶程序保持運行,發(fā)出FLUSH TABLES語句讓讀鎖定保持有效。(如果退出客戶程序,鎖被釋放)然后對主服務器上的數據進行快照。

創(chuàng)建快照最簡單的途徑是使用歸檔程序對主服務器上的數據目錄中的數據庫進行二進制備份。例如,在Unix中使用tar,或者在Windows中使用PowerArchiver、WinRARWinZip或者類似的軟件。要使用tar來創(chuàng)建包括所有數據庫的歸檔文件,進入主服務器的數據目錄,然后執(zhí)行命令:

shell> tar -cvf /tmp/mysql-snapshot.tar .

如果你想讓歸檔只包括this_db數據庫,應使用命令:

shell> tar -cvf /tmp/mysql-snapshot.tar ./this_db

然后將歸檔文件復制到從服務器主機的/tmp目錄。在該機器上,進入從服務器的數據目錄,并使用下述命令解壓縮歸檔文件:

shell> tar -xvf /tmp/mysql-snapshot.tar

如果從服務器的用戶賬戶與主服務器的不同,你可能不想復制mysql數據庫。在這種情況下,應從歸檔中排除該數據庫。你也不需要在歸檔中包括任何日志文件或者master.inforelay-log.info文件。

FLUSH TABLES WITH READ LOCK所置讀鎖定有效時,讀取主服務器上當前的二進制日志名和偏移量值:

mysql > SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+
| File????????? | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| mysql-bin.003 | 73?????? | test???????? | manual,mysql???? |
+---------------+----------+--------------+------------------+

File列顯示日志名,而Position顯示偏移量。在該例子中,二進制日志值為mysql-bin.003,偏移量為73。記錄該值。以后設置從服務器時需要使用這些值。它們表示復制坐標,從服務器應從該點開始從主服務器上進行新的更新。

取得快照并記錄日志名和偏移量后,可以在主服務器上重新啟用寫活動:

mysql> UNLOCK TABLES;

如果你正使用InnoDB表,理想情況應使用InnoDB Hot Backup工具,使用該工具可以獲得一致的快照而不需要在主服務器上進行鎖定,并且可以對應從服務器上使用的快照來記錄日志名和偏移量。Hot Backup是一個附加的非免費(商業(yè))工具,沒有包含在標準 MySQL分發(fā)中。詳細信息參見http://www.innodb.com/manual.phpInnoDB Hot Backup主頁。

不使用Hot Backup工具,最快捷的途徑是使用InnoDB表的二進制快照來關閉主服務器并復制InnoDB數據文件、日志文件和表定義文件(.frm文件)。要記錄當前的日志文件名和偏移量,關閉服務器之前應發(fā)出下面的語句:

mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;

然后記錄前面所示的SHOW MASTER STATUS的輸出中顯示的日志名和偏移量。記錄日志名和偏移量后,解鎖表關閉服務器以確保? 服務器關閉時的快照與當前的日志文件和偏移量相對應:

shell> mysqladmin -u root shutdown

適合MyISAMInnoDB表的另一個方法是對主服務器上的SQL進行轉儲而不是對前面討論的二進制復制進行轉儲。為了實現,可以在主服務器上使用mysqldump --master-data,以后將SQL轉儲文件裝入從服務器。但是,這樣比二進制復制要慢一些。

如果主服務器運行時沒有啟用--logs-bin,SHOW MASTER STATUSmysqldump --master-data顯示的日志名和位置值為空。在這種情況下,當以后指定從服務器的日志文件和位置時需要使用的值為空字符串('')4.

5.??? 確保主服務器主機上my.cnf文件的[mysqld]部分包括一個log-bin選項。該部分還應有一個server-id=Master_id選項,其中master_id必須為12321之間的一個正整數值。例如:

6.??????????? [mysqld]
7.??????????? log-bin=mysql-bin
8.??????????? server-id=1

如果沒有提供那些選項,應添加它們并重啟服務器。

9.??? 停止用于從服務器的服務器并在其my.cnf文件中添加下面的行:

10.??????? [mysqld]
11.??????? server-id=slave_id

slave_id值同Master_id值一樣,必須為12321之間的一個正整數值。并且,從服務器的ID必須與主服務器的ID不相同。例如:

[mysqld]
server-id=2

如果設置多個從服務器,每個從服務器必須有一個唯一的server-id值,必須與主服務器的以及其它從服務器的不相同??梢哉J為server-id值類似于IP地址:這些ID值能唯一識別復制服務器群集中的每個服務器實例。

如果不指定一個server-id值,如果沒有定義master-host,則將它設置為1;否則設置為2。請注意如果server-id太長,主服務器 拒絕所有來自從服務器的連接,并且從服務器拒絕連接到主服務器。這樣,省略server-id只適合用二進制日志備份。

12.如果對主服務器的數據進行二進制備份,啟動從服務器之前將它復制到從服務器的數據目錄中。確保對這些文件和目錄的權限正確。服務器 MySQL運行的用戶必須能夠讀寫文件,如同在主服務器上一樣。

如果使用mysqldum備份,先啟動從服務器(看下一步)

13.啟動從服務器。如果前面已經復制了,用--skip-slave-start選項啟動從服務器,以便它不立即嘗試連接主服務器。你也可能想要用--logs-warnings選項啟動從服務器(默認設置啟用),以便在錯誤日志中顯示更多的問題相關的信息(例如,網絡或連接問題)。放棄的連接將記入錯誤日志,除非其值大于1

14.如果使用mysqldump備份主服務器的數據,將轉儲文件裝載到從服務器:

15.??????? shell> mysql -u root -p < dump_file.sql
16.??????? 在從服務器上執(zhí)行下面的語句,用你的系統(tǒng)的實際值替換選項值:
17.??????? mysql> CHANGE MASTER TO
18.??????? ????->???? MASTER_HOST='master_host_name',
19.??????? ????->???? MASTER_USER='replication_user_name',
20.??????? ????->???? MASTER_PASSWORD='replication_password',
21.??????? ????->???? MASTER_LOG_FILE='recorded_log_file_name',
22.??????? ????->???? MASTER_LOG_POS=recorded_log_position;

下面的表顯示了字符串選項的最大長度:

Master_Host

60

Master_USER

16

Master_PASSWORD

32

Master_Log_File

255

23.啟動從服務器線程:

24.??????? mysql> START SLAVE;

執(zhí)行這些程序后,從服務器應連接主服務器,并補充自從快照以來發(fā)生的任何更新。

如果你忘記設置主服務器的server-id值,從服務器不能連接主服務器。

如果你忘記設置從服務器的server-id值,在從服務器的錯誤日志中會出現下面的錯誤:

Warning: You should set server-id to a non-0 value if master_host is set;
we will force server id to 2, but this MySQL server will not act as a slave.

如果由于其它原因不能復制,從服務器的錯誤日志中也會出現錯誤消息。

從服務器復制時,會在其數據目錄中發(fā)現文件dmaster.inforelay-log.info。從服務器使用這兩個文件跟蹤已經處理了多少主服務器的二進制日志。不要移除或編輯這些文件,除非你確切知你正在做什么并完全理解其意義。即使這樣,最好是使用CHANGE MASTER TO語句。

注釋:master.info內容會覆蓋命令行或in my.cnf中指定的部分選項。詳情參見6.8節(jié),“復制啟動選項”。

有了一個快照,你可以用它根據剛剛描述的從服務器部分來設置其它從服務器。你不需要主服務器的另一個快照;每個從服務器可以使用相同的快照。

注釋:為了保證事務InnoDB復制設置的最大可能的耐受性和一致性,應在主服務器的my.cnf文件中使用innodb_flush_log_at_trx_commit=1sync-binlog=1。

6.5.?不同MySQL版本之間的復制兼容性

MySQL 5.1中使用的二進制日志格式與以前的版本中所使用的大大不同,特別是在字符集處理、LOAD DATA INFILE以及時區(qū)方面。

注釋:你不能從使用新二進制日志格式的主服務器向使用舊二進制日志格式的從服務器復制(例如,從MySQL 5.0MySQL 4.1。這樣操作在復制設置升級服務器時后果嚴重,參見6.6節(jié),“升級復制設置”。

我們推薦使用最近的MySQL版本,因為復制功能在不斷地改進中。我們還推薦主服務器和從服務器使用相同的版本。我們建議升級主服務器和從服務器,運行alphabeta版本到新的(產品)版本。在許多情況下,從新的主服務器向舊的從服務器復制將會失敗。一般原則,運行MySQL 5.1.x的從服務器可以與舊的主服務器(可以運行MySQL 3.23、4.0或者4.1)一起使用,但不能反過來。

前面的信息適合協(xié)議級復制兼容性。然而,還會有一個約束條件,例如SQL級兼容性問題。例如, 5.1版本的主服務器不能復制到5.0版本的從服務器,如果復制語句使用5.1版本的SQL特性而不是5.0版本。這些問題和其它問題均在6.7節(jié),“復制特性和已知問題”中討論。

6.6.?升級復制設置

6.6.1. 將復制升級到5.0版
當在復制設置中升級服務器時,升級過程取決于當前的服務器版本和要升級的服務器版本。

6.6.1.?將復制升級到5.0版

該節(jié)適用于將復制從MySQL 3.23、4.0或者4.1升級到5.1。4.0服務器應為4.0.3或更新版。

當將早期MySQL版本系列主服務器升級到5.1時,應先確保該主服務器的所有從服務器使用了相同的5.1.x版本。如果不是這樣,你應先升級從服務器。升級從服務器時,應先關閉從服務器,升級到相應5.1.x版本,然后重啟從服務器并重新開始復制。5.1版本的從服務器能夠讀取升級前寫入的舊的中繼日志并執(zhí)行日志中包含的語句。升級后從服務器創(chuàng)建的中繼日志為5.1格式。

從服務器升級后,關閉主服務器,將它升級到與從服務器相同的5.1.x版本并重啟它。5.1主服務器能夠讀取升級前寫入的舊的二進制日志并將它們發(fā)送到5.1從服務器。從服務器可以識別舊的格式并正確處理它。升級后主服務器創(chuàng)建的二進制日志采用5.1格式。這樣也可以由5.1從服務器識別。

換句話說,當升級到5.1時沒有什么措施,只有將主服務器升級到5.1之前先將從服務器升級到5.1。請注意從5.1降級到舊版本不會如此簡單:必須確保已經完全處理所有5.1版本的二進制日志或中繼日志,以便在降級前可以移除它們。

6.7.?復制特性和已知問題

一般原則,SQL級復制兼容性要求主服務器和從服務器均支持使用的特性。例如,在MySQL 5.0.0中開始使用TIMESTAMPADD()函數。如果在主服務器上使用該函數,不能復制到MySQL 5.0.0之前的從服務器。如果你計劃在5.1和以前版本的MySQL之間進行復制,你應查閱對應以前版本系列的MySQL參考手冊,查詢該系列復制特征相關信息。

下面列出了關于支持什么和不支持什么的詳細信息。關于復制的其它InnoDB具體信息參見15.2.6.5節(jié),“InnoDB和MySQL復制”。

關于保存的程序和觸發(fā)器的復制問題在20.4節(jié),“存儲子程序和觸發(fā)程序的二進制日志功能”中討論。

·???????? AUTO_INCREMENT、LAST_INSERT_ID()TIMESTAMP值正確實現復制。

·???????? USER()UUID()LOAD_FILE()函數毫無改變地被,這樣不能可靠地在從服務器上工作。

·???????? 下面的限制只適合基于語句的復制,而不是基于行的復制。處理用戶級鎖定的函數GET_LOCK()RELEASE_LOCK()、IS_FREE_LOCK()、IS_USED_LOCK()復制時從服務器不知道在主服務器上同時進行的相關文本;因此如果從服務器上的內容不同,這些函數不用來插入到主服務器的表中(例如不執(zhí)行INSERT INTO mytable VALUES(GET_LOCK(...)))。

·???????? MySQL 5.1FOREIGN_KEY_CHECKSSQL_MODE、UNIQUE_CHECKSSQL_AUTO_IS_NULL變量均復制。但TABLE_TYPE,即STORAGE_ENGINE變量 不復制,有利于在不同的存儲引擎之間進行復制。

·???????? 即使主服務器和從服務器有不同的全局字符集變量,以及即使有不同的全局時區(qū)變量仍可以復制。

·???????? 下面適合使用不同字符集的MySQL服務器之間的復制:

1.??? 必須在主服務器和從服務器上總是使用相同的全局字符集和校對規(guī)則(--default-character-set、--default-collation)。否則,會在從服務器上遇到復制鍵值錯誤,因為在主服務器的字符集中被認為是唯一的鍵值在從服務器的字符集中可能不是唯一的。

2.??? 如果主服務器早于MySQL 4.1.3,則會話中的字符集不應與其全局值不同(換句話說,不要使用SET NAMES、SET CHARACTER SET等等),因為從服務器不知道該字符集的更改。如果主服務器和從服務器均為4.1.3或更新版,可以隨便將會話的字符集變量設置為本地值(例如NAMES、CHARACTER SET、COLLATION_CLIENTCOLLATION_SERVER),因為這些設定值被寫入二進制日志,因此從服務器知道。然而,禁止更改會話中這些變量的全局值;如前面所述,主服務器和從服務器必須具有唯一的全局字符集值。

3.??? 如果在主服務器上的數據庫的字符集與全局collation_server值不同,則應設計CREATE TABLE語句,以便它們不隱含依賴數據庫的默認字符集(Bug #2326);一個好的解決辦法是在CREATE TABLE中明顯說明字符集和校對規(guī)則。

·???????? 應在主服務器和從服務器上設置相同的系統(tǒng)時區(qū)。否則一些語句,例如使用NOW()FROM_UNIXTIME()函數的語句,將不會正確復制??梢允褂媚_本mysqld_safe--timezone=timezone_name選項或通過設置TZ環(huán)境變量設置MySQL服務器運行的系統(tǒng)的時區(qū)。主服務器和從服務器還應有相同的默認連接時區(qū)設置;即主服務器和從服務器應有相同的--default-time-zone參數值。

·???????? CONVERT_TZ(...,...,@global.time_zone)不能正確復制。只有主服務器和從服務器均為5.0.4或更新版才能正確復制CONVERT_TZ(...,...,@session.time_zone)。

·???????? 會話變量只有在更新表的語句中使用時才能正確復制;例如:SET MAX_JOIN_SIZE=1000;INSERT INTO mytable VALUES(@MAX_JOIN_SIZE)不能將相同的數據插入到主服務器上和從服務器上。不適用于通用的SET TIME_ZONE=...;INSERT INTO mytable VALUES(CONVERT_TZ(...,...,@time_zone))。

·???????? 可以將從服務器上的非事務表復為主服務器上的事務表。例如,可以將主服務器上的InnoDB表復制為從服務器上的MyISAM表。然而,復制過程中,如果從服務器在BEGIN/COMMIT塊過程中停止則會產生問題,因為從服務器在BEGIN塊開始時會重啟。該問題出現在TODO中,不久將會得到修復。

·???????? MySQL 5.1中可以正確復制引用用戶變量(@var_name形式的變量)的更新語句;但在4.1以前的版本中卻不可能。請注意從MySQL 5.1開始對用戶變量名的大小寫不再敏感;當在5.1和舊版本之間設置復制時應考慮該問題。

·???????? 從服務器可以使用SSL連接到主服務器。

·???????? 有一個全局系統(tǒng)變量slave_transaction_retries:如果因為某個InnoDB死鎖或超過 InnoDBinnodb_lock_wait_timeoutNDB簇的TransactionDeadlockDetectionTimeoutTransactionInactiveTimeoutREPLICATION SLAVESQL線程未能執(zhí)行某個事務,在給出錯誤停止前自動重試slave_transaction_retries次。 默認值是10。從MySQL 5.0.4開始,可以從SHOW STATUS的輸出中看到重試總次數;參見5.3.4節(jié),“服務器狀態(tài)變量”。

·???????? 如果在主服務器上的CREATE TABLE語句中使用了DATA DIRECTORYINDEX DIRECTORY子句,子句也可以在從服務器上使用。如果在從服務器主機文件系統(tǒng)中不存在一致的目錄或雖然存在但不能被從服務器訪問,則會帶來問題。MySQL 5.1支持一個稱為NO_DIR_IN_CREATEsql_mode選項。如果從服務器運行時將SQL模式設置為包括該選項,復制CREATE TABLE語句時將忽略這些子句。結果是在表的數據庫目錄中創(chuàng)建了MyISAM數據和索引文件。

·???????? 下面的限制只適合基于語句的復制,而不是基于行的復制:如果在查詢中數據修改不確定,主服務器和從服務器上的數據可以不同;也就是由查詢優(yōu)化器確定。(這是常用的但不是很好的習慣,即使不是在復制中也不好)關于該問題的詳細解釋,參見A.8.1節(jié),“MySQL中的打開事宜”。

·???????? READ LOCKFLUSH LOGS、FLUSH MASTERFLUSH SLAVEFLUSH TABLES不記入日志,因為如果復制到從服務器會造成問題。關于語法示例,參見13.5.5.2節(jié),“FLUSH語法”。FLUSH TABLES、ANALYZE TABLE、OPTIMIZE TABLEREPAIR TABLE語句被寫入二進制日志并會復制到從服務器。一般情況不會造成問題,因為這些語句不修改表的數據。但是在某些情況下會帶來問題。如果你復制mysql數據庫中的授權表并且不使用GRANT直接更新那些表,必須在從服務器上執(zhí)行FLUSH PRIVILEGES使新的權限生效。并且,如果使用FLUSH TABLES重新命名MERGE表的MyISAM表,必須手動在從服務器上執(zhí)行FLUSH TABLES。如果不指定NO_WRITE_TO_BINLOG或其別名LOCAL,則這些語句被寫入二進制日志。

·???????? MySQL只支持一個主服務器和多個從服務器。我們計劃將來添加一個投票算法,當前的主服務器出現問題時自動切換。我們還計劃引入代理過程通過向不同的從服務器發(fā)送SELECT查詢以幫助進行負載均衡。

·???????? 當服務器關閉、重啟時,其MEMORY表將變?yōu)榭?。主服務器按下述方法復制該結果:啟動后第1次主服務器使用每個MEMORY表,它通知從服務器需要向表寫入DELETE FROM語句來清空二進制日志的表。詳細信息參見15.4節(jié),“MEMORY (HEAP)存儲引擎”。

·???????? 除了關閉從服務器(而不僅僅是從服務器線程) 臨時表都被復制,并且還沒有在從服務器上執(zhí)行的更新所使用的臨時表也已經復制。如果關閉從服務器,從服務器重啟后更新需要的那些臨時表不可再用。為了避免該問題,臨時表打開時不要關閉從服務器。而應遵照下面的程序:

1.??? 執(zhí)行STOP SLAVE語句。

2.??? 使用SHOW STATUS檢查slave_open_temp_tables變量的值。

3.??? 如果值為0,使用mysqladmin shutdown命令關閉從服務器。

4.??? 如果值不為0,用START SLAVE重啟從服務器線程。

5.??? 后面再重復該程序看下次的運氣是否好一些。

我們計劃在不久的將來修復該問題。

·???????? 可以很安全地連接用--logs-slave-updates選項指定的循環(huán)主服務器/從服務器關系中的服務器。但請注意許多語句在這種設置中不能正確工作,除非你的客戶代碼關注了潛在的在不同的服務器不同順序的更新中可能發(fā)生的這類問題。

這說明你可以象這樣創(chuàng)建設置:

A -> B -> C -> A

服務器ID被編碼在二進制日志事件中,因此服務器A知道何時自己首次創(chuàng)建它讀取的事件并且不執(zhí)行事件(除非用--replicate-same-server-id選項啟動了服務器A,只在很少情況下有意義)。這樣,沒有無限循環(huán)。只有對表執(zhí)行沒有沖突的更新時該類循環(huán)設置才能工作。換句話說,如果在AC中插入數據,絕對不應在A中插入鍵值可能與插入到C中的行相沖突的一行。如果更新的順序很重要,還不應更新兩個服務器上相同的行。

·???????? 如果從服務器上的某個語句產生錯誤,則從服務器上的SQL線程終止,并且從服務器向錯誤日志寫入一條消息。此時應手動連接從服務器,修復該問題(例如,一個不存在的表),然后運行START SLAVE。

·???????? 可以很安全地關閉主服務器并在以后重啟。如果某個從服務器丟失與主服務器的連接,從服務器嘗試立即重新連接。如果失敗,從服務器定期重試。(默認設置是每60秒重試一次??梢酝ㄟ^--master-connect-retry選項更改)從服務器也能夠處理網絡連接中斷。但是,只有從服務器超過slave_net_timeout秒沒有從主服務器收到數據才通知網絡中斷。如果中斷時間短,可以降低slave_net_timeout。參見5.3.3節(jié),“服務器系統(tǒng)變量”。

·???????? 關閉從服務器(凈關閉)也很安全,因為它可以跟蹤它離開的地點。不純凈的關閉操作會產生問題,特別是系統(tǒng)關閉前硬盤緩存未刷新到硬盤上時。如果有不間斷電源,可以大大提高系統(tǒng)容錯能力。不純凈的關閉主服務器會造成主服務器上的表和二進制日志內容之間的不一致性;在主服務器上使用InnoDB表和--innodb-safe-binlog選項可以避免該問題。參見5.11.3節(jié),“二進制日志”。(注釋:MySQL 5.1中不需要--innodb-safe-binlog,由于引入了XA事務支持已經作廢了)。

·???????? 由于MyISAM表的非事務屬性,可以有一個語句只是更新一個表并返回錯誤代碼。例如,多行插入時有一個行超過鍵值約束,或者如果長的更新語句更新部分行后被殺掉了。如果發(fā)生在主服務器上,除非錯誤代碼合法并且語句執(zhí)行產生相同的錯誤代碼,從服務器線程將退出并等待數據庫管理員決定如何做。如果該錯誤代碼驗證行為不理想,可以用--slave-skip-errors選項掩蓋(忽視)部分或全部錯誤。

·???????? 如果從BEGIN/COMMIT系列的非事務表更新事務表,如果提交事務前更新非事務表,對二進制日志的更新可能會不同步。這是因為事務提交后才被寫入二進制日志。

·???????? 事務混合更新事務表和非事務表時,二進制日志中語句的順序是正確的,即使在ROLLBACK時,所有需要的語句也會寫入二進制日志。但是如果在第1個連接的事務完成前,第2個連接更新非事務表,語句記入日志時會出現順序錯誤,因為第2個連接的更新執(zhí)行完后立即寫入日志,而不管第1個連接執(zhí)行的事務的狀態(tài)如何。

6.8.?復制啟動選項

在主服務器和從服務器上,均必須使用server-id選項為每個服務器建立唯一的復制ID。你應為每個主服務器和從服務器從12321的范圍挑一個唯一的正整數。例如:server-id=3

用于主服務器上控制二進制日志的選項的相關描述見5.11.3節(jié),“二進制日志”。

下表描述了可以用于MySQL 5.1從屬復制服務器的選項。你可以在命令行中或在選項文件中指定這些選項。

某些從服務器復制選項按特殊方式處理,當從服務器啟動時如果master.info文件存在并且包含選項值,它們將被忽略掉。下面的選項按這種方式處理:

·???????? --master-host

·???????? --master-user

·???????? --master-password

·???????? --master-port

·???????? --master-connect-retry

·???????? --master-ssl

·???????? --master-ssl-ca

·???????? --master-ssl-capath

·???????? --master-ssl-cert

·???????? --master-ssl-cipher

·???????? --master-ssl-key

5.1中的master.info文件格式包括對應SSL選項的值。并且,文件格式包括文件中的行號,如同第1行。如果你將舊的服務器升級到新的版本,新服務器啟動時自動將smaster.info文件升級到新的格式。然而,如果將新服務器降級到舊的版本,首次啟動舊版本的服務器之前應刪除第1行。

如果從服務器啟動時master.info文件不存在,選項采用選項文件或命令行中指定的值。首次將服務器作為從服務器啟動時,或者已經運行RESET SLAVE然后已經關閉并重啟從服務器時會發(fā)生。

如果從服務器啟動時master.info文件存在,服務器忽略那些選項。使用master.info文件中發(fā)現的值。

如果你使用與master.info文件中相對應的啟動選項的不同的值重啟從服務器,啟動選項的不同的值不會生效,因為服務器繼續(xù)使用master.info文件。要想使用啟動選項的不同的值,必須刪除master.info文件并重啟從服務器,或(最好是)在從服務器運行時使用CHANGE MASTER TO語句重新設置值。

假定在my.cnf文件中指定該選項:

[mysqld]
master-host=some_host

1次作為復制從服務器啟動服務器時,從my.cnf文件讀取并使用選項。服務器然后記錄master.info文件中的值。下次啟動服務器時,它只從服務器的master.info文件讀取主服務器主機值并忽略選項文件中的值。如果你修改my.cnf文件為some_other_host指定其它主服務器主機,更改仍然不會生效。你應使用CHANGE MASTER TO。

因為服務器給已有master.info文件的優(yōu)先權高于剛剛描述的啟動選項,可以選擇不使用這些值的啟動選項,而是使用CHANGE MASTER TO語句來指定。參見13.6.2.1節(jié),“CHANGE MASTER TO語法”。

下面的例子顯示了如何更廣泛地使用啟動選項來配置從服務器:

[mysqld]
server-id=2
master-host=db-master.mycompany.com
master-port=3306
master-user=pertinax
master-password=freitag
master-connect-retry=60
report-host=db-slave.mycompany.com

下面列出了控制復制的啟動選項:許多選項可以在服務器運行時通過CHANGE MASTER TO語句重新進行設置。其它選項,例如--replicate-*選項,只能在從服務器啟動時進行設置。我們計劃將修復該問題。

·???????? --logs-slave-updates

通常情況,從服務器從主服務器接收到的更新不記入它的二進制日志。該選項告訴從服務器將其SQL線程執(zhí)行的更新記入到從服務器自己的二進制日志。為了使該選項生效,還必須用--logs-bin選項啟動從服務器以啟用二進制日志。如果想要應用鏈式復制服務器,應使用--logs-slave-updates。例如,可能你想要這樣設置:

A -> B -> C

也就是說,A為從服務器B的主服務器,B為從服務器C的主服務器。為了能工作,B必須既為主服務器又為從服務器。你必須用--logs-bin啟動AB以啟用二進制日志,并且用--logs-slave-updates選項啟動B。

·???????? --logs-warnings

讓從服務器向錯誤日志輸出更詳細的關于其執(zhí)行操作的消息。例如,通知你網絡/連接失敗后已經成功重新連接,并通知你每個從服務器線程如何啟動。該選項默認啟用;要想禁用它,使用--skip-logs-warnings。放棄的連接不記入錯誤日志,除非該值大于1。

請注意該選項的效果不限于復制??梢詫Ψ掌鞯牟糠謩幼鳟a生警告。

·???????? --master-connect-retry=seconds

在主服務器宕機或連接丟失的情況下,從服務器線程重新嘗試連接主服務器之前睡眠的秒數。如果主服務器.info文件中的值可以讀取則優(yōu)先使用。如果未設置, 默認值為60。

·???????? --master-host=host

主復制服務器的主機名或IP地址。如果沒有給出該選項,從服務器線程不啟動。如果主服務器.info文件中的值可以讀取則優(yōu)先使用。

·???????? --master-info-file=file_name

從服務器用于記錄主服務器的相關信息使用的文件名。默認名為數據目錄中的mysql.info。

·???????? --master-password=password

連接主服務器時從服務器線程用于鑒定的賬戶的密碼。如果主服務器.info文件中的值可以讀取則優(yōu)先使用。如果未設置,假定 密碼為空。

·???????? --master-port=port_number

主服務器正幀聽的TCP/IP端口號。如果主服務器.info文件中的值可以讀取則優(yōu)先使用。如果未設置,假定使用編譯進來的設定值。如果你未曾用configure選項進行修改,該值應為3306

·???????? --master-ssl、--master-ssl-ca=file_name、--master-ssl-capath=directory_name--master-ssl-cert=file_name、--master-ssl-cipher=cipher_list--master-ssl-key=file_name

這些選項用于使用SSL設置與主服務器的安全復制連接。它們的含義與5.8.7.6節(jié),“SSL命令行選項”中描述的相應ssl、--ssl-ca、--ssl-capath、--ssl-cert、--ssl-cipher、--ssl-key選項相同。如果主服務器.info文件中的值可以讀取則優(yōu)先使用。

·???????? --master-user=username

連接主服務器時從服務器線程用于鑒定的賬戶的用戶名。該賬戶必須具有REPLICATION SLAVE權限。如果主服務器.info文件中的值可以讀取則優(yōu)先使用。如果未設置主服務器用戶,假定使用用戶test。

·???????? --max-relay-logs-size=size

自動循環(huán)中繼日志。參見5.3.3節(jié),“服務器系統(tǒng)變量”。

·???????? --read-only

該選項讓從服務器只允許來自從服務器線程或具有SUPER權限的用戶的更新??梢源_保從服務器不接受來自客戶的更新。

·???????? --relay-log=file_name

中繼日志名。默認名為host_name-relay-bin.nnnnnn,其中host_name是從服務器主機的名,nnnnnn表示中繼日志在編號序列中創(chuàng)建。如果中繼日志太大(并且你不想降低max_relay_log_size),需要將它們放到數據目錄之外的其它地方,或者如果想要通過硬盤之間的負載均衡提高速度,可以指定選項創(chuàng)建與主機名無關的中繼日志名。

·???????? --relay-log-index=file_name

中繼日志索引文件使用的位置和名稱。默認名為host_name-relay-bin.index,其中host_name為從服務器名。

·???????? --relay-log-info-file=file_name

從服務器用于記錄中繼日志相關信息的文件名。默認名為數據目錄中的relay-log.info。

·???????? --relay-log-purge={0|1}

禁用或啟用不再需要中繼日志時是否自動清空它們。默認值為1(啟用)。這是一個全局變量,可以用SET GLOBAL Relay_log_purge動態(tài)更改。

·???????? --relay-log-space-limit=size

限制所有中繼日志在從服務器上所占用空間的上限(0值表示“無限制)。從服務器主機硬盤空間有限時很有用。達到限制后,I/O線程停止從主服務器讀取二進制日志中的事件,直到SQL線程被閉鎖并且刪除了部分未使用的中繼日志。請注意該限制并不是絕對的:有可能SQL線程刪除中繼日志前需要更多的事件。在這種情況下,I/O線程將超過限制,直到SQL線程可以刪除部分中繼日志。(不這樣做將會造成死鎖)。--relay-log-space-limit的值不能小于--max-relay-logs-size(或如果--max-relay-logs-size0,選--max-binlog-size)的值的兩倍。在這種情況下,有可能I/O線程等待釋放空間,因為超過了--relay-log-space-limit,但SQL線程沒有要清空的中繼日志,不能滿足I/O線程的需求。強制I/O線程臨時忽視--relay-log-space-limit。

·???????? --replicate-do-db=db_name

告訴從服務器限制默認數據庫(USE所選擇)db_name的語句的復制。要指定多個數據庫,應多次使用該選項,每個數據庫使用一次。請注意不復制跨數據庫的語句,例如當已經選擇了其它數據庫或沒有數據庫時執(zhí)行UPDATE some_db.some_table SET foo='bar'。如果需要跨數據庫進行更新,使用--replicate-wild-do-table=db_name.%。請讀取該選項列表后面的注意事項。

一個不能按照期望工作的例子:如果用--replicate-do-db=sales啟動從服務器,并且在主服務器上執(zhí)行下面的語句,UPDATE語句不會復制:

USE prices;
UPDATE sales.january SET amount=amount+1000;

如果需要跨數據庫進行更新,應使用--replicate-wild-do-table=db_name.%

只檢查默認數據庫”行為的主要原因是語句自己很難知道它是否應被復制(例如,如果你正使用跨數據庫的多表DELETE語句或多表UPDATE語句)。如果不需要,只檢查默認數據庫比檢查所有數據庫要快得多。

·???????? --replicate-do-table=db_name.tbl_name

告訴從服務器線程限制對指定表的復制。要指定多個表,應多次使用該選項,每個表使用一次。同--replicate-do-db對比,允許跨數據庫更新。請讀取該選項列表后面的注意事項。

·???????? --replicate-ignore-db=db_name

告訴從服務器不要復制默認數據庫(USE所選擇)db_name的語句。要想忽略多個數據庫,應多次使用該選項,每個數據庫使用一次。如果正進行跨數據庫更新并且不想復制這些更新,不應使用該選項。請讀取該選項后面的注意事項。

一個不能按照期望工作的例如:如果用--replicate-ignore-db=sales啟動從服務器,并且在主服務器上執(zhí)行下面的語句,UPDATE語句不會復制:

·??????????????? USE prices;
·??????????????? UPDATE sales.january SET amount=amount+1000;

如果需要跨數據庫更新,應使用--replicate-wild-ignore-table=db_name.%。

·???????? --replicate-ignore-table=db_name.tbl_name

告訴從服務器線程不要復制更新指定表的任何語句(即使該語句可能更新其它的表)。要想忽略多個表,應多次使用該選項,每個表使用一次。同--replicate-ignore-db對比,該選項可以跨數據庫進行更新。請讀取該選項后面的注意事項。

·???????? --replicate-wild-do-table=db_name.tbl_name

告訴從服務器線程限制復制更新的表匹配指定的數據庫和表名模式的語句。模式可以包含‘%’和‘_’通配符,與LIKE模式匹配操作符具有相同的含義。要指定多個表,應多次使用該選項,每個表使用一次。該選項可以跨數據庫進行更新。請讀取該選項后面的注意事項。

例如:--replicate-wild-do-table=foo%.bar%只復制數據庫名以foo開始和表名以bar開始的表的更新。

如果表名模式為%,可匹配任何表名,選項也適合數據庫級語句(CREATE DATABASE、DROP DATABASEALTER DATABASE)。例如,如果使用--replicate-wild-do-table=foo%.%,如果數據庫名匹配模式foo%,則復制數據庫級語句。

要想在數據庫或表名模式中包括通配符,用反斜線對它們進行轉義。例如,要復制名為my_own%db的數據庫的所有表,但不復制my1ownAABCdb數據庫的表,應這樣轉義‘_’和‘%’字符:--replicate-wild-do-table=my\_own\%db。如果在命令行中使用選項,可能需要雙反斜線或將選項值引起來,取決于命令解釋符。例如,用bash外殼則需要輸入--replicate-wild-do-table=my\\_own\\%db。

·???????? --replicate-wild-ignore-table=db_name.tbl_name

告訴從服務器線程不要復制表匹配給出的通配符模式的語句。要想忽略多個表,應多次使用該選項,每個表使用一次。該選項可以跨數據庫進行更新。請讀取該選項后面的注意事項。

例如:--replicate-wild-ignore-table=foo%.bar%不復制數據庫名以foo開始和表名以bar開始的表的更新。

關于匹配如何工作的信息,參見--replicate-wild-do-table選項的描述。在選項值中包括通配符的規(guī)則與--replicate-wild-ignore-table相同。

·???????? --replicate-rewrite-db=from_name->to_name

告訴從服務器如果默認數據庫(USE所選擇)為主服務器上的from_name,則翻譯為to_name。只影響含有表的語句(不是類似CREATE DATABASEDROP DATABASEALTER DATABASE的語句),并且只有from_name為主服務器上的默認數據庫時。該選項不可以跨數據庫進行更新。請注意在測試--replicate-*規(guī)則之前翻譯數據庫名。

如果在命令行中使用該選項, ‘>’字符專用于命令解釋符,應將選項值引起來。例如:

shell> mysqld --replicate-rewrite-db="olddb->newdb"

·???????? --replicate-same-server-id

將用于從服務器上。通??梢阅J設置為0以防止循環(huán)復制中的無限循環(huán)。如果設置為1,該從服務器不跳過有自己的服務器id的事件;通常只在有很少配置的情況下有用。如果使用--logs-slave-updates不能設置為1。請注意默認情況下如果有從服務器的id,服務器I/O線程不將二進制日志事件寫入中繼日志(該優(yōu)化可以幫助節(jié)省硬盤的使用)。因此如果想要使用--replicate-same-server-id,讓從服務器讀取自己的SQL線程執(zhí)行的事件前,一定要用該選項啟動。

·???????? --report-host=slave_name

從服務器注冊過程中報告給主服務器的主機名或IP地址。該值出現在主服務器上SHOW SLAVE HOSTS的輸出中。如果不想讓從服務器自己在主服務器上注冊,則不設置該值。請注意從服務器連接后,主服務器僅僅從TCP/IP套接字讀取從服務器的IP號是不夠的。由于 NAT和其它路由問題,IP可能不合法,不能從主服務器或其它主機連接從服務器。

·???????? --report-port=slave_port

連接從服務器的TCP/IP端口號,從服務器注冊過程中報告給主服務器。只有從服務器幀聽非默認端口或如果有一個特殊隧道供主服務器或其它客戶連接從服務器時才設置它。如果你不確定,不設置該選項。

·???????? --skip-slave-start

告訴從服務器當服務器啟動時不啟動從服務器線程。使用START SLAVE語句在以后啟動線程。

·???????? --slave_compressed_protocol={0|1}

如果該選項設置為 1,如果從服務器和主服務器均支持,使用壓縮從服務器/主服務器協(xié)議。

·???????? --slave-load-tmpdir=file_name

從服務器創(chuàng)建臨時文件的目錄名。該選項默認等于tmpdir系統(tǒng)變量的值。當從服務器SQL線程復制LOAD DATA INFILE語句時,從中繼日志將待裝載的文件提取到臨時文件,然后將這些文件裝入到表中。如果裝載到主服務器上的文件很大,從服務器上的臨時文件也很大。因此,建議使用該選項告訴從服務器將臨時文件放到文件系統(tǒng)中有大量可用空間的目錄下。在這種情況下,也可以使用--relay-log選項將中繼日志放到該文件系統(tǒng)中,因為中繼日志也很大。--slave-load-tmpdir應指向基于硬盤的文件系統(tǒng),而非基于內存的文件系統(tǒng):從服務器需要用臨時文件在機器重啟時用于復制LOAD DATA INFILE。系統(tǒng)啟動過程中操作系統(tǒng)也不能清除該目錄。

·???????? --slave-net-timeout=seconds

放棄讀之前從主服務器等候更多數據的秒數,考慮到連接中斷和嘗試重新連接。超時后立即開始第1次重試。由--master-connect-retry選項控制重試之間的間隔。

·???????? --slave-skip-errors=[err_code1,err_code2,... | all]

通常情況,當出現錯誤時復制停止,這樣給你一個機會手動解決數據中的不一致性問題。該選項告訴從服務器SQL線程當語句返回任何選項值中所列的錯誤時繼續(xù)復制。

如果你不能完全理解為什么發(fā)生錯誤,則不要使用該選項。如果復制設置和客戶程序中沒有bug,并且MySQL自身也沒有bug,應不會發(fā)生停止復制的錯誤。濫用該選項會使從服務器與主服務器不能保存同步,并且你找不到原因。

對于錯誤代碼,你應使用從服務器錯誤日志中錯誤消息提供的編號和SHOW SLAVE STATUS的輸出。服務器錯誤代碼列于附錄B:錯誤代碼和消息。

你也可以(但不應)使用不推薦的all值忽略所有錯誤消息,不考慮所發(fā)生的錯誤。無需而言,如果使用該值,我們不能保證數據的完整性。在這種情況下,如果從服務器的數據與主服務器上的不相近請不要抱怨(或編寫bug報告)已經警告你了。

例如:

--slave-skip-errors=1062,1053
--slave-skip-errors=all

從服務器按下面評估--replicate-*規(guī)則,確定是否執(zhí)行或忽視語句:

1.??? 是否有--replicate-do-db--replicate-ignore-db規(guī)則?

·???????? :測試--binlog-do-db--binlog-ignore-db(參見5.11.3節(jié),“二進制日志”)。測試結果是什么?

o??????? 忽視語句:忽視并退出。

o??????? 許可語句:不立即執(zhí)行語句。推遲決策;繼續(xù)下一步。

·???????? 沒有:繼續(xù)下一步。

2.??? 我們目前正執(zhí)行保存的程序或函數嗎?

·???????? :執(zhí)行查詢并退出。

·???????? :繼續(xù)下一步。

3.??? 是否有--replicate-*-table規(guī)則?

·???????? 沒有:執(zhí)行查詢并退出。

·???????? :繼續(xù)下一步并開始按所示順序評估表規(guī)則(首先是非通配規(guī)則,然后是通配規(guī)則)。只有待更新的表根據這些規(guī)則進行比較(INSERT INTO sales SELECT * FROM prices:只有sales根據這些規(guī)則進行比較)。如果要更新幾個表(多表語句),第1個匹配的表(匹配“do”或“ignore)獲贏。也就是說,根據這些規(guī)則比較第1個表。然后,如果不能進行決策,根據這些規(guī)則比較第2個表等等。

4.??? 是否有--replicate-do-table規(guī)則?

·???????? :表匹配嗎?

o??????? :執(zhí)行查詢并退出。

o??????? :繼續(xù)下一步。

·???????? 沒有:繼續(xù)下一步。

5.??? 是否有--replicate-ignore-table規(guī)則?

·???????? :表匹配嗎?

o??????? :忽視查詢并退出。

o??????? :繼續(xù)下一步。

·???????? 沒有:繼續(xù)下一步。

6.??? 是否有--replicate-wild-do-table規(guī)則?

·???????? :表匹配嗎?

o??????? :執(zhí)行查詢并退出。

o??????? :繼續(xù)下一步。

·???????? 沒有:繼續(xù)下一步。

7.??? 是否有--replicate-wild-ignore-table規(guī)則?

·???????? :表匹配嗎?

o??????? :忽視查詢并退出。

o??????? :繼續(xù)下一步。

·???????? 沒有:繼續(xù)下一步。

8.??? 沒有匹配的--replicate-*-table規(guī)則。要根據這些規(guī)則測試其它表嗎?

·???????? :執(zhí)行循環(huán)。

·???????? :我們現在已經測試了所有待更新的表,結果不能匹配任何規(guī)則。是否有--replicate-do-table--replicate-wild-do-table規(guī)則?

o??????? :有“do”規(guī)則但不匹配。忽視查詢并退出。

o??????? 沒有:執(zhí)行查詢并退出。

6.9.?復制FAQ

Q:如果主服務器正在運行并且不想停止主服務器,怎樣配置一個從服務器?

A:有多種方法。如果你在某時間點做過主服務器備份并且記錄了相應快照的二進制日志名和偏移量(通過SHOW MASTER STATUS命令的輸出),采用下面的步驟:

1.??? 確保從服務器分配了一個唯一的服務器ID號。

2.??? 在從服務器上執(zhí)行下面的語句,為每個選項填入適當的值:

??????????? mysql> CHANGE MASTER TO

??????????? ????->???? MASTER_HOST='master_host_name',
??????????? ????->???? MASTER_USER='master_user_name',
??????????? ????->???? MASTER_PASSWORD='master_pass',
??????????? ????->???? MASTER_LOG_FILE='recorded_log_file_name',
????????? ????->???? MASTER_LOG_POS=recorded_log_position;

3.??? 在從服務器上執(zhí)行START SLAVE語句。

如果你沒有備份主服務器,這里是一個創(chuàng)建備份的快速程序。所有步驟都應該在主服務器主機上執(zhí)行。

1.??? 發(fā)出該語句:

???? mysql> FLUSH TABLES WITH READ LOCK;

2.??? 仍然加鎖時,執(zhí)行該命令(或它的變體):

???? shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql

3.??? 發(fā)出該語句并且確保記錄了以后用到的輸出:

???? mysql>SHOW MASTER STATUS

4.??? 釋放鎖:

???? mysql> UNLOCK TABLES;

一個可選擇的方法是,轉儲主服務器的SQL來代替前面步驟中的二進制復制。要這樣做,你可以在主服務器上使用mysqldump --master-data以后裝載SQL轉儲到到你的從服務器。然而,這比進行二進制復制速度慢。

不管你使用這兩種方法中的那一個,當你有一個快照和記錄了日志名與偏移量時,后來根據說明操作。你可以使用相同的快照建立多個從服務器。一旦你擁有主服務器的一個快照,可以等待創(chuàng)建一個從服務器,只要主服務器的二進制日志完整。兩個能夠等待的時間實際的限制是指在主服務器上保存二進制日志的可用硬盤空間和從服務器同步所用的時間。

你也可以使用LOAD DATA FROM MASTER。這是一個方便的語句,它傳輸一個快照到從服務器并且立即調整日志名和偏移量。將來,LOAD DATA FROM MASTER將成為創(chuàng)建從服務器的推薦方法。然而需要注意,它只工作在MyISAM 表上并且可能長時間持有讀鎖定。它并不象我們希望的那樣高效率地執(zhí)行。如果你有大表,執(zhí)行FLUSH TABLES WITH READ LOCK語句后,這時首選方法仍然是在主服務器上制作二進制快照。

Q:從服務器需要始終連接到主服務器嗎?

A:不,不需要。從服務器可以宕機或斷開連接幾個小時甚至幾天,重新連接后獲得更新信息。例如,你可以在通過撥號的鏈接上設置主服務器/從服務器關系,其中只是偶爾短時間內進行連接。這意味著,在任何給定時間,從服務器不能保證與主服務器同步除非你執(zhí)行某些特殊的方法。將來,我們將使用選項來阻塞主服務器直到有一個從服務器同步。

Q:我怎樣知道從服務器與主服務器的最新比較? 換句話說,我怎樣知道從服務器復制的最后一個查詢的日期?

A:你可以查看SHOW SLAVE STATUS語句的Seconds_Behind_Master列的結果。參見6.3節(jié),“復制實施細節(jié)”。

當從服務器SQL線程執(zhí)行從主服務器讀取的事件時,它根據事件時間戳修改自己的時間(這是TIMESTAMP能夠很好復制的原因)。在SHOW PROCESSLIST語句輸出的Time列內,為從服務器SQL線程顯示的秒數是最后一個復制事件的時間戳和從服務器主機的實際時間之間相差的秒數。你可以使用它來確定最后一個復制事件的日期。注意,如果你的從服務器與主服務器連接斷開一個小時,然后重新連接,在SHOW PROCESSLIST結果中,你可以立即看到從服務器SQL線程的Time值為3600。這可能是因為從服務器執(zhí)行的語句是一個一小時之前的。

Q:我怎樣強制主服務器阻塞更新直到從服務器同步?

A:使用下面的步驟:

1.??? 在主服務器上,執(zhí)行這些語句:

???? mysql> FLUSH TABLES WITH READ LOCK;

???? mysql> SHOW MASTER STATUS;

?

記錄SHOW語句的輸出的日志名和偏移量。這些是復制坐標。

2.??? 在從服務器上,發(fā)出下面的語句,其中Master_POS_WAIT()函數的參量是前面步驟中的得到的復制坐標值:

???? mysql> SELECT MASTER_POS_WAIT('log_name', log_offset);

SELECT語句阻塞直到從服務器達到指定的日志文件和偏移量。此時,從服務器與主服務器同步,語句返回。

3.??? 在主服務器上,發(fā)出下面的語句允許主服務器重新開始處理更新:

???? mysql> UNLOCK TABLES;

Q:當設置雙向復制時我應該知道發(fā)出那些語句?

AMySQL復制目前不支持主服務器和從服務器之間的任何鎖定協(xié)議來保證分布式(跨服務器)更新的原子性。換句話說,這樣做是可能的:客戶A根據協(xié)作-主服務器1更新,同時,在它傳給協(xié)作-主服務器2之前,客戶B能夠根據協(xié)作-主服務器2更新,這樣客戶A的更新與它在協(xié)作-主服務器1的更新不同。這樣,當客戶A根據協(xié)作-主服務器2更新時,它產生的表與在協(xié)作-主服務器1上的不同,即使所有根據協(xié)作-主服務器2的更新已經傳過來。這意味著,在雙向復制關系中,你不應該把兩個服務器串連在一起,除非你確信任何順序的更新是安全的,或者除非你在客戶端代碼中注意怎樣避免更新順序錯誤。

你還必須認識到從更新角度,雙向復制實際上并不能顯著地提高性能(或者根本不能提高性能)。兩個服務器都需要做相同數量的更新,如同在一個服務器做的那樣。唯一的差別是鎖競爭要少,這因為源于另一個服務器的更新在一個從線程中序列化。即使這個益處可能被網絡延遲抵消。

Q:怎樣通過復制來提高系統(tǒng)的性能?

A:你應將一個服務器設置為主服務器并且將所有寫指向該服務器。然后根據預算配置盡可能多的從服務器以及??臻g,并且在主服務器和從服務器之間分發(fā)讀取操作。你也可以用--skip-innodb--skip-bdb、--low-priority-updates以及--delay-key-write=ALL選項啟動從服務器,以便在從服務器端提高速度。在這種情況下,為了提高速度,從服務器使用非事務MyISAM表來代替InnoDBBDB表。

Q:為了使用高性能的復制,我應該在自己的應用程序中怎樣準備客戶端代碼?

A:如果你的代碼中數據庫訪問部分已經正確地模塊化,應該能夠平滑和容易地轉換為在復制步驟中運行的代碼。僅需要更改數據庫訪問執(zhí)行部分,以便發(fā)送所有的寫操作到主服務器,以及發(fā)送讀操作到主服務器或某個從服務器。如果你的代碼沒有這個級別,設置一個復制系統(tǒng)以便清除。應先通過下面的函數創(chuàng)建一個包裝庫或模塊:

·???????? safe_writer_connect()

·???????? safe_reader_connect()

·???????? safe_reader_statement()

·???????? safe_writer_statement()

每個函數名的safe_意味著函數比較小心地處理所有錯誤。你可以使用不同名的函數。重要是對于讀連接、寫連接、讀和寫有一個統(tǒng)一的接口。

然后,你應該轉換客戶端代碼使用包裝庫。剛開始這可能是痛苦和恐慌的過程,但從長遠來看是值得的。使用剛才討論的方法的所有應用程序都能夠利用主服務器/從服務器配置的優(yōu)越性,即使是含有多個從服務器的配置。代碼非常容易維護,并且添加排錯選項也很容易。你僅需要修改一兩個函數;例如,記錄每個語句執(zhí)行的時間,或者你的上千個語句中哪個語句發(fā)生了錯誤。

如果你已經編寫了許多代碼,你可能想使用replace工具自動進行轉換,該工具隨標準MySQL一起發(fā)布,或可以自己編寫轉換腳本。理想情況,你的代碼使用一致的程序轉換風格。否則,可能最好重新編寫代碼,或者至少手工對其進行規(guī)則化以使用一致的風格。

QMySQL復制能夠何時和多大程度提高系統(tǒng)性能?

AMySQL復制對于頻繁讀和頻繁寫的系統(tǒng)具有最大好處。理論上,通過使用單個主服務器/多從服務器設置,可以通過添加更多的從服務器來擴充系統(tǒng),直到用完網絡帶寬,或者你的更新負載已經增長到主服務器不能處理的點。

在獲得的收益開始吃平之前,為了確定可以有多少從服務器,以及可以將你的站點的性能提高多少,需要知道查詢模式,并且要通過基準測試并根據經驗確定一個典型的主服務器和從服務器中的讀?。棵腌娮x取量,或者max_reads)吞吐量和寫(max_writes)吞吐量的關系。通過一個假設的帶有復制的系統(tǒng),本例給出了一個非常簡單的計算結果。

假設系統(tǒng)負載包括10%的寫和90%的讀取,并且我們通過基準測試確定max_reads1200 2 × max_writes。換句話說,如果沒有寫操作,系統(tǒng)每秒可以進行1,200次讀取操作,平均寫操作是平均讀操作所用時間的兩倍,并且關系是線性的。我們假定主服務器和每個從服務器具有相同的性能,并且我們有一個主服務器和N個從服務器。那么,對于每個服務器(主服務器或從服務器),我們有:

reads = 1200 2 × writes

reads = 9 × writes / (N + 1) (讀取是分離的, 但是寫入所有服務器)

9 × writes / (N + 1) + 2 × writes = 1200

writes = 1200 / (2 + 9/(N+1))

最后的等式表明了N個從服務器的最大寫操作數,假設最大可能的讀取速率是每分鐘1,200次,讀操作與寫操作的比率是9。

如上分析可以得到下面的結論:

·???????? 如果N = 0(這表明沒有復制),系統(tǒng)每秒可以處理大約1200/11 = 109個寫操作。

·???????? 如果N = 1,每秒得到184個寫操作。

·???????? 如果N = 8,每秒得到400個寫操作。

·???????? 如果N = 17,每秒得到480個寫操作。

·???????? 最后,當 N 趨于無窮大(以及我們預算的負無窮大)時,可以得到非常接近每秒600個寫操作,系統(tǒng)吞吐量增加將近5.5倍。然而,如果只用8個服務器,增加接近4倍。

請注意,這些計算假設網絡帶寬無窮大并忽略掉了其它一些因素,那些因素可能對系統(tǒng)產生重要的影響。在許多情況下,不能執(zhí)行與剛才類似的計算,即如果添加N臺復制從服務器,應該準確預報系統(tǒng)將發(fā)生哪些影響?;卮鹣旅娴膯栴}應能夠幫助你確定復制是否和在多大程度上能夠提高系統(tǒng)的性能:

·???????? 系統(tǒng)上的讀取/寫比例是什么?

·???????? 如果減少讀取操作,一個服務器可以多處理多少寫負載?

·???????? 網絡帶寬可滿足多少從服務器的需求?

Q:如何使用復制來提供冗余/高可用性?

A:利用目前的可用特性,必須設置一個主服務器和一個從服務器(或多個從服務器),以及寫一個腳本來監(jiān)視主服務器是否啟動。如果主服務器失敗,通知應用程序和從服務器切換主服務器。下面是一些建議:

·???????? 告知從服務器更改其主服務器,使用CHANGE MASTER TO語句。

·???????? 通知應用程序主服務器位置的一個很好的方法是對主服務器提供動態(tài)DNS入口。用bind可以使用nsupdate動態(tài)更新DNS。

·???????? 應該用--logs-bin選項而不用 --logs-slave-updates選項運行從服務器。這樣,一旦你在其它從服務器上發(fā)出STOP SLAVE; RESET MASTER, 以及CHANGE MASTER TO語句,該從服務器可以切換為主服務器。例如,假設有下面的設置:

·??????????????? ???????WC
·??????????????? ????????\
·??????????????? ?????????v
·??????????????? ?WC----> M
·??????????????? ???????/ | \
·??????????????? ??????/? |? \
·??????????????? ?????v?? v?? v
·??????????????? ????S1?? S2? S3

M代表主服務器,S代表從服務器,WC代表發(fā)出數據庫寫和讀取操作的客戶;只發(fā)出數據庫讀取操作的客戶沒有給出,因為它們不需要切換。S1S2以及S3是從服務器,用--logs-bin選項而沒有用--logs-slave-updates運行。因為從服務器收到的主服務器的更新沒有記錄在二進制日志中,除非指定 --logs-slave-updates選項,每個從服務器上的二進制日志是空的。如果因為某些原因M 變得不可用,你可以選取一個從服務器變?yōu)樾碌闹鞣掌鳌@?,如果你選取了S1,所有WC應該重新指向S1S2,并且S3然后應從S1復制

確保所有從服務器已經處理了中繼日志中的所有語句。在每個從服務器上,發(fā)出STOP SLAVE IO_THREAD語句,然后檢查SHOW PROCESSLIST語句的輸出,直到你看到Has read all relay log。當所有從服務器都執(zhí)行完這些,它們可以被重新配置為一個新的設置。在被提升為主服務器的從服務器S1上,發(fā)出STOP SLAVERESET MASTER語句。

在其它從服務器S2S3,使用STOP SLAVECHANGE MASTER TO MASTER_HOST='S1'(其中'S1'表示S1實際的主機名)。為CHANGE MASTER添加關于從S2S3如何連接到S1所有信息(userpassword、port)。在CHANGE MASTER命令中,不需要指定從其讀取的S1的二進制日志名或二進制日志位置:我們知道它是第1個二進制日志,位置是4,這是CHANGE MASTER命令的默認值。最后,在S2S3使用START SLAVE 命令。

然后,指示所有WC 把它們的語句指向S1此后,WC發(fā)出的所有發(fā)送到S1更新語句被寫入S1二進制日志,S1則包含M死掉之后的發(fā)送到 S1的每一個更新語句。

結果是下面的配置:

?????? WC
????? /
????? |
 WC?? |? M(unavailable)
? \?? |
?? \? |
??? v v
???? S1<--S2? S3
????? ^?????? |
????? +-------+

M重新啟動后,你必須在M發(fā)出相同的CHANGE MASTER語句,與在S2S3上發(fā)出的語句一樣,以便M變?yōu)?strong>S1從服務器并且恢復在它宕機后丟失的所有WC寫操作。要把 M 再次作為主服務器(例如,因為它是功能最強的機器),使用前面的步驟,好像S1不可用并且M變?yōu)橐粋€新的主服務器一樣。在這個過程中,在S1、S2以及S3作為M從服務器之前,不要忘記在M運行RESET MASTER。否則,它們可能拾取M變得不可用之前的舊WC寫操作。

我們目前正在MySQL集成自動主服務器選擇系統(tǒng),但在準備好之前,你必須創(chuàng)建自己的監(jiān)控工具。

6.10.?復制故障診斷與排除

如果你遵從了上述說明,復制設置仍然不工作,首先檢查下面各項:

·???????? 檢查錯誤日志的消息。許多用戶遇到問題后沒有及時地這樣做而浪費了時間。

·???????? 主服務器記錄到了二進制日志?用SHOW MASTER STATUS檢查。如果已經記錄,Position應為非零。如果沒有記錄,確認正用log-binserver-id選項運行主服務器。

·???????? 是否從服務器在運行?使用SHOWSHOW SLAVE STATUS檢查是否slave_IO_Runningslave_SQL_Running的值均為Yes。如果不是,驗證當啟動從服務器時使用的選項。

·???????? 如果從服務器正在運行,建立了與主服務器的連接嗎?使用SHOW PROCESSLIST,找出I/OSQL線程并檢查它們的State列看它們如何顯示。參見6.3節(jié),“復制實施細節(jié)”。如果I/O線程狀態(tài)為Connecting to master,驗證主服務器上復制用戶的權限、主服務器主機名、DNS設置,是否主服務器真正在運行,以及是否可以從從屬服務器訪問。

·???????? 如果從服務器以前在運行但是現在已經停止,原因通常是在主服務器上成功的部分語句在從服務器上失敗了。如果你正確快照了主服務器,并且從來沒有不通過服務器線程修改從服務器上的數據,這種現象不應發(fā)生。如果發(fā)生,應為一個bug或你遇到了一個6.7節(jié),“復制特性和已知問題” 描述的已知的復制限制。如果是一個bug,參見6.11節(jié),“通報復制缺陷”查閱如何通報的說明。

·???????? 如果某個在主服務器上成功的語句拒絕在從服務器上運行,并且不能執(zhí)行完全的數據庫重新同步(即刪除從服務器的數據庫并從主服務器復制新的快照),嘗試:

1.??? 確定是否從服務器的表與主服務器的不同。盡力了解發(fā)生的原因。然后讓從服務器的表與主服務器的一樣并運行START SLAVE。

2.??? 如果前面的步驟不工作或不適合,盡力了解手動更新是否安全(如果需要),然后忽視來自主服務器的下一個語句。

3.??? 如果你確定可以跳過來自主服務器的下一個語句,執(zhí)行下面的語句:

4.????????????????? mysql> SET GLOBAL SQL_slave_SKIP_COUNTER = n;
5.????????????????? mysql> START SLAVE;

如果來自主服務器的下一個語句不使用AUTO_INCREMENTLAST_INSERT_ID(),n 值應為1。否則,值應為2。使用AUTO_INCREMENTLAST_INSERT_ID()的語句使用值2的原因是它們從主服務器的二進制日志中取兩個事件。

6.??? 如果你確保從服務器啟動時完好地與主服務器同步,并且沒有更新從服務器線程之外的表,則大概詫異是由于bug。如果你正運行最近的版本,請通報該問題。如果你正運行舊版本MySQL,盡力升級到最新的產品版本。

6.11.?通報復制缺陷

如果你確定沒有用戶錯誤,但復制仍然不工作或不穩(wěn)定,則是向我們發(fā)送bug通報的時候了。我們需要盡可能從你那兒獲得更多的信息已跟蹤bug。請花一些時間和努力編寫一份好的bug通報。

如果你有一個重復的測試案例來說明bug,請把它輸入我們的bug數據庫,位置為http://bugs.mysql.com/。如果你有一個“phantom”問題(不能按照期望進行復制),則使用下面的程序:

1.??? 確認未包括用戶錯誤。例如,如果你不用從服務器線程來更新從服務器,數據將不同步,并且會遇到唯一的鍵值違背更新。在這種情況下,從服務器線程停止并等待你手動清理表使它們同步。這不是復制問題。這是一個外部接口問題造成復制失敗。

2.??? --logs-slave-updates--logs-bin選項運行從服務器。這些選項使從服務器將從主服務器接收的更新記入自己的二進制日志。

3.??? 重新設置復制狀態(tài)之前保存所有的證據。如果我們沒有信息或只有粗略的信息,則難以或不可能跟蹤問題。應搜集的證據為:

·???????? 所有主服務器的二進制日志

·???????? 所有從服務器的二進制日志

·???????? 你發(fā)現問題時主服務器的SHOW MASTER STATUS的輸出

·???????? 你發(fā)現問題時主服務器的SHOW SLAVE STATUS的輸出

·???????? 主服務器和從服務器的錯誤日志

4.??? 使用mysqlbinlog檢查二進制日志。下面命令應有助于發(fā)現有問題的查詢,例如:

5.??????????? shell> mysqlbinlog -j pos_from_slave_status \
6.??????????? ???????????/path/to/log_from_slave_status | head

搜集了問題的證據后,首先作為一個測試案例隔離開。然后將問題輸入我們的bug數據庫,位置為http://bugs.mysql.com/,應提供盡可能多的信息。

6.12.?多服務器復制中的Auto-Increment

當將多個服務器配置為復制主服務器時,使用auto_increment時應采取特殊步驟以防止鍵值沖突,否則插入行時多個主服務器會試圖使用相同的auto_increment值。

服務器變量auto_increment_incrementauto_increment_offset可以幫助協(xié)調多主服務器復制和AUTO_INCREMENT列。每個變量有一個默認的(并且是最小的)1,最大值為65,535。

將這些變量設置為非沖突的值,當在同一個表主插入新行時,多主服務器配置主的服務器將不會與AUTO_INCREMENT值沖突。

這兩個變量這樣影響AUTO_INCREMENT列:

·???????? auto_increment_increment控制列值增加的間隔。例如:

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

(這里注明如何使用SHOW VARIABLES以獲得這些變量的當前值)。

·???????? auto_increment_offset確定AUTO_INCREMENT列值的起點。影響到在復制設置主可以有多少主服務器(例如將該值設置為10表示設置可以支持10個服務器)。

考慮下面的命令,假定在前面所示示例中的相同的會話中執(zhí)行這些命令:

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

詳細信息參見5.3.3節(jié),“服務器系統(tǒng)變量”。


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

Vorheriger Artikel: N?chster Artikel: