পদক্ষেপ 1: বিজ্ঞপ্তিগুলি পাওয়ার জন্য একটি পরিষেবা তৈরি করুন এবং এর জন্য একটি সারি তৈরি করুন:
use msdb;
go
create queue dbm_notifications_queue;
create service dbm_notification_service
on queue dbm_notifications_queue
([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]);
go
create event notification dbm_notifications
on server
for database_mirroring_state_change
to service N'dbm_notification_service', N'current database';
go
নোট করুন যে আমি ব্যবহার করছি msdb
, এটি কোনও দুর্ঘটনা নয়। সার্ভার স্তর ঘটনা বিজ্ঞপ্তি থেকে পাঠানো হয় কারণ msdb
এটা অনেক ভালো করেন তাহলে আপনি পুরো উল্টো কথোপকথন শেষবিন্দু (লক্ষ্য) তৈরি হয় msdb
যা যে বোঝা গন্তব্য পরিষেবা এবং কিউ এছাড়া মোতায়েন করা আবশ্যক, msdb
।
পদক্ষেপ 2: ইভেন্ট বিজ্ঞপ্তি প্রক্রিয়াকরণ পদ্ধতি তৈরি করুন:
use msdb;
go
create table dbm_notifications_errors (
incident_time datetime not null,
session_id int not null,
has_rolled_back bit not null,
[error_number] int not null,
[error_message] nvarchar(4000) not null,
[message_body] varbinary(max));
create clustered index cdx_dbm_notifications_errors
on dbm_notifications_errors (incident_time);
go
create table mirroring_alerts (
alert_time datetime not null,
start_time datetime not null,
processing_time datetime not null,
database_id smallint not null,
database_name sysname not null,
[state] tinyint not null,
[text_data] nvarchar(max),
event_data xml not null);
create clustered index cdx_mirroring_alerts
on mirroring_alerts (alert_time);
go
create procedure dbm_notifications_procedure
as
begin
declare @dh uniqueidentifier, @mt sysname, @raw_body varbinary(max), @xml_body xml;
begin transaction;
begin try;
receive top(1)
@dh = conversation_handle,
@mt = message_type_name,
@raw_body = message_body
from dbm_notifications_queue;
if N'http://schemas.microsoft.com/SQL/Notifications/EventNotification' = @mt
begin
set @xml_body = cast(@raw_body as xml);
-- shred the XML and process it accordingly
-- IMPORTANT! IMPORTANT!
-- DO NOT LOOK AT sys.database_mirroring
-- The view represents the **CURRENT** state
-- This message reffers to an **EVENT** that had occured
-- the current state may or may no be relevant for this **PAST** event
declare @alert_time datetime
, @start_time datetime
, @processing_time datetime = getutcdate()
, @database_id smallint
, @database_name sysname
, @state tinyint
, @text_data nvarchar(max);
set @alert_time = @xml_body.value (N'(//EVENT_INSTANCE/PostTime)[1]', 'DATETIME');
set @start_time = @xml_body.value (N'(//EVENT_INSTANCE/StartTime)[1]', 'DATETIME');
set @database_id = @xml_body.value (N'(//EVENT_INSTANCE/DatabaseID)[1]', 'SMALLINT');
set @database_name = @xml_body.value (N'(//EVENT_INSTANCE/DatabaseName)[1]', 'SYSNAME');
set @state = @xml_body.value (N'(//EVENT_INSTANCE/State)[1]', 'TINYINT');
set @text_data = @xml_body.value (N'(//EVENT_INSTANCE/TextData)[1]', 'NVARCHAR(MAX)');
insert into mirroring_alerts (
alert_time,
start_time,
processing_time,
database_id,
database_name,
[state],
text_data,
event_data)
values (
@alert_time,
@start_time,
@processing_time,
@database_id,
@database_name,
@state,
@text_data,
@xml_body);
end
else if N'http://schemas.microsoft.com/SQL/ServiceBroker/Error' = @mt
begin
set @xml_body = cast(@raw_body as xml);
DECLARE @error INT
, @description NVARCHAR(4000);
WITH XMLNAMESPACES ('http://schemas.microsoft.com/SQL/ServiceBroker/Error' AS ssb)
SELECT @error = CAST(@xml_body AS XML).value('(//ssb:Error/ssb:Code)[1]', 'INT'),
@description = CAST(@xml_body AS XML).value('(//ssb:Error/ssb:Description)[1]', 'NVARCHAR(4000)');
insert into dbm_notifications_errors(
incident_time,
session_id,
has_rolled_back,
[error_number],
[error_message],
[message_body])
values (
getutcdate(),
@@spid,
0,
@error,
@description,
@raw_body);
end conversation @dh;
end
else if N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog' = @mt
begin
end conversation @dh;
end
commit;
end try
begin catch
declare @xact_state int = xact_state(),
@error_number int = error_number(),
@error_message nvarchar(4000) = error_message(),
@has_rolled_back bit = 0;
if @xact_state = -1
begin
-- Doomed transaction, it must rollback
rollback;
set @has_rolled_back = 1;
end
else if @xact_state = 0
begin
-- transaction was already rolled back (deadlock?)
set @has_rolled_back = 1;
end
insert into dbm_notifications_errors(
incident_time,
session_id,
has_rolled_back,
[error_number],
[error_message],
[message_body])
values (
getutcdate(),
@@spid,
@has_rolled_back,
@error_number,
@error_message,
@raw_body);
if (@has_rolled_back = 0)
begin
commit;
end
end catch
end
go
রাইটিং সার্ভিস ব্রোকার পদ্ধতিটি আপনার মিল-রান কোড অফ নয়। কাউকে অবশ্যই কিছু মানদণ্ড অনুসরণ করতে হবে এবং চতুর্দিকে ত্রৈমাসিকের অঞ্চলে যেতে খুব সহজ to এই কোডটি কিছু ভাল অভ্যাস দেখায়:
- কোনও লেনদেনে বার্তা প্রেরণাগুলি এবং প্রক্রিয়াজাতকরণ মোড়ক করুন। কোন বুদ্ধিমান, স্পষ্ট।
- সর্বদা প্রাপ্ত বার্তার প্রকারটি পরীক্ষা করুন। একটি ভাল পরিষেবা ব্রোকার পদ্ধতিটি অবশ্যই পাশ থেকে ডায়ালগটি শেষ করে হ্যান্ডেল
Error
এবং EndDialog
বার্তাগুলিকে যথাযথভাবে পরিচালনা করতে হবে। হ্যান্ডেল ফাঁস ( sys.conversation_endpoints
বৃদ্ধি) এর ফলে ফলাফল না করার ফলে
- কোনও বার্তা প্রাপ্তি দ্বারা চিহ্নিত করা হয়েছে কিনা তা সর্বদা পরীক্ষা করে দেখুন। কিছু নমুনা পরে @@ রাউকাউন্ট পরীক্ষা করে
RECEIVE
, যা পুরোপুরি ঠিক। এই নমুনা কোড বার্তা নাম চেক উপর নির্ভর করে (কোনও বার্তা NULL বার্তা প্রকারের নাম বোঝায়) এবং এই কেসটিকে সুস্পষ্টভাবে পরিচালনা করে।
- একটি প্রসেসিং ত্রুটি সারণী তৈরি করুন। এসএসবি সক্রিয় প্রক্রিয়াগুলির পটভূমি প্রকৃতি ত্রুটিগুলি নিরসন করা সত্যিই কঠিন করে তোলে যদি বার্তাগুলি কেবল w / oa ট্রেসটি হারিয়ে যায়।
এছাড়াও, এই কোডটি হাতের কার্য (ডিবিএম পর্যবেক্ষণ) সম্পর্কিত কিছু ভাল-অনুশীলন কোডও করে:
post_time
( বিজ্ঞপ্তিটি কখন প্রেরণ করা হয়েছিল? ), start_time
( কবে বিজ্ঞপ্তিটি কার্যকর করেছিল এমন ক্রিয়াটি কখন শুরু হয়েছিল? ) এবং processing_time
( বিজ্ঞপ্তিটি কখন প্রক্রিয়াজাত করা হয়েছিল ? ) এর মধ্যে পার্থক্য করুন । post_time
এবং start_time
সম্ভবত অভিন্ন বা খুব কাছাকাছি processing_time
হতে পারে তবে এটি কয়েক সেকেন্ড, ঘন্টা, দিন বাদে হতে পারে post_time
। অডিট জন্য আকর্ষণীয় এক সাধারণত হয় post_time
।
- যেহেতু
post_time
এবং processing_time
ভিন্ন, এটি সুস্পষ্ট হওয়া উচিত একটি dBm একটি এমনকি বিজ্ঞপ্তিতে কাজের পর্যবেক্ষণ সক্রিয় যে পদ্ধতি কোন ব্যবসা দিকে তাকিয়ে আছে sys.database_mirroring
দৃশ্য । সেই দৃশ্য প্রক্রিয়াজাতকরণের মুহুর্তে বর্তমান অবস্থাটি প্রদর্শন করবে , যা ঘটনার সাথে সম্পর্কিত বা নাও থাকতে পারে। যদি সমস্যাটি প্রকাশিত হওয়ার চেয়ে ইভেন্টটি পোস্ট হওয়ার পরে দীর্ঘকাল ধরে প্রক্রিয়াজাত হয় (মনে রাখবেন রক্ষণাবেক্ষণ ডাউনটাইম) তবে ডিবিএম যদি খুব দ্রুত রাষ্ট্র পরিবর্তন করে এবং দুটি (বা আরও) ইভেন্ট পোস্ট করে তবে এটি 'স্বাস্থ্যকর' প্রক্রিয়াকরণেও পরিচালনা করতে পারে সারি (যা ঘন ঘন ঘটে): এই পরিস্থিতিতে আপনার পোস্ট করা কোডের মতো প্রক্রিয়াজাতকরণ ঘটনার সাথে সাথে ইভেন্টটি অডিট করবেন তবে বর্তমান, চূড়ান্ত , স্থিতি রেকর্ড করবে । এ জাতীয় নিরীক্ষা পড়া পরে খুব বিভ্রান্ত হতে পারে।
- সর্বদা আসল এক্সএমএল ইভেন্টটি নিরীক্ষণ করুন। এইভাবে আপনি পরে এই এক্সএমএলটি অডিট সারণির কলামগুলিতে 'কাটা' হয়নি এমন কোনও তথ্যের জন্য জিজ্ঞাসা করতে পারেন।
পদক্ষেপ 3: পদ্ধতিটি সারিতে সংযুক্ত করুন:
alter queue dbm_notifications_queue
with activation (
status=on,
procedure_name = [dbm_notifications_procedure],
max_queue_readers = 1,
execute as owner);