Artikel ini membahas masalah yang terjadi selama kueri indeks penyimpan kolom berkluster di Microsoft SQL Server 2014. Artikel ini memberikan resolusi untuk masalah ini.
Ringkasan
Ketika menggunakan kueri yang memindai indeks penyimpan kolom berkluster di Microsoft SQL Server 2014, Anda mungkin, dalam kondisi yang langka, menerima hasil kueri parsial.
Masalah ini terjadi saat operasi berikut dijalankan.
Langkah 1
Pernyataan Transact-SQL [INSERT atau BULK-INSERT] menyisipkan data ke dalam tabel yang memiliki indeks penyimpan kolom berkluster. Selama operasi ini, berlaku ketentuan berikut:
- Ketika pernyataan Transact-SQL mencapai ambang batas grup baris, pernyataan tersebut menutup grup baris R1 yang memiliki segmen S1.
- Segmen S1 mengarah ke kamus lokal D1.
- Pernyataan ini terus menyisipkan baris ke grup baris baru R2.
- Saat grup baris R1 ditutup, kamus lokal D1 juga tidak harus ditutup. Jika kamus D1 masih memiliki ruang yang tersedia, Anda dapat membiarkannya terbuka dan menggunakannya kembali untuk grup baris baru R2.
Langkah 2
Jika pernyataan Transact-SQL diakhiri secara tidak normal atau dibatalkan sebelum menutup grup baris baru R2, ketentuan berikut berlaku:
- Perubahan metadata penyimpan kolom terjadi dalam subtransaksi yang melakukan komitmen secara independen dari transaksi luar.
- Pada titik ini, grup baris R1 persiste dalam tabel sistem dalam status "dalam pembangunan" atau TIDAK TERLIHAT, dan segmen S1 merujuk kamus D1.
- Tidak ada baris yang dibuat dalam tabel sistem untuk kamus D1. Hal ini karena pernyataan Transact-SQL tidak pernah memiliki kesempatan untuk menutup baris yang sudah ada. Oleh karena itu, baris yang ada tetap ada.
Langkah 3
Dalam situasi biasa, jika tugas latar belakang penggerak tuple dimulai setelah pernyataan Transact-SQL berakhir, tugas latar belakang menghapus grup baris R1 yang tidak terlihat dan segmen S1. Jika pernyataan Transact-SQL baru dimulai sekarang dan membuat grup baris R3 yang memiliki segmen baru S3 yang memerlukan kamus lokal baru, Anda tidak dapat menggunakan kembali ID internal kamus D1. Hal ini dikarenakan status dalam memori penyimpanan kolom melacak ID kamus yang digunakan. Oleh karena itu, segmen S3 akan mereferensikan kamus baru D2.
Catatan: Kondisi pada langkah ini adalah kondisi umum. Oleh karena itu, tidak ada kerusakan yang terjadi.
Langkah 4
Jika SQL Server kehilangan status dalam memori kamus D1 sebelum tugas penggerak tuple diterapkan (dan berfungsi seperti yang dijelaskan pada Langkah 3), masalah yang dijelaskan dalam artikel ini akan terjadi.
Catatan
Peristiwa ini terjadi karena salah satu alasan berikut:
- SQL Server mengalami kelebihan memori, dan konten dalam memori kamus D1 diusir dari memori.
- Instans SQL Server dimulai ulang.
- Database yang berisi indeks penyimpan kolom berkluster offline, lalu kembali online.
Setelah salah satu dari kejadian ini terjadi dan SQL Server memuat ulang struktur dalam memori, tidak ada catatan bahwa kamus D1 dan ID internalnya ada. Hal ini karena kamus D1 tidak dipertahankan dalam tabel sistem saat pernyataan Transact-SQL diakhiri atau digabungkan.
Jika tugas latar belakang penggerak tuple dimulai pada titik ini, tidak ada kesalahan yang terjadi karena kondisi yang dijelaskan pada Langkah 3 berlaku.
Jika grup baris baru R3 dibuat sebelum tugas latar belakang penggerak tuple dimulai (per item poin sebelumnya), SQL Server menetapkan ID internal yang sama ke kamus baru D1, dan mereferensikan kamus D1 untuk segmen S3 di grup baris R3.
Ketika tugas latar belakang penggerak tuple dimulai setelah tindakan sebelumnya, ia akan menjatuhkan grup baris yang tidak terlihat R1 dan segmennya S1 bersama dengan kamus baru D1. Hal ini terjadi karena penggerak tuple menganggap bahwa kamus baru D1 dan kamus asli D1 yang direferensikan S1 sama.
Catatan Jika kondisi ini terjadi, Anda tidak dapat mengkueri konten rowgroup R3.
Resolusi
Masalah ini pertama kali diperbaiki dalam pembaruan kumulatif berikut untuk SQL Server:
Pembaruan Kumulatif 1 untuk SQL Server 2014 SP1
Pembaruan Kumulatif 8 untuk SQL Server 2014
Perbaikan untuk masalah ini juga disertakan dalam pembaruan rilis distribusi umum (GDR) berikut:
Pembaruan Keamanan untuk SQL Server 2014 QFE
Pembaruan ini mencakup Pembaruan Kumulatif 8, perbaikan penting ini, dan pembaruan keamanan MS15-058 yang diperlukan.
Pembaruan Keamanan untuk SQL Server 2014 GDR
Pembaruan ini mencakup perbaikan penting ini dan perbaikan keamanan kumulatif melalui MS15-058.
Pembaruan Nonkeamanan untuk SQL Server 2014 Paket Layanan 1 GDR
Pembaruan ini hanya menyertakan perbaikan penting ini.
Tentang pembaruan kumulatif untuk SQL Server
Setiap pembaruan kumulatif baru untuk SQL Server berisi semua hotfix dan semua perbaikan keamanan yang disertakan dengan pembaruan kumulatif sebelumnya. Lihat pembaruan kumulatif terbaru untuk SQL Server:
- Pembaruan kumulatif terbaru untuk SQL Server 2014 SP1
- Pembaruan kumulatif terbaru untuk SQL Server 2014
Informasi Selengkapnya
Pesan kesalahanDalam database yang saat ini terpengaruh, jika Anda menjalankan DBCC CHECKDB setelah menerapkan perbaikan ini, Anda akan menerima pesan kesalahan berikut:
Catatan
Msg 5289, Tingkat 16, Negara Bagian 1, Baris 1
Indeks penyimpanan kolom berkluster 'cci' pada tabel 't' memiliki satu atau beberapa nilai data yang tidak cocok dengan nilai data dalam kamus. Memulihkan data dari cadangan.
Dalam database yang saat ini terpengaruh, ketika menjalankan kueri yang memindai tabel yang terpengaruh setelah menerapkan perbaikan ini, Anda mendapatkan pesan kesalahan berikut:
Catatan
Msg 5288, Tingkat 16, Negara Bagian 1, Baris 1
Indeks penyimpan kolom memiliki satu atau beberapa nilai data yang tidak cocok dengan nilai data dalam kamus. Jalankan DBCC CHECKDB untuk info selengkapnya.
Jika menerima kesalahan ini, Anda dapat menyimpan data yang tidak rusak dengan mengekspor data kolom/grup baris yang tidak terpengaruh secara massal, lalu memuat ulang data setelah Anda menjatuhkan atau membuat indeks penyimpan kolom berkluster. Anda harus mengaktifkan Bendera Pelacakan 10207 untuk menekan kesalahan 5288 dan kembali ke perilaku lama melewatkan grup baris yang rusak.
Catatan: Pesan kesalahan 5288 dan 5289 dibuat untuk grup baris R3 yang memiliki segmen S3 ini. Bendera pelacakan 10207 digunakan untuk mengekstrak segmen grup baris R3 yang tidak terpengaruh oleh kamus D1 yang hilang.
Kueri untuk database yang terpengaruhUntuk menentukan apakah database yang berisi indeks penyimpan kolom sudah terpengaruh oleh masalah ini, jalankan kueri berikut:
select
object_name(i.object_id) as table_name,
i.name as index_name,
p.partition_number,
count(distinct s.segment_id) as damaged_rowgroups
from
sys.indexes i
join sys.partitions p on p.object_id = i.object_id and p.index_id = i.index_id
join sys.column_store_row_groups g on g.object_id = i.object_id and g.index_id = i.index_id and g.partition_number = p.partition_number
join sys.column_store_segments s on s.partition_id = p.partition_id and s.segment_id = g.row_group_id
where
i.type in (5, 6)
and s.secondary_dictionary_id <> -1
and g.state_description = 'COMPRESSED'
and s.secondary_dictionary_id not in
(
select dictionary_id from sys.column_store_dictionaries d
where d.hobt_id = p.hobt_id and d.column_id = s.column_id
)
group by
object_name(i.object_id),
i.name,
p.partition_number
Catatan
Anda harus menjalankan kueri ini terhadap setiap database yang berisi indeks penyimpan kolom di server yang menjalankan SQL Server. Set hasil kosong menunjukkan bahwa database tidak terpengaruh.
Jalankan kueri ini selama periode ketika tidak ada aktivitas yang akan membuat grup baris baru atau mengubah status grup baris yang ada. Misalnya, aktivitas berikut dapat mengubah status grup baris: pembuatan indeks, organisasi ulang indeks, sisipan massal, penggerak tuple mengompresi penyimpanan delta.
Sebelum menjalankan kueri, Anda dapat menonaktifkan tugas penggerak tuple latar belakang dengan menggunakan bendera pelacakan 634. Gunakan perintah ini untuk menonaktifkan tugas latar belakang: DBCC TRACEON ( 634 , -1 ). Setelah kueri selesai dieksekusi, ingatlah untuk mengaktifkan kembali tugas latar belakang menggunakan perintah: DBCC TRACEOFF ( 634 , -1 ).
Pastikan juga tidak ada perintah BULK INSERT/BCP/SELECT-INTO yang menyisipkan data ke dalam tabel yang menggunakan indeks penyimpan kolom saat kueri ini berjalan.
Disarankan untuk menggunakan langkah-langkah ini untuk mencegah kueri mengembalikan positif palsu.
Status
Microsoft telah mengonfirmasi bahwa ini adalah masalah dalam produk Microsoft sebagaimana tercantum di bagian "Berlaku untuk".