マルチバージョン同時実行制御MVCCは、反復可能読み取りを実現します
参照
高性能 MySQL 第3版 1.4 多版本并发控制
MVCCは、データを保存することで、ある時点でのスナップショットに実装されています。MVCC異なるストレージエンジン、一般的に楽観的同時実行性と悲観的同時実行制御の異なる実装。
InnoDBは達成することMVCCです
名詞
系统版本号
事务版本号
记录创建时间
记录删除时间
InnoDBのMVCCは、各ライン記録後に実装2つの列を格納することによって隠されています。行を作成するための時間保存すると、保存されたタイムラインを削除します。確かに時間の値が保存されますが、システムのバージョン番号されません。それぞれが新しいトランザクションを開始し、システムが自動的にバージョン番号をインクリメントします。取引システムのバージョン番号は、トランザクションの開始時刻のバージョン番号です。
反復可能読み取りMVCCの実行プロセス
事务版本号是事务开始时刻的系统版本号
每开始一个新的事务,系统版本号都会自动递增
選択する
戻り値のレコード、次の条件が満たされます
创建时间 <= 当前事务版本号 && ( 删除时间 == null || 删除时间 > 当前事务版本号 )
インサート
插入记录的创建时间 = 当前系统版本号
作成し、新たに挿入されたレコードが現在のシステムのバージョン番号に設定され、時間がnullの削除。
削除
被删除记录的删除时间 = 当前系统版本号
記録された時間を削除するには、DELETEは、現在のシステムのバージョン番号、墓石、とすることができ、実際に削除されていないデータに設定されています。
更新
被更新记录的原记录的删除时间 = 当前系统版本号
新插入记录的创建时间 = 当前系统版本号
時間は、論理削除元のレコードで、現在のシステムのバージョン番号、元のレコードセットを削除するように更新されます。現在のシステムのバージョン番号のために作成された新しいレコードを挿入します。
MVCCは、単独で働いて2レベルがコミットおよび反復読み取る読み取り、及び他の分離レベルは、このメカニズムを使用していません。常にではなく、行の現在のトランザクションのバージョンに合わせてよりも、最新のデータラインを読んでコミットされていない読んで、すべての行のseriablizableロックをお読みください。
MVCCソースの解析
http://www.ningoo.net/html/tag/mysql
http://blog.sina.com.cn/s/blog_4673e603010111ty.html
https://blog.csdn.net/joy0921/article/details/80128857
https://blog.csdn.net/u012919352/article/details/87984786
https://mp.weixin.qq.com/s?__biz=MzIxNTQ3NDMzMw==&mid=2247483670&idx=1&sn=751d84d0ce50d64934d636014abe2023&chksm=979688e4a0e101f2a51d1f06ec75e25c56f8936321ae43badc2fe9fc1257b4dc1c24223699de&scene=21#wechat_redirect
https://dev.mysql.com/doc/refman/5.5/en/innodb-consistent-read.html
https://blog.csdn.net/joy0921/article/details/80128857
三つのフィールドを非表示にします
ROW_IDはdb_roll_pt IDのロールバックトランザクションレコードポインタのIDをdb_trx_id
まず、各データの行ならびにInnoDBが行修飾の前バージョンの履歴を指すためDB_ROLL_PTポインタをロールバックします
- 挿入するときに、新しいデータは、対応するロールバックポインタに記録されているNULLです。
- 現在のレコードが主キーを持っている場合、レコードIDは、ROW_IDが生成されません
ログアンドゥビューを読みます
行によって決定読み取るビューが表示され
次のように特定決意プロセスです。
RR分離レベルの下では、各トランザクションの時間が始まった時に、すべてのアクティブなトランザクションがリスト(読み取りビュー)に、現在のシステムにコピーされます
RCの分離レベルの下で、各ステートメントの開始、意志現在のシステムリストのコピーへのすべてのアクティブなトランザクション(ビューを読みます)
- 「唐チェン-2016PGアセンブリ - マルチデータベースバージョンの実装のインサイダーの.pdf」
https://myslide.cn/slides/3542
読み取りビューのMySQLの···InnoDBのソースコード解析、ロールバックセグメントとパージ処理はじめ https://yq.aliyun.com/articles/560506
mysql> show engine innodb status\G;
------------
TRANSACTIONS
------------
Trx id counter AC16
Purge done for trx's n:o < AC14 undo n:o < 0
History list length 1079
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION AC15, not started
MySQL thread id 4, OS thread handle 0x43c, query id 133 localhost 127.0.0.1 root
show engine innodb status
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX\G;
https://www.cnblogs.com/itcomputer/articles/5084611.html
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX\G;
*************************** 1. row ***************************
trx_id: AC16
trx_state: RUNNING
trx_started: 2019-08-03 11:50:27
trx_requested_lock_id: NULL
trx_wait_started: NULL
trx_weight: 0
trx_mysql_thread_id: 10
trx_query: NULL
trx_operation_state: NULL
trx_tables_in_use: 0
trx_tables_locked: 0
trx_lock_structs: 0
trx_lock_memory_bytes: 376
trx_rows_locked: 0
trx_rows_modified: 0
trx_concurrency_tickets: 0
trx_isolation_level: READ COMMITTED
trx_unique_checks: 1
trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
trx_adaptive_hash_latched: 0
trx_adaptive_hash_timeout: 10000
1 row in set (0.00 sec)
私はAC18 AC17、トランザクションカウンタが= AC19 2つのトランザクションをオープンしました
mysql> show engine innodb status\G;
------------
TRANSACTIONS
------------
Trx id counter AC19
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX\G;
*************************** 1. row ***************************
trx_id: AC18
trx_state: RUNNING
trx_started: 2019-08-03 11:56:40
*************************** 2. row ***************************
trx_id: AC17
trx_state: RUNNING
trx_started: 2019-08-03 11:55:08
mysql> SELECT tx.trx_id
-> FROM information_schema.innodb_trx tx
-> WHERE tx.trx_mysql_thread_id = connection_id();
+--------+
| trx_id |
+--------+
| AC17 |
+--------+
1 row in set (0.07 sec)
mysql> SELECT tx.trx_id
-> FROM information_schema.innodb_trx tx
-> WHERE tx.trx_mysql_thread_id = connection_id();
+--------+
| trx_id |
+--------+
| AC18 |
+--------+
1 row in set (0.00 sec)
mysql> SELECT tx.trx_id
-> FROM information_schema.innodb_trx tx
-> WHERE tx.trx_mysql_thread_id = connection_id();
Empty set (0.00 sec)
https://www.jdon.com/51517
RR(ギャップロックを除く)分離レベルとRC異なる分離レベルは、時間差のスナップショットを作成することです。むしろ、トランザクションの開始時にRR分離レベル、最初の読み取り創造の見解を読んで、RCの分離レベルは声明で読み取りビューを作成するには、開始時間です。
作成/読み込みビューがtrx_sys->ミューテックスを保持する必要性を閉鎖し、劣化システム性能、このバージョン5.7が最適化され、トランザクションがセッションをコミット読み取りビューは、読取り専用キャッシュされますトランザクションを。
Read view中保存的trx_sys状态主要包括
low_limit_id:high water mark,大于等于view->low_limit_id的事务对于view都是不可见的
up_limit_id:low water mark,小于view->up_limit_id的事务对于view一定是可见的
low_limit_no:trx_no小于view->low_limit_no的undo log对于view是可以purge的
rw_trx_ids:读写事务数组
Read view创建之后,读数据时比较记录最后更新的trx_id和view的 high/low water mark和读写事务数组即可判断可见性。
如前所述,如果记录最新数据是当前事务trx的更新结果,对应当前read view一定是可见的。
除此之外可以通过high/low water mark快速判断:
trx_id < view->up_limit_id的记录对于当前read view是一定可见的;
trx_id >= view->low_limit_id的记录对于当前read view是一定不可见的;
如果trx_id落在[up_limit_id, low_limit_id),需要在活跃读写事务数组查找trx_id是否存在,如果存在,记录对于当前read view是不可见的。
storage/innobase/read/read0read.c
http://blog.sina.com.cn/s/blog_4673e603010111ty.html
ストレージ/あるInnobase /含ん/ read0read.ic
view->n_trx_ids 数量
view->up_limit_id
view->low_limit_id
/*********************************************************************//**
Checks if a read view sees the specified transaction.
@return TRUE if sees */
UNIV_INLINE
ibool
read_view_sees_trx_id(
/*==================*/
const read_view_t* view, /*!< in: read view */
trx_id_t trx_id) /*!< in: trx id */
{
ulint n_ids;
ulint i;
if (trx_id < view->up_limit_id) {
return(TRUE);
}
if (trx_id >= view->low_limit_id) {
return(FALSE);
}
/* We go through the trx ids in the array smallest first: this order
may save CPU time, because if there was a very long running
transaction in the trx id array, its trx id is looked at first, and
the first two comparisons may well decide the visibility of trx_id. */
n_ids = view->n_trx_ids;
for (i = 0; i < n_ids; i++) {
trx_id_t view_trx_id
= read_view_get_nth_trx_id(view, n_ids - i - 1);
if (trx_id <= view_trx_id) {
return(trx_id != view_trx_id);
}
}
return(TRUE);
}
ストレージ/あるInnobase /含ん/ read0read.h
struct read_view_struct{
ulint type; /*!< VIEW_NORMAL, VIEW_HIGH_GRANULARITY */
undo_no_t undo_no;/*!< 0 or if type is
VIEW_HIGH_GRANULARITY
transaction undo_no when this high-granularity
consistent read view was created */
trx_id_t low_limit_no;
/*!< The view does not need to see the undo
logs for transactions whose transaction number
is strictly smaller (<) than this value: they
can be removed in purge if not needed by other
views */
trx_id_t low_limit_id;
/*!< The read should not see any transaction
with trx id >= this value. In other words,
this is the "high water mark". */
trx_id_t up_limit_id;
/*!< The read should see all trx ids which
are strictly smaller (<) than this value.
In other words,
this is the "low water mark". */
ulint n_trx_ids;
/*!< Number of cells in the trx_ids array */
trx_id_t* trx_ids;/*!< Additional trx ids which the read should
not see: typically, these are the active
transactions at the time when the read is
serialized, except the reading transaction
itself; the trx ids in this array are in a
descending order. These trx_ids should be
between the "low" and "high" water marks,
that is, up_limit_id and low_limit_id. */
trx_id_t creator_trx_id;
/*!< trx id of creating transaction, or
0 used in purge */
UT_LIST_NODE_T(read_view_t) view_list;
/*!< List of read views in trx_sys */
};
trx_id_t trx_id = row_get_rec_trx_id(rec, index, offsets); //获取记录上的TRX_ID这里需要解释下,我们一个查询可能满足的记录数有多个。那我们每读取一条记录的时候就要根据这条记录上的TRX_ID判断这条记录是否可见
return(view->changes_visible(trx_id, index->table->name)); //判断记录可见性
---------------------
作者:仲培艺
来源:CSDN
原文:https://blog.csdn.net/joy0921/article/details/80128857
版权声明:本文为博主原创文章,转载请附上博文链接!
对于不可见的记录都是通过row_vers_build_for_consistent_read函数查询UNDO构建老版本记录,直到记录可见。
这里需要说明一点 不同的事务隔离级别,可见性的实现也不一样:
READ-COMMITTED
事务内的每个查询语句都会重新创建Read View,这样就会产生不可重复读现象发生
REPEATABLE-READ
事务内开始时创建Read View , 在事务结束这段时间内 每一次查询都不会重新重建Read View , 从而实现了可重复读。
trx_sys-> trx_list
https://blog.csdn.net/longxibendi/article/details/42012629
Read view创建之后,读数据时比较记录最后更新的trx_id和view的high/low water mark和读写事务数组即可判断可见性。
https://cloud.tencent.com/developer/ask/210171
https://blog.jcole.us/innodb/
https://github.com/jeremycole/innodb_ruby/wiki
[root@instance-fjii60o3 ~]# gem install innodb_ruby
-bash: gem: command not found
https://rubygems.org/
[root@instance-fjii60o3 develop]# wget https://rubygems.org/rubygems/rubygems-3.0.4.tgz
-rw-r--r-- 1 root root 883664 Jun 14 11:35 rubygems-3.0.4.tgz
Linuxのインストール宝石https://www.csdn.net/gather_2b/MtjaUgysNDYzNS1ibG9n.html
[root@instance-fjii60o3 rubygems-3.0.4]# bin/gem
/usr/bin/env: ruby: No such file or directory
Linuxはルビーをインストール
https://www.cnblogs.com/xuliangxing/p/7132656.html?utm_source=itdadao&utm_medium=referral
[root@instance-fjii60o3 rubygems-3.0.4]# yum list install | grep ruby
Error: No matching Packages to list
[root@instance-fjii60o3 rubygems-3.0.4]# yum list installed | grep ruby
ruby.x86_64 2.0.0.648-35.el7_6 @updates
ruby-irb.noarch 2.0.0.648-35.el7_6 @updates
ruby-libs.x86_64 2.0.0.648-35.el7_6 @updates
rubygem-bigdecimal.x86_64 1.2.0-35.el7_6 @updates
rubygem-io-console.x86_64 0.4.2-35.el7_6 @updates
Linuxはgitのインストール
[root@instance-fjii60o3 ~]# yum install git
[root@instance-fjii60o3 ~]# git clone https://github.com/jeremycole/innodb_ruby.git
[root@instance-fjii60o3 rubygems-3.0.4]# gem install --user-install innodb_ruby
WARNING: You don't have /root/.gem/ruby/bin in your PATH,
gem executables will not run.
ルビーRubyGemsの(GEM)パッケージマネージャを学ぶのインストールと使用
https://blog.csdn.net/luyaran/article/details/85698936
[root@instance-fjii60o3 rubygems-3.0.4]# yum list installed | grep ruby
Existing lock /var/run/yum.pid: another copy is running as pid 11250.
Another app is currently holding the yum lock; waiting for it to exit...
The other application is: yum
Memory : 90 M RSS (408 MB VSZ)
Started: Sat Aug 3 14:39:05 2019 - 16:44 ago
State : Sleeping, pid: 11250
システムアクティブなトランザクションID
MVCCの可視性https://blog.csdn.net/taozhi20084525/article/details/19501075
[root@instance-fjii60o3 develop]# yum localinstall mysql-community-server-8.0.13-1.el7.x86_64.rpm
Loaded plugins: langpacks, versionlock
Existing lock /var/run/yum.pid: another copy is running as pid 11250.
Another app is currently holding the yum lock; waiting for it to exit...
The other application is: yum
Memory : 89 M RSS (408 MB VSZ)
Started: Sat Aug 3 14:39:05 2019 - 1:15:13 ago
State : Traced/Stopped, pid: 11250
[root@instance-fjii60o3 develop]# tar -xvf mysql-8.0.13-1.el7.x86_64.rpm-bundle.tar -C mysql8.0
mysql-community-client-8.0.13-1.el7.x86_64.rpm
mysql-community-embedded-compat-8.0.13-1.el7.x86_64.rpm
mysql-community-libs-8.0.13-1.el7.x86_64.rpm
mysql-community-server-8.0.13-1.el7.x86_64.rpm
tar: Unexpected EOF in archive
tar: rmtlseek not stopped at a record boundary
tar: Error is not recoverable: exiting now
RubyのツールInnoDBのレコード構造解析
https://cloud.tencent.com/developer/ask/210171
https://github.com/jeremycole/innodb_ruby/wiki
ルビーのインストール
gem install innodb_ruby
InnoDBのフォーマットの解析ツール
https://rubygems.org/gems/innodb_ruby/versions
https://www.cnblogs.com/zengkefu/p/5678356.html
Linuxは、ファイルサイズを表示します
[root@instance-fjii60o3 ~]# du -sh MySQL-5.5.62-1.el7.x86_64.rpm-bundle.tar
2.1M MySQL-5.5.62-1.el7.x86_64.rpm-bundle.tar
[root@instance-fjii60o3 ~]# du -sh develop/
1.1G develop/
MySQLの行レベルのロックを理解するために5分- 「ボトムMysqlのロックを取得」 https://blog.csdn.net/zcl_love_wx/article/details/81983267
テーブルレベルロック、ページレベルのロック、行レベルロック:ロック3つのレベルがあるのMySQL
各タイムロックは、データロック機構の行は行レベルロック(ローレベル)です。行レベルのロックは、MySQL独自の方法をロックされていないが、他のストレージエンジンによってそれ自体が実装さ
主InnoDBストレージエンジンの使用行レベルのロック、およびMySQL分散ストレージエンジンNDBCLUSTER
InnoDBテーブルの行レベルのロックは、2つのタイプに分けられる:共有ロックと排他ロック、および行レベルのロックとテーブル・レベルのロックを可能にするために、実装プロセスのロック機構で共存し、InnoDBはまた、使用意図的ロック(表レベルのロックを)のコンセプトは、我々は共有意図的ロックと意図排他ロックの両方を持つことになります。