2017-08-30 2 views
0

ich InnoDB mvcc jetzt lerne, und ich habe einen Test zeigen versuchen, wie folgt: Versionein Test über mysql innodb mvcc

Mysql:

[[email protected] ~]# mysql --version 
mysql Ver 15.1 Distrib 5.5.52-MariaDB, for Linux (x86_64) using readline 5.1 

Tabellenschema:

MariaDB [liruifeng]> show create table test_a; 
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Table | Create Table                                   | 
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| test_a | CREATE TABLE `test_a` (
    `id` int(11) NOT NULL DEFAULT '0', 
    `a` char(10) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 | 
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------+ 
1 row in set (0.00 sec) 

dann Init mit Daten wie folgt:

MariaDB [liruifeng]> select * from test_a; 
+----+------+ 
| id | a | 
+----+------+ 
| 1 | 1 | 
| 2 | 2 | 
| 3 | 3 | 
+----+------+ 
3 rows in set (0.00 sec) 

und zunächst haben i offen zwei Session in unterschiedlichen Endgeräten, die Prüfschritt zeigen als Faltenbalg:

t1:

MariaDB [liruifeng]> start transaction; 
Query OK, 0 rows affected (0.00 sec) 

MariaDB [liruifeng]> select * from test_a; 
+----+------+ 
| id | a | 
+----+------+ 
| 1 | 1 | 
| 2 | 2 | 
| 3 | 3 | 
+----+------+ 
3 rows in set (0.00 sec) 

t2:

MariaDB [liruifeng]> insert into test_a values (4,4); 
Query OK, 1 row affected (0.01 sec) 

MariaDB [liruifeng]> select * from test_a; 
+----+------+ 
| id | a | 
+----+------+ 
| 1 | 1 | 
| 2 | 2 | 
| 3 | 3 | 
| 4 | 4 | 
+----+------+ 
4 rows in set (0.00 sec) 

t1:

MariaDB [liruifeng]> select * from test_a; 
+----+------+ 
| id | a | 
+----+------+ 
| 1 | 1 | 
| 2 | 2 | 
| 3 | 3 | 
+----+------+ 
3 rows in set (0.00 sec) 

MariaDB [liruifeng]> update test_a set a = 444 where id = 4; 
Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

MariaDB [liruifeng]> select * from test_a; 
+----+------+ 
| id | a | 
+----+------+ 
| 1 | 1 | 
| 2 | 2 | 
| 3 | 3 | 
| 4 | 444 | 
+----+------+ 
4 rows in set (0.00 sec) 

es verwirrt mich, dass warum ein t1 kann die Zeile einfügen von t2 vor t1 Commit aktualisiert? Mein tx_isolation level ist wiederholbar lesen und warum wird dieses Update sql?

meine Isolation zeigen als Balg:

MariaDB [liruifeng]> show variables like 'tx_isolation'; 
+---------------+-----------------+ 
| Variable_name | Value   | 
+---------------+-----------------+ 
| tx_isolation | REPEATABLE-READ | 
+---------------+-----------------+ 
1 row in set (0.00 sec) 

dank Fortschritten :)

+0

Ich sehe ein "START" an einem Terminal, was ist mit dem anderen? Was war der Wert von 'autocommit'? –

+0

@RickJames ja, autocommit :) –

Antwort

0

REPEATABLE-READ sagt, dass die select * from test_a;COMMITs die gleiche Sache bis t1 sagen. Die Tatsache, dass die UPDATE Zeile 4 aber die identischeSELECT kann nicht sehen, ist seltsam, aber gültig.

+0

Also, wenn Programm versuchen, Daten mit einer Where-Klausel wie "a <5" zu aktualisieren, ist es vielleicht gefährlich, wenn andere Transaktionen die Operation einfügen oder aktualisieren? warum das mvcc in mysql so entworfen? :( –

+0

'UPDATE ... WHERE ein <5' würde (zu einem gewissen Grad) alle diese Zeilen sperren.' WHERE a = 5' würde nur die eine Zeile sperren.Im Allgemeinen macht man Transaktionen so schnell, dass subtile Problem wie dieses sind Kein Problem, Produktionssysteme brauchen Millisekunden, nicht Sekunden zwischen Aussagen wie t1 und t2. –