mysql學習筆記

  

第一章 mysql架構與歷史java

mysql 存儲引擎架構 (程序處理和存儲分離)mysql

     程序處理:linux

           1.query processing 查詢處理ios

            2. server task 服務處理nginx

      存儲 :web

          1.數據存儲redis

          2.數據提取算法

    

第一層 客戶端 :認證-->受權-->鏈接-->每一個鏈接開單個線程sql

 

workbench 數據庫

https://www.mysql.com/products/workbench/

 

navicat 

https://www.navicat.com/en/products/navicat-for-mysql

 

 

第二層

           1.查詢,優化,分析,緩存 :解析樹-->優化-->重寫Sql,表讀取順序,選擇索引(hint 影響優化,explain 查看執行效率)

           2. 內置函數 

           3.其餘擴存儲引擎的功能 :存儲過程,觸發器,視圖

第三層 

       存儲引擎 :數據的存儲和提取-->存儲引擎提供的API 

 

併發控制              

  鎖

       1.共享鎖(讀鎖)

        2.排它鎖(寫鎖) 

鎖粒度

    1.table lock 表級鎖

    2.row lock 行級鎖

事務

ACID 

    atom 原子性

    consistency 一致性

   isolation  隔離性

  durability 持久性

隔離級別

 read_uncommited 讀未提交 髒讀

read_comminted 讀已提交

repeatable read 可重複讀  :會產生幻讀,innoDb 經過MVCC解決幻讀

serializable 可串行化

 死鎖

1.兩個或兩個以上事務請求同一資源,並請求鎖定對方資源,致使惡性循環現象

  好比 A,B兩個事務 ,A須要B的資源 B須要A的資源  ,A等待B釋放鎖,B等待A釋放鎖 。無線等待

解決死鎖: 檢查死鎖循環依賴 拋錯

                  等待超時 放棄鎖請求

                 事務中 持有最小行級排它鎖 的事務進行回滾(找一個鎖最少的 回滾)

事務日誌

   1.預寫入式

mysql 事務 默認自動提交

事務是存儲引擎實現的 

InnoDB 會根據隔離級別 自動加鎖

鎖 只在 commit 和 rollback的時候釋放

多版本併發控制

不加鎖 ,作相似數據庫中的標識字段處理(系統版本號)

mvcc -->行級鎖的變種-->避免加鎖處理 -->快照-->隱藏記錄,保存行數據版本號 

mvcc  在 repeatable read 和  read  commited隔離級別下使用

 MySql存儲引擎

查看錶的存儲引擎

show table status like 'user'

InnoDB是mysql默認的事務存儲引擎 

InnoDB  默認repeatable read 隔離級別,經過next-key locking(間隙鎖) 策略,防止幻讀

間隙鎖:對索引中的間隙進行鎖定,防止幻影行的插入 

InnoDB基於聚簇索引創建的,一個表只能有一個聚簇索引(聚簇索引的 葉節點 就是數據存儲的節點),非主鍵索引必須包含主鍵列

myISAM存儲引擎

nyISAM 不支持事務和行級鎖  崩潰沒法恢復,表級鎖 支持全文索引,使用 myisampack壓縮表 (pack 打包) 壓縮的表示不容許修改的 除非解壓   

myISAM設計簡單  數據以緊密格式存儲 某些場景下性能會很好

其餘存儲引擎:Archive  只支持 insert  select 操做 適合日誌 和統計 

                         CSV 存儲引擎

存儲引擎選擇

   1.訂單處理 支持事務的引擎必選

   

轉換表的存儲引擎 :

alter table user ENGINE=INNODB

  

 第二章 mysql 基準測試

 1.爲何要進行基準測試 (硬件測試和軟件測試)

   --軟件:

     驗證系統假設

    重現系統異常

    測試當前運行狀況

    模擬比當前系統更高負載

    規劃將來業務增加

 --硬件

    測試適應可變環境的能力

    測試不一樣的硬件、軟件和操做系統配置

     證實新採購設配 配置是否正確

 

基準測試策略

   ·1.full-stack : 集成式  測試整系統

    2.single-component : 單組件式  單獨測試MySQL

測試指標

   1.吞吐量

    2.響應時間或延遲

    3.併發性

    4.可擴展性

 基準測試方法

 繪圖

集成測試工具

單組件測試工具

mysql基準測試套件 

第三章 服務性能剖析

  1. 經過性能剖析 進行優化

    值得優化的查詢

   異常狀況(執行頻率低)

   未知

 mysql企業監控查詢分析功能

   mysql企業監控器

剖析mysql查詢

剖析服務器負載

捕獲查詢日誌

分析查詢日誌

 

查看查詢響應時間  

show profiles

查看單個查詢 各步驟響應詳情

show profile for query 4

 

預估風險

show status;
show global status;

  

 

 

 查看線程鏈接

show processlist;

 

 性能降低 可能緣由

   1.資源過分使用

   2.資源沒有正確配置

   2.資源已損壞或失靈 

第四章 schema與數據類型優化 

 字段數據類型選擇

  1.最小的數據類型更好

  2.簡單最好 :簡單數據類型 一般佔用cpu比較小, 整數類型比字符串操做代價低,好比:用MySQL自帶日期格式存儲,而不是字符串存儲日期 

  3.避免null

 

整數類型

   tinyint  8位

  smallint 16位

  mediumint 24 位

  int 32位

 bigint 64位

 

實數類型 (帶小數)

 float

double

decimal

字符串類型

 varchar 可變長度

char  定長

varchar(5) 和varchar(200)  存儲 'hello'空間開銷是同樣的 小的列 主要消耗的處理內存少

 

blob 和text

Blob 二進制存儲

tinyblob smallblob blob mediumblob longblob

text 字符存儲(有字符集和排序規則)

tinytext smalltext text mediumtext longtext

 

mysql 會把 blob 和text當作獨立對象 單獨處理

當blob和text值太大時 ,innoDB會用外部的存儲區域來存儲值 並創建指針(1-4字節) 指向實際值

blob和text所有長度字符 不能索引

 

enum 枚舉類型

枚舉類型有必定的開銷  枚舉類型 和 varchar或char 鏈接查詢可能會慢

 

日期和時間類型

DateTime  不分時區

範圍 1001 - 9999 精度爲秒,它把日期和時間 分裝成YYMMDDHHMMSS 格式的整數中 ,8字節存儲空間

TimeStamp 有時區差別

保存了  1970.01.01 午夜以來的秒數 和Unix時間戳相同 只能表示到 2038年  4個字節存儲空間

mysql  提供 from_unixtime() 將unix時間轉化成日期 

                   unix_time()將日期轉化成unix時間戳

 

若是要存儲更小級別的時間格式 怎麼辦

使用 bigint 存儲微妙級別的時間戳或者使用 double秒以後 用小數存儲

位數據類型


bit

5.0以前 和 tinyint同義  以後版本有變化

set 

若要保存不少列 能夠將其和併到一個set 數據類型 函數支持:find_in_set() ,field()

缺點 :改變列的定 使用 alter 代價大 ,不能使用索引

整數列上按位操做

 

選擇表示符

標識列 identifier column

通常 整數類型  而後 自增 auto_increment

字符串作標識列 消耗性能

特殊類型數據

 ip 實際是無符號整數  ,小數點 分紅4段只是爲了更好閱讀 

MySQL提供  函數轉換 : inet_aton 和 inet_ntoa

-- address to number
SELECT INET_ATON('192.168.1.1');

 

-- number to address
SELECT INET_NTOA(3232235777);

Mysql schema 設計陷阱 

1.應避免太多列

2.應避免太多關聯

3.避免過分使用枚舉類型

4.避免使用null

 

範式和反範式

 

範式的優缺點

優勢

      1.範式的更新操做一般比反範式快

      2.減小數據重複

      3.範式話的表一般最小 操做快

      4.減小使用 distinct

缺點

    1.範式一般須要關聯 

    2.範式可能須要拆成多個表

    3.多是單表索引策略無效

 

反範式優缺點

 

優勢

    1.表關聯較少

    2.單表索引策略有效使用

 

混用範式和反範式

 

彙總表和緩存表

 

加快Alter table的速度

 

1.影子copy : 不提供服務的數據庫上進行 alter操做 ,切換數據庫

有些工具能夠幫助咱們完成影子 copy:https://launchpad.net/mysqlatfacebook

2.修改字段的默認值 有較快的方法 :修改 .frm文件

語句爲  alter column

(用 modify column效率很低 會進行重建表)

 

只修改 .frm文件

 ps:mysql建立表對應目錄會建立 .frm文件,用來保存數據表的元信息 數據結構定義等,和存儲引擎無關 數據表必有 命名 tableName.frm 如:user.frm

有肯能不須要重建表的操做

1.刪除 auto_increment

2.增長、移除或更改 emum ,set 常量值

實現方法 :

 1.建立相同結構空表,修改上述常量

  2.鎖表 :flush tables with read lock

  3.交換 .frm文件

  3.釋放鎖:unlock tables

 

高效的載入數據 能夠先禁用索引 載入完成 在開啓索引

 

第五章 建立高性能索引

 

簡單理解索引 :索引到對應值-->找到對應行

 

索引類型  

 

索引在存儲引擎層實現 沒有統一標準

B-tree索引 全部的值都是按順序存儲

 

 

 B-tree索引加快訪問速度

 緣由:不須要全表掃描-->索引根節點 指針 指向-->下一節點-->節點中的值和要查詢的值比較-->找到合適的節點進入下層

  key1<=值<key2

 葉子節點指向被索引數據

B-tree索引限制:不是按照索引最左端查找  不能使用索引  

 

哈希索引

索引列計算哈希碼 

Memery引擎支持 哈希索引

哈希索引沒法進行排序

不支持部分索引列 索引 如 (A,B)列 創建哈希索引 ,查詢 只使用A列 沒法使用索引

哈希索引只支持等值比較  不支持 範圍查詢 意思是 where price>100用不到索引

有哈希衝突時 訪問哈希索引速度會變慢

哈希衝突較多 維護哈希索引代價較高

 

InnoDB有自適應哈希:當某些索引值使用頻繁 InnoDB會在內存中基於B-tree索引建立一個哈希索引

僞哈希索引 例子

數據庫中有 url字段  該字段B-tree索引性能較低 

能夠去除 url 現有索引  新加一列url_crc  其值爲 url對應的 哈希值  CRC32('url-value');

用該列進行數據索引  查詢性能提升 

select * from clicks where url_crc=crc32('http://yahoo.com');

 --缺陷  url_crc列須要維護

全文索引

 全文索引  查找文本中的關鍵詞 

 

索引的優勢

三大優勢:

              1.減小數據掃描數據量

               2.索引避免排序和臨時表

               3.索引能夠將隨機I/O變爲順序I/O

高性能的索引策略

 1.獨立的列

 2.前綴索引和 索引選擇性

       索引選擇性:不重複的索引值 也叫基數   索引選擇性越高 查詢效率越高

  3.多列索引

  4.選擇合適的索引列順序        

  5.聚簇索引  是一種存儲方式

        葉子頁存放 數據行

        

 

 

      聚簇索引優勢:

            1.相關數據放在一塊兒

             2.  訪問速度快

             3.覆蓋索引的掃描 能夠直接使用葉子節點中的主鍵

      缺點:

             1.插入速度嚴重依賴插入順序

              2.聚簇索引更新代價高

              3.插入新行或者更新主鍵 肯能致使頁分裂     

              4.可能致使全表掃描變慢

               5.二級索引肯能更大  二級索引包含主鍵列

               6.二級索引查找須要兩次索引

 

  

 

 innoDB按組件順序插入行

 

uuID 主鍵插入 消耗內存  且索引佔用空間大

 

順序主鍵 併發插入可能致使間隙鎖競爭 

 

使用索引掃描來排序

 

explain 的type  爲 index 說明使用索引掃描來排序 

 

前綴壓縮索引

 

myISAM 壓縮索引塊的方法 

            1.保留索引塊的第一個值

            2.其餘值和第一值進行比較

            如:第一值 ‘perform’ 第二值 ‘performance’ ,前綴壓縮 :'7,ance'

 

冗餘和重複索引

重複索引 :相同列按相同順序建立 同種類型的索引

能夠查詢 infomation_schema  來查看重複索引

也能夠 使用第三方工具 common_schema 來定位  

common_schema 安裝到服務器上 視圖來定位

https://code.google.com/archive/p/common-schema/

它比本身查詢快

select * from information_schema.statistics where  
TABLE_SCHEMA not in ('mysql','performance_schema','information_schema','common_schema') and table_schema='sunny' and table_name='user';

  

未使用的索引

 

 

 索引和鎖

 

索引可使查詢鎖定更少的行 

 InnoDB只有訪問行的時候纔會加鎖,索引能給減小InnoDB訪問的行數。

 

範圍要放在索引的最後

MySQL使用某個索引進行範圍查詢 就沒法在使用另外一個索引 進行排序了。

 

支持多種過濾條件

 

設計索引時不要只爲現有的查詢考慮索引,還要考慮對查詢進行優化

如咱們在country和sex上建立索引 。sex列的選擇性顯然很低 ,能夠咱們在 查詢條件中添加  sex in('m','f','o') 來讓 查詢使用該索引 

這樣作 既不會減小過濾行,也不影響返回結果 可是提升了查詢速度。

可是若是 sex有太多的值 in()列表太長 這樣作就不行了  

 

避免多個範圍條件

 

修復損壞表

檢查表是否損壞

check table user

修復表

repair table user

不是全部的引擎都支持 repair 

InnoDB就不支持 可使用第三方工具

https://launchpad.net/percona-data-recovery-tool-for-innodb  

 

查看索引基數 

show index from user

 

 

cardinality:基數

    索引列的基數 :存儲引擎估算索引列有多少不一樣取值

 

減小索引和數據碎片

 

B-tree索引可能會碎片化 索引會無序 下降查詢效率

碎片化類型:

     1. 行碎片化

           數據行被存儲爲多個多個地方的片斷

     2.行間碎片

     3.剩餘空間碎片

        數據頁中大量的剩餘空間,致使服務器讀取大量不須要的數據

使用 optimize命令優化

optimaize table user

InnoDB不支持 該命令

使用 alter命令重建表  將表存儲引擎改成當前存儲引擎

alter table user ENGINE=INNODB

  

第六章 查詢性能優化

 

1.查詢所需的列或行 不要所有返回

2.去除不須要的關聯

3.切分查詢

4.避免查詢剛更新的數據

5.where 中進行運算  取值和運算髮生在同一階段 效率高

 

mysql的查詢優化處理

 

查詢優化器

       1.重定義表的關聯順序

       2.將外鏈接轉化成內鏈接

       3.使用等價變化規則

       4.優化count() ,min(),max()

       5.預估並轉化爲常數表達式

       6.覆蓋索引掃描

       7.子查詢優化

       8.提早終止查詢

       9.等值傳播

       10.列表 in()的比較

 

 第七章 MySQL高級特性

 

分區表

 分區表 是個獨立的邏輯表,但底層由多個物理表組成。

經過對底層表句柄對象的封裝 實現分區

請求分區表-->句柄對象-->調用存儲引擎的接口

mysql實現分區表的方式-->對底層表封裝-->索引按照分區表的子表定義 沒有全局索引

使用 partition by 定義分區存放的數據

allert table exchange partition

分區表將相關數據放在一塊兒   

1.分區表的做用

  1. 表很是大以致於沒法所有放在內存
  2. 分區表的數據更容易維護
  3. 分區表的數據能夠分佈在不一樣的物理設備上
  4. 用分區表來避免特殊瓶頸 
  5. 分區能夠獨立備份和恢復

 

2. 分區表的限制

 

  1. 一個表最多有1024個分區
  2. 分區表達式必須是整數
  3. 若是分區字段中有主鍵或者惟一索引,主鍵列和惟一索引必須包含進來
  4. 分區表沒法使用外鍵約束

 

3.分區表的原理

 

分區表由多個相關底層表實現,底層表由句柄對象表示。

分區表操做邏輯:

select查詢

        分區層 -->打開並鎖住全部  底層表-->優化器 過濾部分分區-->調用存儲引擎接口 訪問各分區

insert操做

       分區層-->打開並鎖住全部 底層表-->肯定接收數據分區-->向底層表寫入數據

delete操做

     分區層-->打開並鎖住全部表-->肯定分區-->刪除底層表數據

update操做

    分區層-->打開並鎖住全部表-->肯定分區-->取出數據並更新-->肯定updated數據存放分區-->底層表寫入-->刪除原數據

 

4.分區表的類型

  1. 根據範圍進行分區
  2. 根據鍵值進行分區
  3. 使用數學模函數進行分區

 

5.使用分區

 

要保證大數據量的可擴展性 通常有下面兩個策略

  1. 全量掃描數據 不須要任何索引
  2. 索引數據並分離熱點

 

6.可能會遇到的問題

 

  1. null值會使分區過濾無效
  2. 分區列和索引列不匹配 (沒法進行分區過濾)
  3. 選擇分區的成本可能很高
  4. 打開並鎖住全部底層表成本很高
  5. 維護分區的成本很高

 

7.查詢優化

 

分區最大的優勢 :優化器能夠根據分區函數過濾一些分區 

where 條件中帶入分區列 

 

視圖

視圖是個虛擬表 不存聽任何數據 

不能對視圖建立觸發器,不能用 drop table 刪除視圖

 

1.可更新視圖

   updatable view 經過視圖來更新視圖涉及的相關表,刪除甚至向視圖寫入數據

 

  限制條件

  1.   若是視圖中包含 group by , union ,聚合函數 等其餘特殊狀況 就不能更新了  
  2.   更新中有多表關聯語句  更新列 必須在同一個視圖中
  3.   臨時表算法實現的視圖沒法被更新

 

 2.視圖對性能的yingx

3.視圖的限制

   mysql不會保存 視圖定義的原始sql語句

   只能從 .frm文件中獲取

 

外鍵約束

 

innoDB 是 mysql中惟一支持外鍵的存儲引擎,使用外鍵有成本 修改主表示 相應關聯表 要作查詢操做

 

 

mysql內部存儲代碼

  1.  觸發器
  2. 存儲過程
  3. 函數

優勢:

  1. 服務內部執行,節省帶寬和網絡延遲
  2. 代碼重用,簡化應用代碼維護
  3. 提高安全
  4. 服務器端能夠緩存 執行計劃 若反覆調用下降消耗
  5. 應用開發和數據庫開發分工

 

缺點:

  1. mysql未提供好用的開發和測試工具
  2. 存儲代碼使用的函數有限
  3. 存儲代碼可能會帶來部署的複雜性
  4. 給數據服務器帶來太大壓力
  5. 一個存儲過程錯誤 全部應用都沒法訪問
  6. 日誌不怎麼好用

 

1.存儲過程和函數

 

2.觸發器

定義觸發器 注意點

  1. 每一個表每一事件 最多定義一個觸發器
  2. mysql只支持行的觸發

劣勢

  1.  觸發器 掩蓋服務器背後的工做 ,可能不少看不見的工做被觸發器執行
  2.  觸發器問題很難排查
  3. 觸發器可能致使死鎖和等待

3.事件

  

4.在存儲過程當中保存日誌

5.遊標

 MySQL在服務器端提供單向 只讀遊標

6.綁定變量

7.綁定變量優化

 每次執行時服務器 優化策略:

  1. 過濾分區
  2. 儘可能移除 count() ,min().max()
  3. 移除常數表達式
  4. 檢測常量表
  5. 作必要的等值傳播
  6. 分析和優化 ref ,range 索引優化訪問數據
  7. 優化管理順序

8.插件

 存儲過程插件,後臺插件,全文解析插件 ,審計插件,認證插件

9.字符集

 二進制編碼到某類字符的映射

使用 collate 來指定字符串的字符集

select _utf8 'hello' collate utf8_bin;

  

解決字符集問題 

1.alter table將對應列轉成兼容的字符集

2.還可使用編碼前綴和 collate子句將列轉換成兼容的編碼

 字符集校對規則消耗內存

10.全文索引

  全文索引支持各類字符內容的搜索,也支持天然語言的搜索 

  myISAM全文索引也是一種特殊的B-tree索引 分爲兩層

  1. 關鍵字
  2. 文檔指針

     

11.天然語言全文索引

關鍵字整個索引中出現的次數越少 匹配相關度越高

12. 布爾全文索引

myISAM引擎才能使用布爾全文索引

13.全文索引的限制

  1. insert,update,delete全文索引的代價很大:
  2. 修改文本100個單詞 須要100次索引操做
  3. 列的長度影響全文索引的性能
  4. 全文索引會有更多的碎片 可能須要更多的 optimize table
  5. 全文索引影響優化器的工做

 

 

 

使用全文索引時 返回主鍵值 當程序真的須要數據時 再查使用其餘索引

 

14.全文索引的配置和優化

保證索引緩存足夠大

保證索引可以緩存在內存中 

爲全文索引設置單獨的鍵緩存(key cache)

創建停用詞表

忽略過短的單詞

15.分佈式事務

16.內部XA事務

   跨存儲引擎的事務

17.外部事務

18.查詢緩存

19.如何判斷緩存命中

查詢有一些不肯定數據時,則不會被緩存 如:now(),current_date()

查詢中包含任何用戶自定義的函數、用戶變量、臨時表 或者包含列權限級別的表 都不會被緩存

緩存也會帶來必定開銷:

  1. 緩存檢查
  2. 緩存數據添加
  3. 數據插入時緩存失效

20.查詢緩存對內存的使用

查詢緩存徹底存儲在內存中的

查詢緩存的內存 分紅變長的數據塊

數據塊自身有類型 大小和數據自己

數據塊類型有:存儲 ->  查詢結果、查詢、數據表映射、查詢文本等 

21.查詢 緩存配置

query_cache_type

query_cache_size

query_cache_min_res_unit

query_cahce_limit

query_cache_wlock_invalidate 

 

 

查詢緩存空間過小 查詢緩存使用率會很低

 

22. InnoDB緩存機制

 

innoDB有mvccjizhi  因此 使用緩存更復雜 

 

當前事務ID-->內存中數據字典事務ID號(計數器)比較-->大於計數器的ID號纔可使用 緩存 -->若是表上有任何鎖 不可使用緩存-->事務提交-->當前系統事務ID 修改該表計數器

 

23.查詢緩存優化

  1. 多個小表代替一個大表對緩存有幫助
  2. 批量寫入只須要作一次緩存失效,效率高於單條寫入
  3. 因緩存空間太大 因此要控制緩存大小 防止過時操做服務器僵死
  4. 能夠經過 sql_cahe 和sql_no_cahe來控制查詢是否須要緩存
  5. 對於密集型的應用 關閉緩存能夠提升系統性能
  6. 由於互斥信號量的競爭 關閉查詢緩存 對讀密集型的應用也會有好處 能夠測試打開和管查詢緩存性能差別

第八章 優化服務器設置 

 

1.mysql配置的工做原理

 

配置文件通常在 /etc/my.cnf  或者 /etc/mysql/my.cnf 

 

2.mysql 基礎配置文件

2.配置緩衝池  和 日誌文件  由於默認過小了

 

緩衝池 流行的經驗是設置爲 服務器內存的 75% - 80% 

更好的辦法:

( 內存總量 - 系統內存佔用  -  mysql自身須要內存 -  操做系統緩存innoDB日誌文件所需內存 - 其餘配置緩衝或緩存所需內存 如 key cache ,query cache )

/ 1.05(InnoDB 緩衝池自身開銷)

結果 四合五入

 

3.配置內存使用

內存消耗

能夠控制的內存:能夠經過參數配置的內存

不能夠控制的內存:mysql服務運行、解析查詢、內部管理消耗等

 

配置內存步驟

  1. 肯定內存使用上限
  2. 肯定mysql每一個鏈接所需內存 :如 排序緩衝和臨時表
  3. 肯定操做系統須要多少內存纔夠用
  4. 把剩下的內存所有給mysql緩存

重要的緩存

  1. InnoDB緩衝池
  2. InnoDB日誌文件和myISAM數據系統緩存
  3. MyisAM鍵緩存
  4. 沒法手工配置的緩存 如二進制日誌 表定義文件的操做系統緩存

 

innoDB緩衝池 

緩存索引 緩存行數據 自適應hash ,insert buffer ,鎖 ,以及其餘內部數據結構 ,緩衝數據 延遲寫入 實現合併寫入。

緩衝池太大 預熱和關閉 消耗時間  關閉以前須要把髒頁寫回數據庫

查看髒頁數 Innodb_buffer_pool_pages_dirty 

show global status;

 innodb_max_dirty_pages_pct 刷新 髒頁數 閥值

show variables

 

key cache

鍵緩存  只緩存索引

 不超過索引總大小

或者 不超過操做系統緩存總內存的 25% - 50%

 

緩衝區的使用率 公式

 

100-((key_block_unuser * key_cache_block_size)*100/key_buffer_size);

 

show global status where variable_name in('Key_blocks_unused','Key_cache_block_size','Key_buffer_size');
show variables where variable_name in('Key_blocks_unused','Key_cache_block_size','Key_buffer_size');

 100 -(6582 * 1024)*100/16777216=59.82666

 

key block size

mysql鍵緩存塊的大小

 

InnoDB事務日誌 

innoDB使用日誌減小事務提交開銷 -->InnoDB把隨機I/O變成順序I/O--> 日誌寫入磁盤 -->事務持久化

                                                                                                          -->日誌恢復已提交的事務

 

日誌文件大小 

innoDb_log_file_size, innoDb_log_files_in_group 

show variables where variable_name like'Innodb_log%'

size=2*167772160

 

日誌緩衝區 innodb_buffer_size 推薦大小爲  1M - 8M

show VARIABLES where variable_name like'innodb_log%'

16777216  這是默認的大小 咱們來算一下多少M 

16777216 B/1024/1024=16M

InnoDB表空間

InnoDB把數據保存在表空間內,本質上是由一個或多個磁盤文件組成的虛擬文件系統。

InnoD 

  1. 存儲表 索引
  2. 保存回滾日誌
  3. 插入緩衝 
  4. 雙寫緩衝

 innoDb_data_file_path 配置表空間文件

   這些文件存放在 innodb_data_home_dir 指定的目錄

show VARIABLES where variable_name like'innodb_data%';

autoextend:超過度配空間還能增加

max:設置上限 如:ibdata1:12M:autoextend:max:2G

 

innodb_file_per_table 設置innoDb每一個表使用一個 表空間文件

show VARIABLES where variable_name like'innodb_file%';

innodb_file_per_table  on

優勢:易於管理

缺點:刪 除錶慢  能夠先將.ibd指向  0字節文件  而後手動刪除表文件

刪除表 須要掃描緩衝池 找到屬於表空間的頁面

  

InnDb雙寫緩衝  DoubleWrite buffer

 

雙寫緩衝避免頁沒寫完整 致使的數據損壞

innodb_doublewrite

 

配置mysql併發

innodb_thread_concurrency 控制線程併發數  0爲不限制

show VARIABLES where variable_name like'innodb_thread%';

理論上的配置

併發值=cpu數量 * 磁盤數量 * 2;

實踐中 小於理論中  且須要驗證

innodb_thread_sleep_delay 微妙  線程休眠時間  當 併發值 >=設置值 線程delay 而後重試  若是還不能進入內核 則會進入等待隊列

innodb_concurrency_tickets  線程進入內核 會有必定量 ticket供其免費返回內核 不須要併發檢測

show VARIABLES where variable_name like'innodb_concurrency%';

innodb_commit_concurrency  併發提交量 0 不限制

  

 MyIsAM  併發配置

 

myIsAM 設置 concurrent_insert  控制併發

                 0 不容許併發插入

                 1 默認值  沒有空洞 就容許併發插入

                 2  插入表的末尾 即便有空洞

delay_key_write 延遲寫索引 

 

優化 Blob和 text

1.使用 substring()函數

優化排序

使用 max_length_for_sort_data 

第九章 操做系統和硬件優化

 

cpu和I/O資源 影響mysql性能

 

調優服務器的目標

  1. 低延時
  2. 高吞吐

cpu架構

多個cpu和核心

cpu聯機處理事務 OLTP  on-line transaction processing 

數據庫併發問題

  1. 邏輯併發問題

                 應用程序能夠看到的資源競爭:表和行的鎖爭用

        2.內部併發問題

平衡內存和磁盤資源

高速緩存

隨機I/O和順序I/O

順序I/O比隨機I/O快 

存儲引擎執行順序 比隨機讀取快

緩存,讀和寫

屢次寫入 一次刷新

I/O合併

 

工做集

完成某某項工做所須要的數據集

工做集包括索引和數據 

 

選擇硬盤

傳統磁盤讀取數據步驟:

移動讀取磁頭到正確位置

等待磁盤旋轉,磁頭讀取數據

 

磁盤選擇

  1. 存儲容量
  2. 傳輸速度
  3. 訪問時間(隨機查找速度)
  4. 主軸轉速(15000RPM)
  5. 物理尺寸(其餘條件相同 物理尺寸越小 讀取磁頭時間越短)

固態存儲

使用非易失性閃存芯片組成,NV RAM

SSD固態硬盤

PCle卡

SSD經過實現SATA(串行高級技術附件)接口 模擬標準硬盤 能夠直接代替硬盤驅動 插入現有卡槽

高質量閃存設備應具有:

  1. 相比硬盤有更好的隨機讀寫性能
  2. 相比硬盤有更好的順序讀寫性能
  3. 相比硬盤有更好的支持併發

閃存

閃存讀取快  寫入慢 且要作好垃圾回收 技術

閃存有兩種技術

  1.   SLC 單層單元
  2.   MLC 多層單元

flashcache

flashcache是linux內核模塊 使用linux設備映射 他在內存和磁盤之間創建一箇中間層 是facebook開源和使用技術之一 。能夠優化數據庫負載

RAID:磁盤冗餘隊列

爲備份庫選擇硬件

備份庫主要考慮的是成本

 

RAID 磁盤冗餘隊列優化 

 

網絡配置

tcp的積壓 back_log配置 tcp隊列大小

文件系統

線程 

 

GNU/Linux 提供兩種線程庫

  1. LinuxThreads
  2. 原生Posix(NPTL)

NPTL更輕量 更高效

操做系統狀態

 

vmstat 5

 

vmstat : vm stat工具 5s 打印一次報告

 

 procs :r 顯示多少進程正在等待

              b 顯示多少進程正在不可中斷的休眠(等待 I/O 等待 網絡 等待用戶輸入等)

    memory:

                  swpd 頁面交換  

                  free  空閒

                  buff 緩衝

                  cache 操做系統緩存

  io

  system:

    in:每秒中斷

    cs:上下文切換

 

iostat -dx 5

io stat 查看 io信息

rrqm/s和wrqm/s

每秒合併的讀寫請求

r/s和w/s

每秒發送到設備的讀寫請求

rsec/s 和 wsec/s

每秒讀和寫的扇貝數

avgrq -sz

請求的扇貝數

avgqu -sz 

設備隊列中的等待請求數

await

隊列等待

svctm

請求花費秒數

%util

活躍請求所佔時間百分比

 

設備併發請求數

 concurrency=(r/s+w/s)*(svctm/1000); 

 

第10章 複製

 

複製概述

複製解決的基本問題是 讓一臺服務器的數據和另外一臺服務器數據保持同步 一臺主庫數據同步到多臺備份庫。

mysql兩種複製方式

  1. 基於行的複製
  2. 基於語句的複製

複製解決的問題

複製的用途

  1. 數據分佈
  2. 負載均衡
  3. 備份
  4. 高可用性和故障切換

如何複製

主庫-->binary log-->備份庫relay log-->備份庫讀取relay log重放數據

每一個備份庫在主庫上 -->各自建立線程 執行 binlog dump命令 -->讀取主庫二進制文件 將數據發送給備庫

binlog dump不共用 

複製有三個步驟

  1. 主庫上把數據更改記錄到二進制日誌 binary log (二進制日誌事件)
  2. 備份庫 將主庫上的日誌複製到本身的中繼日誌(relay log)
  3. 備份庫讀取中繼日誌事件 將其重放在備份庫中

配置複製

  1. 每臺服務器建立複製帳號
  2. 配置主庫和備份庫
  3. 通知備庫鏈接到主庫從主庫複製數據

sync-binlog=1

 

 發送複製事件到其餘設備

複製過濾器

容許複製服務器上部分數據:重放的時候進行過濾

複製拓撲

  1. 一個mysql備庫實例 只能有一個主庫
  2. 每一個備庫必須有一個惟一服務器ID
  3. 一個主庫能夠有多個備庫
  4. 若是打開了 log_slave_updates選項 備庫能夠把主庫上數據變化傳播到其餘備庫

一主多備

少許寫 大量讀  的時候很是有用

雙主複製

兩臺服務器每一個都設置成對方的主庫和備庫

最大的問題是解決數據衝突

mysql不支持多主複製

 被動模式下的主-主複製

其中一臺服務器是隻讀的被動服務器

 配置主-主服務器對

  1. 確保兩臺服務器上數據相同
  2. 啓用二進制日誌 ,主庫設置惟一服務器ID  並建立複製帳號
  3.  啓用備庫更新日誌記錄,這是故障轉移和故障恢復的關鍵
  4. 把被動服務器配置成只讀 (可選)
  5. 啓動每一個服務器的Mysql實例
  6. 將每一個主庫設置成對方的備庫,使用新建立的二進制日誌開始工做

擁有備庫的 主-主結構

爲每一個主庫增長一個備庫

環形複製

每一個服務器是它以前服務器的主庫,是它以後服務器的主庫

 

 

主庫 分發主庫 備份庫

 

分發主庫 減小 備份庫 建立線程  binlog dump 對主庫內存的消耗, 專門負責分發

設置 slave_compressed_protocal 節約主庫帶寬

分發庫上 每一個表的存儲引擎 必須是 blackhole

 

 樹或金字塔型

優勢 減輕主庫負擔

缺點 中間層出錯 影響節點下面多個服務器

選擇性複製

 

將主庫中的數據--.> 劃分到不一樣的數據庫裏-->數據庫 備份到不一樣備份庫

 

監控複製

show  master logs

show binlog EVENTS

 查看複製事件

 

備庫提高爲主庫

  1. 備庫追遇上主庫(數據)
  2. 中止向老的主庫寫入
  3. 將備庫配置爲新的主庫
  4. 寫操做指向新的主庫,開啓主庫寫入 

 

 肯定主備是否一致

checksum table 來檢測

checksum table user;

可是當複製正在進行時這種方法是不可行的

使用 pt-table-checksum 工具

 

數據損壞或丟失

 

主庫意外關閉

  1.  設置sync_binlog 
  2. 指定備庫從下一個二進制日誌開頭讀(部分日誌事件將永久丟失)
  3. 使用pt-table-checksum 來檢查主備一致性 以便數據修復

備庫意外關閉

  1. 使用pt-slave-restart工具 查找上次中止的位置  

主庫上的二進制日誌損壞 

  1. 忽略損壞位置
  2. flush logs建立新日誌文件
  3. 備庫指向新文件開始位置

備庫上的中繼日誌損壞

  1. 若主庫日誌無缺 使用change master to 命令 丟棄並從新獲取事件

二進制日誌與innoDB事務日誌不一樣步

  1. 沒法修復

數據改變但事件還是有效的sql

  1. 沒法修復

數據改變且事件是無效的sql

  1. 忽略

數據遺漏 事件長度是錯誤的

  1. 忽略 找下個事件的開始

第11章  可擴展的mysql

 

可擴展性

容量 :最大吞吐量不是容量 容量是有效利用量 

 

向上擴展 (垂直擴張)

強悍的硬件  內核 cpu

水平擴展

  1. 複製
  2. 拆分
  3. 數據分片

最簡單的是 加服務器

工做負載分佈到多個節點

按功能拆分

功能被捆綁到單個mysql,就只能垂直擴張 。其中一個功能很是龐大 應尋求不一樣策略

 數據分片

 

目前 擴展大型mysql的應用方案中 數據分片是最通用且最成功的方法

將數據切割成寫塊 存儲到不一樣的節點。

公共服務不拆分,數據龐大增加快的部分進行數據分片 或許可使用面向服務架構

選擇分區鍵

 

多個分區鍵

跨分片查詢

分配數據 分片和節點

分片和節點不必定是一對一 分片的大小應小於節點容量 這樣就能夠在單個節點存儲多個分片

分片小  易於管理 易於數據恢復

 

節點上部署分片

  1. 每一個分片使用使用一個數據庫  表名包含分片號 :查詢語句須要從新 使用佔位符
  2. 每一個節點運行多個mysql實例 每一個實例上有一個或多個分片
  3. 每一個分片各自使用一個數據庫 數據庫名要相同
  4. 每一個分片使用使用一個數據庫 數據庫名包含分片號,  代表不包含分片號

固定分配

數據分配到分片有兩種方法

  1. 固定分配
  2. 動態分配 

固定分區優勢:簡單開銷低  甚至能夠硬編碼

缺點:

  1. 若是分片很大數量很少 很難平衡不一樣分片間的負載
  2. 固定分片沒法自定義數據 放在哪一個分片 有些數據可能比其餘數據活躍 也許被分配到同一個片內 各個分片間的負載不均衡
  3. 修改分片策略比較困難

動態分配

  將每一個數據單元映射到分片 如 創建一個分區函數表

給定用戶ID 獲取分片號 存儲數據

混合動態分配和固定分配

顯示分配

從新均衡分片數據

生成全局惟一ID

  1.auto_increment

   能夠在 一臺auto_increment_offset 設置爲 1 auto_increment_increment 設置爲2 

      那就是 從1 開始每次增加 2     1,3,5,7,9.....全爲奇數

  另外一臺auto_increment_offset 設置爲 2 auto_increment_increment 設置爲2 

    那就是 從2 開始每次增加 2   2,4,6,8,10.....全爲偶數

2.全局節點中建立表

  在全局數據節點中建立表 生成惟一ID

3.使用 redis或memcached

4.批量分配數字(號段)

5.複合值 如 分片號+自增ID

6.UUID

分片工具

經過多實例擴展

mysql 不能徹底發揮硬件性能,當擴展超過24個cpu時 mysql性能趨於平緩  當內存 超過128G也一樣如此

經過集羣擴展

nosql

cap: 一致性(consistency)、可用性(Availability)、分區容錯(partition-tolerance)

保持活躍數據獨立

負載均衡

一個服務器羣儘量平均負載 一般設置負載均衡器

負載均衡的目的

  1. 可擴展性
  2. 高效性
  3. 可用性
  4. 透明性
  5. 一致性

 

 引入中間件

 中間件  能夠是硬件也能夠是軟件  中間件派發請求到指定服務器 並把執行結果 發送給請求機器

負載均衡器

負載均衡算法

 

可用方法

  1. 隨機
  2. 輪詢
  3. 最少鏈接數
  4. 最快響應
  5. 哈希
  6. 權重

第12章 高可用性

更少的宕機時間

宕機的緣由 

  1. 35% 環境問題:磁盤空間耗盡
  2. 35%性能問題: 垃圾sql 還有些bug或錯誤   bad  schema 和索引設計
  3. 20%複製:主庫和備庫數據不一致
  4. 10% 數據丟失或損壞:手動刪除  誤操做

 如何實現高可用性

 避免宕機 1. 對宕機的緣由進行配置和監控 :平均失效時間  MTBF

                 2.發生宕機時要快速恢復:平均恢復時間 MTTR

           

 避免單點失效

增長冗餘 1.增長冗餘量 2.重複組件

       

 共享存儲或磁盤複製

優勢:

    避免數據丟失,爲非存儲組件創建冗餘

   減小系統部分需求 提升組件高可用性

缺點

  mysql崩潰 文件損壞 備庫受影響

  共享存儲建議使用 innodb引擎 ACID

 

中間件解決方案

可使用代理 端口轉發 網絡地址轉換(NAT)或者硬件的負載均衡來實現故障轉移和恢復

 

第13章  雲端的mysql

 

粗略分爲兩類

Iaas:基礎設施及服務

  Iaas 用於託管Mysql服務器的雲端基礎架構 

Dbaas 數據庫及服務

mysql自己做爲雲端管理資源 用戶收到mysql服務器的訪問許可 才能訪問  如 amazon運行的mysql rds 其中一些服務器並不是真實的mysql 但其兼容MySQL協議和查詢

 

雲的優缺點

優勢:

  1. 減小管理和運維成本

缺點:

  1. 資源共享不可預測
  2. 虛擬的共享資源排查故障困難

四種基礎資源

  1. cpu週期
  2. 內存
  3. I/O
  4. 網絡

 

 第14章 應用層優化

sql語句優化

創建了不必的鏈接

鏈接池是否合理

是否保持長鏈接

web服務器問題

不要使用apche作靜態內容服務 可使用 nginx 或 lighttpd 

不要讓Apache填鴨式服務客戶端

不要爲長距離鏈接 apache 啓用 keep-alive 這樣會使重量級進程存活很長時間

尋找最優併發度

緩存

一般緩存越接近客戶端 ,節省資源效率越高

主動緩存

被動緩存 memcached

 

 

應用緩存有多種:

  1.  本地緩存
  2. 本地共享內存緩存
  3. 分佈式內存緩存
  4. 磁盤上的緩存

緩存控制策略

 

  1. TTL time to  live 存活時間 :設置一個過時時間
  2. 顯示失效 :更新數據時使緩存失效
  3. 讀時失效

handlerSocket 和msmcached

 

hadoop

 

 

第15章 mysql備份與恢復

 

邏輯備份  

物理備份

 

增量備份

差別備份

 

 

文件快照 是一種很是好的在下備份方法

相關文章
相關標籤/搜索