Artikel ini membawakan anda beberapa soalan tentang tahap pengasingan transaksi MySQL dan cara MVCC melaksanakannya. Saya harap ia akan membantu anda.
Atomicity: Unit kerja terkecil transaksi, sama ada semuanya berjaya atau semua gagal.
Ketekalan: Selepas transaksi bermula dan tamat, integriti pangkalan data tidak akan dimusnahkan.
Pengasingan: Urus niaga yang berbeza tidak menjejaskan satu sama lain Empat tahap pengasingan ialah RU (baca tanpa komitmen) dan RC (baca komited), RR (baca boleh berulang). , BOLEH DISERIALIASI (sirialisasi).
Ketahanan: Selepas transaksi diserahkan, pengubahsuaian data adalah kekal dan tidak akan hilang walaupun sistem gagal.
Read Uncommitted/RU)
sekali lagi Dipanggil Bacaan Kotor, satu transaksi boleh membaca data yang tidak terikat daripada transaksi lain. Tahap pengasingan ini adalah yang paling tidak selamat kerana urus niaga tanpa komitmen tertakluk kepada pemulangan semula.
Read Committed/RC)
juga dikenali sebagai non-repeatable read, transaksi telah membaca transaksi lain Data diubah suai yang diserahkan mengakibatkan tidak konsisten keputusan yang diperoleh dengan membaca sekeping data yang sama pada masa yang berbeza dalam urus niaga semasa.
Sebagai contoh, dalam contoh berikut, anda akan mendapati SessionA menanyakan data yang berbeza dua kali semasa transaksi. Sebabnya ialah tahap pengasingan semasa ialah RC, dan transaksi SessionA boleh membaca data terkini yang diserahkan oleh SessionB.
|
SesiA | SesiB | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | bermula; |
td> |
|||||||||||||||||||||
2 | pilih * daripada pengguna di mana id=1;(Zhang San) | ||||||||||||||||||||||
3 | kemas kini nama set pengguna='李思' di mana id=1 (komit transaksi tersirat lalai) td > | ||||||||||||||||||||||
4 | pilih * daripada pengguna di mana id=1;(李思) | ||||||||||||||||||||||
5 | kemas kini nama set pengguna='王二' di mana id=1 (komit transaksi tersirat lalai) td> | ||||||||||||||||||||||
6 | pilih * daripada pengguna di mana id=1;(王二) |
juga dikenali sebagai phantom read
, sesuatu perkara boleh dibaca Baca data yang diserahkan oleh transaksi lain , tetapi di bawah tahap pengasingan RR, data ini hanya boleh dibaca sekali Dalam transaksi semasa, tidak kira berapa kali ia dibaca, data masih nilai yang dibaca untuk kali pertama , tidak akan diubah kerana transaksi lain ubah suai dan komit data ini selepas bacaan pertama. Oleh itu, ia juga menjadi bacaan hantu, kerana data yang dibacakan tidak semestinya data terkini.发生时间 | SessionA | SessionB |
---|---|---|
1 | begin; | |
2 | select * from user where id=1;(张三) | |
3 | update user set name='李四' where id=1; (默认隐式提交事务) | |
4 | select * from user where id=1;(张三) | |
5 | update user set name='王二' where id=1;(默认隐式提交事务) | |
6 | select * from user where id=1;(张三) |
Contohnya: apabila data dibaca buat kali pertama dalam SesiA, transaksi seterusnya yang mengubah suai data yang diserahkan tidak akan menjejaskan nilai data yang dibaca oleh SesiA. Ini ialah bacaan berulang.
Masa kejadian |
|
SesiB | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | bermula; |
td> |
|||||||||||||||||||||
2 | pilih * daripada pengguna di mana id=1;(Zhang San) | ||||||||||||||||||||||
3 | kemas kini nama set pengguna='李思' di mana id=1 (komit transaksi tersirat lalai) td > | ||||||||||||||||||||||
4 | pilih * daripada pengguna di mana id=1;(Zhang San) | ||||||||||||||||||||||
5 | kemas kini nama set pengguna='王二' di mana id=1 (komit transaksi tersirat lalai) td> | ||||||||||||||||||||||
6 | pilih * daripada pengguna di mana id=1;(Zhang San) |
Masa kejadian | SesiA | SesiB |
---|---|---|
1 | bermula; |
td> |
2 | mulakan; | |
3 td> | kemas kini nama set pengguna='李思' di mana id=1; | |
4 | pilih * daripada pengguna di mana id=1;(tunggu, tunggu)||
5 | komit; | |
6 | pilih * daripada pengguna di mana id=1;(李思) |
Contoh:
发生时间 | SessionA | SessionB |
---|---|---|
1 | begin; | |
2 | begin; | |
3 | 查询余额 = 1000元 | |
4 | 查询余额 = 1000元 | |
5 | 存入金额 100元,修改余额为 1100元 | |
6 | 取出现金100元,此时修改余额为900元 | |
8 | 提交事务(余额=1100) | |
9 | 提交事务(余额=900) |
发生时间 | SessionA | SessionB |
---|---|---|
1 | begin; | |
2 | begin; | |
3 | 查询余额 = 1000元 | |
4 | 查询余额 = 1000元 | |
5 | 存入金额 100元,修改余额为 1100元 | |
6 | 取出现金100元,此时修改余额为900元 | |
8 | 提交事务(余额=1100) | |
9 | 撤销事务(余额恢复为1000元) |
Dua situasi di atas adalah masalah yang mungkin timbul apabila berbilang transaksi beroperasi pada sekeping data pada masa yang sama Operasi transaksi tertentu mungkin ditimpa, mengakibatkan kehilangan data.
LBCC, Kawalan Konkurensi Berasaskan Kunci.
Menggunakan mekanisme kunci, apabila transaksi semasa perlu mengubah suai data, transaksi semasa dikunci Hanya satu transaksi dibenarkan untuk mengubah suai data semasa pada masa yang sama, dan transaksi lain mesti menunggu untuk kunci dilepaskan.
MVCC, kawalan penukaran berbilang versi, Kawalan Koncurrency Berbilang Versi.
Gunakan versi untuk mengawal masalah data dalam situasi konkurensi Apabila transaksi B mula mengubah suai akaun dan transaksi tidak diserahkan, apabila transaksi A perlu membaca baki akaun, transaksi B akan dibaca di. kali ini Ubah suai data salinan baki akaun sebelum operasi, tetapi jika transaksi A perlu mengubah suai data baki akaun, ia mesti menunggu transaksi B untuk melakukan transaksi.
MVCC menghalang data daripada dikunci apabila membaca daripada pangkalan data, dan permintaan SELECT biasa tidak dikunci, yang meningkatkan keupayaan pemprosesan serentak pangkalan data . Dengan bantuan MVCC, pangkalan data boleh melaksanakan tahap pengasingan seperti READ COMMITTED dan REPEATABLE READ Pengguna boleh melihat versi sejarah sebelumnya atau sebelumnya bagi data semasa, memastikan ciri I (pengasingan) dalam ACID.
Data MVCC yang disimpan oleh enjin storan InnoDB
MVCC InnoDB menyimpan dua rekod selepas setiap baris Lajur tersembunyi dilaksanakan. ID transaksi (DB_TRX_ID) yang menyimpan baris dan penuding balik (DB_ROLL_PT) yang menyimpan baris . Setiap kali transaksi baharu dimulakan, ID transaksi baharu akan dinaikkan secara automatik. Pada permulaan urus niaga, ID urus niaga akan diletakkan dalam ID urus niaga baris yang dipengaruhi oleh urus niaga semasa Apabila membuat pertanyaan, ID urus niaga semasa perlu dibandingkan dengan ID urus niaga yang direkodkan dalam setiap baris.
Mari kita lihat cara MVCC beroperasi di bawah tahap pengasingan BACA BERULANG.
PILIH
InnoDB akan menyemak setiap baris rekod berdasarkan dua syarat berikut:
InnoDB hanya mencari versi lebih awal daripada yang semasa Versi urus niaga baris data (iaitu, nombor urus niaga baris kurang daripada atau sama dengan nombor urus niaga urus niaga semasa), yang memastikan baris yang dibaca oleh urus niaga sama ada sudah wujud sebelum ini. urus niaga bermula, atau telah dimasukkan atau diubah suai oleh urus niaga itu sendiri.
Baris yang dipadamkan perlu dinilai oleh ID transaksi dan versi keadaan sebelum transaksi dibaca Hanya rekod yang memenuhi dua syarat di atas boleh dikembalikan sebagai hasil pertanyaan .
INSERT
InnoDB menyimpan nombor transaksi semasa sebagai nombor versi baris untuk setiap baris yang baru dimasukkan.
DELETE
InnoDB menyimpan nombor transaksi semasa sebagai pengecam pemadaman baris untuk setiap baris yang dipadamkan.
KEMASKINI
InnoDB memasukkan baris rekod baharu, menyimpan nombor transaksi semasa sebagai nombor versi baris dan menyimpan nombor transaksi semasa ke baris asal sebagai pengecam pemadaman baris.
Simpan dua nombor transaksi tambahan ini supaya kebanyakan operasi baca boleh dilakukan tanpa mengunci. Reka bentuk ini menjadikan operasi membaca data sangat mudah, prestasinya sangat baik, dan ia juga memastikan bahawa hanya baris yang memenuhi piawaian dibaca. Kelemahannya ialah setiap baris rekod memerlukan ruang storan tambahan, lebih banyak pemeriksaan baris dan beberapa kerja penyelenggaraan tambahan.
MVCC hanya berfungsi di bawah dua tahap pengasingan: BACA BERULANG dan KOMITED BACA. Dua tahap pengasingan yang lain tidak serasi dengan MVCC kerana READ UNCOMMITIED sentiasa membaca baris data terkini, bukan baris data yang mematuhi versi transaksi semasa. SERIALIZABLE akan mengunci semua baris yang dibaca.
Pelaksanaan MVCC dalam mysql bergantung pada log asal dan paparan baca.
buat asal log
Mengikut tingkah laku yang berbeza, buat asal log terbahagi kepada dua jenis: masukkan buat asal log dan kemas kini log buat asal
Awal. keadaan data semasa memasukkan pangkalan data:
Log buat asal yang dijana semasa operasi kemas kini atau padam. Kerana ia akan menjejaskan rekod sedia ada, untuk menyediakan mekanisme MVCC, log buat asal kemas kini tidak boleh dipadamkan apabila transaksi diserahkan, sebaliknya, ia diletakkan pada senarai sejarah apabila transaksi diserahkan, menunggu urutan pembersihan dilakukan operasi pemadaman terakhir.Apabila data diubah suai buat kali pertama:
Apabila transaksi lain mengubah suai data semasa untuk kali kedua:
Untuk memastikan tiada konflik berlaku semasa menulis log asal masing-masing semasa operasi transaksi serentak, InnoDB menggunakan segmen rollback untuk mengekalkan penulisan serentak dan ketekalan log asal. Segmen rollback sebenarnya adalah satu cara untuk mengatur Buat asal fail. Paparan Baca
Untuk RU(READ UNCOMMITTED) tahap pengasingan, semua urus niaga boleh terus membaca nilai terkini pangkalan data dan SERIALIZABLE tahap pengasingan, semua permintaan akan dikunci dan dilaksanakan secara serentak . Jadi dalam dua kes ini, tidak perlu menggunakan kawalan versi Read View.
Untuk RC(READ COMMITTED) dan RR(REPEATABLE READ) tahap pengasingan dilaksanakan melalui kawalan versi di atas. Logik pemprosesan teras di bawah dua sektor pengasingan adalah untuk menentukan versi mana antara semua versi yang boleh dilihat oleh transaksi semasa. Untuk menyelesaikan masalah ini, InnoDB menambah reka bentuk ReadView ReadView terutamanya mengandungi transaksi baca dan tulis yang aktif dalam sistem semasa dan meletakkan ID transaksi mereka ke dalam senarai. kami namakan senarai ini m_ids.
Logik penghakiman sama ada data rantai versi kelihatan semasa pertanyaan:
Jika nilai atribut trx_id versi yang diakses adalah kurang daripada id transaksi terkecil dalam m_ids senarai, ia menunjukkan bahawa penjanaan Versi transaksi ini telah dilakukan sebelum menjana ReadView, jadi versi ini boleh diakses oleh transaksi semasa.
Jika nilai atribut trx_id versi yang diakses adalah lebih besar daripada id transaksi terbesar dalam senarai m_ids, ini menunjukkan bahawa transaksi yang menjana versi ini telah dijana selepas ReadView dijana, jadi versi ini tidak boleh digunakan oleh akses transaksi semasa.
Jika nilai atribut trx_id versi yang diakses adalah antara id transaksi terbesar dan id transaksi terkecil dalam senarai m_ids, maka anda perlu menentukan sama ada nilai atribut trx_id berada dalam m_ids list. Jika ya, ini bermakna transaksi yang menghasilkan versi ini semasa ReadView dibuat masih aktif, dan versi ini tidak boleh diakses, ini bermakna transaksi yang menghasilkan versi ini semasa ReadView telah dibuat , dan versi ini boleh diakses.
Contohnya:
READ COMMITTED ReadView di bawah tahap pengasingan
Sebelum setiap kali data dibaca Semua jana a ReadView (senarai m_ids)
|
Transaksi 777 | Transaksi 888 | Transaksi 999 | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
mulakan; | |||||||||||||||||||||||||||||||||||||||||||||||||||
T2 | mulakan; | mulakan; | |||||||||||||||||||||||||||||||||||||||||||||||||
T3 | KEMASKINI nama SET pengguna = 'CR7' WHERE id = 1;|||||||||||||||||||||||||||||||||||||||||||||||||||
T4 | ... | ||||||||||||||||||||||||||||||||||||||||||||||||||
T5 | KEMASKINI nama SET pengguna = 'Messi' WHERE id = 1; | SELECT * FROM user where id = 1; | tr>|||||||||||||||||||||||||||||||||||||||||||||||||
T6 | komit; | ||||||||||||||||||||||||||||||||||||||||||||||||||
T7 | KEMASKINI nama SET pengguna = 'Neymar' WHERE id = 1; | ||||||||||||||||||||||||||||||||||||||||||||||||||
T8 | PILIH * DARI pengguna di mana id = 1; | ||||||||||||||||||||||||||||||||||||||||||||||||||
T9 | KEMASKINI nama SET pengguna = 'Dybala' WHERE id = 1; | td>||||||||||||||||||||||||||||||||||||||||||||||||||
T10 | komit; | ||||||||||||||||||||||||||||||||||||||||||||||||||
T11 | PILIH * DARI pengguna di mana id = 1; |
Berikut ialah analisis ReadView dalam kes di atas
Pernyataan SELECT pada titik masa T5:
Rantaian versi pada titik masa semasa:
Ini Apabila pernyataan SELECT dilaksanakan, rantaian versi data semasa adalah seperti di atas Oleh kerana transaksi semasa 777 dan transaksi 888 belum diserahkan, senarai ReadView transaksi aktif pada masa ini ialah m_ids: [777. , 888] , Oleh itu, pernyataan pertanyaan akan berdasarkan data versi terbesar dalam rantai versi semasa yang kurang daripada m_ids, iaitu, Mbappe disoal.
PILIH penyataan pada titik masa T8:
Situasi rantaian versi pada masa semasa:
Pada masa ini, penyataan SELECT dilaksanakan, dan versi data semasa Rantaian adalah seperti di atas, kerana transaksi semasa 777 telah diserahkan, dan transaksi 888 belum diserahkan, jadi senarai ReadView transaksi aktif pada masa ini ialah m_ids: [888 ] , jadi pernyataan pertanyaan akan berdasarkan versi semasa rantaian yang kurang daripada Data versi terbesar dalam m_ids bermakna Messi ditanya.
PILIH pernyataan pada titik masa T11:
Maklumat rantai versi pada titik masa semasa:
Pada masa ini, pernyataan SELECT dilaksanakan, dan data semasa Rantaian versi adalah seperti di atas Oleh kerana transaksi semasa 777 dan transaksi 888 telah diserahkan, senarai ReadView transaksi aktif pada masa ini kosong, jadi pernyataan pertanyaan akan menanyakan data terkini pangkalan data semasa. iaitu, Dybala disoal.
Ringkasan: Transaksi menggunakan tahap pengasingan READ COMMITTED akan menjana ReadView bebas pada permulaan setiap pertanyaan.
ReadView di bawah tahap pengasingan REPEATABLE READ
Menjana ReadView (senarai m_ids) apabila membaca data buat kali pertama selepas transaksi bermula
时间 | Transaction 777 | Transaction 888 | Trasaction 999 |
---|---|---|---|
T1 | begin; | ||
T2 | begin; | begin; | |
T3 | UPDATE user SET name = 'CR7' WHERE id = 1; | ||
T4 | ... | ||
T5 | UPDATE user SET name = 'Messi' WHERE id = 1; | SELECT * FROM user where id = 1; | |
T6 | commit; | ||
T7 | UPDATE user SET name = 'Neymar' WHERE id = 1; | ||
T8 | SELECT * FROM user where id = 1; | ||
T9 | UPDATE user SET name = 'Dybala' WHERE id = 1; | ||
T10 | commit; | ||
T11 | SELECT * FROM user where id = 1; |
Transaksi 999
Jana Pandangan Baca apabila penyataan pilih sedang dilaksanakan pada masa ini masa, kandungan
m_idsialah: [777,888], jadi data yang ditanya sebelum ini berdasarkan versi ReadView boleh dilihat ialah Mbappe.Rantaian versi semasa:PILIH penyata pada titik masa T8:
Pada masa ini dalam transaksi Transaksi 999 semasa. Memandangkan ReadView telah dijana pada titik masa T5, ReadView hanya akan dijana sekali dalam transaksi semasa, jadi
m_id di T5 masih digunakan pada masa ini: [777,999], jadi data pertanyaan pada masa ini masih Mbappe.Rantai versi semasa:PILIH penyataan pada titik masa T11:
, jadi data pertanyaan pada masa ini masih Mbappe. Ringkasan MVCC: 读-写
写-读
READ COMMITTD dan REPEATABLE READ urus niaga kedua-dua tahap pengasingan ini mengakses rantaian versi yang direkodkan apabila melakukan operasi SEELCT biasa Ini membolehkan operasi
dan bagi transaksi yang berbeza dilaksanakan secara serentak, dengan itu meningkatkan prestasi sistem. Pembelajaran yang disyorkan: tutorial video mysqlAtas ialah kandungan terperinci Mari kita bincangkan tentang tahap pengasingan yang dicapai oleh transaksi MySQL dan MVCC. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!