Rumah > Artikel > pangkalan data > Isu berkaitan RR dan bacaan hantu dalam mysql
Artikel ini membawa anda pengetahuan yang berkaitan tentang mysql, yang terutamanya memperkenalkan kandungan yang berkaitan tentang RR dan bacaan hantu, termasuk prinsip MVCC, bacaan hantu penjanaan RR dan bacaan hantu penyelesaian RR Mari kita lihat kandungan di bawah, semoga bermanfaat kepada semua.
Pembelajaran yang disyorkan: tutorial video mysql
2. Prinsip MVCC
Kelebihan terbesar MVCC ialah tiada penguncian untuk membaca dan tiada konflik antara membaca dan menulis.
Dalam aplikasi OLTP (On-Line Transaction Processing), adalah penting bahawa tiada konflik antara membaca dan menulis hampir semua RDBMS menyokong MVCC.
Nota: MVCC hanya berfungsi di bawah dua tahap pengasingan: RC komit baca dan RR baca boleh berulang.
Nota: MVCC hanya berfungsi di bawah dua tahap pengasingan: RC komit baca dan RR baca boleh berulang.
Nota: MVCC hanya berfungsi di bawah dua tahap pengasingan: RC komit baca dan RR baca boleh berulang.
(1) Pelaksanaan pelbagai versi MVCC Apabila MySQL melaksanakan mekanisme MVCC, ia berdasarkan rantaian berbilang versi log asal Mekanisme ReadView.
Untuk rangkaian berbilang versi log asal, berikut ialah contoh:
Penyerahan baca RC: Setiap penyata operasi baca akan memperoleh ReadView Selepas setiap kemas kini, status penyerahan transaksi terkini dalam pangkalan data akan diperoleh, dan anda boleh melihat transaksi yang diserahkan terkini, iaitu setiap penyata Setiap. pelaksanaan mengemas kini paparan keterlihatannya.
Bacaan berulang RR: ReadView tidak akan diperolehi apabila memulakan transaksi ReadView hanya akan diperoleh apabila bacaan syot kilat pertama dimulakan.
Jika anda menggunakan bacaan semasa, anda akan mendapat ReadView baharu dan anda juga boleh melihat data yang dikemas kini.
(2) Bacaan syot kilat dan bacaan semasa
Dalam kawalan konkurensi MVCC, operasi baca boleh dibahagikan kepada dua kategori:
Bacaan syot kilat: Apa yang dibaca ialah versi rekod yang boleh dilihat (yang mungkin versi sejarah), tanpa dikunci.
Operasi: Operasi PILIH yang mudah.
Bacaan semasa: Versi terkini rekod dibaca dan rekod yang dikembalikan oleh bacaan semasa akan dikunci untuk memastikan transaksi lain tidak akan mengubah suai rekod ini secara serentak.
Operasi: operasi baca khas, operasi tambah/kemas kini/padam.
-- 对应 SQL 如下: -- 1. 特殊读操作 SELECT ... FOR UPDATE SELECT ... LOCK IN SHARE MODE -- 共享锁 -- 2. 新增:INSERT -- 3. 更新:UPDATE -- 4. 删除:DELETE
Digabungkan dengan mekanisme ReadView untuk membezakan: Bacaan syot kilat dan bacaan semasa:
Baca syot kilat: Dalam transaksi, ReadView hanya akan diperoleh apabila bacaan syot kilat pertama dimulakan dan berikutnya Operasi baca tidak akan memperolehnya lagi.
Bacaan semasa: ReadView akan diperolehi untuk setiap operasi baca.
Soalan temu bual: Di bawah tahap pengasingan transaksi RR, transaksi A menanyakan sekeping data, transaksi B menambah sekeping data dan transaksi A boleh lihat transaksi B Data?
Soalan ini agak kabur, tetapi kita tahu bahawa titik pemeriksaan umum ialah bacaan RR dan hantu Masalahnya boleh dibahagikan kepada dua kategori:
Dalam keadaan apa, RR menghasilkan bacaan hantu? (Boleh lihat data)
Jawapan: Bacaan semasa (PILIH..UNTUK UDPDATE, PILIH ... LOCK IN SHARE MODE)
Dalam keadaan apakah RR menyelesaikan bacaan hantu? (Tidak dapat melihat data)
Jawapan: Mengunci, bacaan syot kilat
Nota: Bacaan tidak boleh berulang memfokuskan pada UPDATA dan PADAM, manakala bacaan hantu memfokuskan pada INSERT.
Perbezaan terbesar antara mereka ialah cara menyelesaikan masalah yang mereka timbulkan melalui mekanisme kunci.
Kunci yang disebut di sini hanya menggunakan mekanisme penguncian yang pesimis.
Mari kita semak semula: Bacaan hantu
-- 举个栗子:有这样一个查询 SQL SELECT * FROM user WHERE id < 10;
Di bawah transaksi yang sama, 4 keping data ditanya di T1 dan 8 keping ditanya di T2 . Ini mencipta bacaan hantu.
Di bawah transaksi yang sama, 8 keping data ditanya pada masa T1 dan 4 keping data ditanya pada masa T2. Ini mencipta bacaan hantu.
Persediaan eksperimen adalah seperti berikut: Amalan tangan
show variables like 'transaction_isolation'; -- 事务隔离级别 RR select version(); -- 版本 8.0.16 show variables like '%storage_engine%'; -- 引擎 InnoDB -- 1. 手动开启事务提交 begin; -- 开始事务 commit; -- 提交事务 -- 2. 创建表 CREATE TABLE IF NOT EXISTS `student` ( `id` INT NOT NULL COMMENT '主键 id', `name` VARCHAR(50) NOT NULL COMMENT '名字', `age` TINYINT NOT NULL COMMENT '年龄', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT '学生表'; -- 3. 新增数据用于实验 INSERT INTO student (id, name, age) VALUES (5, 'kunkun', 14); INSERT INTO student (id, name, age) VALUES (30, 'ikun', 18);
(1) RR menghasilkan bacaan hantu
Percubaan adalah seperti berikut: Uji bacaan semasa
Eksperimen 1: PILIH dahulu, kemudian PILIH... UNTUK KEMASKINI
Percubaan 2: PILIH dahulu, kemudian KEMASKINI (tiada bacaan hantu akan berlaku )
Eksperimen 1: PILIH dahulu, kemudian PILIH... UNTUK KEMASKINI
-- 事务A: BEGIN; SELECT * FROM student WHERE id < 30; SELECT * FROM student WHERE id < 30 FOR UPDATE; -- 等待事务B commit 后再执行 -- SELECT * FROM student WHERE id < 30 LOCK IN SHARE MODE; COMMIT; -- 事务B: BEGIN; INSERT INTO student (id, name, age) VALUES (20, 'wulikun', 16); COMMIT;
Apa yang berlaku adalah seperti yang ditunjukkan di bawah:
Rekod percubaan adalah seperti yang ditunjukkan di bawah:
Kesimpulan fenomena: Apabila menggunakan bacaan semasa (PILIH ... UNTUK KEMASKINI), bacaan hantu akan berlaku.
Begitu juga menggunakan SELECT ... LOCK IN SHARE MODE akan menghasilkan bacaan hantu.
Eksperimen 2: PILIH dahulu, kemudian KEMASKINI
-- 事务A: BEGIN; SELECT * FROM student WHERE id < 30; UPDATE student SET name = 'zhiyin' WHERE id = 5; -- 等待事务B commit 后再执行 SELECT * FROM student WHERE id < 30; COMMIT; -- 事务B: BEGIN; INSERT INTO student (id, name, age) VALUES (20, 'wulikun', 16); COMMIT;
Apa yang berlaku adalah seperti yang ditunjukkan di bawah :
Rekod percubaan adalah seperti yang ditunjukkan di bawah:
Kesimpulan fenomena: Bacaan semasa (KEMASKINI) tidak akan menghasilkan hantu yang dibaca. INSERT / DELETE tidak akan melakukan perkara yang sama.
(2) RR menyelesaikan bacaan hantu
Percubaan adalah seperti berikut:
Eksperimen 1: Bacaan syot kilat
Eksperimen 2: Kunci (kemas kini rekod yang tidak wujud)
Eksperimen 3 : Tambah Kunci (PILIH ... UNTUK KEMASKINI)
Eksperimen 1: Syot kilat dibaca, PILIHAN biasa
-- 事务A: BEGIN; SELECT * FROM student; SELECT * FROM student; -- 等待事务B commit 后再执行 COMMIT; -- 事务B: BEGIN; INSERT INTO student (id, name, age) VALUES (20, 'wulikun', 16); COMMIT;
berlaku seperti ditunjukkan di bawah :
Rekod percubaan adalah seperti yang ditunjukkan di bawah:
Kesimpulan fenomena: Di bawah tahap pengasingan transaksi RR, terdapat hanya syot kilat Tidak akan ada bacaan hantu semasa membaca (PILIH). Tiada bacaan semasa.
Percubaan 2: Mengunci, (mengemas kini rekod yang tidak wujud)
Di bawah tahap pengasingan RR, transaksi A menggunakan KEMASKINI untuk mengunci dan transaksi B tidak boleh Memasukkan data baharu antara transaksi, supaya data yang dibaca oleh transaksi A sebelum dan selepas KEMASKINI kekal konsisten, mengelakkan bacaan hantu.
-- 事务A: BEGIN; SELECT * FROM student; UPDATE student SET name = 'wulikunkun' WHERE id = 18; -- 记录不存在,产生间隙锁 (5, 30)。 COMMIT; -- 事务B: BEGIN; INSERT INTO student (id, name, age) VALUES (10, 'zhiyin', 16); -- 需要等待事务A结束。 COMMIT; -- 事务C: BEGIN; INSERT INTO student (id, name, age) VALUES (40, 'zhiyin你太美', 32); COMMIT; -- 查询数据库中当前有哪些锁 SELECT INDEX_NAME,LOCK_TYPE,LOCK_MODE,LOCK_STATUS,LOCK_DATA FROM performance_schema.data_locks;
Apa yang berlaku adalah seperti yang ditunjukkan di bawah:
实验记录如下图所示:
现象结论:
一开始先加 临键锁Next-key lock,锁范围为 (5,30]。
因为是唯一索引,且更新的记录不存在,临键锁退化成 间隙锁Gap,最终锁范围为 (5,30)。其余的记录不受影响。
实验三:加锁(SELECT ... FOR UPDATE)
-- 事务A: BEGIN; SELECT * FROM student; SELECT * FROM student WHERE id < 5 FOR UPDATE; COMMIT; -- 事务B: BEGIN; INSERT INTO student (id, name, age) VALUES (4, 'zhiyin', 4); -- 需要等待事务A结束。 COMMIT; -- 事务C: BEGIN; INSERT INTO student (id, name, age) VALUES (5, 'zhiyin你太美', 32); -- 插入成功 COMMIT; -- 查询数据库中当前有哪些锁 SELECT INDEX_NAME,LOCK_TYPE,LOCK_MODE,LOCK_STATUS,LOCK_DATA FROM performance_schema.data_locks;
发生情况如下图所示:
实验记录如下图所示:
现象结论:
先加 临键锁Next-key lock,锁范围为 (-∞,5]。
所以,id
拓展:Gap 锁(间隙锁)
根据 官方文档 可知:
锁是加在索引上的。
记录锁: 行锁,只会锁定一条记录。
间隙锁 :是在索引记录之间的间隙上的锁,区间为前开后开 (,)。
临键锁(Next-Key Lock): 由 记录锁 和 间隙锁Gap 组合起来。
加锁的基本单位是 临键锁,其加锁区间为前开后闭 (,]。
索引上的等值查询,给唯一索引加锁的时候,如果满足条件,临键锁 退化为 行锁。
索引上的等值查询,给唯一索引加锁的时候,如果不满足条件,临键锁 退化为 间隙锁。注意,非等值查询是不会优化的。
推荐学习:mysql视频教程
Atas ialah kandungan terperinci Isu berkaitan RR dan bacaan hantu dalam mysql. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!