InnoDB存儲引擎底層拆解:從頁、事務到鎖,如何撐起MySQL數據庫高效運轉(上)

目錄

Page頁**

B+樹查詢

如何加快記錄的查詢?

索引**

聚簇索引(主鍵)

二級索引(非主鍵)

聯合索引——多列

bufferPool*

Free鏈表

flush鏈表

Flush鏈表刷新方式有如下兩種:

LRU鏈表

針對LRU鏈表方案缺點的優化

redoLog*

redo簡單日志類型

redo復雜日志類型(以MLOG_COMP_REC_INSERT為例:)

redo日志組

MTR(Mini-Transacti on)

redo日志緩沖區——log buffer

redo日志刷盤和日志文件組

undoLog*

事務**

MVCC

鎖*


????????你在電商平臺點擊“提交訂單”按鈕的瞬間,背后發生了什么?

????????數據庫需要在毫秒級內完成:查詢商品庫存、校驗用戶余額、生成訂單記錄、扣減庫存、最終提交事務……這些操作看似“絲滑”,實則由MySQL的核心存儲引擎——??InnoDB??默默支撐。

????????但你可能從未想過:

  • ?

    為什么InnoDB能在磁盤中快速找到一條記錄?是靠怎樣的“數據地圖”?

  • ?

    為什么它能同時處理上萬并發事務,還能保證數據不丟、不亂?

  • ?

    那些耳熟能詳的“B+樹索引”“Buffer Pool緩存”“redo log日志”……它們究竟如何協作?

????????這篇文章,我們從InnoDB最底層的??頁(Page)??開始,一步步拆解它的核心設計:B+樹如何優化查詢、Buffer Pool如何減少磁盤IO、redo/undo日志如何保障事務、事務與鎖如何協同工作……最終還原這個“數據庫隱形引擎”的底層邏輯。

Page**

????????為了避免一條一條讀取磁盤數據,InnoDB采取頁的方式,作為磁盤和內存之間交互的基本單位。一個頁的大小一般是16KB

????????InnoDB為了不同的目的而設計了多種不同類型的頁。比如:存放表空間頭部信息的頁、存放undo日志信息的頁等等。我們把存放表中數據記錄的頁,稱為索引頁or數據頁

往頁中存儲的數據 也稱作:“記錄”

記錄的頭信息包括以下:

記錄是按照主鍵從小到大的順序形成了一個單向鏈表。記錄被刪除后next_record會有影響查詢也只能以頭節點開始逐一向后查詢,但是如果數據量很大,那么性能就無法保證了。針對這個問題,InnoDB采取了圖書目錄的解決方案,即:Page Directory

分組規則如下所示:

① 對于Infimum記錄所在的分組只能有1條記錄。② 對于Supremum記錄所在的分組只能在1~8條記錄之間。③ 剩下的其他記錄所在的分組只能在4~8條記錄之間。

分組步驟如下:① 初始情況下,一個數據頁中只有Infimum記錄和Supremum記錄這兩條,所以分為兩個組。② 之后每當插入一條記錄時,都會從頁目錄中找到對應記錄的主鍵值比待插入記錄的主鍵值大,并且差值最小的槽,然后把該槽對應的n_owned加1。③ 當一個組中的記錄數等于8時,當再插入一條記錄的時候,會將組中的記錄拆分成兩個組(一個組中4條記錄,另一個組中5條記錄)。并在拆分過程中,會在PageDirectory中新增一個槽,并記錄這個新增分組中最大的那條記錄的偏移量。

B+樹查詢

【B樹&B+樹的插入和刪除圖文詳解】B樹和B+樹的插入、刪除圖文詳解 - nullzx - 博客園

【與B樹相同點】

一個節點可以存儲多個元素。

與B樹一樣,葉子節點是有序的。

每個節點中的元素,也都按照從小到大的順序排列,即:左小右大。

所有葉子節點都位于同一層,或者說根節點到每個葉子節點的高度都相同。

【與B樹不同點】

B+樹的葉子節點是有單向指針的,其中:MySQL中采用的是雙向指針。

B+樹的非葉子節點的元素是與葉子節點有冗余的。

如何加快記錄的查詢?

當記錄越來越多,創建的頁也會越來越多,如果僅通過鏈表方式遍歷查詢,性能會出現很大問題。如何解決呢?采用B+樹結構,即:

葉子節點里存儲完整的數據(數據頁),非葉子節點存儲主鍵索引(索引頁)

索引**

聚簇索引(主鍵)

????????聚簇索引的 B + 樹葉子節點直接存儲了完整的行數據。這意味著,InnoDB 表的數據實際上是按照聚簇索引的順序進行物理存儲的。

二級索引(非主鍵)

????????二級索引的 B + 樹葉子節點存儲的是索引列的值以及對應的聚簇索引鍵值

當通過二級索引進行查詢時,首先在二級索引的 B + 樹中找到對應的葉子節點,獲取到聚簇索引鍵值。然后,使用這個聚簇索引鍵值在聚簇索引的 B + 樹中再次查找,才能獲取到完整的行數據。這個過程稱為 “回表”。例如,執行SELECT * FROM table WHERE email = 'example@mail.com',先在email的二級索引 B+樹中找到對應的葉子節點,得到聚簇索引鍵(如id值),再通過這個id值在聚簇索引B+樹中獲取完整的行數據。

聯合索引——多列

目錄項記錄的唯一性

????????為了讓新插入的記錄能找到自己在哪個頁中,就需要保證B+樹同一層內節點的目錄項記錄除頁號字段外是唯一的。所以二級索引的內節點的目錄項記錄的內容實際是有3部分構成的:索引列的值(c2)+主鍵值(c1)+頁號(pageNo)。這樣,如果c2列的值相同,那么可以接著比較主鍵值。所以,歸其根源,我們可以認為,為c2列建立的二級索引其實相當于為(c2,c1)列建立了一個聯合索引。

bufferPool*

為了緩存磁盤中的頁,MySQL服務器啟動時就向操作系統申請了一片連續的內存空間,他們給這片內存起名為Buffer Pool(緩沖池)。默認Buffer Pool只有128M,可以在啟動服務器的時候配置innodb_buffer_pool_size(單位為字節)啟動項來設置自定義緩沖池大小。Buffer Pool對應的一片連續的內存被劃分為若干個頁面,默認也是16KB,該頁面稱為緩沖頁。為了更好的管理Buffer Pool中的這些緩沖頁,InnoDB為每個緩沖頁都創建了控制塊,它與緩沖頁是一一對應的。

Free鏈表

Buffer Pool的初始化過程中,是先向操作系統申請連續的內存空間,然后把它劃分成若干個【控制塊&緩沖頁】對兒。當插入數據的時候,為了能夠知道哪些緩沖頁是空閑且可分配的,MySQL把所有空閑的緩沖頁對應的控制塊作為一個節點放到一個鏈表中,這個鏈表便稱之為free鏈表。

flush鏈表

如果我們修改了Buffer Pool中某個緩沖頁的數據,那么它就與磁盤上的頁不一致了,這樣的緩沖頁也被稱之為臟頁(dirty page)。為了性能問題,我們每次修改緩沖頁后,并不著急立刻把修改刷新到磁盤上,而是將被修改過的緩沖頁對應的控制塊作為節點加入到這個鏈表中,該鏈表也被稱為flush鏈表。

Flush鏈表刷新方式有如下兩種:

【1】從flush鏈表中刷新一部分頁面到磁盤

后臺線程也會定時從flush鏈表中刷新一部分頁面到磁盤,刷新的速率取決于當時系統是否繁忙。——即:BUF_FLUSH_LIST

有時后臺線程刷新臟頁的進度比較慢,導致用戶準備加載一個磁盤頁到Buffer Pool中時沒有可用的緩沖頁。此時,就會嘗試查看LRU鏈表尾部,看是否存在可以直接釋放掉的未修改緩沖頁。如果沒有,則不得不將LRU鏈表尾部的一個臟頁同步刷新到磁盤(與磁盤交互是很慢的,這會降低處理用戶請求的速度)。——即:BUF_FLUSH_SINGLE_PAGE

【2】從LRU鏈表的冷數據中刷新一部分頁面到磁盤

后臺線程會定時從LRU鏈表的尾部開始掃描一些頁面,掃描的頁面數量可以通過系統變量innodb_lru_scan_depth來指定,如果在LRU鏈表中發現臟頁,則把它們刷新到磁盤。——即:BUF_FLUSH_LRU

控制塊里會存儲該緩沖頁是否被修改的信息,所以在掃描LRU鏈表時,可以很輕松地獲取到某個緩沖頁是否是臟頁的信息。

LRU鏈表

線性預讀:如果順序訪問某個區(extent,一個區默認64個頁)的頁面超過了innodb_read_ahead_threshold(默認56)的值,就會觸發一次異步讀取下一個區中全部的頁到Buffer Pool中的請求。

隨機預讀:如果開啟了隨機預讀功能(默認:innodb_random_read_ahead=OFF),如果某個區(extent)有13個連續的頁面都已經被加載到了Buffer Pool中,無論這些頁面是不是順序讀取的,都會觸發一次異步讀取本區全部的頁到Buffer Pool中的請求。

針對LRU鏈表方案缺點的優化

  • 針對預讀的優化①InnoDB規定,當磁盤上的某個頁在初次加載(只是加載,沒有涉及讀取)到BufferPool中的某個緩沖頁時,該緩沖頁對應的控制塊會被放到old區域的頭部。這樣預讀頁就只會在old區域,不會影響young區域中使用比較頻繁的緩沖頁。
  • 針對全表掃描的優化①雖然首次加載放到的是old區域的頭部,但是由于是全表掃描,會對加載的數據進行訪問,那么第一次訪問的時候,就會將該頁放到young區域的頭部。這樣仍然會把那些使用頻率比較高的頁面給“排擠”下去。②那怎么辦呢?由于全表掃描有一個特點,就是它對某個頁的頻繁訪問且總耗時很短。所以,針對這種情況,InnoDB規定,在對某個處于old區域的緩沖頁進行第一次訪問時,就在它對應的控制塊中記錄下這個訪問時間,如果后續的訪問時間與第一次訪問的時間在某個時間間隔內(即:innodb_old_blocks_time,默認為1000,單位為ms),那么該頁面就不會從old區域移動到young區域的頭部,否則將它移動到young區域的頭部。

chunk和BufferPool實例

redoLog*

什么是redo日志

如果我們只在內存的BufferPool中修改了頁面,假設在事務提交后突然發生了某個故障,導致內存中的數據都失效了,那么這個已經提交的事務在數據庫中所做的更改也就丟失了。針對這種問題,怎么處理呢?

【方案1】在事務提交時,把該事務修改的所有頁面都刷新到磁盤,刷新成功了才提示事務提交成功刷新一個完整的數據頁太浪費了雖然我們只修改了一條記錄,但是會將這條記錄所在的頁(16KB)都刷新到磁盤上,會造成大量磁盤I/O的浪費。②隨機I/O刷新起來比較慢一個事務可能包含很多語句,即使是一條語句也可能修改許多頁面,并且該事務修改的這些頁面可能并不相鄰。這就意味著將某個事務修改的BufferPool中的頁面刷新到磁盤時,需要進行很多的隨機I/O。而隨機I/O要比順序I/O慢,尤其是機械硬盤。

【方案2】在事務提交時,只需要把修改的內容記錄一下就好了例如:“將第0號表空間第100號頁面中偏移量為1000處的值更新為2。”

redo簡單日志類型

在對頁面的修改是極其簡單的情況下,redo日志中只需要記錄一下在某個頁面的某個偏移量處修改了幾個字節的值、具體修改后的內容是什么就好了,比如操作MaxRowId

MLOG_1BYTE:表示在頁面的某個偏移量處寫入1字節的redo日志類型。

MLOG_2BYTE:表示在頁面的某個偏移量處寫入2字節的redo日志類型。

MLOG_8BYTE:表示在頁面的某個偏移量處寫入8字節的redo日志類型。

MLOG_WRITE_STRING:表示在頁面的某個偏移量處寫入一個字節序列。

redo復雜日志類型(以MLOG_COMP_REC_INSERT例:

redo日志組

在執行語句的過程中產生的redo日志,被InnoDB劃分成了若干個不可分割的組。比如:更新MaxRowID屬性時產生的redo日志為一組,是不可分割的;向聚簇索引/二級索引對應B+樹的頁面中插入一條記錄時產生的redo日志為一組,是不可分割的等等。?InnoDB認為,比如向某個索引對應的B+樹中插入一條記錄的過程必須是原子的,不能說插入了一半之后就停止了。否則就會形成一棵不正確的B+樹。所以他們規定在執行這些需要保證原子性的操作時,必須以組的形式來記錄redo日志。在進行恢復時,針對某個組中的redo日志,要么把全部的日志都恢復,要么一條也不恢復。

MTR(Mini-Transacti on)

對底層頁面進行一次原子訪問的過程被稱為一個Mini-Transaction(MTR)。

事務、語句、MTR、redo日志之間的關系,如下所示:① 1個事務可以包含N條SQL語句② 1條SQL語句可以包含N個MTR③ 1條MTR可以包含N條redo日志

redolog block

為了更好地管理redo日志,InnoDB把通過MTR生成的redo日志都放在了大小為512字節的頁中,把用來存儲redo日志的頁稱為block。

與Buffer Pool類似,寫入redo日志時也不能直接寫到磁盤中,實際上在服務器啟動時就向操作系統申請了一大片稱為redo log buffer(redo日志緩沖區)的連續內存空間,也可以將其簡稱為log buffer。這片內存空間被劃分成若干個連續的redo log block。

其中,用innodb_log_buffer_size指定log buffer的大小。該啟動選項的默認值為16MB。

redo日志緩沖區——log buffer

向log buffer中寫入redo日志的過程是順序寫入的。其中,buf_free是一個全局變量,該變量指明后續寫入的redo日志應該寫到log buffer中的哪個位置。

一個MTR執行過程中可能產生若干條redo日志,這些redo日志是一個不可分割的組,所以并不是每生成一條redo日志就將其插入到log buffer中,而是將每個MTR運行過程中產生的日志先暫時存到一個地方,當該MTR結束的時候,再將過程中產生的一組redo日志全部復制到log buffer中

不同的事務是可能并發執行的,所以T1、T2的MTR可能是交替執行的。

redo日志刷盤和日志文件組

MTR運行過程中產生的一組redo日志在MTR結束時會被復制到log buffer中。可是這些日志總在內存里也不是辦法,在一些情況下它們會被刷新到磁盤中:

**重點面試題:redolog 在哪些情況刷盤?

①log buffer空間不足50%的時候②事務提交的時候③ 后臺有線程,大約以每秒1次的頻率將log buffer中的redo日志刷新到磁盤。④ 正常關閉服務器時⑤ 做checkpoint時

在MySQL的數據目錄中,默認有名稱為:ib_logfile0和ib_logfile1的兩個文件,logbuffer中的日志在默認情況下就是刷新到這兩個磁盤文件中,也可以通過下一頁中的配置參數對其進行調節和修改:

查看redo日志相關配置信息

datedir:查看數據目錄所在位置。

innodb_log_group_home_dir指定了redo日志文件所在目錄,默認值為當前的數據目錄。

redo日志文件格式

lsn(logsequence number)

lsn是一個全局變量,用來記錄當前總共已經寫入的redo日志量。

lsn初始值為8704,也就是說,一條redo日志什么也沒寫入的時候,lsn的值就是8704。

redo日志刷新到磁盤

flush鏈表

刷入磁盤

mtr1和mtr2生成的redo日志雖然已經寫到磁盤上的log file中了,但是它們修改的臟頁仍然留在Buffer Pool中,所以它們的redo日志不可以被覆蓋。隨著系統運行,如果頁a從Buffer Pool中刷到了磁盤上,那么頁a對應的控制塊就會從flush鏈表中移除掉。而且,它的redo日志占用的空間就可以被覆蓋掉了。

chec kpoint

InnoDB通過全局變量checkpoint_lsn,來表示當前系統中可以被覆蓋的redo日志總量是多少。這個變量的初始值也是8704(因為lsn的初始值就是8704)。比如,現在頁a被刷新到了磁盤上,mtr1生成的redo日志就可以被覆蓋了,所以進行一個增加checkpoint_lsn的操作。我們把這個過程稱為執行一次checkpoint。

redo日志文件組中各個lsn值的關系,如下圖所示:

innodb_flush_log_at_trx_commit

為了保證事務的持久性,用戶線程在事務提交時,需要將該事務執行過程中產生的所有redo日志都刷新到磁盤中。

這個規則我們可以通過系統變量innodb_flush_log_at_trx_commit來進行配置修改,該變量有如下3個可選值:0:在事務提交時,不立即向磁盤同步redo日志,這個任務交給后臺線程來處理;1:在事務提交時,需要將redo日志同步到磁盤。(默認值)2:在事務提交時,需要將redo日志寫到操作系統的緩沖區中,但并不需要保證將日志真正刷新到磁盤。如果操作系統掛掉了,則數據丟失。

剩下內容在下篇持續更新,下方鏈接

InnoDB存儲引擎底層拆解:從頁、事務到鎖,如何撐起MySQL數據庫高效運轉(下)-CSDN博客

undoLog*

事務**

MVCC

*

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/94787.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/94787.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/94787.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【人工智能99問】GPT4的原理是什么?(32/99)

【人工智能99問】GPT4的原理是什么?(32/99) 文章目錄GPT-4簡介一、結構與原理二、使用場景三、優缺點分析四、訓練技巧與關鍵改進五、示例說明六、總結GPT-4簡介 一、結構與原理 1. 架構設計 GPT-4基于Transformer解碼器架構,核心改進包括:…

//Q是一個隊列,S是一個空棧,實現將隊列中的元素逆置的算法。

#include<stdio.h> #include<stdbool.h> #include<stdlib.h> #define Size 6 typedef struct SqNode//隊列結點 {int data;struct SqNode* next; }LinkNode; typedef struct SqQueue//隊列 {LinkNode* front, * rear; //頭指針和尾指針 }LinkQueue; typedef …

畢馬威 —— 公眾對人工智能的信任、態度及使用情況調查

文章目錄 前言 一、背景介紹 二、對人工智能的信任與接受度 三、人工智能的使用與認知情況 四、人工智能的益處與風險 五、人工智能的監管與治理 六、工作場所的人工智能應用 七、人工智能對工作的影響 八、學生對人工智能的應用 九、核心啟示 1.新興經濟體在公眾與員工人工智能…

基于Spring Session + Redis + JWT的單點登錄實現

實現思路 用戶訪問受保護資源時&#xff0c;若未認證則重定向到認證中心認證中心驗證用戶身份&#xff0c;生成JWT令牌并存儲到Redis認證中心重定向回原應用并攜帶令牌應用驗證JWT有效性并從Redis獲取會話信息用戶在其他應用訪問時&#xff0c;通過相同機制實現單點登錄 代碼…

微服務Eureka組件的介紹、安裝、使用

微服務 Eureka 組件的介紹、安裝與使用詳解 在微服務架構中&#xff0c;服務注冊與發現是至關重要的一環&#xff0c;而 Eureka 作為 Netflix 開源的服務注冊中心&#xff0c;廣泛應用于 Spring Cloud 微服務體系中。本文將帶你全面了解 Eureka 的概念、安裝及在 Spring Boot …

【PostgreSQL內核學習:通過 ExprState 提升哈希聚合與子計劃執行效率(一)】

PostgreSQL內核學習&#xff1a;通過 ExprState 提升哈希聚合與子計劃執行效率&#xff08;一&#xff09;引言背景補丁的意義補丁概述JIT & LLVM實際例子&#xff08;以 PostgreSQL 為例&#xff09;提交信息提交描述引入 ExprState 進行哈希計算&#xff1a;支持 JIT 編譯…

web端播放flv視頻流demo(flv.js的使用)

需求&#xff1a;原本是需要前端播放RTMP視頻流的&#xff0c;但是現在的瀏覽器都不支持flash插件了&#xff0c;讓用戶安裝flash插件也不現實&#xff0c;所以直接讓后端將RTMP視頻流轉換成flv視頻流給到前端進行播放。 直接上demo&#xff0c;直接就能播放&#xff0c;如果遇…

【拍攝學習記錄】04-拍攝模式/曝光組合

曝光組合全自動半自動光圈優先手動擋【固定物體長時間不變時候、閃光燈時候、】手機上的光學變焦與數碼變焦是不同的&#xff0c;使用檔位推薦可以提升畫質。手機夜景模式長曝光【車流軌跡、星軌】HDR 大光比【日落時候使用】專業模式&#xff0c;【感光度iso、快門可以調節】…

新liunx部署mysql過程問題

首先看下是什么發行版 cat /etc/os-release CentOS Linux 7 ################################## 使用 yum下載包 發現不行 源不行 那就換成阿里的 # 進入 yum 源配置目錄 cd /etc/yum.repos.d/ # 備份所有默認 repo 文件&#xff08;以 CentOS 為例&#xff0c;其他系統…

Python 第三方庫:Beautiful Soup(HTML/XML 解釋提取)

Beautiful Soup 是一個 用于從 HTML 和 XML 文件中提取數據的 Python 第三方庫。它為復雜的網頁結構提供了簡單易用的解析接口&#xff0c;尤其適合網頁爬蟲和數據提取任務。Beautiful Soup 提供樹型結構訪問、標簽搜索、屬性提取等功能&#xff0c;并支持多種解析器&#xff0…

使用STM32CubeMX使用CAN驅動無刷電機DJI3508

簡介 文章為筆記性質 硬件包括 大疆C板 電機調速器C620 DJI3508電機 CAN知識介紹 CAN的概念 CAN是控制器區域網絡&#xff08;Controller Area Network&#xff09;的縮寫。CAN總線是一種適用于工業設備的高性能總線網絡。說白了就是也就是一種通訊方式而已。 把多個設…

Wi-Fi 802.11s自組網/EasyMesh自組網/802.11ah物聯網

一、前期調研結論 前面詳細探討了自組網和5G無線通信網絡、WiFi無線通信網絡的差異&#xff1a; 自組網 v.s 5G v.s WiFi-CSDN博客 從“分級道路”角度理解無線通信網絡拓撲包括從當前工業應用場景具體案例了解終端無線通信網絡&#xff1a; 5G無線通信網絡場景&#xff08;…

【基于hyperledger fabric的教育證書管理系統】

教育證書管理系統 系統概述 項目背景 隨著數字化轉型的深入推進&#xff0c;教育證書作為個人學術成就和專業資質的重要憑證&#xff0c;在就業市場、高等教育和職業發展中扮演著關鍵角色。然而&#xff0c;傳統教育證書管理體系面臨著數據孤島、證書偽造、驗證流程繁瑣以及跨機…

【Flask】測試平臺開發,集成禪道

概述&#xff1a; 由于公司多數測試人員還是在使用禪道&#xff0c;為了方便&#xff0c;就將禪道直接集成在我們的測試平臺中 一般可以有幾種實現方法 調用禪道的API集成集成本地部署的禪道-可能有跨域問題&#xff0c;需要解決 由于我這里已經部署了一臺本地的禪道系統&…

《UE5_C++多人TPS完整教程》學習筆記45 ——《P46 待機與跳躍(Idle And Jumps)》

本文為B站系列教學視頻 《UE5_C多人TPS完整教程》 —— 《P46 待機與跳躍&#xff08;Idle And Jumps&#xff09;》 的學習筆記&#xff0c;該系列教學視頻為計算機工程師、程序員、游戲開發者、作家&#xff08;Engineer, Programmer, Game Developer, Author&#xff09; St…

用html+js下拉菜單的demo,當鼠標點擊后展開,鼠標點擊別的地方后折疊

使用html js實現下拉菜單demo&#xff0c;因為copy的網站菜單功能失效&#xff0c;就需要自己寫一個邏輯&#xff0c;點擊其他區域折疊菜單&#xff0c;可以參考&#xff1a;<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF…

OpenCV 核心技術:顏色檢測與幾何變換實戰

在計算機視覺任務中&#xff0c;顏色空間轉換和圖像幾何變換是兩大基礎且高頻的操作 —— 前者用于精準分割特定顏色目標&#xff08;如交通信號燈、物體追蹤&#xff09;&#xff0c;后者用于調整圖像的尺寸、位置和視角&#xff08;如文檔矯正、圖像拼接&#xff09;。本文將…

[HFCTF2020]EasyLogin

文章目錄TRYWP總結TRY 注冊admin報錯username wrong。 隨便注冊一個用戶點擊GetFlag&#xff0c;permission deny。 猜測可能是需要admin權限。 看cookie發現有&#xff1a; sses:aok&#xff1a;eyJ1c2VybmFtZSI6ImEiLCJfZXhwaXJlIjoxNzU2NDU1NjczMTAxLCJfbWF4QWdlIjo4NjQwM…

Java接口和抽象類的區別,并舉例說明

Java接口和抽象類是面向對象編程中實現抽象的兩種機制&#xff0c;它們在語法、設計目的和使用場景上有顯著區別&#xff1a;一、核心區別?定義方式?抽象類&#xff1a;使用abstract class聲明&#xff0c;可包含抽象方法和具體方法45。接口&#xff1a;使用interface聲明&am…

docker-相關筆記

1: 導入鏡像 docker load -i myimage.tar# 導出鏡像 docker save myimage:latest > myimage.tar # 導入鏡像 docker load -i myimage.tardocker load -i <文件> 功能&#xff1a;用于導入通過 docker save 命令導出的鏡像歸檔文件&#xff08;通常是 .tar 格式&#…