چند روز قبل مشکلی رخ داده بود به این شرح!
سروری کهSQL server بر روی آن نصب بود بخاطر SQL server ، بیش از 50 درصد CPU usage مداوم پیدا کرده بود. عموما مصرف CPU اس کیوال سرور روی سرورهای قوی بالا نیست و تداوم این حالت به این شدت یعنی بروز مشکل.
اینجا است که این سؤال پیش میاد، SQL Server الان داره چکار میکنه که تا این حد به صورت مداوم مصرف CPU آن بالا رفته؟ (حدودا 2 ساعت تمام به صورت مداوم مصرف CPU بالای 50 درصد بود)
با استفاده از کوئری زیر میشود، عبارات SQL ایی را که هم اکنون در حال اجرا هستند را به صورت زنده مشاهده کرد: (در اس کیوال سرور 2005 به بعد)
USE master;
SELECT st.text, r.session_id, r.status, r.command, r.cpu_time, r.total_elapsed_time
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS st
همچنین با استفاده از کوئری زیر میتوان آخرین 50 کوئری اجرا شده در SQL server را به همراه زمان اجرای آنها گزارشگیری کرد:
SELECT TOP 50
deqs.last_execution_time AS [Time],
dest.text AS [Query]
FROM sys.dm_exec_query_stats AS deqs
CROSS apply
sys.dm_exec_sql_text(deqs.sql_handle) AS dest
ORDER BY
deqs.last_execution_time DESC
http://www.sqlteam.com/article/dynamic-management-views
عموما محدود کردن دسترسی بر اساس IP بهتر است بر اساس راه حلهایی مانند فایروال، IPSec و یا RRAS IP Filter صورت گیرد که جزو بهینهترین و امنترین راه حلهای ممکن هستند.
در ادامه قصد داریم این محدودیت را با استفاده از امکانات خود اس کیوال سرور انجام دهیم (بلاک کردن کاربران بر اساس IP های غیرمجاز). مواردی که در ادامه ذکر خواهند شد در مورد اس کیوال سرور 2005 ، سرویس پک 2 به بعد و یا اس کیوال سرور 2008 صادق است.
اس کیوال سرور این قابلیت را دارد که میتوان بر روی کلیه لاگینهای صورت گرفته در سطح سرور تریگر تعریف کرد. به این صورت میتوان تمامی لاگینها را برای مثال لاگ کرد (جهت بررسی مسایل امنیتی) و یا میتوان هر لاگینی را که صلاح ندانستیم rollback نمائیم (ایجاد محدودیت روی لاگین در سطح سرور).
لاگ کردن کلیه لاگینهای صورت گرفته به سرور
ایجاد جدولی برای ذخیره سازی اطلاعات لاگینها:
USE [master]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Logging](
[id] [int] IDENTITY(1,1) NOT NULL,
[LogonTime] [datetime] NULL,
[LoginName] [nvarchar](max) NULL,
[ClientHost] [varchar](50) NULL,
[LoginType] [varchar](100) NULL,
[AppName] [nvarchar](500) NULL,
[FullLog] [xml] NULL,
CONSTRAINT [PK_IP_Log] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Logging] ADD CONSTRAINT [DF_IP_Log_LogonTime] DEFAULT (getdate()) FOR [LogonTime]
GO
در ادامه یک تریگر لاگین را جهت ذخیره سازی اطلاعات کلیه لاگینها به سرور ایجاد مینمائیم:
USE [master]
GO
CREATE TRIGGER LogonTrigger
ON ALL SERVER
FOR LOGON
AS
BEGIN
DECLARE @data XML
SET @data = EVENTDATA()
INSERT INTO [Logging]
(
[LoginName],
[ClientHost],
[LoginType],
[AppName],
[FullLog]
)
VALUES
(
@data.value('(/EVENT_INSTANCE/LoginName)[1]', 'nvarchar(max)'),
@data.value('(/EVENT_INSTANCE/ClientHost)[1]', 'varchar(50)'),
@data.value('(/EVENT_INSTANCE/LoginType)[1]', 'varchar(100)'),
APP_NAME(),
@data
)
END
SELECT TOP 100 * FROM [master].[dbo].[Logging] ORDER BY id desc
محدود کردن کاربران بر اساس IP
ClientHost ایی که در رخداد لاگین فوق بازگشت داده میشود همان IP کاربر راه دور است. برای فیلتر کردن IP های غیرمجاز، ابتدا در دیتابیس مستر یک جدول برای ذخیره سازی IP های مجاز ایجاد میکنیم و IP های کلیه کلاینتهای معتبر خود را در آن وارد میکنیم:
USE [master]
GO
CREATE TABLE [IP_RESTRICTION](
[ValidIP] [varchar](15) NOT NULL,
CONSTRAINT [PK_IP_RESTRICTION] PRIMARY KEY CLUSTERED
(
[ValidIP] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
سپس تریگر لاگین ما برای منع کاربران غیرمجاز بر اساس IP ، به صورت زیر خواهد بود:
USE [master]
GO
CREATE TRIGGER [LOGIN_IP_RESTRICTION]
ON ALL SERVER
FOR LOGON
AS
BEGIN
DECLARE @host NVARCHAR(255);
SET @host = EVENTDATA().value('(/EVENT_INSTANCE/ClientHost)[1]', 'nvarchar(max)');
IF (
NOT EXISTS(
SELECT *
FROM MASTER.dbo.IP_RESTRICTION
WHERE ValidIP = @host
)
)
BEGIN
ROLLBACK;
END
END;
تریگر فوق خطرناک است! ممکن است خودتان هم دیگر نتوانید لاگین کنید!! (حتی با اکانت ادمین)
بنابراین قبل از لاگین حتما IP لوکال و یا ClientHost لوکال را هم وارد کنید.
اگر گیر افتادید به صورت زیر میشود رفع مشکل کرد:
تنها حالتی که تریگر لاگین را فعال نمیکند Dedicated Administrator Connection است یا DAC هم به آن گفته میشود. به صورت پیش فرض برای ایجاد این اتصال اختصاصی باید به کامپیوتری که اس کیوال سرور بر روی آن نصب است به صورت لوکال لاگین کرد و سپس در خط فرمان دستور زیر را صادر کنید (حرف A آن باید بزرگ باشد):
C:\>sqlcmd -A -d master -q "insert into IP_RESTRICTION(validip) values('<local machine>')"
این نوع تریگرها در قسمت server objects در management studio ظاهر میشوند.
یکی از قابلیتهای جالب SQL Server در یک شبکه محلی امکان link و اتصال آنها به یکدیگر است. به این صورت امکان کوئری گرفتن (و یا اعمال متداول SQL ایی) از دو یا چند سرور مختلف با دستورات T-SQL میسر میشود؛ به نحوی که حس یکپارچگی دیتابیسهای این سرورها را حین کوئری نوشتن خواهیم داشت.
برای مثال فرض کنید دو سرور SQL1 و SQL2 را در شبکه داریم. میخواهیم در سرور SQL1 اتصالی را به سرور SQL2 ایجاد کنیم.
USE master
EXEC sp_addlinkedserver
'SQL2',
N'SQL Server'
sp_addlinkedsrvlogin @useself='false ', @rmtsrvname = 'SQL2',
@rmtuser = 'sa',
@rmtpassword = 'pass#'
دستورات T-SQL فوق کار ثبت یک liked server جدید و اعمال مشخصات کاربری که توسط آن قرار است به سرور SQL2 دسترسی داشت، انجام میدهند.
اکنون جهت بررسی این اتصال در سرور SQL1 کوئری زیر را اجرا میکنیم:
select * from sql2.faxManager.dbo.tblErja
که نحوهی فراخوانی جدول مورد نظر باید به صورت Server.DatabaseName.dbo.TableName در آن رعایت شود.
تا اینجا همه چیز خوب است. مشکل از زمانی شروع میشود که بخواهیم تراکنشها را نیز دخالت دهیم و اصولی کار کنیم. برای مثال:
begin distributed tran
select * from sql2.faxManager.dbo.tblErja
commit tran
خطایی که در ویندوز سرور 2003 با آخرین به روز رسانیها ظاهر میشود به صورت زیر است:
OLE DB provider for linked server returned message "The partner transaction manager has disabled its support for remote/network transactions.".
به صورت پیش فرض این نوع تراکنشهای توزیع شده غیرفعال هستند مگر اینکه فعال شوند و روش حل مشکل نیز به صورت زیر میباشد:
قبل از هر کاری به کنسول سرویسهای ویندوز مراجعه کرده و از در حال اجرا بودن سرویس Distribute Transaction Coordinator اطمینان حاصل کنید.
سپس به قسمت زیر مراجعه نمائید:
نود مربوط به Component Service را گشوده و سپس بر روی My Computer کلیک راست کرده و گزینهی خواص را انتخاب کنید.
در صفحهی بازه شده به برگهی MSTDC مراجعه کرده و بر روی دکمهی Security Configuration کلیک نمائید.
اکنون تنظیمات آنرا مطابق شکل زیر تغییر دهید.
این تنظیم باید بر روی هر دو سرور SQL1 و SQL2 انجام شود.
پس از این تغییرات که شامل راه اندازی مجدد سرویس Distribute Transaction Coordinator نیز خواهد شد، مشکل خطای فوق برطرف شده و امکان استفاده از تراکنشها در linked servers نیز میسر میشود.
مشکل دیگری که به آن برخوردم خطای زیر است:
OLE DB provider for linked server returned message "Cannot start more transactions on this session.".
برای حل این مشکل یک سطر زیر را باید به ابتدای کوئری خود اضافه کرد که جزو الزامات تراکنشهای توزیع شده است و به این صورت از rollback کامل تمامی دستورات موجود فراخوانی شده T-SQL در صورت بروز کوچکترین خطایی اطمینان حاصل میکند:
SET XACT_ABORT ON
برای مطالعه بیشتر:
MSDTC Troubleshooting
Cancellation Token in C# - Part 7
در آخرین قسمت از این سری ویدیوها در مورد کنسلیشن توکن صحبت کردیم و چرایی وجودش و اینکه این توکن رو چه کسی درست میکنه کی درست میکنه چطور مدیریت میکنه.
05:10 Scenario without cancellation token
13:40 What is the cancellation token source
14:53 Demo
18:00 Cancellation Exception
19:10 Review Code of Task Class
21:09 Demo on Asp dotnet core
مدت ویدیو : 27 دقیقه
SQL Server tutorial for beginners
150 videos
In this tutorial, we will start from the very basics and cover topics like joins, views, triggers, system functions, stored procedures, user defined scalar and table valued functions etc. These video tutorials will be useful for frehsers, experienced .NET and SQL Database developers.