Saya mencari praktik terbaik dalam menangani pekerjaan Agen SQL Server terjadwal di grup ketersediaan SQL Server 2012. Mungkin saya melewatkan sesuatu, namun pada kondisi saat ini saya merasa bahwa SQL Server Agent tidak benar-benar terintegrasi dengan fitur SQL2012 yang hebat ini.
Bagaimana saya bisa membuat pekerjaan agen SQL terjadwal menyadari adanya switch node? Sebagai contoh, saya memiliki pekerjaan yang berjalan pada node primer yang memuat data setiap jam. Sekarang jika primary turun, bagaimana saya bisa mengaktifkan pekerjaan pada secondary yang sekarang menjadi primary?
Jika saya menjadwalkan pekerjaan selalu pada sekunder, itu gagal karena kemudian sekunder adalah read-only.
Jawaban:
Dalam pekerjaan SQL Server Agent Anda, miliki beberapa logika kondisional untuk menguji jika instance saat ini melayani peran tertentu yang Anda cari pada grup ketersediaan Anda:
Yang dilakukan adalah menarik peran replika lokal saat ini, dan jika ada dalam
PRIMARY
peran itu, Anda dapat melakukan apa pun yang perlu dilakukan pekerjaan Anda jika itu adalah replika utama. TheELSE
blok opsional, tapi itu untuk menangani logika mungkin jika replika lokal Anda tidak primer.Tentu saja, ubah
'YourAvailabilityGroupName'
kueri di atas ke nama grup ketersediaan aktual Anda.Jangan bingung antara grup ketersediaan dengan instance cluster failover. Apakah instance adalah replika primer atau sekunder untuk grup ketersediaan yang diberikan tidak mempengaruhi objek tingkat server, seperti pekerjaan SQL Server Agent dan sebagainya.
sumber
Daripada melakukan ini berdasarkan per pekerjaan (memeriksa setiap pekerjaan untuk status server sebelum memutuskan untuk melanjutkan), saya telah menciptakan pekerjaan yang berjalan di kedua server untuk memeriksa untuk melihat keadaan server itu.
Pendekatan ini menyediakan sejumlah hal
skrip memeriksa database di bidang di bawah ini
Proc ini dijalankan setiap 15 menit pada setiap server. (memiliki bonus tambahan menambahkan komentar untuk memberi tahu orang-orang mengapa pekerjaan itu dinonaktifkan)
Ini bukan bukti bodoh, tetapi untuk muatan semalam dan pekerjaan per jam itu menyelesaikan pekerjaan.
Bahkan lebih baik daripada menjalankan prosedur ini pada jadwal, alih-alih menjalankannya sebagai respons terhadap Peringatan 1480 (peringatan perubahan peran AG).
sumber
Saya menyadari dua konsep untuk mencapai ini.
Prasyarat: Berdasarkan jawaban Thomas Stringer, saya membuat dua fungsi di master db dari dua server kami:
Hentikan pekerjaan jika tidak dilakukan pada replika utama
Untuk kasus ini, setiap pekerjaan di kedua server membutuhkan salah satu dari dua cuplikan kode berikut sebagai Langkah 1:
Periksa dengan nama grup:
Periksa dengan nama basis data:
Jika Anda menggunakan yang kedua ini, waspadalah terhadap basis data sistem - menurut definisi mereka tidak dapat menjadi bagian dari grup ketersediaan apa pun, jadi itu akan selalu gagal bagi mereka.
Keduanya berfungsi di luar kotak untuk pengguna admin. Untuk pengguna non-admin, Anda harus menambahkan izin tambahan, salah satunya disarankan di sini :
Jika Anda menetapkan tindakan kegagalan untuk Berhenti sukses melaporkan pekerjaan pada langkah pertama ini, Anda tidak akan mendapatkan log pekerjaan penuh dengan tanda silang merah jelek, untuk pekerjaan utama mereka akan berubah menjadi tanda peringatan kuning.
Dari pengalaman kami, ini tidak ideal. Kami awalnya mengadopsi pendekatan ini, tetapi dengan cepat kehilangan jejak mengenai menemukan pekerjaan yang sebenarnya memiliki masalah, karena semua pekerjaan replika sekunder mengacaukan catatan pekerjaan dengan pesan peringatan.
Apa yang kemudian kami lakukan adalah:
Pekerjaan proxy
Jika Anda mengadopsi konsep ini, Anda sebenarnya harus membuat dua pekerjaan per tugas yang ingin Anda lakukan. Yang pertama adalah "pekerjaan proxy" yang memeriksa apakah itu dieksekusi pada replika utama. Jika demikian, ia memulai "pekerjaan pekerja", jika tidak, itu hanya berakhir dengan anggun tanpa mengacaukan log dengan pesan peringatan atau kesalahan.
Meskipun saya pribadi tidak suka gagasan memiliki dua pekerjaan per tugas di setiap server, saya pikir itu pasti lebih dapat dipertahankan, dan Anda tidak perlu mengatur tindakan kegagalan dari langkah untuk Keluar dari kesuksesan pelaporan pekerjaan , yang sedikit canggung.
Untuk pekerjaan, kami mengadopsi skema penamaan. Pekerjaan proxy baru saja dipanggil
{put jobname here}
. Pekerjaan pekerja disebut{put jobname here} worker
. Ini memungkinkan untuk secara otomatis memulai pekerjaan pekerja dari proksi. Untuk melakukannya, saya menambahkan prosedur berikut ke kedua master dbs:Ini menggunakan
svf_AgReplicaState
fungsi yang ditunjukkan di atas, Anda dapat dengan mudah mengubahnya untuk memeriksa menggunakan nama database sebagai gantinya dengan memanggil fungsi lainnya.Dari dalam satu-satunya langkah pekerjaan proxy, Anda menyebutnya seperti ini:
Ini menggunakan Token seperti yang ditunjukkan di sini dan di sini untuk mendapatkan id pekerjaan saat ini. Prosedur kemudian mendapatkan nama pekerjaan saat ini dari msdb, menambahkannya
worker
dan memulai pekerjaan pekerja menggunakansp_start_job
.Meskipun ini masih tidak ideal, itu membuat log pekerjaan lebih rapi dan dapat dipelihara daripada opsi sebelumnya. Selain itu, Anda selalu dapat menjalankan pekerjaan proxy dengan pengguna sysadmin, jadi menambahkan izin tambahan tidak diperlukan.
sumber
Jika proses pemuatan data adalah kueri atau prosedur panggilan sederhana maka Anda dapat membuat pekerjaan pada kedua node dan membiarkannya menentukan apakah itu simpul utama berdasarkan pada properti Updateability dari database, sebelum menjalankan proses pemuatan data:
sumber
Itu selalu lebih baik untuk membuat Langkah Kerja baru yang memeriksa apakah itu adalah Replika Primer maka semuanya baik-baik saja untuk melanjutkan pelaksanaan pekerjaan lain jika itu adalah Replika Sekunder kemudian Hentikan pekerjaan itu. Jangan gagal pekerjaan lain itu akan terus mengirimkan pemberitahuan yang tidak perlu. Alih-alih menghentikan pekerjaan sehingga dibatalkan dan tidak ada pemberitahuan yang dikirim setiap kali pekerjaan ini dieksekusi pada Replika Sekunder.
Di bawah ini adalah skrip untuk menambahkan langkah pertama untuk pekerjaan tertentu.
Catatan untuk menjalankan skrip:
Jika ada beberapa Grup Ketersediaan, maka setel nama AG dalam variabel @AGNameToCheck_IfMoreThanSingleAG untuk AG yang harus diperiksa untuk negara replika.
Perhatikan juga bahwa skrip ini harus berfungsi dengan baik bahkan pada server yang tidak memiliki grup ketersediaan. Akan mengeksekusi hanya untuk versi SQL Server 2012 dan seterusnya.
sumber
Cara lain adalah dengan memasukkan langkah di setiap pekerjaan, yang harus dijalankan terlebih dahulu, dengan kode berikut:
Tetapkan langkah ini untuk melanjutkan dengan langkah berikutnya tentang kesuksesan, dan untuk berhenti dari kesuksesan pelaporan pekerjaan pada kegagalan.
Saya merasa lebih bersih untuk menambahkan langkah ekstra daripada menambahkan logika tambahan ke langkah yang ada.
sumber
Pilihan lain, yang lebih baru, adalah menggunakan master.sys.fn_hadr_is_primary_replica ('DbName'). Saya telah menemukan ini sangat membantu ketika menggunakan SQL Agent untuk melakukan pemeliharaan basis data (ditambah dengan kursor yang telah saya gunakan selama bertahun-tahun) dan juga ketika menjalankan ETL atau tugas khusus basis data lainnya. Keuntungannya adalah ia memilih basis data daripada melihat seluruh Grup Ketersediaan ... jika itu yang Anda butuhkan. Itu juga membuatnya jauh lebih mustahil bahwa perintah akan dieksekusi terhadap database yang "berada" pada primary, tetapi katakanlah failover otomatis terjadi selama pelaksanaan pekerjaan, dan sekarang pada replika sekunder. Metode di atas yang melihat replika utama lihat sekali dan jangan perbarui. Perlu diingat, ini hanya cara yang berbeda untuk mencapai hasil yang sangat mirip dan memberikan lebih banyak kontrol granular, jika Anda membutuhkannya. Juga, alasan metode ini tidak dibahas ketika pertanyaan ini diajukan adalah karena Microsoft tidak merilis fungsi ini sampai setelah SQL 2014 dirilis. Berikut adalah beberapa contoh bagaimana fungsi ini dapat digunakan:
Jika Anda ingin menggunakan ini untuk pemeliharaan basis data pengguna, inilah yang saya gunakan:
Saya harap ini tip yang bermanfaat!
sumber
Saya menggunakan ini:
sumber