Ngày nay, Microsoft không có thói quen phản đối mọi thứ, nhưng khi họ làm vậy, đó là có lý do - và chắc chắn không phải vì họ muốn làm cho cuộc sống của bạn khó khăn hơn. Ngược lại, hầu như luôn luôn là do họ đã phát triển những cách tốt hơn và hiện đại hơn để giải quyết những vấn đề tương tự.
Nhưng thói quen rất khó để phá vỡ; hỏi tôi làm sao tôi biết. Thường xuyên, tôi thấy mọi người bám vào một cách cũ hơn để hoàn thành một số nhiệm vụ, mặc dù có một cách tốt hơn.
Tôi muốn chia sẻ một vài ví dụ gần đây giúp minh họa cách sử dụng các tính năng SQL Server không dùng nữa tiếp tục gây hại cho chúng tôi. Trong phần đầu tiên này, tôi muốn nói về…
bộ xử lý
Bảng hệ thống sys.sysprocesses
đã được thay thế trong SQL Server 2005 bằng một tập hợp các dạng xem quản lý động (DMV), đáng chú ý nhất là sys.dm_exec_requests
, sys.dm_exec_sessions
và sys.dm_exec_connections
. Tài liệu chính thức cho sys.sysprocesses
cảnh báo:
Một ví dụ gần đây
Gần đây, một trong các nhóm của chúng tôi đang điều tra vấn đề về độ trễ của trình đọc nhật ký. Chúng tôi chú ý rất nhiều đến độ trễ ở đây, cùng với bất kỳ giao dịch nào đang diễn ra trong thời gian dài, do tác động xuống cấp của các công nghệ sử dụng trình đọc nhật ký - như Nhóm khả dụng và sao chép giao dịch. Các cảnh báo đầu tiên của chúng tôi thường được phát hiện trên một bảng điều khiển biểu thị độ trễ của trình đọc nhật ký so với thời lượng giao dịch (Tôi sẽ giải thích các điểm kịp thời mà tôi đã gắn nhãn t0
và t1
ngay):
Họ đã xác định, hãy nói vào thời điểm t0
, rằng một phiên nhất định có một giao dịch mở đang chặn quá trình đọc nhật ký. Đầu tiên họ kiểm tra đầu ra của DBCC INPUTBUFFER
, để cố gắng xác định xem phiên này đã diễn ra những gì, nhưng kết quả chỉ đơn giản cho thấy rằng họ cũng đã phát hành các đợt khác trong quá trình giao dịch của mình:
event_type parameters event_info -------------- ---------- --------------- Language Event 0 SET ROWCOUNT 0;
Lưu ý rằng DBCC INPUTBUFFER
cũng có một sự thay thế có khả năng hơn trong các phiên bản hiện đại:sys.dm_exec_input_buffer
. Và mặc dù nó không có cảnh báo rõ ràng về việc không dùng nữa, nhưng tài liệu chính thức cho DBCC
lệnh có cú huých nhẹ nhàng này:
Sau khi không nhận được gì từ bộ đệm đầu vào, họ truy vấn sys.sysprocesses
:
SELECT spid, [status], open_tran, waittime, [cpu], physical_io, memusage, last_batch FROM sys.sysprocesses WHERE spid = 107;
Các kết quả tương tự cũng vô dụng, ít nhất là về mặt xác định phiên đã làm gì để giữ cho giao dịch của họ mở và làm gián đoạn trình đọc nhật ký:
Tôi đang đánh dấu physical_io
vì giá trị này đã làm dấy lên một cuộc thảo luận về việc họ có muốn mạo hiểm giết phiên ngủ hay không. Suy nghĩ là, trong trường hợp tất cả các I / Os vật lý đó đều được ghi, việc hủy giao dịch có thể dẫn đến việc khôi phục kéo dài và gián đoạn - có khả năng làm cho vấn đề trở nên tồi tệ hơn. Tôi sẽ không đưa ra thời gian thực tế về vấn đề này, nhưng hãy nói rằng điều này đã trở thành một cuộc trò chuyện kéo dài và nó khiến hệ thống ở trạng thái này từ lúc t0
đến thời gian t1
trên biểu đồ trên.
Tại sao đây là vấn đề
Vấn đề trong trường hợp cụ thể này là họ đã dành thời gian đó để xem xét một quyết định dựa trên thông tin không đầy đủ. Những I / O đó đọc hay viết? Nếu người dùng có một giao dịch đang mở và chỉ đọc nhiều dữ liệu, thì việc khôi phục giao dịch đó sẽ ít tác động hơn nhiều so với việc họ đã thay đổi rất nhiều dữ liệu. Vì vậy, thay vì sys.sysprocesses
, hãy xem DMV hiện đại hơn, sys.dm_exec_sessions
, có thể cho chúng tôi biết về phiên này:
SELECT session_id, [status], open_transaction_count, cpu_time, [reads], writes, logical_reads, last_request_start_time, last_request_end_time FROM sys.dm_exec_sessions WHERE session_id = 107;
Kết quả:
Ở đây chúng ta thấy rằng sys.dm_exec_sessions
chia I / O vật lý riêng biệt thành các lần đọc và ghi. Điều này cho phép chúng tôi đưa ra quyết định sáng suốt hơn nhiều, nhanh hơn nhiều so với t1 - t0
, về tác động của khả năng khôi phục. Nếu I / O đều được ghi và tùy thuộc vào con số cao như thế nào, chúng tôi có thể chần chừ thêm một chút và có lẽ dành thời gian cố gắng xác định vị trí người dùng (vì vậy chúng tôi có thể vỗ tay hoặc hỏi họ tại sao họ có một giao dịch mở ). Nếu chúng ta biết rằng nó chủ yếu là lượt đọc, thay vào đó, chúng ta có thể nghiêng về việc kết thúc phiên và buộc giao dịch quay trở lại.
Chắc chắn rồi, sys.sysprocesses
có dbid
và waittime
. Nhưng dbid
là không đáng tin cậy và dù sao cũng hơi hữu ích, đặc biệt là đối với các truy vấn cơ sở dữ liệu chéo; có nhiều thông tin tốt hơn trong sys.dm_tran_locks
. Thông tin chờ (thời gian và kiểu chờ cuối cùng) có thể được tìm thấy trong sys.dm_exec_requests
, nhưng thông tin chi tiết hơn được cung cấp trong sys.dm_exec_session_wait_stats
(được thêm vào SQL Server 2016). Một lời bào chữa mà tôi đã từng nghe rất nhiều đó là sys.dm_exec_sessions
bị thiếu open_tran
, nhưng open_transaction_count
đã được thêm lại trong SQL Server 2012. Vì vậy, thậm chí có rất ít lý do để nghĩ đến việc sử dụng sys.sysprocesses
hôm nay.
Nếu bạn muốn khám phá tần suất sys.sysprocesses
đã được tham chiếu kể từ khi Máy chủ SQL khởi động lại lần cuối, bạn có thể chạy truy vấn này dựa trên bộ đếm hiệu suất DMV:
SELECT instance_name, cntr_value FROM sys.dm_os_performance_counters WHERE [object_name] LIKE N'%:Deprecated Features%' AND instance_name = N'sysprocesses' ORDER BY cntr_value DESC;
Nếu bạn thực sự muốn tránh ngủ đêm nay hoặc bạn chỉ muốn liên tục thêm vào danh sách giặt là những thứ bạn lo lắng, hãy xóa vị ngữ đối với instance_name
. Điều này sẽ cung cấp cho bạn một ý tưởng cấp cao, đáng sợ về số thứ mà phiên bản của bạn đang chạy mà cuối cùng bạn sẽ cần phải thay đổi.
Trong thời gian chờ đợi, hãy tải xuống sp_WhoIsActive
, Thủ tục được lưu trữ cực kỳ hữu ích của Adam Machanic để theo dõi và khắc phục sự cố các quy trình SQL Server trong thời gian thực. Chúng tôi đã triển khai quy trình được lưu trữ này cho mọi trường hợp trong môi trường của chúng tôi và bạn cũng vậy, bất kể công cụ giám sát cao cấp nào khác mà bạn có thể đang sử dụng.
Lần sau
Trong Phần 2, tôi sẽ nói một chút về SQL Server Profiler, một ứng dụng mà mọi người sử dụng nhiều hơn vì quen thuộc hơn bất kỳ thứ gì khác - mà không nhận ra nó có thể nguy hiểm như thế nào.