InnoDB, işlem vermeden önce işlem verilerini nerede saklar?


12

JDBC teknolojisini kullanarak READ_COMMITTEDve READ_UNCOMMITTEDevde bazı testler yaptım .

Ben READ_UNCOMMITTEDaslında henüz taahhüt edilmemiş bazı işlem verileri (UPDATE-sorgu gerçekleştirebilir) gibi, taahhüt edilmemiş verileri okuyabilir görüyorum .

Sorular

  • Bir READ_UNCOMMITTEDişlem başka bir işlemden kaydedilmemiş verileri okuyabilecek şekilde , kaydedilmemiş veriler nerede saklanır ?
  • Bir READ_COMMITTEDişlemin onaylanmamış verileri okuması, yani "kirli okuma" yapması neden mümkün değildir ? Bu kısıtlamayı hangi mekanizma uygular?

Yanıtlar:


11

" Bir READ_UNCOMMITTED işleminin başka bir işlemdeki kaydedilmemiş verileri okuyabileceği şekilde, kaydedilmemiş veriler nerede depolanıyor? "

Yeni taahhüt edilmemiş kayıt (kümelenmiş PK) sürümleri, sayfadaki kaydın "geçerli" sürümü olarak kabul edilir. Böylece arabellek havuzunda ve / veya tablo alanında (ör. Tablename.ibd) saklanabilirler. Daha sonra READ-UNCOMMITTED dışında herhangi bir durumda bir anlık görüntü / görünüm oluşturması gereken işlemlerin, UNDO kayıtlarını ( sistem tablo alanında depolanan) kullanarak satırın önceki bir sürümünü (geçmiş listesini izleyerek ) oluşturması gerekir. Taahhütsüz kaydı okurken, InnoDB'nin Değişiklik Arabelleğinden bazı taahhüt edilmemiş ikincil dizin kayıtlarını da okuması ve kaydı kullanıcıya sunmadan önce bunları uygulaması gerekebilir .

Bu davranış InnoDB'de geri alma işlemlerini nispeten pahalı hale getirebilir. Bu işlemler temizleme kayıtlarını engelleyeceğinden ve eski kayıt sürümlerinin geçmiş listesi büyüdüğünden ve bu eski sürümleri yeniden oluşturmak için gereken UNDO kayıtlarından dolayı, güncellenmiş kayıtları tutan uzun süredir devam eden boş işlemlerden de potansiyel performans sorunlarına yol açabilecek büyük faktördür. talep üzerine büyümeye devam edecektir. Daha uzun ve daha uzun bir geçmiş listesini (UNDO kayıtlarının tek tek bağlantılı bir listesi olan) geçmeleri ve yeniden yapılandırmak için daha fazla çalışma yapmaları gerektiğinden, kaydın eski / kararlı bir sürümünü okuması gereken yeni işlemleri yavaşlatır. kaydın eski sürümü. Böylece çok fazla CPU döngüsü kullanıyorsunuz (dahili kilitleme ilkellerinden bahsetmiyorum: muteksler, rw_ kilitler, semaforlar, vb.

Umarım bu mantıklı mıdır? :)

Bir FYI olarak, MySQL 5.7'de UNDO tablo alanını ve günlükleri sistem tablo alanının dışına taşıyabilir ve otomatik olarak kısaltabilirsiniz. Arındırma işlemlerini önleyen uzun bir işleminiz varsa oldukça büyüyebilir, bu da çok uzun ve sürekli büyüyen bir geçmiş listesi uzunluğuna neden olur. Onları sistem tablo alanında saklamak, büyük / büyüyen bir ibdata1 dosyasının en yaygın nedeniydi ve bu da daha sonra bu alanı geri kazanmak için kesilemez / küçültülemez / vakumlanamaz.


4

Sen sordun

bir READ_UNCOMMITTED işleminin başka bir işlemden kaydedilmemiş verileri okuyabileceği şekilde, kaydedilmemiş veriler nerede depolanır?

Sorunuzu cevaplamak için InnoDB Mimarisinin neye benzediğini bilmeniz gerekir.

Aşağıdaki resim Percona CTO Vadim Tkachenko tarafından yıllar önce oluşturuldu

InnoDB Mimarisi

InnoDB İşlem Modeli ve Kilitleme Üzerine MySQL Belgelerine Göre

KOMİT, mevcut işlemde yapılan değişikliklerin kalıcı hale getirildiği ve diğer oturumlara görünür hale geldiği anlamına gelir. Öte yandan bir ROLLBACK deyimi, geçerli işlem tarafından yapılan tüm değişiklikleri iptal eder. Hem COMMIT hem de ROLLBACK, geçerli işlem sırasında ayarlanmış olan tüm InnoDB kilitlerini serbest bırakır.

COMMIT ve ROLLBACK veri görünürlüğünü yönettiğinden, READ COMMITTED ve READ UNCOMMITTED değişiklikleri kaydeden yapılara ve mekanizmalara güvenmek zorundadır

  1. Geri Alma Segmentleri / Boşluğu Geri Al
  2. Günlükleri Yeniden Yap
  3. İlgili Tablolara Karşı Boşluklar Kilidi

Geri Alma Segmentleri ve Geri Alma Alanı, değişiklikler uygulanmadan önce değişen verilerin neye benzediğini bilir. Günlükleri Yeniden Yap, verilerin güncellenmesi için hangi değişikliklerin ileriye doğru döndürüleceğini bilir.

Ayrıca sordun

Neden bir READ_COMMITTED işleminin taahhüt edilmemiş verileri okuması, yani "kirli okuma" yapması mümkün değildir? Bu kısıtlamayı hangi mekanizma uygular?

Günlükleri Yeniden Yap, Alanı Geri Al ve Kilitli satırlar devreye girer. Ayrıca InnoDB Tampon Havuzu'nu ( innodb_max_dirty_pages_pct , innodb_buffer_pool_pages_dirty ve innodb_buffer_pool_bytes_dirty ile kirli sayfaları ölçebileceğiniz ) dikkate almalısınız .

Bunun ışığında, OKU TAAHHÜT hangi verilerin kalıcı olarak göründüğünü bilecektir. Bu nedenle, taahhüt edilmemiş kirli sayfaları aramaya gerek yoktur. TAAHHÜT OKUYUN, yapılan kirli bir okumadan başka bir şey olmayacaktır. OKUL UNCOMMITTED, hangi satırların kilitleneceğini ve verilerin görünür olmasını sağlamak için hangi yineleme günlüklerinin okunup yoksayıldığını öğrenmeye devam ederdi.

İzolasyonu Yönetmek için Satırların Kilitlenmesini tam olarak anlamak için lütfen InnoDB İşlem Modelini ve Kilitlemeyi okuyun


1
İlk olarak, cevabım ve gönderimin modifikasyonu için teşekkür ederim ... Peki, bir KOMİT'ten önce, değişiklikler sistemin diğer kullanıcıları tarafından görülemiyor mu? Burada kullanıcı tam anlamıyla bir işlem anlamına gelir, değil mi? READ UNCOMMITTED onaylanmamış verileri okuyabildiğinden, bu yalıtım düzeyi bu verileri nerede okur? Bir veritabanındaki belirli bir veri öğesi için birden fazla taahhüt edilmemiş veri kaynağı olabilir mi? Öyleyse, hangi taahhüt edilmemiş veri parçası okunacaktır?
Shuzheng
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.