উত্তর:
এটি দেখার জন্য আমার কিছুটা সময় ছিল এবং যেহেতু আমার কাছে ইতিমধ্যে কয়েকটি ডেমো স্ক্রিপ্ট লেখা ছিল, তাই বাকী অংশগুলি পরীক্ষা করা খুব সহজ ছিল। আসুন সেটআপটি করি, তারপরে ফলাফলগুলি দেখুন। এটি প্রয়োজনীয় বিভাজনযুক্ত টেবিল এবং সূচক তৈরি করবে।
CREATE PARTITION FUNCTION YourMom ( INT )
AS RANGE LEFT FOR VALUES ( 1000000, 2000000, 3000000, 4000000, 5000000 );
CREATE PARTITION SCHEME YourDad
AS PARTITION YourMom
ALL TO ( [PRIMARY] );
CREATE TABLE dbo.YourAuntDebbie
(
Id INT,
StopUsingDeprecatedDataTypes NTEXT
) ON YourDad (Id);
DECLARE @counter INT = 1;
WHILE @counter < 6
BEGIN
RAISERROR('Run number: %d', 0, 1, @counter) WITH NOWAIT;
INSERT dbo.YourAuntDebbie WITH ( TABLOCK ) ( Id, StopUsingDeprecatedDataTypes )
SELECT TOP 1000000 x.n + CASE WHEN @counter = 1 THEN 0
WHEN @counter = 2 THEN 1000000
WHEN @counter = 3 THEN 2000000
WHEN @counter = 4 THEN 3000000
WHEN @counter = 5 THEN 4000000
ELSE 0
END,
REPLICATE(N'A', x.n % 10000)
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY @@ROWCOUNT ) AS n
FROM sys.messages AS m
CROSS JOIN sys.messages AS m2 ) AS x;
SET @counter += 1;
END;
CREATE CLUSTERED INDEX ix_whatever
ON dbo.YourAuntDebbie ( Id ) ON YourDad(Id);
এটি আমাকে 1 মিলিয়ন সারি সহ 5 টি পার্টিশন এবং একটি খালি বিভাজন দেয়।
SELECT OBJECT_NAME(p.object_id) AS table_name, p.partition_number, p.rows
FROM sys.partitions AS p
WHERE p.object_id = OBJECT_ID('dbo.YourAuntDebbie');
অভিনব টেবিল:
+----------------+------------------+---------+
| table_name | partition_number | rows |
+----------------+------------------+---------+
| YourAuntDebbie | 1 | 1000000 |
| YourAuntDebbie | 2 | 1000000 |
| YourAuntDebbie | 3 | 1000000 |
| YourAuntDebbie | 4 | 1000000 |
| YourAuntDebbie | 5 | 1000000 |
| YourAuntDebbie | 6 | 0 |
+----------------+------------------+---------+
সূচী পুনর্নির্মাণগুলির জন্য কোন তালা লাগবে তা দেখার জন্য আমি এখানে XE অধিবেশন ব্যবহার করছি:
CREATE EVENT SESSION Locks
ON SERVER
ADD EVENT sqlserver.lock_acquired
( SET collect_resource_description = ( 1 )
ACTION ( sqlserver.sql_text )
WHERE ( sqlserver.equal_i_sql_unicode_string(sqlserver.database_name, N'Crap')
AND package0.equal_uint64(sqlserver.session_id, ( 61 )))),
ADD EVENT sqlserver.lock_released
( SET collect_resource_description = ( 1 )
ACTION ( sqlserver.sql_text )
WHERE ( sqlserver.database_name = N'Crap'
AND sqlserver.session_id = ( 61 )))
ADD TARGET package0.event_file
( SET filename = N'c:\temp\Locks' )
WITH ( MAX_MEMORY = 4096KB,
EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY = 30 SECONDS,
MAX_EVENT_SIZE = 0KB,
MEMORY_PARTITION_MODE = NONE,
TRACK_CAUSALITY = ON,
STARTUP_STATE = OFF );
GO
সেই জায়গায়, আমি আমার পার্টিশনগুলি পুনর্নির্মাণ করতে পারি, এবং তারপরে এক্সইয়ের মধ্যে খনন করতে পারি।
ALTER EVENT SESSION Locks ON SERVER STATE = START;
ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 1 WITH (ONLINE = OFF);
GO
ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 2 WITH (ONLINE = OFF);
GO
ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 3 WITH (ONLINE = OFF);
GO
ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 4 WITH (ONLINE = OFF);
GO
ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 5 WITH (ONLINE = OFF);
GO
ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 6 WITH (ONLINE = OFF);
GO
ALTER EVENT SESSION Locks ON SERVER STATE = STOP;
এখন, আমি এক্সে ইভেন্টের শেডিং স্টাফগুলি শেষের দিকে রাখব, কারণ এটি বেশ কুৎসিত, এবং ফলাফলগুলি দেখার জন্য সবাইকে এই জায়গায় বসানোর কোনও কারণ নেই। আমি উদাহরণ হিসাবে প্রথম পার্টিশনের ফলাফলগুলি ব্যবহার করতে যাচ্ছি তবে তারা 6 টি পার্টিশন এমনকি খালিটি পর্যন্ত প্রায় অভিন্ন।
আমি আপডেটের ফলাফলগুলি কেবলমাত্র বস্তুর স্তরের লকগুলিতে সীমাবদ্ধ করছি এগুলিই আমাদের যত্নশীল।
+---------------+-------------------------+----------------+--------------+-------+------------------+--------+
| EventName | EventDate | ObjectName | ResourceType | Mode | PARTITIONREBUILT | Events |
+---------------+-------------------------+----------------+--------------+-------+------------------+--------+
| lock_acquired | 2017-10-03 13:21:14.554 | YourAuntDebbie | OBJECT | SCH_M | PARTITION = 1 | 1 |
| lock_acquired | 2017-10-03 13:21:14.554 | YourAuntDebbie | OBJECT | SCH_S | PARTITION = 1 | 1 |
| lock_released | 2017-10-03 13:21:14.554 | YourAuntDebbie | OBJECT | SCH_S | PARTITION = 1 | 1 |
| lock_acquired | 2017-10-03 13:21:14.603 | YourAuntDebbie | OBJECT | S | PARTITION = 1 | 6 |
| lock_acquired | 2017-10-03 13:21:14.603 | YourAuntDebbie | OBJECT | SCH_S | PARTITION = 1 | 30 |
| lock_released | 2017-10-03 13:21:14.603 | YourAuntDebbie | OBJECT | SCH_S | PARTITION = 1 | 24 |
| lock_released | 2017-10-03 13:21:14.867 | YourAuntDebbie | OBJECT | SCH_M | PARTITION = 1 | 1 |
+---------------+-------------------------+----------------+--------------+-------+------------------+--------+
আমি যা বলতে পারি, প্রতিটি বিভাজনের জন্য , SCH-M
সূচি পুনর্নির্মাণের শুরুতে একটি লক বের করা হয় এবং টেবিলের শেষে প্রকাশিত হয় ।
উদাহরণস্বরূপ, আমি যদি কোনও লেনদেনে পুনরায় বিল্ডিং চালিত করি তবে:
BEGIN TRAN
ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 1 WITH (ONLINE = OFF);
--ROLLBACK
এবং তারপরে অন্য এসএসএমএস উইন্ডোতে:
SELECT *
FROM dbo.YourAuntDebbie AS yad
WHERE yad.Id = 6000000
AND 1 = (SELECT 1)
আমি পুনর্নির্মাণ না করা পর্যন্ত নির্বাচনটি অবরুদ্ধ করা আছে। এটি শেষ হয়ে গেলে, ক্যোয়ারী প্ল্যানটি পার্টিশন নির্মূলকরণটি ঘটতে দেখায় , তাই কেবলমাত্র পুনরায় তৈরি করা পার্টিশন 1 পুরো টেবিলটির জন্য প্রদর্শিত হবে।
আশাকরি এটা সাহায্য করবে!
এখন এখানে ভয়াবহ XE অধিবেশন শেরডিং কোড:
CREATE TABLE #Locks
(
ID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
WaitsXML XML
);
INSERT #Locks
( WaitsXML )
SELECT CONVERT(XML, event_data) AS TargetData
FROM sys.fn_xe_file_target_read_file( 'c:\temp\Locks*.xel', NULL, NULL, NULL);
WITH locks
AS ( SELECT l.WaitsXML.value('(/event/@name)[1]', 'VARCHAR(128)') AS EventName,
l.WaitsXML.value('(/event/@timestamp)[1]', 'DATETIME2(3)') AS EventDate,
l.WaitsXML.value('(event/data[@name="object_id"]/value)[1]', 'NUMERIC') AS ObjectId,
l.WaitsXML.value('(event/data[@name="resource_type"]/text)[1]', 'VARCHAR(128)') AS ResourceType,
l.WaitsXML.value('(event/data[@name="mode"]/text)[1]', 'VARCHAR(128)') AS Mode,
l.WaitsXML.value('(event/action[@name="sql_text"]/value)[1]', 'VARCHAR(128)') AS SQLText,
l.WaitsXML
FROM #Locks AS l )
SELECT locks.EventName,
locks.EventDate,
ISNULL(OBJECT_NAME(locks.ObjectId), 'Unknown') AS ObjectName,
locks.ResourceType,
locks.Mode,
SUBSTRING(
locks.SQLText,
CHARINDEX('PARTITION', locks.SQLText),
CHARINDEX('WITH', locks.SQLText, CHARINDEX('PARTITION', locks.SQLText))
- CHARINDEX('PARTITION', locks.SQLText)) AS PARTITIONREBUILT,
COUNT(*) AS Events
FROM locks
WHERE OBJECT_NAME(locks.ObjectId) = 'YourAuntDebbie'
--OR OBJECT_NAME(locks.ObjectId) IS NULL
GROUP BY ISNULL(OBJECT_NAME(locks.ObjectId), 'Unknown'),
SUBSTRING(
locks.SQLText,
CHARINDEX('PARTITION', locks.SQLText),
CHARINDEX('WITH', locks.SQLText, CHARINDEX('PARTITION', locks.SQLText))
- CHARINDEX('PARTITION', locks.SQLText)),
locks.EventName,
locks.EventDate,
locks.ResourceType,
locks.Mode
ORDER BY locks.EventDate;