লক এসক্লেশন - এখানে কী হচ্ছে?


138

এসকিউএল সার্ভার ২০০৮-এ একটি টেবিল (কলাম সরিয়ে) পরিবর্তন করার সময় আমি জেনারেট চেঞ্জ স্ক্রিপ্ট বোতামটি ক্লিক করেছি এবং আমি লক্ষ্য করেছি যে এটির পরিবর্তিত স্ক্রিপ্টটি কলামটি ড্রপ করে, "যান" বলে এবং তারপরে একটি অতিরিক্ত ALTER TABLE স্টেটমেন্ট চালায় যা সেট হিসাবে প্রদর্শিত হয় "টেবিল" টেবিলের জন্য লক বৃদ্ধি। উদাহরণ:

ALTER TABLE dbo.Contract SET (LOCK_ESCALATION = TABLE)

আমার এও লক্ষ্য করা উচিত যে পরিবর্তন স্ক্রিপ্টটি এটিই শেষ কাজ করছে। এটি এখানে কী করছে এবং কেন এটি LOCK_ESCALATION টেবিলটিতে সেট করছে?

উত্তর:


165

" লক এসক্লেশন " কীভাবে এসকিউএল বড় আপডেটগুলির জন্য লক পরিচালনা করে hand এসকিউএল যখন অনেকগুলি সারি পরিবর্তন করতে চলেছে, তখন ডাটাবেস ইঞ্জিনের জন্য অনেক ছোট জিনিস লক করার পরিবর্তে কম, বৃহত্তর লক (যেমন পুরো টেবিল) নেওয়া আরও কার্যকর।

আপনার যখন বিশাল টেবিল থাকে তবে এটি সমস্যাযুক্ত হতে পারে, কারণ পুরো টেবিলটিতে একটি লক নেওয়া আরও দীর্ঘ সময়ের জন্য অন্যান্য প্রশ্নগুলিকে লক আউট করতে পারে। এটি হ'ল ট্রেড অফ: অনেকগুলি ছোট-দানাদার লকগুলি কম (বা এক) মোটা দানাযুক্ত লকগুলির চেয়ে ধীরে ধীরে হয় এবং এক সারণীর বিভিন্ন অংশ লক করে একাধিক প্রশ্ন থাকলে কোনও প্রক্রিয়া অন্যটির অপেক্ষায় থাকলে অচলাবস্থার সম্ভাবনা তৈরি করে।

LOCK_ESCALATIONএসকিউএল ২০০৮-এ নতুন একটি টেবিল-স্তরের বিকল্প রয়েছে , যা লক বর্ধনের নিয়ন্ত্রণ করতে দেয়। ডিফল্ট, "টেবিল" লকগুলি টেবিল স্তরের সমস্ত পথে বাড়ানোর অনুমতি দেয়। অক্ষম বেশিরভাগ ক্ষেত্রে পুরো টেবিলটিতে লক বর্ধন রোধ করে। টেবিলটি বিভাজনযুক্ত না থাকলে স্বয়ংক্রিয়ভাবে টেবিল লককে অনুমতি দেয়, সেই ক্ষেত্রে লকগুলি কেবলমাত্র পার্টিশন স্তর পর্যন্ত তৈরি করা হয়। দেখুন এই ব্লগ পোস্টে আরও তথ্যের জন্য।

আমার সন্দেহ হয় যে টেবিলটি পুনরায় তৈরি করার সময় আইডিই এই সেটিংটি যুক্ত করেছে কারণ টেবিলটি এসকিউএল ২০০ 2008-এ ডিফল্ট। এটি লক্ষ করুন যে এসকিউএল ২০০ 2005-এ LOCK_ESCALATION সমর্থিত নয়, তাই স্ক্রিপ্টটি স্ক্রিপ্ট চালানোর চেষ্টা করলে আপনাকে এটি ছিনিয়ে নিতে হবে need 2005 উদাহরণ। এছাড়াও, যেহেতু টেবিলটি ডিফল্ট, তাই আপনার স্ক্রিপ্টটি পুনরায় চালানোর সময় আপনি নিরাপদে সেই লাইনটি সরাতে পারবেন।

আরও মনে রাখবেন যে এসকিউএল ২০০৫-এ এই সেটিংটি উপস্থিত হওয়ার আগে সমস্ত লকগুলি টেবিলের স্তরে আরো বাড়তে পারে - অন্য কথায়, "টেবিল" এসকিউএল 2005 এ একমাত্র সেটিং ছিল।



6
@ dma_k - এই বিকল্পটি প্রাসঙ্গিক নয় CREATE TABLEকারণ টেবিলটি এখনও বিদ্যমান নেই তাই লক করার মতো কিছুই নেই।
জাস্টিন গ্রান্ট

1
তবে এসএসএমএসে একটি সারণী ডিজাইনের সময় পরিবর্তন স্ক্রিপ্টে প্রাথমিক ALTER TABLE বিবৃতি দেওয়ার পরে LOCK_ESCALATION বিবৃতি কেন ? অবশ্যই সেই সময়ের মধ্যে কাজ ইতিমধ্যে সম্পন্ন হয়েছে। এটি টেবিলের কাঠামো পরিবর্তন করার আগে হওয়া উচিত নয় ?
বিপরীত প্রকৌশলী

2
@ ডেভবোল্টম্যান - সেটটি সারণী বিবৃতিটির অংশ। এটি আলাদা বিবৃতি নয়। ডকস.মাইক্রোসফট.এইন
জাস্টিন গ্রান্ট

2
জাস্টিনগ্র্যান্ট, এখনও, @ ডেভবোল্টম্যানের প্রশ্ন দাঁড়িয়েছে। এসএসএমএসের জন্য যে স্ক্রিপ্টটি তৈরি করা হয়েছে তা বলুন, একটি নতুন কলাম যুক্ত করে দুটি পৃথক ALTER TABLEবিবৃতি রয়েছে has প্রথম ALTER TABLE ADD column, তারপরে GO, তারপর দ্বিতীয় ALTER TABLE SET LOCK_ESCALATION=TABLE, তারপরে দ্বিতীয় GO। সুতরাং, LOCK_ESCALATIONকলামটি যুক্ত হওয়ার পরে সেট করা আছে। বাস্তবতার পরে এটি সেট করার বিষয়টি কী? এই দুটি ALTER TABLEবিবৃতি একটি লেনদেনের মধ্যে আবৃত হয়, কিন্তু এখনও কলামটি LOCK_ESCALATIONসেট হওয়ার আগে যুক্ত করা হয়। আমি মনে করি আমি আরও কিছু খনন করব এবং আরও একটি উত্তর লিখব।
ভ্লাদিমির বারানভ

11

আপনার স্ক্রিপ্টের মূল অংশটি আগে চালানোর আগে এবং পরে এই মানটির তুলনা করে আপনার স্ক্রিপ্টে LOCK_ESCALATION বিবৃতি অন্তর্ভুক্ত করার দরকার আছে কিনা তা আপনি পরীক্ষা করতে পারেন:

SELECT lock_escalation_desc FROM sys.tables WHERE name='yourtablename'

আমার ক্ষেত্রে, সীমাবদ্ধতা ছেড়ে দিতে বা সংযোজন করতে টেবিল পরিবর্তন করা এই মানটি সংশোধন করে না বলে মনে হয়।


11

জাস্টিন গ্রান্টের উত্তরটি LOCK_ESCALATIONসেটিংটি সাধারণভাবে কী করে তা ব্যাখ্যা করে তবে একটি গুরুত্বপূর্ণ বিবরণ মিস করে এবং এসএসএমএস কেন সেট করে যে কোডটি উত্পন্ন করে তা ব্যাখ্যা করে না। বিশেষত, এটি খুব আশ্চর্যজনক দেখাচ্ছে যে LOCK_ESCALATIONস্ক্রিপ্টের সর্বশেষ বিবৃতি হিসাবে সেট করা আছে।

আমি কয়েকটি পরীক্ষা করেছি এবং এখানে কী ঘটছে তা আমার বোঝার জন্য।

সংক্ষিপ্ত সংস্করণ

যে ALTER TABLEবিবৃতিটি স্পষ্টভাবে একটি কলাম যুক্ত করে, ড্রপ করে বা পরিবর্তিত করে তা টেবিলে একটি স্কিমা সংশোধন (এসসিএইচ-এম) লক নেয়, যার LOCK_ESCALATIONকোনও টেবিলের সেটিংয়ের সাথে কোনও সম্পর্ক নেই । LOCK_ESCALATIONDML বিবৃতি (সময় আচরণ লক প্রভাবিত INSERT, UPDATE, DELETE, ইত্যাদি), DDL বিবৃতি সময় নয় ( ALTER)। এসসিএইচ-এম লক হ'ল সর্বদা পুরো ডাটাবেস অবজেক্টের একটি লক, এই উদাহরণে সারণী।

এই কারণেই বিভ্রান্তি আসে।

এসএসএমএস ALTER TABLE <TableName> SET (LOCK_ESCALATION = ...)সমস্ত স্ক্রিপ্টে বিবৃতি যুক্ত করে , এমনকি যখন এটি প্রয়োজন হয় না। যখন এই বিবৃতিটির প্রয়োজন হয়, তখন এটি টেবিলের বর্তমান সেটিংস সংরক্ষণের জন্য যুক্ত করা হয়, সেই স্ক্রিপ্টে টেবিল স্কিমায় পরিবর্তনের সময় কোনও নির্দিষ্ট উপায়ে টেবিলটি লক না করা

অন্য কথায়, টেবিল হয় প্রথম SCH-এম লক দিয়ে লক ALTER TABLE ALTER COLUMNযখন সব টেবিল স্কিমা পরিবর্তন কাজ সম্পন্ন করা হয় বিবৃতি। শেষ ALTER TABLE SET LOCK_ESCALATIONবিবৃতি এটি প্রভাবিত করে না। এটা শুধুমাত্র ভবিষ্যতে DML বিবৃতি (প্রভাবিত INSERT, UPDATE, DELETE, ইত্যাদি) যে টেবিল জন্য।

প্রথম নজরে এটি দেখে মনে SET LOCK_ESCALATION = TABLEহচ্ছে যেন আমরা পুরো টেবিলটি পরিবর্তন করছি (আমরা এখানে এর স্কিমাটি পরিবর্তন করছি) এর সাথে কিছু করার আছে তবে এটি বিভ্রান্তিকর।

দীর্ঘ সংস্করণ

কিছু ক্ষেত্রে টেবিলটি পরিবর্তন করার সময় এসএসএমএস একটি স্ক্রিপ্ট তৈরি করে যা পুরো টেবিলটি পুনরায় তৈরি করে এবং কিছু সহজ ক্ষেত্রে (কোনও কলাম যুক্ত বা বাদ দেওয়ার মতো) স্ক্রিপ্টটি টেবিলটি পুনরায় তৈরি করে না।

আসুন উদাহরণ হিসাবে এই নমুনা সারণীটি নেওয়া যাক:

CREATE TABLE [dbo].[Test](
    [ID] [int] NOT NULL,
    [Col1] [nvarchar](50) NOT NULL,
    [Col2] [int] NOT NULL,
 CONSTRAINT [PK_Test] 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

প্রতিটি টেবিলের একটি LOCK_ESCALATIONসেটিংস থাকে, যা TABLEডিফল্টরূপে সেট করা থাকে । আসুন এখানে এটি পরিবর্তন করুন:

ALTER TABLE dbo.Test SET (LOCK_ESCALATION = DISABLE)

এখন, আমি Col1যদি এসএসএমএস টেবিল ডিজাইনারের টাইপটি পরিবর্তন করার চেষ্টা করি , এসএসএমএস একটি স্ক্রিপ্ট তৈরি করে যা পুরো টেবিলটি পুনরায় তৈরি করে:

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_Test
    (
    ID int NOT NULL,
    Col1 nvarchar(10) NOT NULL,
    Col2 int NOT NULL
    )  ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_Test SET (LOCK_ESCALATION = DISABLE)
GO
IF EXISTS(SELECT * FROM dbo.Test)
     EXEC('INSERT INTO dbo.Tmp_Test (ID, Col1, Col2)
        SELECT ID, CONVERT(nvarchar(10), Col1), Col2 FROM dbo.Test WITH (HOLDLOCK TABLOCKX)')
GO
DROP TABLE dbo.Test
GO
EXECUTE sp_rename N'dbo.Tmp_Test', N'Test', 'OBJECT' 
GO
ALTER TABLE dbo.Test ADD CONSTRAINT
    PK_Test PRIMARY KEY CLUSTERED 
    (
    ID
    ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

GO
COMMIT

আপনি এটি উপরে LOCK_ESCALATIONতৈরি সারণীর জন্য সেট করে তা উপরে দেখতে পারেন । এসএসএমএস টেবিলের বর্তমান সেটিংস সংরক্ষণের জন্য এটি করে। এসএসএমএস এই লাইনটি জেনারেট করে, সেটিংয়ের বর্তমান মান ডিফল্ট TABLEমান হলেও । ভবিষ্যতে যদি এই ডিফল্টটি পরিবর্তিত হয় তবে কেবল নিরাপদ এবং স্পষ্ট থাকতে এবং ভবিষ্যতের সম্ভাব্য সমস্যাগুলি প্রতিরোধ করার জন্য আমার ধারণা। এইবার বুঝতে পারছি.

এই উদাহরণে এটি SET LOCK_ESCALATIONবিবৃতি উত্পন্ন করার জন্য সত্যই প্রয়োজন , কারণ সারণীটি নতুনভাবে তৈরি হয়েছিল এবং এর সেটিংসটি সংরক্ষণ করতে হবে।

আমি যদি এসএসএমএস টেবিল ডিজাইনার যেমন একটি নতুন কলাম যুক্ত করার সাথে টেবিলে একটি সাধারণ পরিবর্তন করার চেষ্টা করি, তবে এসএসএমএস একটি স্ক্রিপ্ট তৈরি করে যা টেবিলটি পুনরায় তৈরি করে না:

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.Test ADD
    NewCol nchar(10) NULL
GO
ALTER TABLE dbo.Test SET (LOCK_ESCALATION = DISABLE)
GO
COMMIT

আপনি দেখতে পাচ্ছেন, এটি এখনও ALTER TABLE SET LOCK_ESCALATIONবিবৃতিটি যুক্ত করে , যদিও এই ক্ষেত্রে এটির প্রয়োজন হয় না। প্রথমটি ALTER TABLE ... ADDবর্তমান সেটিংস পরিবর্তন করে না। আমার অনুমান, এসএসএমএস বিকাশকারীরা সিদ্ধান্ত নিয়েছিলেন যে এই ALTER TABLE SET LOCK_ESCALATIONবিবৃতিটি কীভাবে অপ্রয়োজনীয় তা নির্ধারণ করার চেষ্টা করার চেষ্টা করা উপযুক্ত নয় এবং কেবল নিরাপদ থাকার জন্য এটি সর্বদা উত্পন্ন করে। প্রতিবার এই বিবৃতি যুক্ত করার কোনও ক্ষতি নেই।

আবারও, টেবিল-প্রশস্ত LOCK_ESCALATIONসেটিংস অপ্রাসঙ্গিক যখন টেবিলের স্কিমা ALTER TABLEবিবৃতিতে পরিবর্তন হয় । LOCK_ESCALATIONসেটিং কেবলমাত্র ডিএমএল স্টেটমেন্টের লকিং আচরণকেই প্রভাবিত করে, যেমন UPDATE

অবশেষে, আমার একটি বক্তব্য ALTER TABLE, আমার উপর জোর দিন:

ALTER TABLE এ উল্লিখিত পরিবর্তনগুলি তত্ক্ষণাত্ কার্যকর করা হবে। পরিবর্তনগুলি যদি সারণীতে সারিগুলির পরিবর্তনগুলির প্রয়োজন হয় তবে ALTER TABLE সারিগুলি আপডেট করে। পরিবর্তনের সময় টেবিলের জন্য অন্য কোনও সংযোগ এমনকি টেবিলে মেটাডেটা উল্লেখ না করে তা নিশ্চিত করার জন্য টেবিলে টেবিলের স্কিমা মডিফাই (SCH-M) লকটি অর্জন করে, অনলাইন সূচক অপারেশনগুলি বাদে শেষের দিকে খুব ছোট SCH-M লক প্রয়োজন। অলটার টেবিলে ... সুইচ অপারেশনে লকটি উত্স এবং লক্ষ্য টেবিল উভয়তেই অর্জিত হয়। টেবিলটিতে করা পরিবর্তনগুলি লগ এবং সম্পূর্ণ পুনরুদ্ধারযোগ্য। যে পরিবর্তনগুলি খুব বড় সারণীতে সমস্ত সারিগুলিকে প্রভাবিত করে, যেমন একটি কলাম কমানো বা এসকিউএল সার্ভারের কয়েকটি সংস্করণে, একটি ডিফল্ট মান সহ একটি নট কলাম যুক্ত করা অনেকগুলি লগ রেকর্ডগুলি সম্পূর্ণ করতে এবং তৈরি করতে দীর্ঘ সময় নিতে পারে। এই অল্টার টেবিলের বিবৃতিগুলি যে কোনও INSERT, আপডেট, বা অনেকগুলি সারিগুলিকে প্রভাবিত করে এমন বিবৃতি মুছে ফেলার মতো একই যত্নের সাথে সম্পাদন করা উচিত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.