Mysql介紹... 4mysql
登陸mysql mysql –u root –p【掌握】... 4linux
SQL語言... 4sql
DCL. 4shell
grant. 4數據庫
revoke. 4express
DDL. 4windows
建庫... 4緩存
刪庫... 4安全
Mysqldumpslow過濾日誌(定位縮小範圍)... 13
分析Explain(記重要的參數的含義,分析給出建議)... 15
Show processlist(第二階段還會講,看鏈接數等)... 17
運行狀態分析(運行一段時間,看是否要打開或調整)... 20
關係型數據庫
修改密碼 mysqladmin –u root –p[oldpassword] password newpassword
使用客戶端數據庫管理軟件 若是沒法鏈接就執行
GRANT ALL PRIVILEGES ON *.* TO ‘用戶名’@’%’ IDENTIFIED BY ‘密碼’ WITH GRANT OPTION;
或者本身博客
(data control language):數據控制語言,用於控制不一樣數據對象訪問級別的語句。定義了數據庫、表、列、用戶的訪問權限和安全級別(grant、revoke)【瞭解】
語法:grant 權限 on 數據庫對象 to 用戶;
Grant select on testdb.* to ‘user_1’@’%’;
revoke select on testdb.* from ‘user_1’@’%’;
(data definition languages):數據定義語言,數據庫、表、索引等對象的定義(create、drop、alter、truncate、rename)【掌握】
create database dbname default charset=utf8;
drop database dbname
一、 create table table_name (col1 type1[not null] [primary key],col2 type2[not null],…);
二、 create table table_name1 like table_name2;建立一個與當前某各表結構類似的空表。
三、數值類型、日期時間、字符串
四、經常使用函數( 數值函數、字符串函數、日期時間函數、其餘函數)
desc table_name;
drop table table_name;
alter table table_name
MODIFY col_name column_definition –修改字段類型
CHANGE old_col_name new_col_name definition –修改字段名稱
ADD col_name column_definition –添加字段
DROP col_name;--刪除字段
(data manipulation language):數據操做語言,用於增刪改查記錄,並檢查數據完整性,(insert、delete、update、select)
insert into table1(field1,field2) values(value1,value2);
delete from table1 where 範圍;
update table1 set field1=value1 where 範圍;
select * from table1 where 範圍;
select * from table1 order by field1,field2 [desc];
Select count(1) as totalcount from table1;
Select sum(field1) as sumvalue from table1;
Select avg(field1) as avgvalue from table1;
Select max(field1) as maxvalue from table1;
Select min(field1) as minvalue from table1;
內鏈接相對其餘連接效率高。
Select col1,col2,….from table1,table2 where table1.col3=table2.col2;
外連接分爲左外鏈接和右外鏈接。
左外鏈接:select col1,col2,….from table1 left join table2 on table1.col2=table2.col3;
右外鏈接:select col1,col2,….from table1 right join table2 on table1.col2=table2.col3;
Select * from table1 where col[in][=](select col2 from table2 where 範圍);
mysqldump –u root –p 123123 ultrax > 20141210.sql;
# ultrax 備份的數據庫名,20141210.sql備份的sql文件名
#視圖 存儲過程、函數都要備份
mysql –u root –p 123123 ultrax< 20141210.sql;
#命令不一樣、符號不一樣
MyISAM 【掌握】 |
5.5版本之前默認的存儲引擎。 不支持事務、外鍵;適用於對事務完整性沒有要求、以select、insert爲主的應用。 |
Innodb 【掌握】 |
提供了具備提交、回滾、崩潰修復能力的事務安全。 對此MyISAM寫的處理效率會差一些,而且會佔用更多磁盤空間以保留數據和索引。 在併發條件下要求數據的一致性,數據準確性要求高的。 |
Memory 【瞭解】 |
使用存在內存中的內容來建立表。 每一個memory表只實際對應一個磁盤文件。此類型的表訪問很是快,默認使用了HASH索引。可是一旦服務關閉,表中數據就會丟失。 對錶的大小有限制,數據不能持久。一般用於更新不太頻繁的小表。 |
視圖是一種虛擬存在的表,對於使用視圖的用戶來講基本上是透明的。在數據庫中不佔用存儲空間。
一、 能夠限制用戶數據,聚焦特定數據
二、 能夠簡化查詢操做。
三、 能夠保護基本數據的安全性。
四、 能夠合併分離數據,創建分區視圖。
三種方法
1、Create view person_v as select * from table_name;
2、create view person_v as select id,name,age from table_name;
3、create view person_v[vid,vname,vage] as select * from table_name;
Show create view view_name;
原子性atomic,不能嵌套
一致性consistent
隔離性isolated
持續性druable
begin開始一個事務
Commit提交事務(只有提交以後才生效)
Rollback回滾事務
1. Mysql中只有innodb和dbd支持事務
2. ddl和dcl不能回滾。
3. 隱式提交ddl:create table、create database、lock tables、alter function、start transaction等
存儲過程是事先通過編譯並存儲在數據庫中一段sql語句的集合。
存儲過程當中使用參數的類型:in out inout
delimiter $$
create procedure 存儲過程名(參數列表)
begin
sql代碼塊
end
$$
drop procedure if exists 存儲過程名;
注意事項:
一、 建立存儲過程必需要有參數列表項,若沒有參數使用空參「()」..
二、 刪除存儲過程時存儲過程名後面沒有「()」.
三、 定義變量語句: set @變量名=初始值。
call 存儲過程名([參數]);
取bbs中指定日期的帖子,返回帖子數
存儲過程調用者,在調用存儲過程時傳入的參數。
存儲過程內部給調用者返回的參數。
調用者既能給存儲過程傳入參數,又能從存儲過程獲得返回參數。
IF(exPR1,expr2,expr3) #若是exPR1 爲true,則返回exPR2,不然返回exPR3
WHILE expression DO
Statements
END WHILE;
索引是提升select操做性能的最佳方法。全部列類型均可以使用索引。每一個表至少支持16個索引。
注意:只對select有做用。
索引列:
一、最適合使用索引的列是出如今where子句中的列,或者鏈接子句中指定的列。
二、使用惟一索引。在惟一列上添加索引。
三、使用短索引。
四、不能濫用索引。索引不能添加太多。在修改表數據的索引須要更新,有的時候須要重構,比較耗時。
一、 創建在主鍵上。
二、 常常用在鏈接列上。
三、 常常須要排序的列上。
四、 使用在where子句的列上。
五、 在常常須要條件搜索的列上。
一、 不多使用的列。
二、 有不多不一樣數值的列。
三、 當列的字段類型爲text 、image、bit時,不添加索引。
四、 當修改遠大於檢索時。(涉及到索引更新或重構)。
一、 隱式轉化致使索引失效。
二、 <>、not in、not exists、!=、like 致使索引失效。
三、 對索引列進行運算(+、-、*、\、!=),致使索引失效。
例如:select * from table1 where age+3=10;
四、 不要在sql中使用雙引號。
五、 不要將空值與運算符進行比較。 應使用 is null 、is not null
當給一張表的某列建立主鍵時,就會給該列添加主鍵索引。
Alter table table_name ADD PRIMARY KEY (col_list);
不能使用create index 的方式爲表添加主鍵索引。
索引的列是惟一的並且不能存在null值。
兩種建立方式:
直接建立索引:
Create index index_name ON table_name(col_list);
經過修改表,爲表添加索引:
Alter table table_name ADD index index_name (col_list);
ALTER TABLE article ADD INDEX X(category_id,comments,views);
建立方法:
1.create unique index index_name on table_name(col_list);
2.alter table_name add UNIQUE index_name(col_list);
惟一索引的列的值必須是惟一的,能夠爲空值。
Drop index 索引名 on 表名;
DROP INDEX X ON article;
Show index from 表名;
SHOW INDEX FROM article;
分類 |
特色 |
引擎 |
備註 |
表級鎖 |
開銷小、鎖定力度大 發生衝突機率高,不會出現死鎖。 |
Mysam memory |
|
行級鎖 |
開銷大、鎖定力度小 發生衝突機率高,會出現死鎖。 |
innodb |
常說的 死鎖 |
頁面鎖 |
開銷介於表級鎖和行級鎖之間,會出現死鎖。 |
bdb |
沒人用 |
Show status like ‘table%’;
#table_locks_waited和 table_locks_immediate狀態變量來分析數據庫的所競爭,table_locks_waited越高,所競爭越嚴重。
同一個查詢器session鎖表lock table 表名 write;
另外一個查詢器session就不能使用;
第一個表釋放unlock tables;後,另外一個查詢器可查詢。
Show status like ‘innodb_row_lock%’;
#獲取innodb行鎖爭用狀況;
#重點看innodb_row_lock_current_waits 、innodb_row_lock_time_avg
查詢優化的實際 就是讓優化器能按照預想的合理方式運行。
(根據現象肯定抓取範圍---》定位排查縮小範圍---》對定位出來的sql進行分析,肯定出問題----》給出建議)
每步的作法shell腳本(查看mysql服務器狀態)、慢查詢、
慢查詢(重點)(抓取範圍 和 定位)、explain分析
Mysql的配置文件my.cnf
1.Vi /etc/my.cnf #在最後添加
log-slow-queries=/var/log/mysql/slowquery.log #慢查詢日誌寫哪裏、需提早建好這路徑、文件
long_query_time=2#超時閥值,默認是10 s。單位爲 秒。
2.驗證慢查詢日誌是否開啓
show_variables like ‘%slow%’;
slow_query_log、 log_slow_queries爲on,即爲開啓;
如未開啓,在mysql 命令行中: set global log_slow_queries=ON;
日誌內容
#Time時間戳
Query_time查詢時間
Lock_time鎖定時間
Rows_sent行數
Rows_examined
下面是捕捉出來的語句(正常是select語句,不要加沒加索引的條件,由於log會太大)
mysqldumpslow –s c –t 3 –g 「left join」 /var/log/mysql/slowquery.log #記錄中包含left join的
# -s 表示按照何種方式排序, c (訪問次數)、t(時間)、 l(查詢時間)、 r(返回記錄數);ac 、at 、al 、ar,表示倒序;
# -t 表示取前面多少條記錄
# -g 表示後面能夠寫一個正則匹配模式,不分大小寫
1. Mysqldumpslow –s c –t 20 /var/log/mysql/slowquery.log #訪問次數最多的20個sql
2. Mysqldumpslow –s r –t 20 /var/log/mysql/slowquery.log #返回記錄集最多的20個sql
3. Mysqldumpslow –t 10 –s t –g 「left join」 /var/log/mysql/slowquery.log #按照時間返回前10條裏包含left join的sql語句
4. Mysqldumpslow –s l –t 20 /var/log/mysql/slowquery.log #查詢時間最長的20個sql
1.使用mysqldumpslow過濾查詢日誌,查看sql;
2.若是是模糊的查詢條件,使用具體值替換;
3.用explain來分析sql;
(不必定是具體的sql :between N and N)定位出了問題,接下來用explain來分析
1.只能解釋select操做
2不包括 觸發器、存儲過程的信息;不包括 用戶自定義函數對查詢的影響狀況;
3.不考慮cache;
4.不能顯示mysql在執行查詢時所做的優化工做;
5.部分統計信息是估算的,不是精確值;
寫sql時,where語句後面的mkey(varchar)=111,索引被轉換了,沒用上索引。致使type爲all、row很大;改爲=’111’,type變好了,key用的主鍵索引、row=1;
發現一個慢查詢,查詢時服務器io飆升,io佔用率達到100%,執行時間長達7s。
思路典型:
1.抓到慢查詢,同時監控了服務器 [ io佔用率高 ];
2.explain分析(type all;key null沒用索引、row也很大、extra usingfilesort、using temporary(臨時表),猜想:內存放不下、放在磁盤,和磁盤交互增長,致使了io問題;
3.解決反饋開發、 dba :拆sql;
CREATE TABLE IF NOT EXISTS article (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
author_id int(10) unsigned NOT NULL,
category_id int(10) unsigned NOT NULL,
views int(10) unsigned NOT NULL,
comments int(10) unsigned NOT NULL,
title varbinary(255) NOT NULL,
content text NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO article
(author_id, category_id, views, comments, title, content) VALUES
(1, 1, 1, 1, '1', '1'),
(2, 2, 2, 2, '2', '2'),
(1, 1, 3, 3, '3', '3');
EXPLAIN
SELECT author_id FROM article WHERE category_id = 1 AND comments > 1 ORDER BY views DESC LIMIT 1;
優化:索引---放那些字段上加呢?索引的原則給字段加索引;再繼續explain看狀況。調整索引。再explain,直到調到滿意。
Step 1.
where條件中使用了category_id 、comments 、views三個字段,給三個字段都加上索引;
Step 2.
由於comments檢索用了> <符號,致使了索引無效,去掉此字段上的索引再試試。
Sleep |
一般表明資源未釋放,可能會致使too many connections鏈接 |
|
Waiting for net,reading from net,writing to net |
偶爾出現也無妨,如大量出現,迅速檢查數據庫到前端的網絡鏈接狀態和流量 |
|
Locked |
有更新操做鎖定。一般使用innodb能夠更好的減小locked狀態的產生 |
|
Copy to tmp table |
索引及現有結構沒法涵蓋查詢條件,纔會創建一個臨時表來知足查詢要求,產生巨大的io壓力。很可怕的搜索語句會致使這樣的狀況,若是是數據分析,或週期性的數據清理任務,偶爾出現,可容許。頻繁出現就要優化。一般與連表查詢有關,建議逐漸習慣不使用連表查詢。 |
|
Sending data |
並非發送數據,從物理磁盤獲取數據的進程,若是影響的結果集較多,就要從不一樣磁盤碎片去抽取數據,偶爾出現能夠,若有鏈接較多,就要考慮優化查詢的索引項。 |
|
Freeding items |
理論上不會出現不少,偶爾出現無妨。如大量出現,內存、磁盤可能已經出現問題,如磁盤滿或損壞。 |
|
Sorting for |
同sending data |
slowmysql.sh
1.配置my.cnf 中,最後添加:
[client]
User=root
Password=123123
2.安裝bc,yum install bc
3.chmod 777 –R slowmysql.sh
4.sh slowmysql.sh
執行完成後,會顯示mysql
缺省最大鏈接數是100,調到更高只是爲了出現問題時給咱們更多的緩衝時間而不是任其一直處於那麼高的狀態。
指標:max_connections設置的最大鏈接數;historic max_used_connections以往達到的最大鏈接數
(鏈接數設置多少---參數優化)
緩存sql文本和查詢結果,若是運行相同的sql,服務器就直接從緩存中取到結果,而不須要再去解析和執行sql。將客戶端提交給mysql的select類query請求返回結果集cache到內存中
若是表更改了【表中數據、結構的改變insert、update、delete、truncate、alter table、drop table、drop database】,那使用這個表的緩存的查詢就失效,查詢緩存值的相關條目被清空。
不常改變數據且有大量相同sql查詢的表,設置query cache會節約很大性能。
查詢必須是徹底相同的才能被認爲是相同的。一樣的查詢字符串,因爲其它緣由可能被認爲是不一樣的,使用不一樣的數據庫、不一樣的協議版本、不一樣默認字符集的的查詢被認爲是不一樣的查詢,而分別緩存。【需合理開啓與設置query cache】
1 更改後失效2.要徹底相同
1. 編輯 my.cnf,添加:
query_cache_size=268435456 #設置query cache所使用的內存大小,默認值爲0。大小必須是1024的整數倍。
query_cache_type=1 #給全部查詢作cache
query_cache_limit=1048576 #容許cache單條query結果集的最大容量,默認是1MB,超過此參數設置的query結果集將不會被cache。
2. 重啓mysql
SHOW VARIABLES LIKE '%query_cache%';
query_cache_limit : #容許cache單條query結果集的最大容量
query_cache_size :#query cache所使用的內存大小
query_cache_type :#控制query cache功能的開關,可設置爲0 、1、2;
0(OFF) 關閉query cache,任何狀況都不會使用query cache;
1 (ON) 開啓 query cache,當select語句中使用SQL_NO_CACHE提示後,不使用query chache;
2(DEMAND) 開啓query cache,僅當select語句中使用了SQL_CACHE提示後,才使用query chache。最靈活。
Show status like ‘%qcache%’;
Qcache_free_blocks :數目大說明可能有碎片
Qcache_free_memory:緩存中空閒內存
Qcache_hits:每次查詢在緩存中命中時就增長
Qcache_inserts:每次插入一個查詢就增長
Qcache_lowmem_prunes:緩存出現內存不足且必需要清理以便爲更多查詢提供空間的次數。這個數最好長時間來看;若是這個數字在不斷增加,就表示可能碎片很是嚴重,或者內存不多。(上面的free_blocks和free_memory能夠告訴你屬於哪一種狀況)
Qcache_total_blocks:緩存中塊的總數量
命中率= Qcache_hits/(Qcache_hits+Qcache_inserts)
碎片率=Qcache_free_blocks/Qcache_total_blocks #如超過20%,可用flush query cache整理緩存碎片
利用率=(query_cache_size – Qcache_free_memory)/query_cache_size #低於25%說明query_cache_size設置的過大,可適當減少;高於80%,並且Qcache_lowmem_prunes>50,說明query_cache_size可能有點小,要不就是碎片太多。
Show global status;mysql服務器運行狀態
日誌滿了-磁盤滿-併發上來—磁盤不夠
SHOW VARIABLES LIKE 'log_%'; #是否啓用了日誌
Show master status;日誌狀態
Show master logs;日誌信息
問題:mysql:error 1040:too many connections
解決:訪問量高—增長從服務器;配置中的 最大鏈接數。
查看鏈接數
#容許的最大鏈接數
SHOW VARIABLES LIKE 'max_connections';
#以往達到的最大鏈接數
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
比較理想的設置:Max_used_connections/max_connections*100% 大概85%
鏈接的狀態:show full processlist;
sleep:線程正在等待客戶端發送新的請求.
query:線程正在執行查詢或正將結果發送給客戶端。
locked:線程等待表鎖
analyzing and statistics:線程正在收集存儲引擎的統計信息,並生成查詢的執行計劃。
copying to tmp table [on disk]:線程正在執行查詢,並將結果集都複製到臨時表中,此狀態通常要麼是group by操做,要麼是文件排序操做,或者是union操做。如這個狀態後面還有 on disk標記,那表示mysql正將一個內存臨時表放到磁盤上。
sorting result:線程正對結果集排序。
sending data:線程可能在多個狀態之間傳送數據,或生菜結果集,或在向客戶端返回數據。
Key_buffer_size 是對MyISAM引擎的表影響大的參數。
#查看key_buffer_size參數設置的大小,單位b
SHOW VARIABLES LIKE 'key_buffer_size';
SHOW GLOBAL STATUS LIKE 'key_read%';
#計算索引未命中緩存的機率
Key_cache_miss_rate=key_reads/key_read_requests *100%
Key_cache_miss_rate在0.1%如下都很好,若是key_cache_miss_rate在0.01%如下的話,而key_buffer_size分配過多,能夠適當減小。
#
SHOW VARIABLES LIKE 'table_open_cache';
#
SHOW GLOBAL STATUS LIKE 'open%tables%'
#Open_tables表示打開表的數量;opened_tables打開過的表數量(opened_tables大 說明配置的table_open_cache可能過小)
比較合適的值:Open_tables/Opened_tables*100%>=85%
Open_tables/table_open_cache*100%<=95%()
存儲空間比例的計算,是否是過度使用,是否是不多使用但也佔了很大存儲空間
Show global status like ‘Handler_read_rnd_next’;
SHOW GLOBAL STATUS LIKE 'com_select';
表掃描率:Handler_reader_rnd_next/Com_select’
若是表掃描超過4000,說明進行了太多表掃描,有可能索引沒建好[根本緣由];臨時的解決增長read_buffer_size值(Show variables like ‘read_buffer_size’;)會有效,最好不超過8MB.(能夠容納內容進來,方便提取)
SHOW VARIABLES LIKE'read_rnd_buffer_size';
#進行隨機掃描的時候使用buffer,可是太隨機優化的東西都用不上,性能會不太好,遇到的比較少)read_rnd_buffer_size值適當的調大,對提升order by 操做的性能有必定效果
SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
0 : log thread每隔1秒就會將log buffer中的數據寫入到文件,同時還會通知文件系統進行文件同步flush操做,保證數據確實寫入到磁盤上。比較看重性能,高併發寫的日誌服務器,設爲0.
1: 通常爲1。每次事務結束都會出發log thread將log buffer中的數據寫入文件並通知文件系統同步文件。比較合理,性能稍差。
2 : log thread會在每次事務結束時,將數據寫入事務日誌,但寫入僅僅調用了文件系統的文件寫入操做。文件系統什麼時間將緩存中的這些數據同步到物理磁盤,log thread就不知道了。對數據一致性、完整性要求不高時,設爲2.
#每一個日誌文件大小
SHOW VARIABLES LIKE 'innodb_log_file_size';
一個日誌組中每一個日誌文件的大小。在高寫入負載尤爲是大數據集的狀況下很重要。這個值越大性能相對越高,但反作用是恢復時間加大,掃描恢復時間長。【可恢復的多,因此用時長】
通常64M—512M,具體取決於服務器的空間。
SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'interactive_timeout';
# wait_timeout 取值範圍1-2147483(windows),1-31536000(linux);
#interactive_timeout取值隨wait_timeout變更;
#默認都是28800s(8小時)、
#兩個參數要一樣的值、同時設置,timeout纔會生效。
原理
主數據庫負責寫(一個主庫集中寫,保證了數據一致)、從庫讀(從庫橫向擴展,分流了壓力)
實現
1.master打開二進制日誌,將改變 記錄到 二進制日誌
2.slave將master的二進制日誌拷貝到它的中繼日誌(relay log)。(slave開始一個工做線程—io線程,io線程在master上打開一個普通的鏈接,而後開始binlog dump process。從master的二進制日誌中讀取事件,如已經跟上master,會睡眠並等待maste產生新時間,io線程將這些事件寫入中繼日誌)
3.slave重作中繼日誌中的事件。(sql線程從中繼日誌讀取事件,並重放其中的事件而更新slave數據,和master中數據一致。只要該進程與io線程保持一致,中繼日誌一般位於os緩存中,因此中繼日誌開銷小)
(創建在主從複製上。也是主從複製的目的)
(後面會講、負載均衡 策略)
Session、mysql(query_cache 、命中率)表空間、日誌
Top_session:當前正在運行的sql、
柱狀圖 summary—sql、邏輯io、物理io
數據庫選型(mysql數據庫、服務器os):sql(抓取定位分析)、架構(主從、分庫分表)、參數(鏈接數、表掃描、超時、打開表數)
原則:never make a change in production first
Have a good benchmark or reable load
Start with a good baseline
Only change 1thing at a time
Identify a set of possible changes
Try each change separately
Try in combinations of 2 then 3 ,etc
Monitor the results
Query performance –query analyzer,slow query log,etc.
Throughput
Single query time
Average query time
Cpu
Io
Network
Document and save the results