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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 5.1版本无innodb trx_MySQL 5.7: Innodb 事务子系统优化-阿里云开发者社区

發(fā)布時間:2025/3/12 数据库 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 5.1版本无innodb trx_MySQL 5.7: Innodb 事务子系统优化-阿里云开发者社区 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

MySQL5.7 : Innodb 事務(wù)子系統(tǒng)優(yōu)化

之前寫了篇博客介紹了Percona Server對Read View的優(yōu)化,順帶簡單提到了MySQL5.7的事務(wù)子系統(tǒng)優(yōu)化,詳細見http://mysqllover.com/?p=834?。 另外一篇博客http://mysqllover.com/?p=1087?也有所涉及。

本文總體介紹了幾個和事務(wù)子系統(tǒng)相關(guān)的worklog以及其代碼實現(xiàn)。這部分代碼值得細讀,因為他們是5.7 Innodb比較核心的改動,極大的提升了只讀場景下的性能。

這個worklog包含幾點變化:

第一,無需顯示的開啟只讀事務(wù),所有的事務(wù)開始默認(rèn)為只讀事務(wù),當(dāng)遇到讀寫SQL時,自動加入讀寫列表。

第二,只讀事務(wù)不為其分配事務(wù)ID,因此如果SHOW ENGINE INNODB STATUS時看到大量事務(wù)的ID表現(xiàn)的很怪異時(非常大的整數(shù)值),不要覺得奇怪。

該改進帶來的最大的好處是你無需修改你的業(yè)務(wù)SQL。其實這才是用戶能接受的特性,如果沒有量級別的提升,誰會愿意去改代碼呢?

不過顯而易見的,這個優(yōu)化也帶了某些 運維的‘退化’,例如你再也無法從SHOW ENGINE INNODB STATUS中發(fā)現(xiàn)一個活躍的長時間不提交的只讀事務(wù)(例如:BEGIN;SELECT;SELECT…),你需要去查詢INNODB_TRX表來獲得這些信息。

我們以一個典型的例子來開啟這個話題,首先準(zhǔn)備一個簡單的表。隔離級別為READ-COMMIT

CREATE TABLE t1 (a INT PRIMARY KEY, b INT);

INSERT INTO t1 VALUES (1,RAND()*100),(2,RAND()*100);

BEGIN;

以BEGIN顯式開啟一個事務(wù);

b) SELECT * FROM t1;

分配一個事務(wù)句柄:

ha_innobase::open

ha_innobase::info_low

update_thd

check_trx_exists

innobase_trx_allocate

trx_allocate_for_mysql

新分配的事務(wù)句柄會加入到trx_sys->mysql_trx_list,并重復(fù)使用。

開始一個只讀事務(wù),開啟的事務(wù),不分配事務(wù)ID, 不分配回滾段

row_search_mvcc->trx_start_if_not_started->trx_start_low

Assign Read View

row_search_mvcc

trx_assign_read_view

MVCC::view_open

分配的read view會拷貝當(dāng)前的活躍事務(wù)ID,設(shè)置最高和最低可見事務(wù)ID,然后加入到活躍事務(wù)的read view鏈表上(MVCC::m_views)

c) UPDATE t1 SET b=b+1 WHERE a=2;

row_search_mvcc

lock_table

trx_set_rw_mode

將事務(wù)轉(zhuǎn)換成讀寫事務(wù)模式,分配回滾段,分配事務(wù)ID。加入讀寫事務(wù)鏈表(trx_sys->rw_trx_ids, trx_sys->rw_trx_set, trx_sys->rw_trx_list)。

d) COMMIT; 事務(wù)提交

代碼:

在該worklog種優(yōu)化了read view的創(chuàng)建,對MVCC控制視圖部分的代碼進行了重構(gòu)。

具體包括以下幾個方面:

在之前版本中,read view的創(chuàng)建的復(fù)雜度為O(N),因為需要掃描讀寫事務(wù)鏈表;

現(xiàn)在創(chuàng)建一個read view 需要以下幾步:

Step 1:

view->prepare(trx->id);

拷貝事務(wù)ID(不包含自己的事務(wù)ID),相當(dāng)于做一個當(dāng)前活躍讀寫事務(wù)的快照存放在視圖中,直接使用memcpy的方式 (copy_trx_ids(trx_sys->rw_trx_ids)),這一點和percona的優(yōu)化是一樣的。

設(shè)置m_low_limit_no ,m_low_limit_id

Step 2:

view->complete();

設(shè)置視圖的m_up_limit_id,表示所有小于這個值的修改都可見

Step 3:

UT_LIST_ADD_FIRST(m_views, view);

將視圖加入到活躍視圖鏈表中。

b)?在之前版本中是在持有trx_sys mutex時創(chuàng)建的read view。

為了降低分配/釋放read view的開銷,維護了兩個read view鏈表,一個用于放當(dāng)前活躍的視圖鏈表,一個用于放空閑的、可分配的視圖鏈表。

當(dāng)系統(tǒng)啟動時,會初始化一定數(shù)量的read view放到空閑鏈表上。

Percona實現(xiàn)了類似的方案,不同的是Percona的read view在事務(wù)完成后不是放到空閑鏈表,而是下次繼續(xù)重用(但從活躍鏈表移除,不管是否是讀寫事務(wù))

c) 對于autocommit的只讀事務(wù),即時當(dāng)前沒有活躍事務(wù),也可能因為創(chuàng)建read view ,而大量別的線程在釋放read view,導(dǎo)致trx_sys mutex沖突。

針對該問題,實際上我已經(jīng)在博文http://mysqllover.com/?p=1087中描述過了,對于自動提交的查詢,在關(guān)閉read view時是不從視圖鏈表上移除的,在再次開啟事務(wù)重用該read view時,如果這期間沒有讀寫事務(wù),都無需重新初始化read view,直接使用即可。 因此如果一臺實例上的都是自動提交的只讀事務(wù),完全可以避免trx_sys mutex的開銷。

d) 需要持有trx_sys mutex來遍歷rw_trx_list,以判斷更改是否可見,或者根據(jù)事務(wù)id獲取事務(wù)對象trx_t

由于已經(jīng)保存了事務(wù)ID的快照,因此直接根據(jù)二分查找查找有序數(shù)組即可,無需遍歷讀寫事務(wù)鏈表

參考函數(shù)ReadView::changes_visible

trx_sys_t新增成員rw_trx_set,用于維護從trx_id到trx_t的映射。這樣可以根據(jù)事務(wù)ID快速找到對應(yīng)的事務(wù)對象而無需掃描事務(wù)鏈表。參考函數(shù)trx_get_rw_trx_by_id

主要更改:

在完成上述修改后,無需再維持ro_trx_list了,因為所有事務(wù)默認(rèn)都被當(dāng)做只讀事務(wù),這個鏈表開銷完全可以忽略掉的。

該worklog主要實現(xiàn)了隱式鎖向現(xiàn)式鎖轉(zhuǎn)換的一個優(yōu)化點。在獲取活躍事務(wù)對象時,無需持有l(wèi)ock_sys mutex鎖。

在連續(xù)內(nèi)存中預(yù)分配事務(wù)對象,保持內(nèi)存的連續(xù)性有利于編譯器或者CPU做出某些優(yōu)化,例如內(nèi)存預(yù)取之類的(不是很了解這一塊,不展開敘述)

為了實現(xiàn)事務(wù)對象內(nèi)存分配,回收等,在底層分裝了一些pool類,事務(wù)對象實際上被管理在一個池結(jié)構(gòu)中。

后面我再單獨寫一篇博客來介紹新加的這些底層結(jié)構(gòu)。

在啟動時,初始化trx_pools (trx_pool_init),初始化時分配4M內(nèi)存,在shutdown時釋放(trx_pool_close())

為了管理事務(wù)對象池,設(shè)計了三個類:TrxFactory,TrxPoolLock,TrxPoolManagerLock

獲取事務(wù)對象:trx_create_low —-> trx_pools->get()

釋放事務(wù)對象:trx_free —->?trx_pools->free(trx)

相關(guān)代碼:

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/5753

總結(jié)

以上是生活随笔為你收集整理的mysql 5.1版本无innodb trx_MySQL 5.7: Innodb 事务子系统优化-阿里云开发者社区的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。