Rumah  >  Artikel  >  Java  >  Penemubual: Bagaimanakah MySQL melaksanakan ACID?

Penemubual: Bagaimanakah MySQL melaksanakan ACID?

Java后端技术全栈
Java后端技术全栈ke hadapan
2023-08-17 14:39:00697semak imbas

Dalam temuduga, penemuduga hanya perlu bertanya tentang ACID MySQL, dan kemudian dia boleh segera membaca esei lapan bahagian (ada yang mungkin belum dapat menjawabnya). Apa yang lebih menjijikkan ialah ada penemuduga yang tidak mengikut rutin dan terus bertanya, bagaimana MySQL melaksanakan ACID?

Anda keliru Sejujurnya, soalan ini boleh menghalang 95% orang.

Hari ini, artikel ini membincangkan prinsip pelaksanaan ACID di bawah enjin MySQL InnoDB  Ia tidak terlalu menghuraikan pengetahuan asas seperti apa itu transaksi dan maksud tahap pengasingan.

ACID

Sebagai pangkalan data hubungan, bagaimanakah MySQL menjamin ACID berdasarkan enjin InnoDB yang paling biasa.

  • (Atomicity)Atomicity:Transaksi ialah unit pelaksanaan terkecil dan tidak membenarkan pembahagian. Atomicity memastikan bahawa tindakan sama ada selesai sepenuhnya atau tidak mempunyai kesan sama sekali; pangkalan data secara serentak, satu transaksi tidak diganggu oleh transaksi lain.
  • (Ketahanan) Ketahanan: Selepas transaksi dilakukan. Perubahan kepada data dalam pangkalan data adalah berterusan, walaupun pangkalan data gagal.

Pengasingan

Mari kita bincangkan tentang pengasingan dahulu.

Tahap Pengasingan Selepas penyerahan, perubahan yang dibuat akan dilihat oleh transaksi lain
Baca Berulang Dalam transaksi, hasil pembacaan data yang sama sentiasa sama, tidak kira sama ada transaksi lain beroperasi pada data dan sama ada transaksi itu dilakukan. Tahap lalai InnoDB.
Siri Urus niaga dilaksanakan secara bersiri. Setiap bacaan memerlukan kunci perkongsian tahap jadual.

Tahap pengasingan yang berbeza adalah untuk menyelesaikan masalah yang berbeza. Iaitu, bacaan kotor, bacaan hantu dan bacaan tidak boleh diulang.

Bacaan berulangTidak Dibenarkan muncul Tidak dibenarkan munculBoleh muncul
隔离级别 脏读 不可重复读 幻读
Baca tanpa komitmen Boleh muncul Boleh muncul Boleh muncul
Baca Dihantar Tidak dibenarkan muncul
Siri tidak dibenarkan tidak dibenarkan tidak dibenarkan

Tahap pengasingan yang berbeza, bagaimana pengasingan dicapai, dan mengapa perkara yang berbeza tidak boleh mengganggu satu sama lain? Jawapannya ialah Locks dan MVCC.

Kunci

Mula-mula mari kita bincangkan tentang kunci yang ada pada MySQL?

Kebutiran

Dari segi kebutiran, ia bermaksud kunci meja, kunci halaman dan kunci baris. Kunci meja termasuk kunci dikongsi yang disengajakan, kunci eksklusif yang disengajakan, kunci meningkat sendiri, dsb. Kunci baris dilaksanakan pada peringkat enjin oleh setiap enjin. Tetapi tidak semua enjin menyokong kunci baris Contohnya, enjin MyISAM tidak menyokong kunci baris.

Jenis kunci baris

Dalam transaksi InnoDB, kunci baris dilaksanakan dengan mengunci entri indeks pada indeks. Ini bermakna InnoDB menggunakan kunci peringkat baris hanya apabila data diambil melalui keadaan indeks, jika tidak, kunci jadual digunakan. Kunci peringkat baris juga dibahagikan kepada dua jenis: kunci kongsi dan kunci eksklusif, serta kunci kongsi niat dan kunci eksklusif niat yang perlu diperoleh sebelum dikunci.

  • Shared lock: read lock, transaksi lain dibenarkan tambah S lock, transaksi lain tidak dibenarkan tambah X lock iaitu transaksi lain hanya boleh membaca tetapi tidak boleh menulis. pilih...kunci dalam mod kongsi Kunci. select...lock in share mode 加锁。
  • 排它锁:写锁,不允许其他事务再加S锁或者X锁。insert、update、delete、for update
Kunci eksklusif: kunci tulis, tiada transaksi lain dibenarkan untuk menambah kunci S atau kunci X. masukkan, kemas kini, padam, untuk kemas kiniKunci.

Kunci baris ditambah

apabila diperlukan, tetapi ia tidak dilepaskan serta-merta apabila ia tidak diperlukan lagi, tetapi ia tidak dikeluarkan sehingga tamat transaksi. Ini adalah protokol kunci dua fasa. 🎜🎜

Algoritma Pelaksanaan Kunci Baris

Kunci Rekod

Kunci pada rekod baris tunggal akan sentiasa mengunci rekod indeks.

Gap Lock

Gap Lock, fikirkan sebab baca phantom, sebenarnya row lock hanya boleh lock row, tapi bila masukkan rekod baru, apa yang perlu dikemaskini ialah "gap" antara rekod. Jadi tambah kunci jurang untuk menyelesaikan bacaan hantu.

Kunci Kekunci Seterusnya

Kunci Jurang + Kunci Rakam, dibiarkan terbuka dan tertutup.

Pengasingan kunci

Pengenalan umum kepada kunci bawah, anda boleh melihatnya. Dengan kunci, apabila transaksi menulis data, transaksi lain tidak boleh mendapatkan kunci tulis dan tidak boleh menulis data Ini memastikan pengasingan antara urus niaga pada tahap tertentu. Tetapi seperti yang dinyatakan sebelum ini, jika kunci tulis ditambah, mengapa transaksi lain juga boleh membaca data, bukankah kunci baca tidak boleh diperoleh?

MVCC

Seperti yang dinyatakan sebelum ini, dengan kunci, transaksi semasa tidak boleh mengubah suai data tanpa kunci tulis, tetapi ia masih boleh dibaca, walaupun baris data telah diubah suai dan diserahkan oleh transaksi lain, baris yang sama masih boleh dibaca berulang kali. Ini ialah MVCC, kawalan penukaran berbilang versi, Kawalan Koncurrency Berbilang Versi.

Rantai versi

Format storan rekod baris dalam Innodb, dengan beberapa medan tambahan: DATA_TRX_ID dan DATA_ROLL_PTR.

  • DATA_TRX_ID: Nombor versi baris data. Digunakan untuk mengenal pasti ID transaksi yang mengubah suai rekod baris ini baru-baru ini.
  • DATA_ROLL_PTR: Penunjuk ke bahagian putar balik baris. Semua versi lama yang direkodkan dalam baris ini disusun dalam bentuk senarai terpaut dalam undo log.

buat asal log: Rekod log sebelum data diubah suai, yang akan diterangkan secara terperinci kemudian.

Penemubual: Bagaimanakah MySQL melaksanakan ACID?

ReadView

dicipta pada permulaan setiap SQL dan mempunyai beberapa atribut penting:

  • trx_ids: Koleksi nombor versi transaksi (tidak komited) aktif dalam sistem semasa.
  • low_limit_id: "Maksimum nombor versi transaksi+1" sistem semasa semasa mencipta paparan baca semasa.
  • up_limit_id:Apabila paparan baca semasa dibuat, "sistem berada dalam transaksi aktifnombor versi minimum"
  • creator_trx_id:
Penemubual: Bagaimanakah MySQL melaksanakan ACID?

Mulakan pertanyaan

Sekarang mulakan pertanyaan, pilihan datang dan satu baris data ditemui.

  • DATA_TRX_ID 5b68b9a35001cc3e94268a1d1034606d= low_limit_id:

    Menunjukkan bahawa data dijana selepas paparan baca semasa dibuat dan data tidak dipaparkan.


    • Apa yang perlu dilakukan jika ia tidak dipaparkan. Cari versi sejarah dari log buat asal mengikut DATA_ROLL_PTR Jika tidak ditemui, biarkan ia kosong.
  • up_limit_id <low_limit_id : Ia bergantung pada tahap pengasingan.

Penemubual: Bagaimanakah MySQL melaksanakan ACID?

Baca hantu tahap RR

Dengan kunci dan MVCC, pengasingan transaksi diselesaikan. Untuk mengembangkan di sini, adakah tahap RR lalai menyelesaikan bacaan hantu? Bacaan hantu biasanya menyasarkan MASUKKAN, dan sasaran tidak boleh berulang KEMASKINI.

perkara 1 perkara 2
mulakan mulakan
pilih * dari dept
- masukkan ke dalam dept(name) values("A")
- commit
update dept set name="B"

🎜🎜

Kami menjangkakan ia menjadi

id  name
1   A
2   B

Ia sebenarnya ternyata

id  name
1   B
2   B

Malah, tahap pengasingan MySQL repeatable read tidak sepenuhnya menyelesaikan masalah pembacaan hantu, tetapi menyelesaikan masalah bacaan hantu semasa membaca data. Masih terdapat masalah bacaan hantu untuk operasi pengubahsuaian, yang bermaksud MVCC tidak teliti dalam menyelesaikan bacaan hantu.

Atomicity

Mari kita bercakap tentang atomicity. Seperti yang dinyatakan sebelum ini, buat asal log menggulung semula log. Pengasingan MVCC sebenarnya bergantung padanya untuk mencapai, seperti juga atomicity. Kunci untuk mencapai atomicity adalah untuk dapat membuat asal semua pernyataan SQL yang berjaya dilaksanakan apabila transaksi ditarik balik.

Apabila transaksi mengubah suai pangkalan data, InnoDB akan menjana log buat asal yang sepadan jika pelaksanaan transaksi gagal atau pemulangan dipanggil, menyebabkan urus niaga ditarik balik, maklumat dalam log buat asal boleh digunakan untuk melancarkan semula data ke; cara sebelum pengubahsuaian. Buat asal log ialah log logik, yang merekodkan maklumat yang berkaitan dengan pelaksanaan SQL. Apabila pemulangan berlaku, InnoDB akan melakukan perkara yang bertentangan dengan kerja sebelumnya berdasarkan kandungan log buat asal:

  • Untuk setiap sisipan, pemadaman akan dilaksanakan apabila melancarkan semula;
  • Untuk setiap pemadaman, sisipan akan dilaksanakan apabila melancarkan semula; data itu kembali.
  • Ambil operasi kemas kini sebagai contoh: apabila transaksi melaksanakan kemas kini, log asal yang dijana akan mengandungi kunci utama bagi baris yang diubah suai (untuk mengetahui baris mana yang telah diubah suai), lajur mana yang telah diubah suai, dan nilai lajur ini sebelum dan selepas pengubahsuaian Apabila melancarkan semula, anda boleh menggunakan maklumat ini untuk memulihkan data kepada keadaan sebelum kemas kini.

    Kegigihan

    Innnodb mempunyai banyak log, dan kegigihan bergantung pada log semula.

    Cara menjalankan pernyataan kemas kini SQL

    Kegigihan pastinya berkaitan dengan penulisan Teknologi WAL yang sering disebut dalam MySQL, nama penuh WAL ialah Write-Ahead Logging cakera itu. Sama seperti berniaga di kedai kecil, ada papan merah jambu dan buku akaun Apabila tetamu datang, tulis di papan merah jambu dahulu, dan kemudian tulis buku akaun apabila anda tidak sibuk.

    redo log

    redo log ialah papan merah jambu ini Apabila rekod perlu dikemas kini, enjin InnoDB akan terlebih dahulu menulis rekod ke log buat semula (dan mengemas kini memori pada masa ini, kemas kini telah selesai). Pada masa yang sesuai, rekod operasi ini dikemas kini ke cakera, dan kemas kini ini sering dilakukan apabila sistem agak melahu, sama seperti yang dilakukan oleh pekedai selepas ditutup.

    buat semula log mempunyai dua ciri:

    • Saiz fixed, penulisan kitaran
    • crash-safe

    for log redo, terdapat dua fasa: komit dan menyediakan. mungkin berbeza daripada menggunakannya. Status perpustakaan yang dipulihkan daripada log adalah tidak konsisten Okay, mari kita pergi ke sini dahulu dan lihat yang lain.

    Buffer Pool

    InnoDB juga menyediakan cache The Buffer Pool mengandungi pemetaan beberapa halaman data dalam cakera, yang berfungsi sebagai penampan untuk mengakses pangkalan data:

    .
    • Apabila membaca data, ia akan dibaca dari Buffer Pool terlebih dahulu Jika ia tidak berada dalam Buffer Pool, ia akan dibaca dari cakera dan dimasukkan ke dalam Buffer Pool
    • Apabila menulis data ke pangkalan data , ia akan ditulis dahulu Masukkan Kolam Penampan, dan data yang diubah suai dalam Kolam Penampan akan dimuat semula ke cakera dengan kerap.

    Penggunaan Buffer Pool sangat meningkatkan kecekapan membaca dan menulis data, tetapi ia juga membawa masalah baharu: jika MySQL rosak dan data yang diubah suai dalam Buffer Pool tidak dibuang ke cakera, ia akan menyebabkan data rasuah. Hilang, ketahanan transaksi tidak terjamin.

    Jadi saya menyertai log buat semula. Apabila data diubah suai, selain mengubah suai data dalam Buffer Pool, operasi juga akan direkodkan dalam log buat semula

    Apabila transaksi diserahkan, antara muka fsync akan dipanggil untuk mengepam log buat semula.

    Jika MySQL rosak, anda boleh membaca data dalam log buat semula dan memulihkan pangkalan data apabila dimulakan semula.

    log buat semula menggunakan WAL (Pengelogan tulis ke hadapan, log tulis ke hadapan terlebih dahulu ditulis pada log dan kemudian dikemas kini ke Kolam Penampan, memastikan data tidak akan hilang akibat masa henti MySQL, sekali gus memenuhi ketahanan). Memerlukan. Dan terdapat dua kelebihan untuk melakukan ini:

    • Pembilasan halaman kotor ialah IO rawak, buat semula log IO berurutan
    • Pembilasan halaman kotor berada dalam unit Halaman, dan keseluruhan halaman pengubahsuaian pada Halaman mesti ditulis manakala log buat semula hanya mengandungi IO tidak sah yang benar-benar memerlukan untuk ditulis mengurangkan.

    binlog

    Bercakap tentang ini, anda mungkin tertanya-tanya bahawa terdapat juga log sampah yang juga digunakan untuk operasi menulis dan digunakan untuk pemulihan data.

    • Tahap: buat semula log adalah unik untuk enjin innoDB, dan lapisan pelayan dipanggil binlog (log arkib)
    • Kandungan: redolog ialah log fizikal, merekodkan "pengubahsuaian yang dibuat pada halaman data tertentu"; binlog adalah logik Log ialah logik asal pernyataan, seperti "tambah 1 pada medan c baris dengan ID=2"
    • Penulisan: redolog ditulis dalam gelung dan mempunyai banyak peluang penulisan, binlog dilampirkan dan ditulis apabila transaksi dilakukan
    binlog dan buat semula log

    untuk penyata update T set c=c+1 where ID=2;

    1. Pelaksana terlebih dahulu mencari enjin untuk mendapatkan ID talian=2. ID ialah kunci utama dan boleh didapati terus menggunakan carian pokok. Jika halaman data di mana baris dengan ID = 2 terletak dalam ingatan, ia akan dikembalikan terus kepada pelaksana jika tidak, ia perlu dibaca ke dalam memori dari cakera terlebih dahulu dan kemudian dikembalikan.
    2. Pelaksana mendapat data baris yang diberikan oleh enjin, menambah 1, N+1 pada nilai ini untuk mendapatkan baris data baharu, dan kemudian memanggil antara muka enjin untuk menulis baris data baharu ini.
    3. Enjin mengemas kini baris data baharu ini ke dalam memori dan merekodkan operasi kemas kini ke dalam log buat semula Pada masa ini, log buat semula berada dalam keadaan sediakan. Kemudian maklumkan kepada pelaksana bahawa pelaksanaan telah selesai dan transaksi boleh diserahkan pada bila-bila masa.
    4. Pelaksana menjana binlog operasi ini dan menulis binlog ke cakera.
    5. Pelaksana memanggil antara muka transaksi komit enjin, dan enjin menukar log buat semula yang baru ditulis kepada keadaan komit, dan kemas kini selesai

    Kenapa perlu tulis log buat semula dahulu?

    • Buat semula pertama dan kemudian bin: binlog hilang, satu kemas kini hilang, dan ia masih 0 selepas pemulihan.
    • Tang pertama dan kemudian buat semula: Terdapat satu lagi transaksi, dan ia adalah 1 selepas pemulihan.

    Ketekalan

    Ketekalan ialah matlamat utama yang diusahakan oleh urus niaga. Sudah tentu, yang di atas adalah semua jaminan di peringkat pangkalan data, dan pelaksanaan ketekalan juga memerlukan jaminan di peringkat aplikasi.

    Iaitu, untuk perniagaan anda, sebagai contoh, operasi pembelian hanya memotong baki pengguna dan tidak mengurangkan inventori Sudah pasti mustahil untuk memastikan status itu konsisten.

    Ringkasan

    Kita semua biasa dengan MySQL, dan kita juga tahu apa itu ACID, tetapi bagaimana ACID MySQL dilaksanakan?

    Kadang-kadang, seperti yang anda tahu bahawa terdapat batal log dan buat semula log, tetapi anda mungkin tidak tahu mengapa ada apabila anda mengetahui tujuan reka bentuk, ia akan menjadi lebih jelas.

Atas ialah kandungan terperinci Penemubual: Bagaimanakah MySQL melaksanakan ACID?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:Java后端技术全栈. Jika ada pelanggaran, sila hubungi admin@php.cn Padam