主頁 > 前端設計 > 幾年了?作為一個碼農終于把MySQL日記看懂了,為此肝出此文!!!

幾年了?作為一個碼農終于把MySQL日記看懂了,為此肝出此文!!!

2020-10-13 04:15:44 前端設計

目錄

一、寫作背景

二、文章指引

三、必要概念字典介紹

四、認識二進制日記(Binlog)

4.1 Binlog概念

4.2 Binlog 作用

4.3 Binlog 記錄程序及刷盤時機

4.4 Binlog 記錄格式

五、認識事務日記(Undo log)

5.1 Undo log 概念

5.2 Undo log 作用

5.3 Undo log 記錄程序及刷盤時機

5.4 Undo log 總結

六、認識事務日記 (Redo log)

6.1 Redo log 概念

6.2 Redo log 作用

6.3 Redo log 的兩階段提交

6.4 Redo log 容災恢復程序

6.5 Redo log 刷盤時機

6.6 Redo log 存盤方式

6.7 Redo Log 檢查點

6.8 Redo Log LSN

6.9 Redo log 容災恢復程序與LSN

七、了解 ChangeBuffer

7.1 為啥提到ChangeBuffer

7.2 ChangeBuffer概念及作用

7.3 ChangeBuffer與Redo log區別

7.4 有沒有用到ChangeBuffer對于Redo log的區別

7.5 ChangeBuffer的merge程序

八、日記大連貫U-R-B,一舉攻破拿下

8.1 制造演示資料

8.2 假設沒有日記和ChangeBuffer 示范

8.3 考慮所有日記和ChangeBuffer 示范--現有Innodb流程

8.3.1 兩階段提交程序

8.3.2 merge 程序

8.3.3 資料刷盤程序

九、結尾


一、寫作背景

大家都清楚,日志是 MySQL資料庫的重要組成部分,記錄著資料庫運行期間各種狀態資訊,MySQL日志主要包括錯誤日志查詢日志慢查詢日志二進制日志(binlog)事務日志(redo log、undo log)幾大類,

其中,二進制日記事務日記尤為重要,一直被人重視、深入研究;可是事實很殘忍,重視或者說大多數人一般都是了解個表面,真正懂得人并不多,真想攻破這兩塊日記必須下血本,而且還不一定能攻破,但是不要緊,為了讓你們省下血本還能順利攻破這兩塊日記,我連續研究幾周MySQL日記,最終肝出了這篇文章

二、文章指引

文章指導:文章第三節內容切莫跳過但如果覺得第四、第五、第六和第七節沒意思或者已經有了概念直接進入文章第八節一舉攻破拿下,

文章方向:理論、原理篇,

三、必要概念字典介紹

基礎不牢地動山搖,還是常規套路,先把必要知識普及/溫習一遍,當后續文章出現疑慮反過來看下這些概念字典,說不定能 “柳暗花明又一村” 呢?

寫了又寫,想了又想,糾結了好久,這部分知識確實有點多,最后還是決定將這些必要概念字典單獨分出一個文章,后續打算用截圖方式引入各個章節中,建議遇到不懂名詞查閱一下字典,

點擊獲取通往字典的大門的鑰匙--想學習進階資料庫知識???這些概念必須攻破!

圖1:進階知識部分示意圖

四、認識二進制日記(Binlog)

4.1 Binlog概念

Binlog 是邏輯日記,用于記錄資料庫執行的寫入操作(查詢不記錄)資訊,Server層記錄和引擎層無關,并且是以追加方式進行寫入,可以通過引數 max_binlog_size 設定每個Binlog檔案的大小,檔案大小達到設定值時會生成新的檔案來保存日記,

4.2 Binlog 作用

在實際應用中,主要用在兩個場景:主從復制和資料恢復

  • 主從復制場景:在Master主端開啟Binlog,將Binlog發生到各個Slave從端,Slave從端重放Binlog從而達到主從資料一致
  • 資料恢復場景:通過使用 mysqlbinlog 工具來恢復資料

4.3 Binlog 記錄程序及刷盤時機

Binlog何時記錄將在第六點進行介紹,大致記錄程序是先寫Binlog Buffer,然后通過刷盤時機,控制刷入OS Buffer,控制fsync()進行寫入Binlog File日記磁盤的程序,

對于Binlog,MySQL是通過引數sync_binlog引數來控制刷盤時機,取值是0、1和N三種值,0表示由系統自行判斷何時呼叫sync()寫入磁盤;1表示每次事務commit都要呼叫fsync()寫入磁盤;N表示每N個事務,才會呼叫fsync()寫入磁盤,

圖2:記憶體和磁盤日記結構圖

4.4 Binlog 記錄格式

MySQL5.7.7版本之前默認格式是STATEMENT,版本之后默認是ROW,可以通過引數 binlog-format指定,

STATMENT

基于SQL陳述句復制,每一條修改資料的sql陳述句都會被記錄到Binlog中

優點:不需要記錄每一行的變化,記錄Binlog日記量減少,

缺點:在某種情況下會導致主從資料不一致,比如執行sysdate()、slepp()等,具體可以自己去深入了解,

ROW

推薦使用,MySQL高版本的默認值,基于行的復制,不記錄每條sql資訊,僅僅記錄哪行資料被修改了

優點:沒有STATMENT模式中所說的主從資料不一致情況,

缺點:記錄行,需要更多的空間,會產生大量的日記,

MIXED上面兩種模式的混合,一般情況采用STATMENT模式保存Binlog,特殊情況采用ROW模式保存Binlog,

五、認識事務日記(Undo log)

5.1 Undo log 概念

Undo log是邏輯日記、回滾日記,比如一條修改+3的邏輯陳述句,Undo log會記錄對應一條-3的邏輯日記,一條插入陳述句則會記錄一條洗掉陳述句,這樣發生錯誤時,根據執行Undo log就可以回滾到事務之前的資料狀態,

5.2 Undo log 作用

  • 回滾資料:當程式發生例外錯誤時等,根據執行Undo log就可以回滾到事務之前的資料狀態,保證原子性,要么成功要么失敗,
  • MVCC一致性視圖:通過Undo log找到對應的資料版本號,是保證MVCC視圖的一致性的必要條件,

5.3 Undo log 記錄程序及刷盤時機

刷盤程序及時機類似于Binlog和Redo,可以參考Redo log刷盤時機章節給出的圖片,已經體現出來了,

5.4 Undo log 總結

Undo log日記內容不是很多,重點是回滾多版本控制MVCC那塊,此外,我記得印象筆記深刻的是長事務會導致日記過多,這個日記就是Undo log,因為長事務存在,導致需要保存很多視圖快照,其實這里就是設及到Undo log何時洗掉和生成的問題,當時糾結好久,其實很簡單,生成是事務開始后寫Redo log之前生成,當沒有事務需要用到Undo log時就會被洗掉,舉個例子,如果事務A一直存活,那么事務A之后產生的事務B、C...等等就算提交了,也不會被洗掉,因為事務A需要用到B、C...事務去找A的版本,所以避免長事務可以減少Undo log日記量,當然還可以提高性能,

六、認識事務日記 (Redo log)

6.1 Redo log 概念

Redo log 是重做日記,屬于InnoDB引擎的日記,是物理日記,日記記錄的內容的是資料頁的更改,這個頁 “做了什么改動”,如:add xx記錄 to Page1,向資料頁Page1增加一個記錄,

6.2 Redo log 作用

  • 前滾操作:具備crash-safe能力,提供斷電重啟時解決事務丟失資料問題,
  • 提高性能:先寫Redo log記錄更新,當等到有空閑執行緒、記憶體不足、Redo log滿了時 “刷臟”,寫Redo log是順序寫入,刷臟是隨機寫,節省的是隨機寫磁盤的 IO 消耗(轉成順序寫),所以性能得到提升,此技術稱為WAL技術:Write-Ahead Logging,它的關鍵點就是先寫日記磁盤,再寫資料磁盤

6.3 Redo log 的兩階段提交

更新記憶體后引擎層寫Redo log將狀態改成prepare為預提交第一階段,Server層寫Binlog,將狀態改成commit為提交第二階段,兩階段提交可以確保Binlog和Redo log資料一致性,

6.4 Redo log 容災恢復程序

MySQL的處理程序如下

  • 判斷redo log是否完整,如果判斷是完整(commit)的,直接用Redo log恢復
  • 如果redo log只是預提交prepare但不是commit狀態,這個時候就會去判斷binlog是否完整,如果完整就提交Redo log,用Redo log恢復,不完整就回滾事務,丟棄資料,

只有在redo log狀態為prepare時,才會去檢查binlog是否存在,否則只校驗redo log是否是 commit就可以啦, 怎么檢查binlog:一個完整事物binlog結尾有固定的格式,

6.5 Redo log 刷盤時機

Undo log的刷盤時機和Redo log差不多,但是對于Undo log我沒找到對應的刷盤引數設計,所以不在提,Redo log每次先寫入Redo Log Buffer中,然后通過刷盤時機控制刷入OS Buffer時間和刷入日記磁盤的時間,

圖3:記憶體和磁盤日記結構圖

在Undo Log中,MySQL是通過引數innodb_flush_log_at_trx_commit來控制刷盤時機,取值是0、1和2三種值,0表示事務提交后,每秒寫入OS Buffer并呼叫fsync()寫入日記磁盤中;1表示每次事務提交會寫入OS Buffer并呼叫fsync()將日記寫入日記磁盤中,2表示事務每次提交寫入到OS Buffer,每秒呼叫fsync()寫入日記磁盤,可見引數為1是最安全的,同時也是默認值,

圖4:Redo log刷盤時機引數對應操作圖

6.6 Redo log 存盤方式

圖5:Redo log File環形存盤結構圖

上圖是日記磁盤的Redo log環形設計圖(從頭寫,寫到結束又從頭開始寫~回圈),write pos和check point是兩個指標,write pos指標指向當前日記檔案寫入的位置check point指標指向當前要擦除的開始位置,圖中綠色部分是可以寫入Redo log地方,每次寫入,write pos指標會順時針推進,當然基本不會與check point指標重合,因為MySQL有這種機制去實作,每次觸發檢查點checkpoint,check point會指標向前推進,這個程序就是需要進行刷日記和資料磁盤,記錄相應的LSN,引出難點LSN,

6.7 Redo Log 檢查點

啥時候會觸發檢查點checkpoint,網上找了點資料:啥時候資料庫會觸發檢查點checkpoint

圖6:檢查點觸發時機

Checkpoint發生的時間、條件及臟頁的選擇等都非常復雜,而Checkpoint所做的事情無外乎是將緩沖池中的臟頁刷回到磁盤,不同之處在于每次重繪多少頁到磁盤,每次從哪里取臟頁,以及什么時間觸發Checkpoint,這些本文不會去研究,

6.8 Redo Log LSN

LSN這個概念,比較復雜,我介紹完你們不一定懂!LSN稱為日志的邏輯序列號(log sequence number),在innodb存盤引擎中,lsn占用8個位元組,LSN的值會隨著日志的寫入而逐漸增大,可以簡單理解SLN就是記錄從開始到現在已經產生了多少位元組的Redo log值

存盤方式兩個指標又是通過LSN計算得到指向位置,因為LSN記錄的是檔案的大小位元組,當超過檔案大小時,需要用取模計算出這兩個指標位置,取模使得寫入就會從頭開始寫,這樣使得兩個指標在一個檔案中,一直落在回圈位置,你追我趕的程序,這就是Redo log 環形邏輯思想設計實作,

上面提到LSN比較復雜,是因為它有很多個值,輸入命令"show engine innodb status;",可以看到四個的lsn記錄

圖7:LSN值串列

為了方便識別,我都為它們重新命名,如下,名詞記不住,后面無法繼續深入

1、記憶體日記:redo log buffer lsn;磁盤日記:redo log file lsn;

一般關系為:redo log buffer lsn >= redo log file lsn,如果刷盤時機為1,則redo log buffer lsn = redo log file lsn,

2、記憶體資料頁:data buffer lsn;資料磁盤資料頁:data disk lsn;

一般關系為data buffer lsn > data disk lsn,如果已經刷入資料磁盤,則data buffer lsn = data disk lsn,

3、檢查點:chckpoint lsn;

后面提到檢查點刷盤,資料刷盤和日記刷盤(如果有日記刷盤:則說明我假設的日記刷盤的時機設定值不為1,為1是同步的,即始終redo log buffer lsn = redo log file lsn,不會由檢查點觸發刷日記磁盤),

都說Redo log是環形記錄,那么怎么記錄的?下面結合LSN給出記錄程序虛構圖,可以對比6.6 Redo log 存盤方式圖
相關知識:日記磁盤 + redo log file lsn + checkpoint lsn + 雙指標(write pos、check point)

1-8按時間順序發生,1點是假設最初的狀態;2、3點寫日記磁盤;4點是觸發了檢查點checkpoint,進行刷盤,checkpoint lsn=1開始,刷盤結束并更新checkpoint lsn=512,在5點、6點已經刷過了一回圈記憶體、二回圈記憶體,從頭開始寫入log,兩個指標指向回到了頭部,第7點也是一個觸發checkpoint的程序,9點是假設沒有更新,最后達到平衡的結果,即記憶體中資料頁和日記都完成了刷盤,

圖8:Redo Log File存盤程序

整個流程:

在某些情況下,觸發checkpoint,觸發資料頁和日志頁刷盤,此時將記憶體中的臟資料---"資料臟頁"和"日志臟資料" 分別刷到資料磁盤和日記磁盤中,而且兩者刷盤速度不一樣,checkpoint會保護機制,當資料刷盤速度超過日志刷盤時,將會暫時停止資料刷盤,等待日志刷盤進度超過資料刷盤,

刷盤時,對于資料磁盤,全部都是在記憶體中,此時每次刷一個資料頁到記憶體更新資料頁也更新了data disk lsndata buffer lsn(在更新記憶體資料頁時,會更新data buffer lsn)

對于日記磁盤,除了要記錄checkpoint lsn的值為檢查點 checkpoint的值(必須在結束時 直接記錄一個值,速度很快),這里是針對日記刷盤時機不是1(1是同步快取刷日記刷盤)時,并且日記還沒刷到日記磁盤需要觸發將快取中日記提前刷到日記磁盤中,此時會將redo buffer log刷到redo log file中也更新了redo log file lsnredo log buffer lsn

模擬檢查點觸發前后,整個流程變化,一個資料頁和日記,資料變化及lsn從179-180的變化圖(刷盤時機不為1)

6.9 Redo log 容災恢復程序與LSN

結合6.4 Redo log 容災恢復程序和6.8的LSN知識,再次細化6.4的Redo log恢復程序

重啟innodb時,Redo log完不完整,采用6.4知識程序,用Redo log恢復,啟動資料庫時,InnoDB會掃描資料磁盤的資料頁data disk lsn和日志磁盤中的checkpoint lsn,兩者相等則從checkpoint lsn點開始恢復,恢復程序是利用 redo log到buffer pool,直到checkpoint lsn等于redo log file lsn,則恢復完成,

如果checkpoint lsn 小于 data disk lsn,說明在檢查點觸發后還沒結束刷盤時資料庫宕機了,因為checkpoint lsn最新值是在資料刷盤結束后才記錄的,檢查點之后有一部分資料已經刷入資料磁盤,這個時候資料磁盤已經寫入部分的部分恢復將不會重做,直接跳到沒有恢復的lsn值開始恢復,

七、了解 ChangeBuffer

7.1 為啥提到ChangeBuffer

為啥本文我會提到ChangeBuffer呢,其實很多時候會將ChangeBuffer和Redo log搞混,兩者都是巧用記憶體,減少磁盤IO,為了不弄混我覺得有必要專門對這個進行一個講解,

7.2 ChangeBuffer概念及作用

下面是我對ChangeBuffer的簡單介紹

也就是說對于更新的操作,如果用到了ChangeBuffer,更新的資料所在的資料頁如果不在記憶體中,將不用去資料磁盤將資料頁讀到記憶體,而是將這一次操作記錄在ChangeBuffer中,ChangeBuffer 主要節省的則是隨機讀磁盤的 IO 消耗,下次讀取查詢等讀取資料頁時用上ChangeBuffer中的記錄即可,其實也是一種巧用記憶體的思想,

7.3 ChangeBuffer與Redo log區別

Redo log 主要節省的是隨機寫磁盤的 IO 消耗(轉成順序寫),而 ChangeBuffer 主要節省的則是隨機讀磁盤的 IO 消耗

這句話怎么理解,看下面:

Redo log 與 ChangeBuffer(含磁盤持久化) 這2個機制,不同之處在于優化了整個變更流程的不同階段

先不考慮Redo log、ChangeBuffer機制,簡化抽象一個更新(insert、update、delete)流程:

  1. 從磁盤讀取待變更的行所在的資料頁,讀入記憶體頁中
  2. 對記憶體頁中的行,執行變更操作
  3. 將變更后的資料頁,寫入至資料磁盤中

其中,流程中的步驟1涉及隨機讀磁盤IO;步驟3涉及隨機寫磁盤IO;剛好對應ChangeBuffer和Redo log,

對那句話的理解答案:

  • ChangeBuffer機制,優化了步驟1——避免了隨機讀磁盤IO ,將不在記憶體中的資料頁的操作寫入ChangeBuffer中,而不是將資料頁從磁盤讀入記憶體頁中
  • Redo log機制, 優化了步驟3——避免了隨機寫磁盤IO,將隨機寫磁盤,優化為了順序寫磁盤(寫Redo log,確保crash-safe)

7.4 有沒有用到ChangeBuffer對于Redo log的區別

Redo log機制,為了保證crash-safe,一直都會用到, 有無用到ChangeBuffer機制,對于redo log這步的區別在于—— 用到了ChangeBuffer機制時,在Redo log中記錄的本次變更,是記錄new change buffer item相關的資訊,而不是直接的記錄物理頁的變更(文章中第八節都有體現這一程序), 在我們mysql innodb中, ChangeBuffer機制不是一直會被應用到,僅當待操作的資料頁當前不在記憶體中,需要先讀磁盤加載資料頁時,ChangeBuffer才有用武之地,

7.5 ChangeBuffer的merge程序

除了訪問這個資料頁會觸發 merge 外,系統有后臺執行緒會定期 merge,在資料庫正常關閉(shutdown)的程序中,也會執行 merge 操作,

merge程序做三步

  1. 從磁盤讀入資料頁到記憶體(老版本的資料頁);
  2. 從 change buffer 里找出這個資料頁的 change buffer 記錄 (可能有多個),依次應用,得到新版資料頁;
  3. 寫 redo log,這個 redo log 包含了資料的變更和 change buffer 的變更,

八、日記大連貫U-R-B,一舉攻破拿下

前面分別講的是Binlog、Undo log和Redo log,下面將他們都串聯起來,在一些流程體現全部日記,

同樣,以一些最經典的更新陳述句例子展開說明,

8.1 制造演示資料

測驗陳述句:插入陳述句+查詢陳述句,a欄位是普通索引

1、insert into ta(a,b) values(2,5),(7, 5)
2、select * from t where a in (2, 7)

假設原來的資料如下圖,資料頁page1在記憶體中,page2不在,插入的資料(2,5)落在page1,資料(7,5)落在page2中,

8.2 假設沒有日記和ChangeBuffer 示范

先不考慮所有日記及ChangeBuffer機制,簡化抽象一個更新insert流程

  1. 從磁盤讀取待變更的行所在的資料頁,讀入記憶體頁中
  2. 對記憶體頁中的行,執行變更操作
  3. 將變更后的資料頁,寫入至資料磁盤中

8.3 考慮所有日記和ChangeBuffer 示范--現有Innodb流程

程序是 兩階段提交-----日記刷盤------資料刷盤(涉及Redo log lsn 和 ChangeBuffer的內容)

8.3.1 兩階段提交程序

  1. 資料(2,5)所在頁page1在記憶體中直接更新記憶體;資料(7,5)所在頁page2不在記憶體中,記錄change buffer(具有唯一性的索引或者沒有使用change buffer的操作是將磁盤中的資料頁讀入記憶體中并做更新),
  2. 寫undo日記,先寫快取,后面根據刷盤引數決定何時刷入磁盤,后面的redo/Binlog都一樣,日記刷盤 在每一個日記中基本已經提到,它和設定的引數有關,具體刷盤可以參考上文4.3和6.5章節,下文不會再展開介紹,
  3. 寫redo日記(先記在記憶體中的更新,然后記不在記憶體中的change buffer的改變)
  4. 日記狀態改成prepare階段,
  5. 寫Binlog日記,
  6. 提交事務,日記狀態改成commit階段,

8.3.2 merge 程序

緊接著上文,圖片可上下參考,假設現在執行查詢陳述句 “select * from t where a in (2, 7)” ,此次查詢索引a=7所在的資料頁不在記憶體中,并且上一步更新已經在change buffer中有記錄,將會觸發merge程序(參考第七章節7.5),

  1. 將page2讀入記憶體
  2. 依次應用change buffer中的記錄,得到最新版資料頁
  3. 寫入redo,之前記錄的changebuffer改動,現在改成資料頁的改動

至于changebuffer被應用后是洗掉還是標記,還有redo中原有的記錄changebuffer的改動怎么調整是洗掉還是修改成資料頁的改動這里下面的圖是按照自己的想法描述出來,如有誤望留言指正,

8.3.3 資料刷盤程序

資料刷盤flush的有四種情況

  1. InnoDB 的 redo log 寫滿了,這時候系統會停止所有更新操作,把 checkpoint 往前推進,redo log 留出空間可以繼續寫
  2. 系統記憶體不足,當需要新的記憶體頁,而記憶體不夠用的時候,就要淘汰一些資料頁,空出記憶體給別的資料頁使用,如果淘汰的是“臟頁”,就要先將臟頁寫到磁盤
  3. MySQL 認為系統“空閑”的時候
  4. MySQL 正常關閉的情況

資料刷盤也代表著Redo log檢查點checkpoint觸發,這一步將聯系到第六章6.7和6.8中的章節內容,較為復雜,

假設資料刷盤flush的四種情況發生了一種,那么聯系上文的程序將如下

  1. 將臟頁從記憶體中刷回到資料磁盤
  2. 刷完后更新檢查點checkpoint的值

流程中間某個環節資料庫宕機后,恢復具體程序,這些留在心里了,沒往上去寫,讀者可以自行思考,不難,

九、結尾

整個文章講了Binlog、Undo log和Redo log,隨帶一提ChangeBuffer,前面四五六七章是分講,最后第八章是對整個日記相關聯講解,對此,講到這里,基本上要把我要將的已經講完,內容挺多,有耐心可以慢慢啃,不懂歡迎留言!

思考環節,下面留下兩個問題,歡迎大家留言解答

1、為啥Binlog沒有crash-safe功能?

2、保證crash-safe為啥要用兩個日記,不能用一個日記嗎(Redo log或Binglog)?

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/170137.html

標籤:其他

上一篇:2020電賽省賽實戰(二)ADS1292心電檢測儀

下一篇:MySql領域經典之作,“不敢自詡為MySql專家,豈敢錯過這本神書”

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more