MySQL 學習筆記

mysql 總體結構

  • 示例圖:

image

  • 簡單結構:html

    1. 鏈接器
    2. 分析器
    3. 優化器
    4. 執行器

mysql 日誌種類(redo log和binlog)

  • 本質區別:mysql

    1. redo log 記錄物理日誌
    2. binlog 記錄邏輯日誌,好比操做了哪行記錄
  • 用update的過程來理解(我的理解,可見極客時間的MySQL專欄 02 篇)算法

    1. 執行器找引擎查取數據(如找 ID=2 這一行)
    2. 引擎返回搜索到的數據給執行器,執行器更改數據(如 set num=num+1 )
    3. 執行器通知引擎寫數據(如 update)
    4. 引擎寫入數據(內存)
    5. 引擎寫 redo log(prepare),返回執行完成
    6. 執行器生成 binlog ,寫入磁盤,執行器調用引擎的事務提交接口
    7. 引擎寫 redo log(commit)
    8. 完成操做

mysql 事務語法(文檔

  • START TRANSACTION|BEGIN [WORK]:顯式地開啓一個事務,begin 等同於 begin work。
  • COMMIT:等同於 COMMIT WORKsql

    • commit work with chain :表示立刻自動開啓一個相同隔離級別的事務
    • commit work :當事務提交後會自動斷開與服務器的鏈接
  • ROLLBACK:回滾
  • SAVEPOINT identifier:SAVEPOINT容許你在事務中建立一個保存點,一個事務中能夠有多個SAVEPOINT
  • RELEASE SAVEPOINT identifier:刪除一個事務的保存點
  • ROLLBACK TO [SAVEPOINT] identifier:將事務回滾至標記點
  • 示例數據庫

    begin;
    insert into t select 1;
    savepoint t1;
    insert into t select 2;
    savepoint t2;
    release savepoint t1;
    insert into t select 2;
    ERROR 1062(23000):Duplicate entry'2'for key'PRIMARY'
    rollback to savepoint t2;
    select * from t;
    rollback;
  • 能夠在 information_schema.innodb_trx 這個表中查詢長事務數組

    # 查找持續時間超過 60s 的事務
    select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60;

索引

常見索引模型

  • 哈希
  • 有序數組
  • 搜索樹服務器

    • B+樹

基於聚簇索引和非聚簇索引的查詢

  • 主鍵索引(聚簇索引)和非主鍵索引(非聚簇索引)的數據儲存結構和聯繫如圖:

image

  • 經過主鍵索引查詢會只查詢主鍵索引數,經過非主鍵索引查詢則會先查詢對應索引樹,再經過查找到的主鍵值查找主鍵索引數,該過程成爲回表

索引維護

  • 插入新值時:對於 B+ 樹,若插入的新紀錄比當前列最大值要大,則爲追加操做,若小可能會觸發數據挪動頁分裂框架

    • 追加:插入一條新記錄,不涉及到挪動其餘記錄,也不會觸發葉子節點的分裂(如自增主鍵的插入數據模式)。
    • 數據挪動:若插入新值比當前列最大值小,則須要邏輯上挪動後面的數據,空出位置。
    • 頁分裂:所在的數據頁已經滿了,根據 B+ 樹的算法,這時候須要申請一個新頁,而後挪動部分數據過去。
  • 刪除數據時:當相鄰兩個頁因爲刪除了數據,利用率很低以後,會將數據頁作合併

關鍵實戰問題記錄

  1. 如何避免長事務對業務的影響?
  • 應用開發端來看:ide

    1. 確認是否使用了 set autocommit=0。這個確認工做能夠在測試環境中開展,把 MySQL 的 general_log 開起來,而後隨便跑一個業務邏輯,經過 general_log 的日誌來確認,在業務功能測試階段要求輸出全部的 general_log ,分析日誌行爲提早發現問題。通常框架若是會設置這個值,也就會提供參數來控制行爲,你的目標就是把它改爲1。
    2. 確認是否有沒必要要的只讀事務。有些框架會習慣無論什麼語句先用 begin/commit 框起來。我見過有些是業務並無這個須要,可是也把好幾個 select 語句放到了事務中。這種只讀事務能夠去掉。
    3. 業務鏈接數據庫的時候,根據業務自己的預估,經過SET MAX_EXECUTION_TIME 命令,來控制每一個語句執行的最長時間,避免單個語句意外執行太長時間。(爲何會意外?在後續的文章中會提到這類案例)
  • 數據庫端來看:工具

    1. 監控 information_schema.Innodb_trx 表,設置長事務閾值,超過就報警/或者kill;
    2. Percona 的 pt-kill 這個工具不錯,推薦使用;
    3. 若是使用的是 MySQL 5.6 或者更新版本,把 innodb_undo_tablespaces 設置成2(或更大的值)。若是真的出現大事務致使回滾段過大,這樣設置後清理起來更方便。
相關文章
相關標籤/搜索