RDBMS:關係型數據庫管理系統
C/S:通過專有協議
關係模型:表(行,列),二維關係;
範式:第一範式、第二範式、第三範式(在之前的博客中已經做過說明)
關係運算:
選擇 投影
數據庫:表,索引,視圖(虛表)
SQL:Structure Query Language
DDL,DML
編程接口:
存儲過程
存儲函數
觸發器
事件調度器
過程式編程:選擇、循壞
三層模型:
物理層 邏輯層 視圖層
解決方案:
Oracle, Sybase, Infomix, DB2
MySQL, MariaDB, PostgreSQL, SQLite
MariaDB
插件式存儲引擎
單進程多線程
連接線程
守護線程
配置文件:集中式的配置,能夠爲mysql的各應用程序提供配置信息
[mysqld]
[mysqld_safe]
[mysqld_multi]
[server]
[mysql]
[mysqldump]
[client]
啓動查找路徑:/etc/my.cnf à /etc/mysql/my.cnf à $MYSQL_HOME/my.cnf à --default-extra-file=/path/to/somedir/my.cnf à ~/.my.cnf
安裝方法:
os vendor:rpm
MYSQL:
rpm
展開可用
源碼
安裝後的設定:
1) 爲所有root用戶設定密碼;
mysql>SET PASSWORD FOR
mysql> update mysql.user SET password=PASSWORD(‘your_pass’) WHERE clause;
#mysqladmin
2) 刪除所有匿名用戶
Mysql>DROP USER ‘’@’localhost’;
上述兩步驟可運行命令:mysql_secure_installation
3) 建議關閉主機名反解功能;
skip_name_resolve = ON
mysql --> mysqld
客戶端程序:
mysql:交互式的CLI工具;
mysqldump:備份工具,基於mysql協議向mysqld發起查詢請求,並將查得的所有數據轉換成insert等寫操作語句保存文本文件中;
mysqladmin:基於mysql協議管理mysqld;
mysqlimport:數據導入工具;
非客戶端類的管理工具:
myisamchk,myisampack
如何獲取程序默認使用的配置;
mysql --print-defaults
mysqld --print-defaults
客戶端類應用程序的可用選項:
-u, --user=
-h, --host=
-p, --passowrd=
-P, --port=
--protocol=
-S, --socket=
-D, --database=
-C, --compress
mysql -e "SQL"
mysql的使用模式:
交互模式:
可運行命令有兩類:
客戶端命令:
\h,help
服務器端命令:
SQL,需要語句結束符(冒號;)
腳本模式:
# mysql -uUSERNAME -hHOST -pPASSWORD < /path/from/somefile.sql
mysql> source /path/from/somefile.sql
服務器端(msyqld):工作特性有多種定義方式
命令行選項
配置文件參數
獲取可用參數列表:
mysqld --help –verbose
獲取運行中的mysql進程使用各服務器參數及其值;
mysql> SHOW GLOBAL VARIABLES;
mysql> SHOW [SESSION] VARIABLES;
注意:其中有些參數支持運行時修改,會立即生效;有些參數不支持,且只能通過修改配置文件,並重啓服務器程序生效;
有些參數的作用域是全局的,且不可改變;有些可以爲每一個用戶提供單獨的配置;
修改服務器變量的值:
mysql> help SET
全局:
mysql> SET GLOBAL system_var_name=value;
mysql> SET @@global.system_var_name=value;
會話:
mysql> SET [SESSION] system_var_name=value;
mysql> SET @@[session.]system_var_name=value;
狀態變量:用於保存mysqld運行中的統計數據的變量;
mysql> SHOW GLOBAL STATUS;
mysql> SHOW [SESSION] STATUS;
SQL:ANSI SQL
SQL-86, SQL-89, SQL-92, SQL-99, SQL-03
MYSQL數據類型:
字符型
數值型
日期時間型
內建類型
字符型:
CHAR, BINARY:定長數據類型;
VARCHAR, VARBINARY:變長數據類型;需要結束符;
TEXT:TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT
BLOB: TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB
ENUM, SET
字符型修飾符:
NOT NULL:非空約束;
NULL:
DEFAULT ‘STRING’:指明默認值;
CHARACTER SET ‘’:使用的字符集;
COLLATION:使用的排序規則;
mysql > SHOW CHARACTER SET;
msyql> SHOW COLLATION;
數值型:
精確數值型:
整型:TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT
十進制型:DECIMAL
近似數值型
浮點型:
FLOAT
DOUBLE
BIT
整型數據修飾符:
NOT NULL
NULL
DEFAULT NUMBER
AUTO_INCREMENT:
UNSIGNED
PRIMARY KEY|UNIQUE KEY
NOT NULL
mysql> SELECT LAST_INSERT_ID();
日期時間型:
DATE
TIME
DATETIME
TIMESTAMP
YEAR(2), YEAR(4)
日期時間型修飾符:
NOT NULL
NULL
DEFAULT
內建類型SET和ENUM的修飾符:
NOT NULL
NULL
DEFAULT
SQL MODE:定義mysqld對約束等的響應行爲;
修改方式:
mysql> SET GLOBAL sql_mode='MODE';
mysql> SET @@global.sql_mode='MODE';
需要修改權限:僅對修改後新創建的會話有效;對已經建立的會話無效;
mysql> SET SESSION sql_mode='MODE';
mysql> SET @@session.sql_mode='MODE';
常用MODE:TRADITIONAL, STRICT_TRANS_TABLES, or STRICT_ALL_TABLES
DDL:數據定義語言;
CREATE,ALTER,DROP
DB組件:數據庫、表、索引、視圖、用戶、存儲過程、存儲函數、觸發器、事件調度器等;
CREATE相關的常用命令:
CREATE DATABASE
CREATE EVENT
CREATE FUNCTION
CREATE FUNCTION UDF
CREATE INDEX
CREATE PROCEDURE
CREATE SERVER
CREATE TABLE
CREATE TABLESPACE
CREATE TRIGGER
CREATE USER
CREATE VIEW
DML:數據操作語言;
INSERT,DELETE,UPDATE,SELECT
數據庫:
CREATE,ALTER,DROP
{DATABASE|SCHEMA}
[IF EXISTS]
[IF NOT EXISTS]
表:二維關係
設計表:遵循規範;
定義:字段,索引
字段:字段名,字段數據類型,修改符
約束,索引:應該創建在經常用作查詢條件的字段上;
索引:實現級別在存儲引擎;
分類:
稠密索引、稀疏索引;
B+索引、hash索引、R樹索引、FULLTEXT索引
聚集索引、非聚集索引
簡單索引、組合索引
創建表:CREATE TABLE
1) 直接創建;
2) 通過查詢現存的表創建;新表會被直接插入查詢而來的數據;
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(create_definition,...)]
[table_options]
[partition_options]
select_statement
3) 通過複製現存的表的表結構創建;不復制數據;
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name { LIKE old_tbl_name | (LIKE old_tbl_name) }
注意:Storage Engine是指表類型,也即在表創建時指明其使用的存儲引擎;同一個庫中表要使用同一種存儲引擎類型;
查看錶結構:
DESCRIBE tb1_name;
查看錶狀態信息:
SHOW [FULL] TABLES [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr]
修改表:ALTER TABLE
刪除表:DROP TABLE
MYSQL數據文件類型:
數據文件、索引文件
重做日誌、撤銷日誌、二進制日誌、錯誤日誌、查詢日誌、慢查詢日誌、中繼日誌;
DDL&&DML:
索引管理:
按特定數據結構存儲的數據;
索引類型:
聚集索引、非聚集索引:數據是否與索引存儲在一起;
主鍵索引、輔助索引
稠密索引、稀疏索引:是否索引了每一個數據項;
B+ TREE、HASH、R TREE
簡單索引、組合索引
左前綴索引;
覆蓋索引;
管理索引的途徑:
創建索引:創建表時指定:CREATE INDEX
創建或刪除索引:修改表的命令
刪除索引:DROP INDEX
查看錶上的索引:
SHOW {INDEX | INDEXES | KEYS}
{FROM | IN} tbl_name
[{FROM | IN} db_name]
[WHERE expr]
視圖:VIEW
虛表
創建方法:
CREATE VIEW view_name [(column_list)] AS select_statement [WITH [CASCADED | LOCAL] CHECK OPTION]
刪除視圖:
DROP VIEW [IF EXISTS] view_name [, view_name] ...[RESTRICT | CASCADE]
視圖中的數據事實上存儲於“基表”中,因此,其修改操作也會針對基表實現;其修改操作受基表限制;
DML:
INSERT,DELETE,UPDATE,SELECT
INSERT:
一次插入一行或多行數據;
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
{VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
INSERT tbl_name [(col1,...)] VALUES (val1,...), (val21,...)
UPDATE:
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
注意:一定要有限制條件,否則將修改所有行的指定字段;
限制條件:
WHERE
LIMIT
SELECT:
Query Cache
查詢執行路徑中的組件:查詢緩存、解析器、預處理器、優化器、查詢執行引擎、存儲引擎;
SELECT語句的執行流程:
FROM Clause --> WHERE Clause --> GROUP BY --> HAVING Clause --> ORDER BY --> SELECT --> LIMIT
單表查詢:
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[SQL_CACHE | SQL_NO_CACHE]
select_expr [, select_expr ...]
[FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[FOR UPDATE | LOCK IN SHARE MODE]
DISTINCT:數據去重;
SQL_CACHE:顯示指定存儲查詢結果於緩存之中;
SQL_NO_CACHE:顯示查詢結果不予緩存;
query_cache_type的值爲'ON'時,查詢緩存功能打開;SELECT的結果符合緩存條件即會緩存,否則,不予緩存;顯式指定SQL_NO_CACHE,不予緩存;
query_cache_type的值爲'DEMAND'時,查詢緩存功能按需進行;顯式指定SQL_CACHE的SELECT語句纔會緩存;其它均不予緩存;
字段顯示可以使用別名:
col1 AS alias1, col2 AS alias2, ...
WHERE子句:指明過濾條件以實現“選擇”的功能:
過濾條件:布爾型表達式;
算術操作符:+, -, *, /, %
比較操作符:=, !=, <>, <=>, >, >=, <, <=
BETWEEN min_num AND max_num
IN (element1, element2, ...)
IS NULL
IS NOT NULL
LIKE:
%: 任意長度的任意字符;
_:任意單個字符;
RLIKE:
REGEXP:匹配字符串可用正則表達式書寫模式;
邏輯操作符:
NOT
AND
OR
XOR
GROUP:根據指定的條件把查詢結果進行“分組”以用於做“聚合”運算:
avg(), max(), min(), count(), sum()
HAVING: 對分組聚合運算後的結果指定過濾條件;
ORDER BY: 根據指定的字段對查詢結果進行排序;
升序:ASC
降序:DESC
LIMIT [[offset,]row_count]:對查詢的結果進行輸出行數數量限制;
對查詢結果中的數據請求施加“鎖”:
FOR UPDATE: 寫鎖,排他鎖;
LOCK IN SHARE MODE: 讀鎖,共享鎖
多表查詢:
交叉連接,笛卡爾乘積;
內連接:
等值連接:讓表之間的字段以“等值”建立連接關係;
不等值連接
自然連接;
自連接;
外連接:
左外連接:
FROM tb1 LEFT JOIN tb2 ON tb1.col=tb2.col
右外連接:
FROM tb1 RIGHT JOIN tb2 ON tb1.col=tb2.col
子查詢:在查詢語句嵌套着查詢語句
基於某語句的查詢結果再次進行查詢
用在WHERE子句中的子查詢:
1) 用於比較表達式中的子查詢;子查詢僅能返回單個值:
SELECT Name,Age FROM students WHERE Age>(SELECT avg(Age) FROM students);
2) 用於IN中的子查詢:子查詢應該單鍵查詢並返回一個或多個值構成列表;
SELECT Name,Age FROM students WHERE Age IN (SELECT Age FROM teachers);
3) 用於EXISTS;
用於FROM子句中的子查詢:
使用格式:SELECT tb_alias.col1,... FROM (SELECT clause) AS tb_alias WHERE Clause;
聯合查詢:UNION將兩外或多個返回值字段相同的查詢的結果合併輸出
SELECT Name,Age FROM students UNION SELECT Name,Age FROM teachers;
練習1:導入hellodb.sql生成數據庫
1) 在students表中,查詢年齡大於25歲,且爲男性的同學的名字和年齡;
2) 以ClassID爲分組依據,顯示每組的平均年齡;
3) 顯示第2題中平均年齡大於30的分組及平均年齡;
4) 顯示以L開頭的名字的同學的信息;
5) 顯示TeacherID非空的同學的相關信息;
6) 以年齡排序後,顯示年齡最大的前10位同學的信息;
7) 查詢年齡大於等於20歲,小於等於25歲的同學的信息,用三種方法;
方法一:
方法二:
方法三:
練習2:導入hellodb.sql,以下在students表上進行;
1) 以ClassID分組,顯示每班的同學的人數;
2) 以Gender分組,顯示其年齡之和;
3) 以ClassID分組,顯示其平均年齡大於25的班級;
4) 以Gender分組,顯示各組中年齡大於25的學員的年齡之和;
Mysql的用戶和權限:
創建用戶賬號:
CREATE USER 'username'@'host' IDENTIFIED BY 'your_password';
刪除用戶賬號:
DROP USER 'username'@'host';
查看用戶獲得的權限:
SHOW GRANTS FOR 'username'@'host';
Mysql的權限級別:
庫級別
表級別
字段級別
管理類
程序類
管理類:
CREATE TEMPORARY TABLES
CREATE USER
FILE
SUPER
SHOW DATABASES
RELOAD
SHUTDOWN
REPLICATION SLAVE
REPLICATION CLIENT
LOCK TABLES
PROCESS
Storage routine:存儲例程
storage procedure
storage function
庫和表級別:
ALTER
ALTER ROUTINE
CREATE
CREATE ROUTINE
CREATE VIEW
DROP
EXECUTE
INDEX
GRANT OPTION: 是否可以轉授權限的權限;
SHOW VIEW
數據操作(表級別):
SELECT
INSERT
UPDATE
DELETE
字段級別:
SELECT(col1,...)
UPDATE(col1,...)
INSERT(col1,...)
所有權限:
ALL [PRIVILEGES]
用戶重命名:RENAME USER
RENAME USER old_user_name TO new_user_name
修改密碼:
1) SET PASSWORD FOR
2) UPDATE mysql.user SET password=PASSWORD('your_password') WHERE clause;
3) mysqladmin password
mysqladmin [OPTIONS] command command....
-u, -h, -p
忘記管理員密碼的解決方法:
1) 啓動mysqld進程時,爲其使用:--skip-grant-tables --skip-networking
2) 使用UPDATE命令修改管理員密碼;
3) 關閉mysqld進程,移除上面兩個選項,重啓mysqld;
mysql中的授權相關的表:
db、host、user
columns_priv、tables_priv, procs_priv
授權與取消授權:GRANT, REVOKE
GRANT priv1, priv2, ... ON [TABLE|FUNCTION|PROCEDURE] db_name.tb_name|routine TO 'username'@'host' [IDENTIFIED BY 'password'] [REQUIRE ssl_option] [WITH with_option]
GRANT OPTION
| MAX_QUERIES_PER_HOUR count
| MAX_UPDATES_PER_HOUR count
| MAX_CONNECTIONS_PER_HOUR count
| MAX_USER_CONNECTIONS count
REVOKE priv1,priv2,... ON [TABLE|FUNCTION|PROCEDURE] db_name.tb_name|routine FROM 'username'@'host',...;
Mysql cache
SELECT --> QUERY CACHE --> PARSER --> OPTIMIZER --> EXECUTING ENGINE --> STORAGE ENGINE
緩存:hit(命中),miss(未命中)
Key-value
衡量緩存的有效性:命中率,hit/(hit+miss)
次數;
query_cache_type
ON,OFF,DEMAND
SQL_CACHE | SQL_NO_CACHE
QUERY CACHE:
Key:查詢語句的hash碼;
Value:查詢語句的執行結果;
什麼樣的語句不會緩存?
查詢語句中有不確定數據時不會緩存;
一般來講,如果查詢中包含用戶自定義的函數(UDF)、存儲函數、用戶變量、臨時表、mysql庫中表、或者任何包含權限信息表,都不會緩存;
緩存什麼場景下比較有效?
對於存在需要大量資源的查詢非常適合啓用緩存;
與緩存功能相關的服務器變量:
Query_cache_limit:mysql能夠緩存的最大查詢結果;如果某查詢的結果大於此值,則不會被緩存;
Query_cache_min_res_unit:查詢緩存中分配內存的最小單位
計算公式:(query_cache_size-Qcache_free_memory)/Qcache_queries_in_cache
Query_cache_size:查詢緩存的總體可用空間;其必須是1024的倍數;
Query_cache_wlock_incalidate:當其他會話鎖定此次查詢用到的資源時,是否不能再從緩存中返回數據;
與緩存相關的狀態變量:
Qcache_hits/Com_select
衡量緩存是否足夠有效的另一種思路:Qcache_hits/Qcache_inserts
如果此比值大於3:1,說明緩存也是有效的;如果高於10:1,相當理想;
緩存優化的思路:
1) 批量寫入比單次寫入對緩存的影響要小很多;
2) 緩存空間不宜過大,大量緩存的同時失效會導致Mysql假死;
3) 必要時,使用SQL_CACHE或SQL_NO_CACHE手動控制緩存;
4) 對寫密集型的應用場景,禁用緩存反而能提高性能;
碎片整理:FLUSH QUERY_CACHE
清空緩存:RESET QUERY_CACHE
Mysql的存儲引擎
表類型:
CREATE TABLE ... ENGINE=
InnoDB:
處理大量的短期事務:
數據存儲於“表空間”中;
1) 所有InnoDB表的數據和索引放置於同一個表空間中;
表空間文件:datadir定義的目錄下;
數據文件:ibddata1,ibddata2,…
2) 每個表單獨使用一個表空間存儲表的數據和索引;
innodb_file_per_table=ON
數據文件(存儲數據和索引):tb1_name.ibd,
表格式定義:tb1_name.frm
基於MVCC來支持高併發,支持所有的四個隔離級別,默認級別爲REPEATABLE READ,間隙鎖防止幻讀;
使用聚集索引
支持“自適應hash索引”
鎖粒度:行級鎖
MariaDB(XtraDB (percona))
數據存儲:表空間
併發:MVCC,間隙鎖
索引:聚集索引、輔助索引
性能:預計操作、自適應hash、插入緩存區
備份:支持熱備(xtrabaup)
MyISAM:
支持全文索引(FULLTEXT index)、壓縮、空間函數(GIS);但不支持事務,且爲表級鎖;崩潰後無法恢復;
適用場景:只讀(或者寫較少)、表較小(可以接受長時間進行修復操作)
Aria:crash-safe
文件:
tb1_name.frm:表格式定義
tb1_name.MYD:數據文件
tb1_name.MYI:索引文件
特性:
加鎖和併發:表級鎖
修復:手工或自動修復、但可能丟失數據
索引:非聚集索引
延遲更新索引鍵:
壓縮表
行格式:dynamic,fixed,compressed,compact,redundent
其它的存儲引擎:
CSV:將普通的CSV(字段通過逗號分隔)作爲MySQL表使用;
MRG_MYISAM:將多個MyISAM表合併稱爲一個虛擬表;
BLACKHOLE:類似於/dev/null,不真正存儲任何數據;
MEMORY:所有數據都保存於內存中,內存表;支持hash索引;表級鎖;臨時表;
PERFORMANCE_SCHEMA僞存儲引擎;
ARCHIVE:只支持SELECT和INSERT操作;支持行級鎖和專用緩存區;
FEDERATED:用於訪問其它遠程MySQL服務器的一個代理,它通過創建一個到遠程MySQL服務器的客戶端連接,並將查詢傳輸到遠程服務器進行,而後完成數據存取;
在MariaDB的上實現是FederatedX
MariaDB支持的其它存儲引擎:
OQGraph
SphinxSE
TokuDB
Cassandra
CONNECT
SQUENCE
併發控制:
鎖:
讀鎖:共享鎖
寫鎖:獨佔鎖
鎖粒度:
表級鎖;
行級鎖
鎖策略:在鎖粒度及數據安全性尋求的平衡機制;每種存儲引擎都可以自行實現其鎖策略和鎖粒度;
Mysql在服務器級也實現了鎖,表級鎖,用戶可以顯示請求;
1) LOCAK TABLES tbl_name [[AS] alias] lock_type [, tbl_name [[AS] alias] lock_type] ...
lock_type:
READ [LOCAL] | [LOW_PRIORITY] WRITE
UNLOCK TABLES
2) FLUSH TABLES tb_name[,...] [WITH READ LOCK] [FOR UPDATE]
3) SELECT clase [FOR UPDATE] [WITH READ LOACK]
分類:
隱式鎖:由存儲引擎自動施加鎖;
顯示鎖:
Mysql事務:
事務:一組原子性的SQL查詢,或者說一個獨立工作單元。
事務日誌:
ACID測試:
A:atomicity,原子性;整個事務中的所有操作要麼全部成功執行,要麼全部失敗後回滾;
C:consistency,一致性;數據庫總是從一個一致性狀態轉換爲另一個一致性狀態;
I:Isolation,隔離性;一個事物所做出的操作在提交之前,是不能爲其它所見;隔離有多種隔離級別;
D:durability:持久性,一旦事務提交,其所做的修改會永久保存於數據庫中;
事務:
啓動事務:START TRANSACTION
…
結束事務:
1) COMMIT:提交
2) ROLLBACK:回滾
注意:只有事務型存儲引擎方能支持此操作;
建議:顯示請求和提交事務,而不要使用自動提交功能:
autocommit={1|0}
事務支持savepoint
SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier
事務隔離級別:
READ UNCOMMITTED (讀未提交)
READ COMMITTED (讀提交)
REPEATABLE READ (可重讀)
SERIALIZABILE (可串行化)
可能存在問題:
髒讀;
不可重複讀;
幻讀;
加鎖讀;
tx_isolation:服務器變量,默認爲REPEATABLE-READ;可在SESSION級進行修改;
SET tx_isolation=''
READ-UNCOMMITTED
READ-COMMITTED
REPEATABLE-READ
SERIALIZABLE
MVCC: 多版本併發控制
死鎖:
兩個或多個事務在同一資源相互佔用,並請求鎖定對方佔用的資源的狀態;
事務日誌:
事務日誌的寫入類型爲追加,因此其操作爲“順序IO”;此日誌通常也被稱爲“預寫式日誌”;
MySQL中的索引:
基本法則:索引應該構建在被用作查詢條件的字段上;
索引類型:
B+ Tree索引:順序存儲,每一個葉子節點到根結點的距離是相同的;左前綴索引,適合查詢範圍類的數據;
可以使用B-Tree索引的查詢類型:全鍵值、鍵值範圍或鍵前綴查找;
全值匹配:精確某個值, "Jinjiao King";
匹配最左前綴:只精確匹配起頭部分,"Jin%"
匹配範圍值:
精確匹配某一列並範圍匹配另一列:
只訪問索引的查詢
不適合使用B-Tree索引的場景:
如果不從最左列開始,索引無效; (Age,Name)
不能跳過索引中的列;(StuID,Name,Age)
如果查詢中某個列是爲範圍查詢,那麼其右側的列都無法再使用索引優化查詢;(StuID,Name)
Hash索引:基於哈希表實現,特別適用於精確匹配索引中的所有列;
注意:只有Memory存儲引擎支持顯式hash索引;
適用場景:
只支持等值比較查詢,包括=, IN(), <=>;
不適合使用hash索引的場景:
存儲的非爲值的順序,因此,不適用於順序查詢;
不支持模糊匹配;
空間索引(R-Tree):
MyISAM支持空間索引;
全文索引(FULLTEXT):
在文本中查找關鍵詞;
索引優點:
索引可以降低服務需要掃描的數據量,減少了IO次數;
索引可以幫助服務器避免排序和使用臨時表;
索引可以幫助將隨機I/O轉爲順序I/O;
高性能索引策略:
獨立使用列,儘量避免其參與運算;
左前綴索引:索引構建於字段的左側的多少個字符,要通過索引選擇性來評估
索引選擇性:不重複的索引值和數據表的記錄總數的比值;
多列索引:
AND操作時更適合使用多列索引;
選擇合適的索引列次序:將選擇性最高放左側;
冗餘和重複索引:
不好的索引使用策略
通過EXPLAIN來分析索引的有效性:
EXPLAIN SELECT clause
獲取查詢執行計劃信息,用來查看查詢優化器如何執行查詢
輸出:
id:當前查詢語句中,每個SELECT語句的編號;
複雜類型的查詢有三種:
簡單子查詢;
用於FROM中的子查詢;
聯合查詢:UNION;
注意:UNION查詢的分析結果會出現一額外匿名臨時表;
select_type:簡單查詢爲SIMPLE;
複雜查詢:
SUBQUERY:簡單子查詢;
DERIVED:用於FROM中的子查詢;
UNION:UNION語句的第一個之後的SELECT語句;
UNION RESULT:匿名臨時表;
table:SELECT語句關聯到的表;
type:關聯類型,或訪問類型,即Mysql決定的如何去查詢表中的行的方式;
ALL:全表掃描;
index:根據索引的次序進行全表掃描;如果在Extra列出現“using index”表示了是歐陽覆蓋索引,而非全表掃描;
range:有範圍限制的根據索引實現範圍掃描,掃描位置始於索引中的某一點,結束於另一點;
ref:根據索引返回表中匹配某單個值的所有行;
eq_ref:僅返回一個行,但與需要額外與某個參考值做比較;
const, system: 直接返回單個行;
possible_keys:查詢可能會用到的索引;
key: 查詢中使用了的索引;
key_len: 在索引使用的字節數;
ref: 在利用key字段所表示的索引完成查詢時所有的列或某常量值;
rows:MySQL估計爲找所有的目標行而需要讀取的行數;
Extra:額外信息
Using index:MySQL將會使用覆蓋索引,以避免訪問表;
Using where:MySQL服務器將在存儲引擎檢索後,再進行一次過濾;
Using temporary:MySQL對結果排序時會使用臨時表
Using filesort:對結果使用一個外部索引排序;
Mysql日誌
1. 查詢日誌:
log_output = {TABLE|FILE|NONE}
log_output = TABLE,FILE
FILE: gerenal_log
general_log = {ON|OFF}:是否啓用查詢日誌;
general_log_file=www.log:當log_output有file類型時,日誌信息的記錄位置;
2. 慢查詢日誌;
slow_query_log={ON|OFF}:是否啓用慢查詢日誌;
slow_query_log=/path/to/somefile:日誌文件路徑;
log_slow_filter=admin,filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk
log_slow_rate_limit =
log_slow_verbosity =
3. 錯誤日誌;
Mysqld啓動和關閉過程中輸出的信息;
Mysqld運行中產生的錯誤信息;
Event scheduler運行一個event時產生的日誌信息;
在主從複製架構中的從服務器上啓動從服務器線程時產生的日誌信息;
log_error = /path/to/somefile
log_warings={ON|OFF}:是否記錄警告信息於錯誤日誌中;
4. 二進制日誌;
SHOW {BINARY|MASTER} LOGS:查看主服務器端處於由mysqld維護狀態中的二進制日誌文件;
SHOW BINLOG EVENTS [IN ‘log_name’] [FROM pos] [LIMIT [offset,] row_count]:顯示指定的二進制日誌文件中的相關事件;
日誌記錄格式:
基於“語句”記錄:statement
基於“行”記錄:row
“混合”:mixed
二進制日誌文件的構成:
日誌文件:文件名前綴.文件名後綴;
索引文件:文件名前綴.index
服務器變量:
log_bin=/path/to/somefile
binlog_format =MIXED
sql_log_bin=ON
max_binlog_size=1073741824
二進制日誌文件的單文件上限;
Max_binlog_cache_size=18446744073709547520
max_binlog_stmt_cache_size = 18446744073709547520
sync_binlog=0:設定多久同步一次二進制日誌文件;0表示不同步;任何正值都表示記錄多少個語句後同步一次;
二進制日誌的格式:
# at 19364
#140829 15:50:07 server id 1 end_log_pos 19486 Query thread_id=13 exec_time=0 error_code=0
SET TIMESTAMP=1409298607/*!*/;
GRANT SELECT ON tdb.* TO tuser@localhost/*!*/;
# at 19486
事件發生的日期和時間:(140829 15:50:07)
事件發生在服務器的標識(server id)
事件的結束位置:(end_log_pos 19486)
事件的類型:(Query)
事件發生時所在的服務器執行此事件的線程的id:(thread_id=13)
語句的時間戳與將其寫入二進制文件中的時間差:(exec_time=0)
錯誤代碼:(error_code=0)
事件內容:(SET TIMESTAMP=1409298607/*!*/;GRANT SELECT ON tdb.* TO tuser@localhost)
GTID事件專屬:事件所屬的全局事務的GTID:(GTID 0-1-2)
二進制日誌的查看命令:
Mysqlbinlog
-j, --start-position=#:從指定的事件位置查看
--stop-position=#:只顯示到指定的時間位置;
--start-datetime=name
--stop-datetime=name
YYYY-MM-DD hh:mm:ss
5. 中繼日誌:
6. 事務日誌(innodb存儲引擎)
Mysql的備份和恢復
爲什麼要備份?
災難恢復:硬件故障、軟件故障、自然災害、******;誤操作;測試;
要注意的要點:
可容忍丟失多少數據;
恢復需要在多長時間內完成;
需要恢復什麼;
備份類型:
完全備份,部分備份;
部分備份:僅備份其中一張表或多張表;
完全備份,增量備份,差異備份
增量備份:僅備份從上次完全備份或增量備份之後變化的數據部分;
熱備份、溫度備份和冷備份;
熱備份:在線備份,讀寫操作不受影響;
溫備份:在線備份,讀操作可繼續進行,但寫操作不允許;
冷備份:離線備份,數據庫服務器離線,備份期間不能爲業務提供讀寫服務;
MyISAM: 溫備
InnoDB:熱備
物理備份和邏輯備份:
物理備份:直接複製數據文件進行的備份;
邏輯備份:從數據庫中“導出”數據另存而進行的備份;
邏輯備份:
與存儲引擎無關;
規則備份時需要考慮的因素:
持鎖的時長;
備份過程時長;
備份負載
恢復過程時長;
備份什麼?
數據、額外的數據(二進制日誌和InnoDB的事務日誌)、代碼(存儲過程和存儲函數、觸發器、時間調度器等)、服務器配置文件;
設計備份方案:
完全備份+增量備份
備份工具:
mysqldump:邏輯備份工具,適用於所有存儲引擎,溫備;完全備份,部分備份;對InnoDB存儲引擎支持熱備;
cp,tar等文件系統工具:物理備份工具,適用於所有存儲引擎;冷備:完全備份,部分備份;
lvm2的快照:幾乎熱備;藉助於文件系統工具實現物理備份;
mysqlhotcopy:幾乎冷備;僅適用於MyISAM存儲引擎;
備份方案之備份工具的選擇:
mysqldump+binlog:
mysqldump:完全備份,通過備份二進制日誌實現增量備份;
lvm2快照+binlog:幾乎熱備,物理備份;
xtrabakup:
對InnoDB:熱備,支持完全備份
對MyISAM引擎:溫備,只支持完全備份;
mysqldump工具介紹:
mysqldump:客戶端,通過mysql協議連接至msyqld;
-A,--all-databases
MyISAM,InnoDB:溫備
-x,--lock-all-tables:鎖定所有表;
-l,--lock-tables:鎖定備份的表;
InnoDB:
--single-transaction:啓動一個大的單一事務實現備份;
-B,--databases db_name1 db_name2 …:備份指定的數據庫
-C,--compress:壓縮傳輸;
命令的語法格式:
mysqldump [OPTIONS] database [tables]:備份單個庫,或庫指定的一個或多個表
mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3…]:備份一個或多個庫;
mysqldump [OPTIONS] --all-databases [OPTIONS]:備份所有庫
其它選項:
-E,--events:備份指定庫的時間調度器;
-R,--routines:備份存儲過程和存儲函數;
--triggers:備份觸發器
--master-data[=#]:
1:記錄CHANGE MASTER TO 語句;此語句未被註釋;
2:記錄爲註釋語句;
--flush-logs,-F:鎖定表之後執行flush logs命令;
注意:二進制日誌文件與數據文件不應該放置於同一磁盤;
幾乎熱備:lvm2快照,流程:
1. 請求鎖定所有表;
mysql> FLUSH TABLES WITH READ LOCK;
2. 記錄二進制日誌文件及事件位置;
mysql> SHOW MASTER STATUS;
3. 創建快照;
lvcreate -L SIZE -s -p r -n NAME /dev/VG_NAME/LV_NAME
4. 釋放鎖;
mysql> UNLOCK TABLES
5. 掛載快照卷,複製數據進行備份;
cp, rsync, tar等命令複製數據;
6. 備份完成之後,刪除快照卷;
演示:利用mysqldump工具備份;
1. 創建備份目錄,存放備份文件;
2. 使用mysqldump工具,備份到備分目錄;
Note:用--databases指明數據庫時,備份的語句中有創建數據庫的語句,如果不用--databases指明,則要手動創建;
3. 我們的策略是完全+增量+binlog備份方式,如果要使用binlog二進制日誌重讀,就要確定從備份的那一刻開始,binlog的起始文件位置,這是就喲啊使用--master-data=[#]選項;(確保二進制日誌是開啓的)
1) 首先開啓二進制日誌;
2) 備份;
3) 查看二進制文件;
4. 修改數據庫內容;
5. 刪除hellodb數據庫,模擬數據庫崩潰,
6. 數據庫恢復;
1) 準備好要做時間點恢復的二進制文件;
2) 查看二進制日誌,把最後數據庫刪除操作的position截取掉,重定向一個新的文件中;
3) 將二進制文件重定向新的文件;
4) 恢復數據會執行大量的寫操作,可以先關閉二進制日誌文件;
複製備份文件爲.sql結尾;
導入數據庫;
可以看出數據庫恢復到了備份時的狀態;
5) 利用二進制文件,恢復到數據庫崩潰之前的時間點;
查看錶中數據;
演示2:基於lvm2快照備份;
1. 創建分區;
2. 創建lvm
3. 創建mysql數據庫目錄,並將邏輯卷掛載至此目錄;
4. 更改此目錄的屬組屬主;
5. 修改mysql配置文件/etc/my.cnf,修改數據目錄;
6. 開啓服務,查看數據目錄文件;
7. 先關閉數據庫二進制日誌進行數據寫入;
查看導入的數據庫;
8. 開啓二進制日誌,創建備份;
1) 開啓二進制日誌;
2) 請求鎖定所有表,FLUSH TABLES爲將所有內存的數據寫入磁盤中;
3) 記錄二進制時間位置;
4) 創建快照;
5) 釋放鎖;
6) 掛載快照卷並進行拷貝操作,文件屬性需要保留;
7) 備份完成後,刪除快照;
9. 快照備份完成,對數據庫進行一些修改,方便後面時間點還原;
10. 恢復;
1) 手動模擬宕機並模擬數據庫丟失;
2) 複製備份文件到數據目錄,登錄數據庫,還原到備份的狀態;
3) 利用二進制日誌回滾還原;
過程跟上面利用mysqldump工具一樣。
備份還原工具:Xtrabackup
Percona,www.percona.com
Innobackupex:客戶端工具,以mysql協議連入mysqld,不支持離線備份
--user=
--password=
大概流程:
備份
完全備份策略:完整備份+增量備份+二進制日誌
全量備份:# innobackupex --user=USER --password=PASSWORD BACKUPDIR(生成的備份目錄爲BASEDIR)
第一次增量備份:# innobackupex –user=USER –password=PASSWORD --incremental BACKUPDIR --incremental-basedir=BASEDIR(基於上一次 全量備份,生成的備份目錄basedir爲BASEDIR1)
第二次增量備份:# innobackupex --user=root --password=taoxiu --incremental BACKUPDIR --incremental-basedir= BASEDIR1
準備:# innobackupex --apply-log --redo-only BASEDIR
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-1
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INCREMENTAL-DIR-2
恢復:
# innobackupex –copy-back BASEDIR
改變屬主屬組:
# cd /datadir
# chown –R mysql.mysql ./*
NOTE:查看備份目錄中的xtrabackup-binlog-info,可以查看最後一次增量備份的end-points;最後可通過二進制日誌還原到機器崩潰時的狀態;
注意:
1) 將數據和二進制文件放置於不同的設備;二進制日誌也應該週期性地備份;
2) 將數據和備份分開存放,建議不在同一設備、同一主機、同一機房、同一地域;
3) 每次災難恢復後都應該立即做一次完全備份;
4) 備份後的數據應該週期性地做還原測試;
從備份中恢復應該遵循的步驟:
1) 停止mysql服務器;
2) 記錄服務器配置和文件權限;
3) 將備份恢復到mysql數據目錄;此步驟依賴具體的備份工具;
4) 改變配置和文件權限;
5) 以限制方式啓動mysql服務器;比如通過網絡訪問;
[mysqld]
skip-networking
socket=/tmp/mysql-recovery.sock
6) 載入額外的邏輯備份;而檢查和重放二進制日誌;
7) 檢查已經還原的數據;
8) 以完全訪問模式重啓服務器;
mysql的複製架構:
系統擴展的方式:
Scale up:向上擴展,垂直擴展;
Scale out:向外擴展,水平擴展
複製:水平擴展;
複製的功用:
負載均衡
數據分佈
備份
高可用性
MYSQL升級測試
複製架構的問題:
1. 主節點是單點;
2. 寫操作無法有效均衡;
數據庫擴展的思路;
複製、切片
複製有三個步驟:
1. 在主庫上啓用二進制日誌;
2. 備庫從主庫複製二進制日誌,並保存至本地的中繼日誌中;
3. 備庫從中繼日誌中讀取事件並於本地執行一次;
複製總結:
Master:啓用二進制日誌,有唯一的server-id
Binlog dump:將從服務的io thread發出讀取二進制日誌事件的請求對應的數據發送給對方;
Slave:啓用中繼日誌,並關閉二進制日誌(建議),有唯一的server-id
Io-thread:想master請求二進制日誌中的事件;
SQL thread:從中繼日誌中讀取事件並在本地執行;
複製工作架構:
從服務器:有且只能有一個主服務器;
MariaDB 10:支持多源複製,即支持多個主服務器;
主服務器:可以有多從;
異步:從服務器的數據可能會落後於主服務器;
主從複製:
版本:雙版本一致,從節點版本低於主節點版本可能引起錯誤;
複製起點:從哪兒複製?
1. 從0開始:適用於主從均爲新建立的服務器;
2. 主服務已經運行一段時間且存不小的數據量;
完全備份主服務上的數據,並將數據恢復至從服務器;從服務器從備份時主服務器二進制日誌所在位置;
配置過程:
Master:
1. 啓用二進制日誌
2. 定義server-id
3. 創建有複製權限的賬號;REPLICATION SLAVE, REPLICATION CLIENT
MariaDB [(none)]> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO repluser@'192.168.19.%' IDENTIFIED BY 'replp@ss';
Slave:
1. 啓動中繼日誌;
2. 定義server-id
3. 使用有複製權限的賬號連接master
4. 啓動io thread以及sql thread
連接master:
查看從節點的狀態信息
MariaDB [(none)]> SHOW SLAVE STATUS\G
主主:
互爲主從:
1、數據不一致;
2、自動增長id
定義一個節點使用奇數id
auto_increment_offset=1
auto_increment_increment=2
定義另一個節點使用偶數id
auto_increment_offset=2
auto_increment_increment=2
1) 各自使用不同的server id
2) 都啓用binlog和relay log
3) 定義自動增長的id字段的增長方式
4) 都授權有複製權限的用戶賬號
5) 各自把對方指定爲主服務器
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repluser'@'172.16.%.%' IDENTIFIED BY 'replpass';
複製中應該注意的問題:
1. 如何限制從服務器只讀?
更改slave的全局服務器變量read-only爲YES;
注意:此限制對於擁有super權限用戶無效;
MariaDB [mysql]> SET GLOBAL read_only = 1;
或者更改配置文件:
[mysqld]
read_only = 1
阻止所有用戶執行寫操作:
MariaDB [mysql]> flush tables with read lock;
2. 如何保證主從複製時的事務安全?
前提:mysql對二進制日誌事件數據會有緩衝;
在master上設置參數:
Sync_binlog = 1
如果用到的爲InnoDB存儲引擎:
Innodb_flush_logs_at_trx_commit
Innodb_support-xa=on
在slave節點:
Skip_slave_start
主節點:
Sync_master_info = 1
從節點:
Sync_relay_log = 1
Sync_relay_log_info = 1
3. 半同步複製:
半同步:master要等待一個從節點把數據完整複製過去;
由google貢獻的補丁:以插件的方式存在;
Master:
MariaDB [testdb]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
MariaDB [testdb]> SHOW GLOBAL VARIABLES LIKE '%semi%';
MariaDB [testdb]> SET GLOBAL rpl_semi_sync_master_enabled=1;
MariaDB [testdb]> SET GLOBAL rpl_semi_sync_master_timeout=1000;
Slave:
MariaDB [mysql]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
MariaDB [mysql]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';
MariaDB [mysql]> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
注意:只需要關閉並啓動IO_THREAD即可;
主節點在聯繫從節點超時後,會自動降低爲異步模式;
在主節點驗證正是是否已經工作於半同步模式:
SHOW GLOBAL STATUS LIKE '%semi%';
4. 複製過濾器
讓slave僅複製有限的幾個數據庫,甚至於僅複製某數據庫內有限的幾張表的機制;
有兩種方案:
1) 在主節點上過濾;
在向二進制日誌記錄事件時,僅記錄指定數據庫的相關操作;
binlog_do_db = # 數據庫白名單
binlog_ignore_db = # 數據庫黑名單
2) 在從節點過濾;
僅從中繼日誌中讀取指定的數據庫或表的相關事件並應用於本地:
問題:會造成網絡帶寬和磁盤IO的浪費;
Replicate_Do_DB=
Replicate_Ignore_DB=
Replicate_Do_Table=
Replicate_Ignore_Table=
Replicate_Wild_Do_Table=
Replicate_Wild_Ignore_Table=
5. 基於SSL的複製
前提:支持SSL
1) 主服務器端配置證書和私鑰,並創建一個要求必須使用SSL連接的複製賬號(REQUIRE SSL);
2) SLAVE端連接master時,使用MASTER_SSL相關的選項來配置證書等信息;
6. 跟複製功能相關的文件;
Master.info:用於保存slave連接至master時的相關信息;
Relay_log.info:保存了當前slave節點上已經複製的當前二進制日誌和本地relay log日誌對應關係;
7. 複製的監控和維護
1) 清理日誌:PURGE
2) 複製監控
SHOW MASTER STATUS
SHOW BINLOG EVENTS
SHOW BINARY LOGS;
SHOW SLAVE STATUS
3) 如何判斷slave是否落後於master
Seconds_Behind_Master:0
4) 如何確定主從節點數據是否一致?
通過表自身的CHECKSUM檢查;
使用percona-tools中的pt_table-checksum
5) 數據不一致的修復方法;
重複複製;
演示:配置主從複製
實驗環境:主節點爲node1,從節點爲node2;
1. 編輯主節點服務器mysql配置文件啓用二進制日誌,並啓動mariadb服務;
2. 編輯從節點的配置文件啓動中繼日誌,並啓動mariadb服務;
3. 在主節點上創建並授權一個擁有複製權限的賬號,並記錄此時的二進制結束位置;
4. 在從節點上設置連接服務器的相關信息,並啓動複製;
5. 開啓複製線程,並查看slave狀態;
6. 測試,在主節點莊創建數據庫並查看二進制日誌,觀察從節點狀態是否有延遲;
主節點上:
從節點上:
7. 如果從服務器需要只能讀不能寫,所有要設置其全局參數爲只讀;
演示:主主複製;
兩個主節點分別爲node1,node2;
1. 編輯node1配置文件,啓動二進制日誌和中繼日誌;
2. 配置node2配置文件,啓動二進制日誌和中繼日誌;
3. 分別啓動兩個節點的mariadb服務,並各自創建並授權一個有複製權限的賬號;
Node1:
Node2:
4. 分別記錄兩個節點的二進制日誌位置;
Node1:
Node2:
5. 分別在兩個主節點上把另一個節點指定爲主節點;
Node1:
Node2:
6. 測試,看看兩節點能否相互複製;
1) 在node1上創建數據庫和表;
2) 在node2上查看;
3) 在node2上向表中插入數據;
4) 在node1上查看,並在node1上插入數據;
Node2上查看:
演示:半同步複製;
實驗環境:主節點:node1,從節點:node2。主從複製模型;
1. 編輯主節點配置文件;
2. 編輯從節點配置文件;
3. 啓動主節點mariadb服務,授權一個有複製權限的賬號,並查看二進制文件位置;
4. 指定從節點的的連接主節點複製的相關信息,並啓動複製功能;
5. 主從複製安裝完之後,爲了實現半同步複製,在主節點上安裝支持同步複製的插件semisync_master.so,並啓動該插件;
查看器狀態爲關閉狀態,需要手動啓動;
6. 在node2節點上安裝插件;
查看其運行狀態並手動開啓;
7. 查看同步複製的狀態;
在從節點上關閉複製進程,再重新打開;
再次打開主節點查看同步複製狀態;
MHA集羣配置:
MHA(master ha)是一款開源的mysql開可用程序,它爲mysql主從複製架構提供了autom ating master failover功能。MHA在監控到master節點故障時,會提升其中擁有最新數據的slave節點成爲新的master節點,在此期間,MHA會通過其它從節點獲取額外信息來避免一致性方面的問題。MHA還提供了master節點的在線切換功能,即按需切換master/slave節點。
MHA服務有兩種特色,MHA|Manager(管理節點)和MHA Node(數據節點);
MHA Manager:通常單獨部署在一臺獨立機器上管理多個master/slave集羣,每個master/slave集羣稱作一個application;
MHA node:運行在每臺mysql服務器上(master/slave/manager),它通過監控具備解析和清理logs功能的腳本來加快故障轉移。
MHA架構圖:
MHA組件:
Manager節點:
-masterha_check_ssh:MHA依賴的SSH環境監測工具;
-masterha_check_repl:mysql複製環境檢測工具;
-masterha_manager:MHA服務主程序;
-masterha_check_status:MHA運行狀態探測工具;
-masterha_master_monitor:mysql master節點可用性檢測工具;
-masterha_master_switch:master節點切換工具;
-masterha_conf_host:添加或刪除配置的節點;
-masterha_stop:關閉MHA服務的工具;
Node節點:
-save_binary_logs:保存和複製master的二進制日誌;
-apply_diff_relay_logs:識別差異的中繼日誌事件並應用於其它slave;
-filter_mysqlbinlog:去除不必要的ROLLBACK事件(MHA已不再使用這個工具);
-purge_relay_logs:清除中繼日誌(不會阻塞SQL線程)
自定義擴展:
-secondary_check_script:通過多條網絡路由檢測master的可用性;
-master_ip_failover_script:更新application使用的masterip
-shutdown_script:強制關閉master節點;
-report_script:發送報告;
-init_conf_load_script:加載初始配置參數;
-master_ip_online_change_script:更新master節點的ip地址;
演示:MHA集羣
1. 實驗環境準備;
1) 各節點信息;
Node1:192.168.19.141 MHA Manager
Node2:192.168.19.200 Mariadb master
Node3:192.168.19.134 Mysql slave
Node4:192.168.19.143 Mysql slave
其中node2與node3作半同步複製,node2與node4作主從複製;
2) 在各節點的/etc/hosts文件配置內容中添加以下內容:
3) 各節點的mysql配置;
Master節點node2:
Slave節點node3配置;
Slave節點node4配置:
2. 配置主從複製
1) 在node2節點上創建創建並授權一個擁有複製權限的賬號,並記錄此時二進制結束位置;
2) 在node3節點上設置連接主服務器的相關信息,並啓動複製;
3) 在node3上開啓複製線程,並查看狀態;
4) 在ndoe4節點上設置連接主節點node2相關信息,並啓動複製線程;
3. 在所有mysql節點授權擁有管理權限的用戶可在本地網絡中有其他節點上遠程訪問,此時,我們只需要在主節點上運行即可,命令便可複製到其它節點;
Note:順便增加主機名的權限,否則後期測試時可能會出錯;
同時,在node3和node4上創建複製權限的賬號;
4. 安裝配置MHA;
1) 準備基於ssh互相通信環境;
MHA集羣中的各節點彼此之間需要基於ssh互信通信,以實現遠程控制及數據管理功能。簡單起見,可在manager節點生成密鑰對,並設置其可遠程連接本地主機後,將死要文件及authorized_keys文件複製給餘下的所有節點;
以下操作在manager節點node1上操作:
Node2上操作:
Node3上操作:同node2一樣將自己的公鑰文件發給node2和node4;
Node4上操作:將自己的公鑰文件發給node2和node3;
2) 安裝MHA
Manager節點:
其它節點:
3) 初始化MHA
Manager節點需要爲每一個監控的master/slave集羣提供一個專用的配置文件,而所有的master/slave集羣也可共享全局配置。全局配置文件默認爲/etc/masterha_default.cnf,其爲可選配置。這裏我們自定一個集羣配置文件/etc/masterha/mha1.cnf,配置內容如下:
創建相關文件夾目錄:
檢測各節點間ssh互信通信配置是否ok,最後一行出現All SSH connection tests passed successfully表示成功;
檢查管理的mysql複製集羣的連接配置參數是否ok;
啓動MHA,並查看master節點狀態:
如果要聽孩子MHA,需要使用masterha_stop命令;
#masterha_stop --conf=/etc/masterha/mha1.cnf
4) 測試故障轉移;
a. 在master節點關閉mariadb服務;
#killall -9 mysqld mysqld_safe
b. 在manager節點查看日誌;
Note:故障轉移完成後,manger將會自動停止,此時使用masterha_check_status命令檢測將會遇到錯誤;
c. 提供新的從節點以修復集羣;
原有master節點故障後,需要重新準備一個新的mysql節點,基於來自於master節點的備份恢復數據後,將其配置爲新的master的從節點即可。注意,新加入的節點如果爲新增節點,其ip地址要配置爲原來master節點的IP,否則,還需要修改mha1.cnf中的響應server的ip;
5. 進一步工作;
1) 提供額外檢測機制,以免對master的監控做出誤判;
2) 在master節點上提供虛擬ip地址向外提供服務,以免master節點轉換時,客戶端請求無法正確送達;
3) 進行故障轉移時對原有master節點執行STONITH操作以避免腦裂;可通過指定shutdon_script實現;
4) 必要時,進行在線master節點轉換;