Tìm các thủ tục chưa được gọi trong <n> ngày


7

Chúng tôi đang xóa các thủ tục và bảng lưu trữ cũ.

Làm thế nào tôi có thể biết những thủ tục chưa được gọi gần đây?

dm_exec_procedure_statsdm_exec_query_statskhông đáng tin cậy, vì chúng chỉ trả về các thủ tục trong bộ đệm của kế hoạch.


Bạn đã thử tìm kiếm mã nguồn của mình cho mỗi tên thủ tục chưa?
Jon Seigel

2
@JonSeigel sẽ không thực sự giúp đỡ; một thủ tục có thể là mã nguồn theo phương thức mà người dùng không thường xuyên gọi. Bạn sẽ không thể nói điều đó từ mã nguồn.
Aaron Bertrand

3
@Aaron: Hiếm khi! = Không bao giờ, mặc dù câu hỏi nói "gần đây", nhưng có lẽ về giả định của một giải pháp. Nếu một tên thủ tục được lưu trữ nhất định không bao giờ được tìm thấy trong mã nguồn, điều đó sẽ giúp ích khá nhiều.
Jon Seigel

1
@JonSeigel là đúng, giả sử không ai gọi bất kỳ thủ tục được lưu trữ nào theo cách thủ công. Vẫn chưa có đủ thông tin cho điều đó được giả định, và ngay cả khi nó được giả định, tôi không nghĩ rằng tôi có thể dựa vào nó trong lương tâm tốt.
Aaron Bertrand

1
@Aaron: Tất cả điều này phụ thuộc rất lớn vào môi trường, vì vậy, nói chung, tôi đồng ý với bạn. Tôi nghĩ ít nhất, nếu một thủ tục được lưu trữ hoặc tên bảng không xuất hiện trong bất kỳ mã nào, thì đó là một dấu hiệu rất tốt đối tượng không được sử dụng. Tôi cho rằng một yếu tố phức tạp sẽ là các phiên bản trước của ứng dụng nếu nó giống như ứng dụng của nhà cung cấp. Một lần nữa, tình huống.
Jon Seigel

Câu trả lời:


12

Nếu sys.dm_exec_procedure_statskhông đáng tin cậy cho bạn (có thể nhiều hơn vì thông tin không tồn tại khởi động lại hơn bất kỳ điều gì liên quan đến bộ đệm của kế hoạch), SQL Server không theo dõi điều này theo bất kỳ cách nào khác.

Cách duy nhất để làm điều này là thêm ghi nhật ký vào các thủ tục được lưu trữ của bạn (hoặc vào ứng dụng gọi chúng, nếu điều đó là khả thi và bao gồm đủ) hoặc chạy một dấu vết phía máy chủ được nhắm mục tiêu liên tục và xem xét dấu vết.

Cũng lưu ý rằng chỉ vì một thủ tục chưa được gọi trong một tuần không có nghĩa là nó sẽ không được gọi vào ngày mai. Bạn có thể có các quy trình báo cáo chỉ được gọi là hàng tháng hoặc hàng năm hoặc một số hoạt động tối nghĩa không thường xuyên xảy ra. Xóa quy trình được lưu trữ đó có thể là ngày hoặc tuần thảm họa kể từ bây giờ, có khả năng vượt quá mọi bản sao lưu bạn có tại thời điểm đó (và giả sử bạn không tuân theo các thực tiễn tốt nhất và lưu trữ các quy trình được lưu trữ của bạn trong kiểm soát nguồn).

Cách an toàn nhất, IMHO, là đổi tên các thủ tục được lưu trữ (có thể có zzz_tiền tố để chúng sắp xếp xuống cuối danh sách) mà bạn đã xác định thông qua các phương tiện khác là ứng viên tiềm năng của việc "quá cũ" - ít nhất là khi bạn làm điều đó với một lần vô tình và một cái gì đó bị phá vỡ, thật dễ dàng để đổi tên nó một lần nữa, khôi phục chức năng mà không phải tranh giành mã cũ trong các bản sao lưu. Chỉ xóa các thủ tục khi một chu kỳ kinh doanh đầy đủ đã trôi qua và không ai phàn nàn.


Trên thực tế, nó không đáng tin cậy vì không khởi động lại. Chúng tôi không khởi động lại cơ sở dữ liệu trong nhiều tháng. Nếu tôi truy vấn khung nhìn này, nó chỉ trả về lần thực hiện cuối cùng của ngày hôm nay và tôi biết rằng một số procs đã được thực hiện ngày hôm nay. MSDN cho biết: "Khung nhìn trả về một hàng cho mỗi gói thủ tục được lưu trong bộ nhớ cache và thời gian tồn tại của hàng miễn là thủ tục được lưu vẫn được lưu trong bộ nhớ cache"
Felipe Fujiy Pessoto

1
Nếu bạn chỉ có thể lưu trữ kế hoạch bộ đệm cho các quy trình đã được thực hiện ngày hôm nay, thì máy chủ của bạn sẽ được cung cấp rất ít về mặt bộ nhớ (về mặt vật lý hoặc nhân tạo thông qua bộ nhớ máy chủ tối đa), hoặc bạn có cách, cách, có quá nhiều thủ tục duy nhất được gọi và / hoặc kế hoạch của họ phức tạp hơn mức cần thiết. Máy chủ của bạn có bao nhiêu bộ nhớ? Có bao nhiêu kế hoạch được lưu trữ cùng một lúc?
Aaron Bertrand

Lưu ý rằng, nếu doanh nghiệp của bạn đang sử dụng một cái gì đó tương tự như Lịch 4-4-5 , một chu kỳ kinh doanh có thể theo thứ tự 5/6 năm , nếu một cái gì đó được chạy mỗi năm nhuận / tuần.
Đồng hồ-Muse

6

Nếu bạn có thể sửa đổi các quy trình, hãy thêm một dòng vào đầu mỗi (điều này khá dễ tự động hóa):

exec sp_trace_generateevent 82, N'<procedure__name>';

Việc sử dụng sp_trace_generateeventlà khá lành tính và không ảnh hưởng đến luồng / kết quả / kết quả thực hiện thủ tục. Quan trọng nhất là nó không có tương tác với giao dịch hiện tại. Nó không biến một thủ tục chỉ đọc thành một quy trình ghi dữ liệu, với tất cả các hàm ý ghi nhật ký và khóa. Nếu không có sự kiện theo dõi dấu vết 82, execcuộc gọi về cơ bản là miễn phí (không có op).

Tiếp theo tạo một dấu vết phía máy chủ và chụp sự kiện 82 (user_event đầu tiên). Sau n ngày thu thập các dấu vết được tạo và tổng hợp việc sử dụng. Hãy chắc chắn rằng dấu vết của bạn ghi vào một đĩa có đủ không gian và đủ băng thông IO. Để có thêm tín dụng, bạn cũng có thể kiểm tra các dấu vết định kỳ và xóa execcuộc gọi khỏi mọi thủ tục bạn tìm thấy ở đó, vì được chứng minh là được gọi.


Vì điều này đòi hỏi phải sửa đổi tất cả các quy trình, nên nó có lợi thế gì khi thiết lập dấu vết phía máy chủ để nắm bắt tất cả RPC: Bắt đầu các sự kiện (và chỉ chụp cơ sở dữ liệu / tên)? Rằng sau một thời gian bạn có thể ngừng chụp một số sự kiện? Nếu không, nó có vẻ như nhiều công việc hơn là chỉ thiết lập một dấu vết.
Aaron Bertrand

1
@AaronBertrand: RPC: Bắt đầu ghi lại bất kỳ sự kiện RPC nào, ví dụ : INSERT ... (@var), không phải là một cuộc gọi thủ tục. Và không nắm bắt được một cuộc gọi thủ tục được nhúng trong một lô, ví dụ. exec sp_foo 'bar'. Bên cạnh tính chính xác, rõ ràng dấu vết làm bằng tay có thể loại bỏ các thủ tục đã biết, thường được gọi, chỉ tập trung vào những người bị nghi ngờ không bao giờ được gọi. Tôi thấy nhiều lợi thế.
Remus Rusanu

Bạn có thể lọc tên đối tượng để loại bỏ các cuộc gọi không thủ tục khác cũng như các cuộc gọi bạn biết được sử dụng. Và bao gồm SP: Bắt đầu nắm bắt những thứ là một phần của một đợt. Vẫn nghĩ rằng điều đó dễ dàng hơn nhiều. Đừng nghĩ việc tự động thay đổi này cho mọi thủ tục được lưu trữ trên hệ thống khá đơn giản như bạn thực hiện, cộng với việc loại bỏ một thông tin khác mà bạn có về các thủ tục bằng cách ghi đè sửa đổi_date.
Aaron Bertrand

3

Biết những gì đã được gọi gần đây chỉ giúp cho những thứ thường được gọi và nhiều đối tượng trong cơ sở dữ liệu phức tạp không được gọi thường xuyên nhưng vẫn cần thiết. Tôi biết không có cách đơn giản để xác định những gì không được sử dụng.

Những gì tôi sẽ làm là khởi động Profiler trên hộp dev hoặc qa của tôi và sau đó lấy mọi ứng dụng đánh vào nó và chạy qua chức năng. (nếu bạn có QA chính thức, một bộ kiểm tra hồi quy tốt sẽ giúp ích cho việc này). Tôi sẽ thiết lập dấu vết của mình để viết lên bàn. Bây giờ ít nhất bạn biết những gì procs gọi ứng dụng và có thể loại bỏ chúng khỏi danh sách.

Đảm bảo mọi công việc trên máy chủ prod đều có một công việc tương đương trên máy chủ thử nghiệm của bạn và chạy chúng. Điều đó nên tìm thêm một số.

Bây giờ danh sách các sp tiềm năng của bạn nhỏ hơn nhiều.

Danh sách các bảng hoạt động của bạn chỉ nên bao gồm những bảng được đề cập trong một trong các bảng và bảng mà bạn biết bạn cần như bảng kiểm toán. YoOu có thể tạo ra một danh sách các tiềm năng để loại bỏ từ đó.

Bây giờ khi bạn có danh sách các tiềm năng cần loại bỏ, bạn sẽ thấy một số tiềm năng khá rõ ràng như usp_my_proc_Old (khi bạn có USP_My_proc trong db). Đó là những ứng cử viên đầu tiên của tôi để loại bỏ. Các bảng không có dữ liệu là một tập hợp rõ ràng khác tại thời điểm này. Các bảng / procs đề cập rõ ràng đến một chức năng mà bạn biết đã bị loại bỏ sẽ là các chức năng tiếp theo. Giả sử gần đây bạn đã thay thế chức năng lưu trữ kết quả khảo sát bằng một thiết kế mới. Bạn có thể muốn giữ bảng (Bạn có thể cần dữ liệu) nhưng các procs gọi bảng đó có thể đã hết hạn và có thể đi.

Tùy thuộc vào các ràng buộc pháp lý của bạn, bạn có thể không muốn loại bỏ bất kỳ bảng nào có dữ liệu. Chúng tôi có dữ liệu cụ thể của khách hàng cho các khách hàng mà chúng tôi không còn có, vì chúng tôi đang ở trong một ngành được quy định và đôi khi được yêu cầu cung cấp dữ liệu cho kiểm toán viên và các nhà quản lý và luật sư. Tuy nhiên, bạn có thể di chuyển các bảng này sang db lưu trữ khác nếu bạn muốn xóa cơ sở dữ liệu sản xuất thực tế của mình.

Sau đó bắt đầu nhìn vào những gì họ làm. Bạn có thể loại bỏ bất kỳ Proc nào sẽ không chạy, đặc biệt nếu một trong các bảng mà nó tham chiếu không còn tồn tại. Nếu một bảng có một trường ngày, có bất kỳ ngày gần đây? Nếu lần cuối cùng trường dữ liệu được điền vào ngày là năm 2008, thì đó là một ứng cử viên tốt cho một bảng mà chúng ta không cần nữa.

Khi bạn có một danh sách một số đối tượng tiềm năng cần xóa, sau đó gửi danh sách xung quanh cho tất cả các nhà phát triển của bạn và hỏi họ xem họ có sử dụng bảng / Proc hay không hoặc biết nó dùng để làm gì. Đừng làm điều này với một danh sách khổng lồ 1000 đối tượng. Gửi không quá 10-20 tại một thời điểm và cố gắng nhóm chúng để chúng rõ ràng về các chủ đề liên quan.

Để loại bỏ tiềm năng, bạn có thể thêm quy trình ghi nhật ký vào Proc hoặc trình kích hoạt ghi nhật ký vào bảng và đặt ngày khi đối tượng sẽ bị loại nếu không có mục nào trước ngày đó.


2

Chạy một dấu vết trên một cái gì đó như:

  • SP: Đã hoàn thành
  • SP: StmtCompleted
  • RPC: Đã hoàn thành
  • SQL: BatchCompleted
  • SQL: StmtCompleted

Xem xét lọc theo ID cơ sở dữ liệu. Khi bạn đã biên soạn đủ dữ liệu, bạn có thể đưa ra quyết định của mình. Tất nhiên, hãy lưu ý rằng một dấu vết sẽ có hiệu năng trúng để đảm bảo lần truy cập này không gây ra sự cố vận hành.


2
Đối với dấu vết tôi cho rằng bạn thực sự chỉ cần nắm bắt RPC: Bắt đầu. Bạn không cần phải nắm bắt các lô ad hoc hoặc tất cả các thông tin bổ sung đi kèm với một nửa các sự kiện đã hoàn thành để xác định các thủ tục lưu trữ nào đang được sử dụng tích cực. Ngoài ra, tất nhiên, điều này sẽ chỉ giúp xác định các thủ tục sắp tới.
Aaron Bertrand

1

Một trong những khách hàng của tôi có cùng một vấn đề, nhưng đó là trường hợp xấu nhất mà tôi từng thấy. Một số nhà phát triển giả mạo đã tạo ra hàng ngàn thủ tục được lưu trữ (hơn 6k), hầu hết trong số đó không được sử dụng.

Bây giờ họ thăm dò ý kiến ​​sys.dm_exec_cached_plans cứ sau 5 phút và chèn vào bảng để theo dõi. Chỉ các tên thủ tục được lưu trữ chưa tồn tại trong bảng được chèn vào.

Như những người khác đã đề cập, trải qua các chu kỳ kinh doanh hàng quý / hàng năm rất được khuyến khích.


0

Vấn đề không phải là DMV không đáng tin, mà là họ không nắm bắt được thông tin mà bạn muốn. Tạo một công việc chạy định kỳ sử dụng chúng để nắm bắt thông tin mà bạn muốn - chạy nó hai lần một ngày nếu dữ liệu của bạn bị mất trong 24 giờ. Cho rằng DMV không thực sự chuyên sâu, thậm chí hàng giờ nếu bạn muốn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.