Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Log Transaksi SQL Server — Bagian 2

Ini adalah artikel kedua dalam seri yang didedikasikan untuk log transaksi SQL Server dan kekhususannya. Di sini kita akan memeriksa detail catatan log.

Catatan Log

Catatan log adalah inti dari mekanisme logging dan pemulihan. Catatan log menjelaskan satu perubahan dalam database. Jadi, setiap perubahan pada database memiliki catatan log atau catatan log yang membantu menjelaskan perubahan tertentu. Meskipun Anda tidak perlu memahami detail catatan log, untuk memahami apa yang terjadi dengan pencatatan dan pemulihan, detail tersebut sangat menarik.

Catatan log memiliki Nomor Urutan Log unik yang kami definisikan di artikel pertama. Nomor Urutan Log memungkinkan catatan log ditemukan di log transaksi. Selain itu, setiap halaman file data memiliki LSN di header halamannya yang mengidentifikasi catatan log terbaru yang perubahannya tercermin pada halaman. Ini sangat penting untuk pemulihan kerusakan.

Catatan log untuk transaksi bersamaan digabungkan dalam log transaksi sesuai dengan waktu terjadinya. Catatan log disimpan dalam blok log di kumpulan buffer hingga di-flush ke disk.

Tidak ada operasi yang tidak dicatat dalam database pengguna atau sistem. Namun, ada pengecualian:di tempdb, penyimpanan versi dan operasi file kerja tidak dicatat. Catatan log tidak pernah berpindah dalam log transaksi.

Apa yang ada di dalam Catatan Log?

Informasi dalam catatan log memungkinkan untuk dikerjakan ulang (digulung ke depan) atau dibatalkan (diputar kembali). Kemampuan catatan log ini sangat penting untuk memungkinkan transaksi dibatalkan, dan untuk pekerjaan pemulihan. Catatan log berisi banyak bidang, tergantung pada jenis catatan log. Ada beberapa bidang umum di antara semua catatan, termasuk:

  • Jenis catatan log
    • mulai pencatatan log transaksi
    • melakukan catatan log transaksi
    • mengalokasikan halaman dengan mengubah bitmap alokasi
    • menyisipkan baris
    • menghapus satu baris
    • memodifikasi baris
  • Konteks catatan log , jika ada.
  • ID transaksi yang menjadi bagian dari catatan log jika ada. Sebagian besar catatan log adalah bagian dari transaksi.
  • Panjang catatan log . Catatan log biasanya memiliki ukuran tetap, dan kemudian tergantung pada jumlah data yang ada di catatan log, akan ada porsi variabel juga.
  • LSN dari catatan log sebelumnya dalam transaksi yang sama . Jika ada. LSN pada dasarnya adalah penunjuk ke catatan log transaksi sebelumnya yang dihasilkan oleh transaksi tertentu. Rantai LSN sebelumnya ini memungkinkan transaksi tertentu untuk dibatalkan, karena pengembalian dilakukan dalam urutan terbalik, mulai dari catatan log terbaru.
  • Jumlah ruang log yang dipesan jika catatan log harus dibatalkan.

Reservasi Ruang Log

Setiap catatan log yang dihasilkan di bagian penerusan suatu transaksi harus mencadangkan ruang kosong di log transaksi agar catatan log dapat diputar kembali, tanpa log transaksi harus bertambah.

Mekanisme reservasi ruang log sangat konservatif, selalu memesan ruang yang cukup, dan biasanya lebih banyak, untuk berjaga-jaga jika terjadi situasi yang tidak terduga. Misalnya, pembaruan atau penghapusan pada tabel terkompresi akan memesan lebih banyak ruang daripada pembaruan atau penghapusan serupa pada tabel yang tidak dikompresi. Ini terjadi karena rollback pembaruan pada tabel terkompresi mungkin harus mengatasi baris yang diperbarui tidak lagi berada di halaman terkompresi, dan karenanya harus menulis kolom lebar penuh dalam catatan log alih-alih data terkompresi.

Jenis Catatan Log

Ada banyak jenis catatan log, termasuk:

  • LOP_FORMAT_PAGE Operasi halaman format log — adalah tempat halaman telah diformat, yang berarti headernya telah dibuat. Catatan log akan mencatat setidaknya tajuk halaman dan kemungkinan beberapa konten halaman lainnya jika halaman telah dibuat dan diisi sebagai bagian dari operasi seperti pembuatan indeks atau pembangunan kembali)
  • LOP_MODIFY_ROW Operasi ini mengubah sebagian kecil dari data yang ada.
  • LOP_SET_BITS Catatan log ini berlaku untuk bitmap alokasi.
  • LOP_INSERT_ROWS dan LOP_DELETE_ROWS
  • LOP_SET_FREE_SPACE Berlaku untuk PFS – alokasi bitmap yang melacak status alokasi halaman.

Setiap catatan log yang akan membuat perubahan pada halaman data atau halaman indeks dalam indeks tabel termasuk :

    • ID unit alokasi
    • ID halaman dan ID slot catatan di halaman, yang pada dasarnya adalah ID catatan berbasis nol dari data atau catatan indeks di halaman.
    • Gambar setelah, atau gambar sebelum dan sesudah dari data yang diubah. Mungkin ada beberapa set ini dalam satu catatan log. After-image memungkinkan pengulangan terjadi. Gambar sebelumnya memungkinkan terjadinya pembatalan.

Kunci Pencatatan

Beberapa catatan log menyertakan bitmap yang kuncinya ditahan saat perubahan yang dijelaskan terjadi. Bitmap berisi:

      • Hitung jumlah kunci.
      • Jenis dan mode penguncian apa – misalnya, penguncian halaman dalam mode X.
      • Apa kuncinya

Selama pemulihan kerusakan dan kegagalan pencerminan database/kelompok ketersediaan, kunci ini akan diperoleh untuk semua catatan log yang akan dibatalkan. Hal ini memungkinkan fitur pemulihan cepat di Enterprise Edition dari SQL Server 2005 dan seterusnya.

Mencatat Catatan dalam Transaksi

Semua transaksi menghasilkan setidaknya tiga catatan log, selalu dalam urutan berikut:

        • LOP_BEGIN_XACT – termasuk informasi seperti SPID, nama transaksi, dan waktu mulai. Semua transaksi yang dimulai oleh SQL Server memiliki nama untuk menggambarkan operasi (misalnya AllocFirstPage, DROPOBJ)
        • Catatan lain untuk transaksi tersebut.
        • LOP_COMMIT_XACT – jika transaksi dilakukan.
        • LOP_ABORT_XACT – jika transaksi dibatalkan.

Keduanya termasuk waktu akhir untuk transaksi.
Catatan log dalam suatu transaksi dihubungkan bersama mundur oleh LSN. Ini berarti bahwa catatan log berikutnya yang dihasilkan untuk transaksi memiliki LSN dari catatan log sebelumnya yang dibuat untuk transaksi tertentu ini. Hal ini memungkinkan transaksi untuk dibatalkan dengan benar. Beberapa catatan log sama sekali tidak bersifat transaksional, termasuk:

        • Perubahan ruang kosong PFS (tidak mungkin direkonsiliasi dengan transaksi lain)
        • Perubahan bitmap yang berbeda (hanya perubahan satu arah)

Memeriksa Catatan Log

Ada dua cara untuk memeriksa catatan log. Anda dapat menggunakan fungsi LOGINFO DBCC, tetapi disarankan untuk menggunakan fungsi bernilai tabel fn_dblog. Ini memiliki sintaks yang sangat sederhana:

SELECT * FROM fn_dblog (startLSN, endLSN);
GO

Ini adalah fungsi yang sangat kuat karena:

        • mengembalikan kumpulan hasil tabel yang dapat dikelola dengan mudah.
        • memungkinkan predikat kompleks digunakan.
        • memindai semua log transaksi di bagian log yang aktif, dari awal transaksi terlama yang tidak terikat hingga catatan log terbaru. Ini dapat ditimpa menggunakan tanda jejak 2537

Bidang startLSN dan endLSN biasanya diteruskan sebagai NULL
Berikut demonya:

USE DBTest2014
GO
 
SET NOCOUNT ON;
GO
 
--Set the SIMPLE recovery mode with no auto-stats
-- to avoid unwanted log records
ALTER DATABASE DBTest2014 SET RECOVERY SIMPLE;
ALTER DATABASE DBTest2014 SET AUTO_CREATE_STATISTICS OFF;
 
CREATE TABLE [TEST_TABLE] ([C1] INT, [C2] INT, [C3] INT);
 
INSERT INTO [TEST_TABLE] VALUES (1,1,1);
GO
 
--Clear out the log
CHECKPOINT;
GO
 
-- Implicit transaction
INSERT INTO [TEST_TABLE] VALUES (2,2,2);
GO
 
SELECT * FROM fn_dblog(null, null);
GO

Berikut adalah kumpulan hasil yang dipersingkat. Sebenarnya fn_dblog mengembalikan berbagai catatan berbeda seperti Panjang catatan Log, Bit Bendera, Cadangan Log, AllocUnitId, PageID, SlotID, LSN Halaman Sebelumnya, dan lainnya.

Memodifikasi Isi Baris

Modifikasi log dicatat dalam dua cara:sebagai LOP_MODIFY_ROW atau LOP_MODIFY_COLUMNS catatan. Tidak peduli metode mana yang digunakan, itu akan mencatat byte yang sebenarnya sedang diubah. Misalnya, mengubah nilai INT dari 1 menjadi 24 hanya mencatat satu byte perubahan karena tiga byte nol lainnya tidak berubah. SQL Server akan menggunakan LOP_MODIFY_ROW catatan log jika ada satu bagian dari baris yang diperbarui. Porsi didefinisikan sebagai berikut:setiap kolom dengan panjang variabel dalam baris adalah "porsi" dan seluruh area lebar tetap dari baris adalah "porsi", bahkan jika beberapa kolom sedang diperbarui, tetapi hanya jika byte sedang yang diperbarui berjarak 16 byte atau kurang dalam satu baris.

LOP_MODIFY_ROW berisi:

  • Sebelum gambar
  • Setelah gambar
  • Indeks kolom kunci jika ada
  • Kunci bitmap

LOP_MODIFY_COLUMNS berisi:

  • Sebelum dan sesudah larik offset
  • Array panjang
  • Indeks kolom kunci jika ada
  • Kunci bitmap
  • Sebelum dan sesudah pemasangan gambar

Catatan Log Kompensasi

Ini adalah jenis catatan log khusus yang digunakan untuk membantu pengembalian transaksi. Ketika transaksi mundur, perubahan yang dijelaskan oleh setiap catatan log dalam transaksi harus dibatalkan dalam database. Rollback dimulai dengan catatan log terbaru untuk transaksi dan mengikuti tautan LSN sebelumnya hingga catatan log LOP_BEGIN_XACT. Untuk setiap catatan log:

  • Lakukan "anti-operasi" yang akan meniadakan efek dari catatan log
  • Buat catatan log, tandai sebagai catatan log KOMPENSASI, karena mengompensasi catatan log di bagian penerusan transaksi.
  • LSN catatan log KOMPENSASI sebelumnya menunjuk ke catatan log sebelum yang dikompensasikannya. Ini pada dasarnya menyebabkan catatan log tidak lagi menjadi bagian dari rantai catatan log untuk transaksi.
  • Ruang log yang dicadangkan untuk catatan log dilepaskan

Catatan log KOMPENSASI tidak dapat dibatalkan, hanya diulang.

Mengembalikan Transaksi

Berikut adalah representasi grafis dari apa yang terjadi ketika transaksi dibatalkan:

Mari kita periksa kode berikut:

USE DBTest2014
GO
 
SET NOCOUNT ON;
GO
 
ALTER DATABASE DBTest2014 SET RECOVERY SIMPLE;
ALTER DATABASE DBTest2014 SET AUTO_CREATE_STATISTICS OFF;
 
CREATE TABLE [TEST_TABLE] ([C1] INT, [C2] INT, [C3] INT);
 
INSERT INTO [TEST_TABLE] VALUES (1,1,1);
INSERT INTO [TEST_TABLE] VALUES (2,2,2);
GO
--Clear out the log
CHECKPOINT;
GO
-- Explicit transaction to insert a new record
BEGIN TRAN;
INSERT INTO [TEST_TABLE] VALUES (3,3,3);
GO
 
SELECT * FROM fn_dblog(null, null);
GO
--Roll it back
ROLLBACK TRAN;
GO
 
SELECT * FROM fn_dblog(null, null);

Di sini kita dapat melihat catatan log khusus dengan deskripsi “KOMPENSASI”

Jika kita melihat LSN sebelumnya, kita dapat melihat bahwa LOP_INSERT_ROWS yang kami lakukan, menautkan kembali ke …0f40:0001 dan ini adalah transaksi BEGIN karena bagian forward dari transaksi tersebut menautkan kembali ke catatan log sebelumnya. LOP_DELETE_ROW catatan log kompensasi tidak menautkan kembali ke catatan yang dikompensasikannya — catatan itu menautkannya (ke catatan log transaksi BEGIN).

Jadi DELEDE telah mengkompensasi INSERT dan menghapusnya dari daftar catatan log. LOP_ABORT_XACT adalah sinyal bahwa transaksi diakhiri dengan rollback. Anda juga dapat melihat bahwa LOP_ABORT_XACT tautan kembali ke LOP_BEGIN_XACT.
Saat kami melakukan pencatatan log kompensasi, Reservasi Ruang Log turun [-74]. Jadi sebenarnya memberikan kembali beberapa ruang yang disediakan untuk bagian forward dari transaksi (LOP_INSERT_ROWS [178]). Seperti yang Anda lihat, sistem reservasi ruang log sangat konservatif — INSERT menyimpan lebih banyak ruang daripada yang dikembalikan DELETE.

Rollback dan Cadangan Diferensial

Jika database memiliki cadangan lengkap yang diambil, maka transaksi memperbarui 100.000 catatan tetapi transaksi dibatalkan, mengapa cadangan diferensial begitu banyak data? Tentunya rollback transaksi berarti tidak ada yang berubah? Potongan teka-teki yang hilang di sini adalah bahwa memutar kembali suatu transaksi tidak menghapus semua perubahan yang dilakukan oleh transaksi tersebut. Seperti yang telah kita lihat, rollback harus menghasilkan catatan log kompensasi, karena rollback harus menghasilkan perubahan lain untuk mengkompensasi bagian forward dari transaksi. Header halaman dari semua halaman yang terpengaruh diubah setidaknya dua kali. Satu untuk memperbarui LSN halaman untuk bagian forward transaksi dan satu kali untuk memperbarui LSN halaman untuk bagian rollback transaksi. Dalam kedua kasus, pembaruan akan menyebabkan tingkat ditandai sebagai berubah dalam bitmap diferensial. Tidak peduli apa perubahannya, hanya saja ada sesuatu yang berubah. Tidak ada cara untuk mengecualikan perluasan ini dari cadangan diferensial.

Ringkasan

Pada artikel ini, kita telah melihat catatan log. Catatan log adalah inti dari mekanisme logging dan pemulihan. Setiap perubahan dalam database memiliki catatan log yang terkait dengannya. Setiap catatan log menjelaskan perubahan kecil. Perubahan besar memiliki beberapa catatan log di dalam satu transaksi. Ada banyak jenis catatan log yang berbeda dan kami telah melihat beberapa di antaranya.

Log transaksi pada dasarnya adalah topik yang sangat besar dan beberapa artikel tidak cukup untuk mengungkap semua detailnya. Jadi jika Anda ingin mendapatkan informasi lebih rinci, saya sarankan Anda membaca buku berikut:Manajemen Log Transaksi SQL Server oleh Tony Davis dan Gail Shaw dan artikel ini:Manajemen Log Transaksi.

Baca juga:

Selami Log Transaksi SQL Server — Bagian 1
Selami Log Transaksi SQL Server — Bagian 2


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Melewati array ke Prosedur Tersimpan SQL Server

  2. mengisolasi sub-string dalam string sebelum simbol di SQL Server 2008

  3. Hasilkan Tanggal antara rentang tanggal

  4. COS() Contoh di SQL Server

  5. Cara Memperbaiki "Pernyataan ALTER TABLE SWITCH gagal" Msg 4982 (SQL Server)