【Mysql培訓】Mysql數據庫高級管理與性能優化實戰---待從新編輯

基於Mysql 5.7

10.30:環境配置,介紹,特性,事務,重點是事務中的隔離性,鎖,索’引html

10.31:創建 索引、還原備份,mysql

內容安排:

  Mysql背景案例分析sql

  Mysql介紹數據庫

  Mysql特性緩存

  Mysql性能調優安全

  Mysql運行監控服務器

  Mysql備份與恢復併發

  Mysql主從複製與讀寫分離函數

  Mysql分庫分表之MyCAT高併發

Mysql背景案例分析

  數據庫在大促高併發場景下的做用

  大促高併發場景下數據庫面臨哪些考驗?

  數據庫優化方向?

    1.去IOE

    2.28原則,8讀,2寫。2讀有效數據,8讀無效數據。

Mysql介紹

  關係型數據庫,其餘關係型數據庫Oracle,sqlServer,非關係型Redis,一些國產數據庫,如達夢等。半結構化數據庫。MariaDB?

  在數據庫中,每一個數據庫有三個文件:一個樣式(描述文件)、一個數據文件、一個索引文件。樣式文件以.fmr爲後綴,描述表的結構(列、列類型、索引等)。.ISD(ISAM)或.MYD(MyISAM),包含數據文件上的全部索引的索引樹。.ISM(ISAM)或.MYI(MyIsam)該文件依賴於表是否有索引而存在。

  show warnings;

存儲引擎

  存儲引擎就是如何存儲數據、如何爲存儲的數據創建索引和如何更新、查詢數據等技術的實現方法。有Myiasm,InnoDB,Merge等,Mysql8去除了Myisam引擎,主要保留了InnoDB。

  MyIsam:默認引擎(5.1以前),表級鎖定,適用於大量的讀操做的表、文件存儲結構,串行的讀寫方式。

  InnoDB:默認行級鎖,也支持表級鎖,支持外鍵、事務處理,適用於大量的寫操做的表,並行的讀寫方式。

  經過如下代碼能夠看到數據庫的引擎:

show variables like '%engine%';

  上面是經過Navicat For Mysql的方式輸入命令,也可經過C:\Program Files\MySQL\MySQL Server 5.7\bin>mysql -u root -p 便可進入命令行的形式。

  

事務

  經過begin開啓事務,commit或者rollback結束事務。

BEGIN;//開啓事務
insert into classtypes VALUES('t4','學英語');
COMMIT;//提交事務

  Mysql可經過 set autocommit=1; 修改是否自動提交,1表示自動提交,0表示不自動提交。Mysql的AutoCommit(自動提交)默認是開啓,因此不開啓事務的狀況下,會自動提交sql。自動提交對Mysql的性能有必定影響,舉個例子來講,若是你插入了1000條數據,Mysql會commit1000次的,若是咱們把AutoCommit關閉掉,經過程序來控制,只要一次commit就能夠了。

   ACID  http://www.javashuo.com/article/p-fneajkwc-md.html    

  查看事務隔離級別。

  show VARIABLES like '%iso%';

   

  若A表開啓事務,B開啓事務,A中插入數據,AB均不能查到數據。A提交事務,A能查到數據,B不能查到數據(Oracle此時能查到數據(默認讀已提交),這是事務的I屬性,隔離性,讀未提交、讀已提交可讀取到,可重複讀,串行化不可讀到),B關閉事務,能查到數據。

 修改事務隔離級別。

set TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

 修改爲功。

   在Navicat裏經過set修改數據庫隔離級別後, show VARIABLES like '%iso%'; 仍是之前的隔離級別,需重啓Mysql服務。

鎖機制

  MyISAM,表級鎖,對整個表文件進行鎖定。開銷小,加鎖快,不會出現死鎖。

  InnoDB,默認行級鎖,也支持表級鎖,對錶文件中局部數據進行鎖定,開銷大,加鎖慢,會出現死鎖。哪一種狀況會出現死鎖?

  查看錶結構。

show CREATE TABLE classtypes;

表的結構數據以下:

    MDL=meta data lock,元數據鎖,在事務開啓期間,不能更改數據庫結構,發生阻塞。如alert TABLE classtypes add num TINYINT(1); http://blog.itpub.net/29896444/viewspace-2101567/

  咱們修改同一行數據classtype='t1',發生阻塞,提示錯誤。

 

而後咱們修改classname,仍是出錯,把這兩行都鎖住了,這是由於classname不是索引。

 

   間隙鎖。

   sql+ lock in SHARE mode

字段類型

  數值:tinyint,smallint,mediumint,int(默認長度11),bigint,decimal

  字符:varchar,char,text,blog

  時間:datetime,8位,1000-01-01 00:00:00 ——9999-12-31-23:59:59

     timestamp,4位,1970-01-01 00:00:01——2038

       date,3位,1000-01-01——9999-12-31

  一個表的字段有id,age,長度都是int(5),那麼age最大長度是多少?

  若是,插入如下數據,9999超過了2^6-1,會不會出錯。最大值int*5???

  枚舉:enum,只能選擇其一,如性別,一個enum字段有'M','F'兩個,那麼只能插入這兩個中的其中一個。

索引

  目的:加快檢索查詢。

  分類:普通索引,惟一索引,主鍵索引,全文索引等。惟一索引能夠爲NULL,主鍵索引不能爲NULL。建索引條件=區分度高,是查詢條件

  先提出幾個問題,爲何要加主鍵,加索引爲何會變快,爲何要給兩個字段都加索引,爲何加了索引刪除修改操做變慢?

  平時建表都會給表加一個主鍵,這個主鍵有什麼用呢?事實上, 一個加了主鍵的表,並不能被稱之爲表。一個沒加主鍵的表,它的數據無序的放置在磁盤存儲器上,一行一行的排列的很整齊, 跟咱們認知中的數據很接近。若是給表上了主鍵,那麼表在磁盤上的存儲結構就由【整齊排列的結構】轉變成了【樹狀結構】,也就是上面說的【平衡樹結構】,換句話說,就是整個表就變成了一個索引。也就是所謂的「彙集索引」。 這就是爲何一個表只能有一個主鍵, 一個表只能有一個「彙集索引」,由於主鍵的做用就是把表的數據格式轉換成【索引】的格式放置。

 其中樹的全部結點(底部除外)的數據都是由主鍵字段中的數據構成,也就是一般咱們指定主鍵的id字段。最下面部分是真正表中的數據。 假如咱們執行一個SQL語句:

  select * from table where id = 1256;

首先根據索引定位到1256這個值所在的葉結點,而後再經過葉結點取到id等於1256的數據行。 這裏不講解平衡樹的運行細節(節點處採用二分法), 可是從上圖能看出,樹一共有三層, 從根節點至葉節點只須要通過三次查找就能獲得結果。以下圖:

假如一張表有一億條數據 ,須要查找其中某一條數據,按照常規邏輯, 一條一條的去匹配的話, 最壞的狀況下須要匹配一億次才能獲得結果,用大O標記法就是O(n)最壞時間複雜度,這是沒法接受的,並且這一億條數據顯然不能一次性讀入內存供程序使用, 所以, 這一億次匹配在不經緩存優化的狀況下就是一億次IO開銷,以如今磁盤的IO能力和CPU的運算能力, 有可能須要幾個月才能得出結果 。若是把這張錶轉換成平衡樹結構(一棵很是茂盛和節點很是多的樹),假設這棵樹有10層,那麼只須要10次IO開銷就能查找到所須要的數據, 速度以指數級別提高,用大O標記法就是O(log n),n是記錄總樹,底數是樹的分叉數,結果就是樹的層次數。換言之,查找次數是以樹的分叉數爲底,記錄總數的對數,用公式來表示就是

用程序來表示就是Math.Log(100000000,10),100000000是記錄數,10是樹的分叉數(真實環境下分叉數遠不止10), 結果就是查找次數,這裏的結果從億降到了個位數。所以,利用索引會使數據庫查詢有驚人的性能提高。

然而, 事物都是有兩面的, 索引能讓數據庫查詢數據的速度上升, 而使寫入數據的速度降低,緣由很簡單的, 由於平衡樹這個結構必須一直維持在一個正確的狀態, 增刪改數據都會改變平衡樹各節點中的索引數據內容,破壞樹結構, 所以,在每次數據改變時, DBMS必須去從新梳理樹(索引)的結構以確保它的正確,這會帶來不小的性能開銷,也就是爲何索引會給查詢之外的操做帶來反作用的緣由。

  

  創建索引:CREATE INDEX id on vote_records(id);    \G 縱向排列。

  查看索引:

  %,左邊索引不生效,右邊生效。檢索數據超過30%不走索引。

 

 

 解決辦法,reverse,覆蓋索引(不須要回查,即經過查到的key再次查詢獲得數據)

複合索引,如一個索引爲 A,B,那麼 where A 會走索引, where A,B走索引, where B不走索引

  

lock鎖表:

 

 插入數據會被阻塞:

 

 執行UNLOCK TABLES;後解鎖,插入成功:

 查看日誌是否開啓:

mysql> show variables like 'log_%';
OFF是關閉,ON是開啓。在C:\ProgramData\MySQL\MySQL Server 5.7下的my.ini中設置。

 

 重啓服務後,能夠看到log-bin成功開啓了:

secure_file_priv:

 

 

 select * into outfile 'E:/test.sql' fields terminated by ',';

     CRUD truncate和delete的區別。

  有一個表user(id,age),有三條數據(id=1,age=18),(id=1,age=18),(id=1,age=18),執行delete from user後可rollback,插入第四條,id=4

  執行truncate,不可rollback,插入第四條,id=1

  show processlist;

  C:\ProgramData\MySQL\MySQL Server 5.7\Data下的ib_logfile0是全do日誌,包括select.宕機用這個。主從用mysql-bin-00262日誌。

show VARIABLES like '%innodb_flush_log%';

   

 

 

  爲何只讀模式,5.7比5.6快3倍?怎麼優化的?

 

  集羣(Cluster):

    多個mysql服務器,減輕數據庫負擔。主從分離,讀寫分離。master用來寫,slave用來讀

查詢是否開啓告訴查詢緩存,

 

  tuning-primer.sh

經常使用函數

預防死鎖:

開發規範:

優化:

開發同窗和DBA都須要瞭解業務狀況:

  區分SQL的執行環境,是前臺仍是後臺?

  評估SQL的執行頻率,天天千萬次查詢和前次查詢是不同的。

  評估SQL返回的數據量,關心每條數據仍是隻關心前100條?關心全部字段,仍是真正對用戶有意義的字段?

  評估表的數據量和增量,從而評估SQL的執行效率。

開發同窗寫SQL時要注意:

  儘可能避免查詢的結果超過正常的需求,不多有人關心10W頁後的數據。

  儘可能減小表之間的關聯,多表之間的關聯要使用表的別名來引用表的字段。

  不要使用select * ,具體到字段。

  儘可能減小使用distinct,like,group by,oder by等。

  儘可能減小子查詢,也不要寫成inner join格式。

  必定要使用綁定變量。

狀態查看:

 show global status like '%variables%';

  

 show full processlist;

 

show engine innodb mutex;

 

show engine innodb status;

 

show profile;

 

 

show warnings;

 mysql show query;

 查看profile是否開啓:

select @@have_profiling;

show status like '%perf%';

show engine performance_schema status;

 

 

 select THREAD_ID,NAME,TYPE,INSTRUMENTD from threads;

查詢讀寫top5的等待:

select EVENT_NAME,COUNT_READ 'read',COUNT_WRITE 'write',COUNT_MISC 'misc',(COUNT_MISC+COUNT_WRITE+COUNT_READ) as SUM_IO from file_summary_by_event_name order by 5desc limit 5;

查詢讀寫top5的file

統計在表上鎖的top5

統計發生table lock消耗時間最高的表

 

Mysql特性

  開源、免費、跨平臺、安全性、成本低、支持各類開發語言、支持強大的內置函數、數據存儲量大?

Mysql性能調優

分區:把一個表的數據分紅N多個區塊,分區後仍是一張表,須要一個分區鍵,不是分區鍵會掃描全部分區

  做用:提高數據庫的訪問性能

  適用:平時訪問量不是特別大,表結構變動也很少,並且歷史數據訪問量低下,可能會作成分區表,這樣平時基本上只要訪問最近的分區段,還有利於老數據的清理。

分區類型
range分區:基於一個給定的連續區間範圍(區間要求連續而且不能重疊),把數據分配到不一樣的分區
list分區:相似於range分區,區別在於list分區是居於枚舉出的值列表分區,range是基於給定的連續區間範圍分區
hash分區:基於給定的分區個數,把數據分配到不一樣的分區
key分區:相似於hash分區
注意:不管哪一種分區,要麼你分區表上沒有主鍵/惟一鍵,要麼分區表的主鍵/惟一鍵都必須包含分區鍵,也就是說不能使用主鍵/惟一鍵字段以外的其它字段分區。

建立表時建立分區:

-- 建立分區表
CREATE TABLE `tbl_user_part` (
   `id` int(11) NOT NULL , `username` varchar(255) DEFAULT NULL, `email` varchar(20) DEFAULT NULL, `age` tinyint(4) DEFAULT NULL, `type` int(11) DEFAULT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP -- PRIMARY KEY (`id`,`age`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 PARTITION BY RANGE (age) ( PARTITION p0 VALUES LESS THAN (20), PARTITION p1 VALUES LESS THAN (40), PARTITION p2 VALUES LESS THAN (60), PARTITION p3 VALUES LESS THAN (80), PARTITION p4 VALUES LESS THAN MAXVALUE );

表結構:

建立表後建立分區:

 

 

 

 

http://www.javashuo.com/article/p-twvhojqy-bb.html

分表:把一張表分紅多個表。

  做用:提高數據庫的訪問性能。

  適用:數據量很是大,並且訪問上沒有絕對的熱點,基本上全部數據都會被訪問到。

分庫:把一個數據庫分紅多個數據庫

  做用:提高數據庫的訪問性能。

Mysql運行監控

Mysql備份與恢復

備份1

  Mysql導入、導出。導出 mysqldump,

 mysqldump -uroot -p examol vote_records>D:/vote_records.sql  必定不能加分號!!!要在bin下面執行, 不是Mysql裏!!!

  導入 source,先  use database; 選擇導入的數據庫,

  source D:/Program Files/feiq/Recv Files/vote_records/vote_records.sql;  導入數據。

 

還原:

 

 http://www.javashuo.com/article/p-sgfzhhhh-bg.html

 

 

Mysql主從複製與讀寫分離

要求:

1.主庫、版本一致

 2.主庫中的日誌備份,從庫日誌還原增量

 3.主庫產生增量日誌,從庫同步增量日誌

步驟:

 1.p34=

 Mysql分庫分表之MyCAT

相關文章
相關標籤/搜索