Saya sudah menyiapkan Grup Ketersediaan Selalu, dan saya ingin memastikan pengguna saya menggunakan ApplicationIntent = ReadOnly di string koneksi mereka.
Dari SQL Server via DMVs (atau Extended Events atau apa pun), dapatkah saya memberi tahu jika pengguna terhubung dengan ApplicationIntent = ReadOnly di string koneksi mereka?
Tolong jangan jawab dengan cara MENCEGAH koneksi - bukan itu pertanyaan ini. Saya tidak bisa begitu saja menghentikan koneksi, karena kami memiliki aplikasi yang ada yang terhubung tanpa string yang benar, dan saya perlu tahu yang mana sehingga saya dapat bekerja dengan pengembang dan pengguna untuk memperbaikinya secara bertahap dari waktu ke waktu.
Asumsikan bahwa pengguna memiliki banyak aplikasi. Sebagai contoh, Bob terhubung dengan SQL Server Management Studio, dan dengan Excel. Dia terhubung dengan SSMS ketika dia perlu melakukan pembaruan, dan Excel ketika dia perlu membaca. Saya perlu memastikan dia menggunakan ApplicationIntent = ReadOnly ketika dia terhubung dengan Excel. (Itu bukan skenario yang tepat, tetapi cukup dekat untuk diilustrasikan.)
sumber
sqlserver.read_only_route_complete
karena dipicu hanya pada primer.Jawaban:
Mengambil pada
sqlserver.read_only_route_complete
Extended Event yang disebutkan oleh Kin dan Remus, ini adalah acara Debug yang bagus , tetapi tidak membawa banyak informasi dengannya - hanyaroute_port
(mis. 1433) danroute_server_name
(misalnya sqlserver-0.contoso.com) secara default . Ini juga hanya akan membantu menentukan kapan koneksi maksud baca-saja berhasil. Ada suaturead_only_route_fail
peristiwa tetapi saya tidak bisa memecatnya, mungkin jika ada masalah dengan URL perutean, sepertinya tidak menyala ketika instance sekunder tidak tersedia / shutdown sejauh yang saya tahu.Namun saya memiliki beberapa keberhasilan bergabung yang dengan
sqlserver.login
acara dan pelacakan kausalitas diaktifkan, bersama dengan beberapa tindakan (sepertisqlserver.username
) untuk membuatnya berguna.Langkah-langkah untuk Mereproduksi
Buat sesi Acara Diperpanjang untuk melacak acara yang relevan, ditambah tindakan yang berguna dan melacak hubungan sebab akibat:
Jalankan sesi XE (pertimbangkan pengambilan sampel karena ini adalah acara Debug), dan kumpulkan beberapa info masuk:
Catatan di sini sqlserver-0 adalah sekunder saya yang dapat dibaca dan sqlserver-1 primer. Di sini saya menggunakan
-K
saklarsqlcmd
untuk mensimulasikan login maksud aplikasi read-only dan beberapa login SQL. Peristiwa baca-saja menyalakan login niat baca-saja yang berhasil.Saat menjeda atau menghentikan sesi, saya dapat menanyakannya dan mencoba menghubungkan kedua peristiwa tersebut, misalnya:
Kueri harus menampilkan info masuk dengan dan tanpa maksud hanya-baca aplikasi:
read_only_route_complete
adalah acara Debug jadi gunakan dengan hemat. Pertimbangkan contoh pengambilan sampel.Saya berusaha mendapatkan
pair_matching
target untuk bekerja tetapi kehabisan waktu. Ada beberapa potensi untuk pengembangan di sini, seperti:sumber
Tidak, tampaknya tidak ada properti koneksi terbuka DMV (baik di sys.dm_exec_connections atau sys.dm_exec_sessions ) atau bahkan CONNECTIONPROPERTY yang berkaitan dengan
ApplicationIntent
kata kunci ConnectionString.Namun, mungkin layak meminta, melalui Microsoft Connect, bahwa properti ini ditambahkan ke
sys.dm_exec_connections
DMV karena tampaknya merupakan properti koneksi yang disimpan di suatu tempat dalam memori SQL Server, berdasarkan info berikut yang ditemukan di halaman MSDN untuk Dukungan SqlClient untuk Ketersediaan Tinggi, Pemulihan Bencana (cetak miring yang dicetak miring):Jika
USE
pernyataan dapat diverifikasi, makaApplicationIntent
perlu ada di luar upaya koneksi awal. Namun, saya belum memverifikasi perilaku ini secara pribadi.PS Saya telah berpikir bahwa kita dapat menggunakan fakta bahwa:
USE
pernyataan dieksekusi.Idenya adalah untuk membuat Database baru semata-mata dengan tujuan untuk menguji dan melacak pengaturan ini. DB baru akan digunakan dalam Grup Ketersediaan baru yang akan ditetapkan hanya mengizinkan
READ_WRITE
koneksi. Teorinya adalah bahwa di dalam Logon Trigger, diEXEC(N'USE [ReadWriteOnly]; INSERT INTO LogTable...;');
dalamTRY...CATCH
konstruk, dengan dasarnya tidak ada diCATCH
blok, tidak akan menghasilkan kesalahan untuk koneksi ReadWrite (yang akan masuk sendiri dalam DB baru), atauUSE
kesalahan akan pada koneksi ReadOnly, tetapi maka tidak ada yang akan terjadi karena kesalahan ditangkap dan diabaikan (danINSERT
pernyataan itu tidak akan pernah tercapai). Dalam kedua kasus tersebut, peristiwa Logon aktual tidak akan dicegah / ditolak. Kode Pemicu Logon secara efektif adalah:Sayangnya, ketika menguji efek mengeluarkan
USE
pernyataan diEXEC()
dalam bagianTRY...CATCH
dalam Transaksi, saya menemukan bahwa pelanggaran akses adalah pengguguran tingkat batch, bukan aborsi tingkat pernyataan. Dan pengaturanXACT_ABORT OFF
tidak mengubah apa pun. Saya bahkan membuat Prosedur Disimpan SQLCLR sederhana untuk digunakanContext Connection = true;
dan kemudian dipanggilSqlConnection.ChangeDatabase()
dalam atry...catch
dan Transaksi masih dibatalkan. Dan Anda tidak dapat menggunakanEnlist=false
pada Context Connection. Dan menggunakan koneksi reguler / eksternal di SQLCLR untuk melangkah keluar dari Transaksi tidak akan membantu karena itu akan menjadi Koneksi yang sama sekali baru.Ada kemungkinan yang sangat, sangat tipis bahwa HAS_DBACCESS dapat digunakan sebagai pengganti
USE
pernyataan, tetapi saya benar-benar tidak memiliki harapan tinggi untuk dapat menggabungkan informasi Koneksi saat ini ke dalam ceknya. Tapi saya juga tidak punya cara untuk mengujinya.Tentu saja, jika ada Bendera Jejak yang dapat menyebabkan pelanggaran akses tidak dibatalkan secara batch, maka rencana yang disebutkan di atas harus bekerja ;-).
sumber
ROLLBACK
dalam Pemicu LoginINSERT
ke log tabel :-)Anda ingin menjadi seberapa sakit? Aliran TDS tidak terlalu sulit untuk diproksi, kami melakukannya untuk aplikasi SaaS kami. Bit yang Anda cari (secara harfiah sedikit) ada di pesan login7. Anda bisa membuat pengguna Anda terhubung melalui proxy dan login / menegakkan bit di sana. Sial, Anda bahkan bisa menyalakannya untuk mereka. :)
sumber
Apakah aplikasi Anda menggunakan akun layanan atau mungkin beberapa akun layanan? Jika demikian, gunakan Peristiwa Diperpanjang untuk memantau lalu lintas login Anda tetapi mengecualikan akun layanan Anda di server utama selalu aktif. Anda sekarang harus dapat melihat siapa yang masuk ke server selalu aktif primer dan tidak menggunakan string koneksi sekunder readonly. Saya bersiap untuk menginstal Always-On dan inilah yang akan saya lakukan kecuali Anda memberi tahu saya ini tidak akan berhasil.
sumber
Sayangnya saya tidak memiliki lingkungan untuk menguji yang berikut ini, dan tidak diragukan lagi ada beberapa poin di mana ia mungkin gagal, tetapi saya akan membuangnya di sana untuk apa nilainya.
Prosedur tersimpan CLR memiliki akses ke koneksi saat ini melalui
new SqlConnection("context connection=true")
konstruk (diambil dari sini ). Jenis SqlConnection memperlihatkan properti ConnectionString . Karena ApplicationIntent ada dalam string koneksi awal saya kira itu akan tersedia di properti ini dan dapat diuraikan. Ada banyak hand-off dalam rantai itu, tentu saja, begitu banyak peluang untuk semuanya menjadi berbentuk buah pir.Ini akan dijalankan dari Pemicu Logon dan nilai-nilai yang diperlukan bertahan sesuai kebutuhan.
sumber