Bagaimana saya bisa menambahkan kolom baris ke tabel besar dengan downtime minimal

21

Menggunakan SQL Server 2008 dan yang lebih baru, saya ingin menambahkan kolom rowversion ke tabel besar namun ketika saya cukup

ALTER TABLE [Tablename]
ADD Rowversion [Rowversion] NOT NULL

Maka tabel tidak tersedia untuk pembaruan terlalu lama.

Strategi apa yang dapat saya gunakan untuk mengurangi waktu henti ini? Saya akan mempertimbangkan apa pun. Semakin sederhana tentu saja semakin baik, tetapi saya akan mempertimbangkan strategi apa pun.

Pemikiran saya adalah sebagai pilihan terakhir, saya bisa mempertahankan tabel pementasan salinan yang dikelola oleh pemicu dan kemudian mengubah tabel pementasan ke dalam tabel asli. Tapi saya berharap sesuatu yang lebih sederhana / mudah.

Michael J Swart
sumber

Jawaban:

26

Pertimbangkan untuk membuat tabel baru dengan skema yang sama ditambah kolom versi baris, dan tambahkan tampilan di atas kedua tabel yang melakukan gabungan semua. Mintalah orang lain menggunakan tampilan, dan menulis alih-alih pemicu terhadap tabel & tampilan yang mendasarinya.

Sisipan harus dikirim ke tabel baru, pembaruan harus memindahkan data ke tabel baru, dan penghapusan harus diterapkan ke kedua tabel.

Kemudian lakukan gerakan batch di latar belakang, pindahkan sebanyak mungkin catatan sekaligus ke meja baru. Anda masih dapat memiliki masalah konkurensi saat ini sedang berlangsung, dan beberapa rencana eksekusi craptacular, tetapi ini memungkinkan Anda tetap online saat gerakan sedang berlangsung.

Idealnya, Anda memulai proses pada hari Jumat sore untuk meminimalkan efek pada pengguna akhir, dan mencoba menyelesaikannya sebelum Senin pagi. Setelah siap, Anda dapat mengubah tampilan menjadi hanya tabel baru, dan rencana eksekusi craptacular hilang. Idealnya.

Untuk menghindari pemicu pemicu saat data dimigrasi dalam kumpulan, lihat jumlah baris dalam tabel yang dihapus / dimasukkan dalam pemicu, dan lewati aktivitas jika mendekati jumlah baris dalam kumpulan Anda.


Pada akhirnya, Michael memutuskan untuk melewatkan tampilan (dan tidak menghapus dari tabel asli) untuk mendapatkan rencana yang lebih stabil. Pertukaran itu pada dasarnya memegang dua salinan tabel. Dia mengubahnya menjadi serangkaian posting blog .

Brent Ozar
sumber
7

Jika Anda punya waktu untuk merencanakan ke depan, ada solusi yang jauh lebih mudah ... (biasanya)

Kunci panjang hampir pasti disebabkan oleh pemisahan halaman pada lapisan penyimpanan. Jadi paksa mereka sesuai jadwal Anda sendiri.

  1. Tambahkan kolom sementara yang bisa NULL dengan tipe data VARBINARY(8).
  2. Temukan waktu kendur yang tersedia di database untuk memperbarui kumpulan catatan yang ada dengan nilai yang valid untuk bidang tersebut. ( 0x0000000027F95A5Bmisalnya)
  3. Pembaruan akan memaksa pemisahan halaman yang diperlukan dan mengalokasikan lebih banyak ruang ke tabel.
  4. Saat Anda tertangkap, jatuhkan kolom sementara (tidak menyentuh penyimpanan yang dialokasikan) dan tambahkan kolom versi baris.
  5. Tidak ada halaman terbelah, dan kunci yang dibutuhkan hanya cukup lama untuk mengisi nilai.

Saya telah menggunakan ini dengan sukses untuk menambahkan kolom baris ke tabel baris 150M dalam waktu kurang dari 10 menit.

Peringatan ... jika Anda memiliki tabel dengan bidang varchar besar (terutama varchar(max)) SQL Server memutuskan untuk membangun kembali tabel alih-alih menggunakan kembali ruang yang baru tersedia. Masih berusaha mencari jalan keluar untuk hal itu.

Scott Lynch
sumber
Menarik, saya kira saya tidak menentukan apa yang "terlalu panjang" berarti dalam pertanyaan saya. Jika> 30 menit terlalu lama untuk skenario Anda dan 10 menit dapat ditoleransi, solusi ini akan berhasil. Skenario saya adalah berusaha mencapai nol downtime atau lebih spesifik <10 detik yang dicapai oleh jawaban Brent.
Michael J Swart
1

Jika yang TIMESTAMPAnda tambahkan adalah NULLABLE:

  1. Tambahkan VARBINARY(8)kolom
  2. Isi dengan data.

Setelah itu dihuni, di belakang laporan SQL kembali, DROPyang VARBINARY(8)kolom Anda hanya menambahkan dan penduduknya, dan tambahkan TIMESTAMP NULLkolom.


Jika yang TIMESTAMPAnda tambahkan adalah NOT NULLABLE:

  1. Tambahkan BINARY(8)kolom
  2. Isi dengan data.

Setelah itu dihuni, di belakang laporan SQL kembali, DROPyang BINARY(8)kolom Anda hanya ditambahkan dan penduduknya dan ADD THE TIMESTAMP NOT NULLkolom.

Paul White mengatakan GoFundMonica
sumber