日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL深入(一)

發布時間:2024/9/19 数据库 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL深入(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

MySQL深入(一)

文章目錄

  • MySQL深入(一)
      • MySQL的事務隔離
        • 事務隔離強度
        • 臟讀
        • 臟寫
        • 不可重復讀
        • 幻讀
        • 解決臟讀,臟寫,不可重復讀和幻讀現象
      • 變量
      • mysql存儲過程
        • 存儲過程中的三種傳遞參數
        • 創建存儲過程
        • 調用存儲過程
        • 刪除存儲過程
      • 函數
        • 創建函數
        • 調用函數
        • 刪除函數
      • MySQL的一些關鍵文件
      • MySQL邏輯框架
        • 分層
      • InnoDB存儲引擎(默認引擎)
        • InnoDB主要特性
        • InnoDB體系
        • InnoDB的后臺線程
        • Innodb內存
        • LRU List、Free List 和 Flush List
        • undo log和redo log
        • bin log
        • bin log

MySQL的事務隔離

MySQL有四類隔離級別:

  • Read Uncommitted(讀取未提交內容)
  • Read Committed(讀取提交內容)
  • Repeatable Read(可重讀)
  • Serializable(可串行化)
  • 事務隔離強度

    隔離強度從上到下逐漸增強,如圖:

    • Read Uncommitted :在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。也就是說基本沒有任何事務隔離性,其他事務的沒進行事務提交的修改和回滾都有可能影響其他事務的執行結果。
    • Read Committed :在該隔離級別,一個事務只能看見已經提交事務所做的改變。也就是說該級別下,一個事務對某數據的多次讀取操作仍然可以出現前后讀取不一致的情況。假設事務A對數據Data進行進行三次查詢,而有事務B,C分別前后對數據進行了修改并提交了,那么事務A可能會讀到三個不同的數據。
    • Repeatable Read :MySQL的默認事務隔離級別,在該隔離級別,同一事務的多個實例在并發讀取數據時,會看到同樣的數據,但其他事務的插入數據是可以看見的。也就是說,事務A在事務中讀取的數據不會因為其他事務的提交了的修改,而導致出現讀取結果被修改的現象。但是,假設其他事務有插入操作,并且插入的數據剛好符合事務A中查詢條件的范圍,那么事務A可能會讀取到其他事務插入的數據,導致讀取數據的數量前后不一致,也就是所謂的幻讀。
    • Serializable :這是最高的隔離級別,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題。通過共享鎖實現。也就是說,假設事務A要讀取某三行數據,那么這三行就被事務A占有,并且只占有這三行數據,也就是說事務A整個過程中看見的就這三行數據,其他事務無法對這三行數據進行任何操作。但這也導致了性能的問題,

    臟讀

    發生條件: 在事務級別Read Uncommitted下,多事務讀取修改情況下。

    導致臟讀的主要原因是所有事務都可以看到其他未提交事務的執行結果,假設有事務A,并且事務A在事務中有多次讀取的情況,現有事務B對事務A讀取的數據進行修改并且沒有進行提交,而且可能失敗并發生回滾現象。那么事務A可能讀取到的數據可能是B沒有提交的修改后的數據,也可能是B事務失敗后回滾的數據。

    臟寫

    發生條件: 在事務級別Read Uncommitted下,多事務讀取修改情況下。

    和臟讀類似,主要原因是所有事務都可以看到其他未提交事務的執行結果。

    假設有兩事務A,B對數據Data進行修改,在事務A之前有事務B對數據Data修改,然后事務A在進行修改并提交了,但是事務B因為某些原因導致事務失敗并進行回滾,那么事務B回滾到的數據是其操作之前的狀態,那么事務A的修改就被事務B回滾的數據覆蓋了。結果就導致了事務A提交的修改無效了。

    不可重復讀

    發生條件: 在事務級別Read Uncommitted,Read Committed下,多事務讀取修改情況下。

    可以說是臟讀的縮小版,在Read Committed事務級別下,一個事務只能已經提交事務所做的改變,但這無法完全避免事務讀取數據的前后一致。

    假設事務A對數據Data進行進行三次查詢,而有事務B,C分別前后對數據進行了修改并提交了,那么事務A可能會讀到三個不同的數據。這就是不可重復讀。雖然B,C事務都提交了,但是這個提交結果可能會導致其他事務的讀取結果。

    幻讀

    發生條件: 在事務級別Read Uncommitted,Read Committed,Repeatable Read下,多事務情況讀取插入刪除情況下。

    幻讀一般是因為,事務的插入和刪除導致的,幻讀就如其命一樣,在一個多次讀取的事務中,前后讀取到的數據個數不一樣,這就是幻讀,如同幻覺一般,數據會突然出現和消失。

    假設事務A有多次讀取操作,并且有事務B,C分別進行插入刪除操作,在A第一次讀取后,事務B對表進行插入操作,插入的數據剛好符合A的查詢條件,那么A再次讀取數據,就會發現讀取的數據中多出了幾行數據,如同出現幻覺一般。在A再次讀取后面,C把多條數據進行了刪除,并且刪除的數據剛好符合A中查詢的條件,那么A再次讀取時,A就無法讀取完整的數據了。

    解決臟讀,臟寫,不可重復讀和幻讀現象

    開啟事務級別Serializable,serializable下會完全鎖定字段,若一個事務來查詢同一份數據就必須等待,直到前一個事務完成并解除鎖定為止。是完整的隔離級別。但這也導致了一些并發性能的問題,多個事務對同一行數據查詢操作,為了安全,那么就只能逐個事務排隊對數據進行操作,效率上大打折扣。

    變量

    系統變量:全局變量,會話變量

    自定義變量:用戶變量,局部變量

    #參看當前會話系統變量 show session variables; #參考全局系統變量 show global variables; show global variables like '%';#查看指定系統變量命 select @@global.變量命#設置全局系統變量 set global 變量名 = 值; set @@global.變量名=值;#設置用戶變量 set @用戶變量=值;#申明局部變量 declare 變量命 類型; #設置局部變量 SET 局部變量命=值;

    mysql存儲過程

    存儲過程是為了完成特定功能的SQL語句集,經編譯創建并保存在數據庫中,用戶可通過指定存儲過程的名字并給定參數(需要時)來調用執行。

    mysql的存儲過程的寫法跟一般語言的函數寫法很相似,主要還是聲明,方法體和返回值組成。

    存儲過程中的三種傳遞參數

    傳遞參數主要分三大種:IN,OUT,INOUT。分別是輸入參數,輸出參數和輸入輸出參數。

    在創建存儲過程中IN和INOUT可以作為存儲過程的傳入值使用,而OUT是作為輸出值使用,類似于函數中的return。

    創建存儲過程

    #創建名為sp_name的存儲過程 CREATE PROCEDURE sp_name(IN p_in int) BEGIN#編寫SQL語句 END;#創建一個有權限的存儲過程 CREATE DEFINER = {username} PROCEDURE sp_name(IN p_in int) BEGIN#編寫SQL語句 END;#創建一個包含查詢語句的存儲過程 #delimiter用來聲明語句的結束符號從分號;臨時改為$,主要為了區分存儲體中的SQL結束和存儲過程的結束符 delimiter $ CREATE PROCEDURE check_user(IN user_id int,IN password int,OUT result int) BEGIN#這里是通過OUT變量來傳遞放回值SELECT count(*) INTO resultFROM USERTableWHERE id=user_id AND Password=password; END$

    調用存儲過程

    存儲過程的調用使用call關鍵字,并且在通過傳遞的參數來獲得放回值。

    #存儲過程的調用使用call關鍵字 #通過用戶變量@userchecke_result獲取放回值 set @userchecke_result=0 call check_user(5,123456,@userchecke_result)

    刪除存儲過程

    使用drop刪除

    DROP PROCEDURE sp_name;

    函數

    MySQL 有很多內置的函數,但是我們也可以定義屬于自己的函數。

    創建函數

    CREATE FUNCTION fun_name(id int,pwd int) RETURN INT BEGINDECLARE result INT DEFAULT 0;SELECT count(*) INTO resultFROM userTableWHERE use_id=id AND password=pwd;RETURN result; END $

    調用函數

    函數的調用直接使用即可

    SELECT fun_name(5,123456);

    刪除函數

    DROP FUNCUTION sp_name;

    MySQL的一些關鍵文件

    logbin文件:二進制日志文件

    logerror文件:錯誤日志文件

    my.ini文件:MySQL配置文件

    MySQL邏輯框架

    分層

    MySQL邏輯框架分4層:

  • 連接層
  • 服務層
  • 存儲引擎層
  • 存儲層
    • 連接層:負責客戶端和連接服務,該層上引入了線程池地 概念,為通過認證通過安全接入的客戶端提供線程。
    • 服務層:主要完成大部分的核心服務功能,如SQL接口,并完成緩存查詢,SQL的分析和優化及部分內置函數的執行。
    • 存儲引擎層:存儲引擎真正的負責了MySQL中數據的存儲和提取,服務器通過api和存儲引擎進行通信。不同的存儲引擎擁有不同的存儲功能。
    • 數據存儲層:主要將數據存儲與運行在裸設備的文件存儲系統之上,并完成與存儲引擎的交互。

    查看MySQL引擎

    #查看所有引擎 show engine; #查看使用引擎 SHOW VARIABLES LIKE 'storage_engine';

    InnoDB存儲引擎(默認引擎)

    InnoDB是事務型數據庫,支持事務安全表(ACID),支持行鎖定和外鍵。支持 行鎖設計MVCC外鍵提供一致性非鎖定讀

    InnoDB主要特性

    • 為MySQL提供了具有提交、回滾和崩潰恢復能力的事物安全(ACID兼容)存儲引擎。
    • InnoDB存儲引擎為在主內存中緩存數據和索引而維持它自己的緩沖池。
    • InnoDB支持外鍵完整性約束

    InnoDB體系

    內存池 :負責維護緩存磁盤上的數據,重做日志緩沖,維護內部數據等。

    后臺線程:負責刷新內存池的數據,保證緩存的是最新的數據;將內存數據刷新到磁盤中等。

    InnoDB的后臺線程

    InnoDB是一個單進程多線程的模型,后臺不同的線程負責不同的任務。

    Master Thread :負責將緩沖池中的數據異步刷新到硬盤中,保證數據一致性,包括臟頁的刷新、合并插入、UNDO頁的回收等。

    IO Thread :InnoDB引擎中大量使用異步IO來處理IO請求。可以通過系統變量查看io線程的個數:

    SHOW VARIABLES LIKE 'innodb_%io_threads';

    Purge Thread:事務被提交后,undolog不再需要,需要Purge Thread回收。

    Page Cleaner Thread:將臟頁刷新操作放入單獨的線程中完成。

    Innodb內存

    InnoDB 存儲引擎是基于磁盤存儲的,也就是說數據都是存儲在磁盤上的,由于 CPU 速度和磁盤速度之間的鴻溝, InnoDB 引擎使用緩沖池技術來提高數據庫的整體性能。

    緩沖池中緩存的數據頁類型有: 索引頁、數據頁、 undo 頁、插入緩沖、自適應哈希索引、 InnoDB 的鎖信息、數據字典信息等 。在InnoDB中,緩沖池中的頁大小默認為16KB。

    LRU List、Free List 和 Flush List

    • Free List(空閑鏈表):用于保存內存中空閑的內存頁。
    • LRU List:InnoDB通過LRU(Latest Recent Used,最近最少使用)算法來管理緩沖池。而LRU List就是用來保存最近使用過的數據位置的鏈表。當緩沖池放不下新讀取的頁時,就會釋放LRU列表尾端的頁。
    • Flush List:在LRU List 中的頁被修改后,稱該頁為 臟頁(dirty page) 。臟頁存儲于 Flush List,表示緩沖池中的頁與磁盤頁不一致,等待被調度刷新。

    undo log和redo log

    • redo log :redo log是InnoDB存儲引擎層的日志, **用于記錄事務操作的變化,記錄的是數據修改之后的值。**InnoDB 將重做日志首先寫入 redo buffer cache,之后通過一定頻率寫入到重做日志(redo logo)中。
    • undo log :保存了事務發生之前的數據的一個版本,可以用于回滾,同時可以提供多版本并發控制下的讀(MVCC)。

    bin log

    用于復制,在主從復制中,從庫利用主庫上的binlog進行重播,實現主從同步。

    log和redo log

    • redo log :redo log是InnoDB存儲引擎層的日志, **用于記錄事務操作的變化,記錄的是數據修改之后的值。**InnoDB 將重做日志首先寫入 redo buffer cache,之后通過一定頻率寫入到重做日志(redo logo)中。
    • undo log :保存了事務發生之前的數據的一個版本,可以用于回滾,同時可以提供多版本并發控制下的讀(MVCC)。

    bin log

    用于復制,在主從復制中,從庫利用主庫上的binlog進行重播,實現主從同步。

    總結

    以上是生活随笔為你收集整理的MySQL深入(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。