SQL Server DB trở nên không sử dụng được qua đêm


9

Hôm qua, cơ sở dữ liệu SQL Server của tôi đã ổn. Ngày nay, nó gần như không thể sử dụng được - nó bị chậm lại bởi hệ số từ năm đến hai mươi, tùy thuộc vào thời điểm tôi đánh nó.

Một số dữ liệu đã được thêm vào máy chủ trong quá trình tải qua đêm, nhưng không có gì giống như một khối lượng sẽ ảnh hưởng đến cơ sở dữ liệu nhiều như vậy. Khoảng 50.000 bản ghi văn bản thuần túy (không có XML hoặc các phần mềm khác).

Máy chủ đã được vá vào sáng nay trước khi chúng tôi khởi động lại nó. Tuy nhiên, không có máy chủ cơ sở dữ liệu nào khác của chúng tôi cũng bị vá đang hoạt động khác đi.

Resource Monitor dường như đề xuất rằng IO đĩa của nó bị lỗi. Nó chạy gần 100% dung lượng trên tệp .mdf toàn bộ thời gian, ngay cả khi không có nhiều thực sự xảy ra trong cơ sở dữ liệu. Truy cập vào Templog.ldf cũng đang chạy khá cao.

Không ai ở đây là một DBA chuyên gia (tất cả chúng ta đều là những nhà phát triển với số lượng kỹ năng SQL khác nhau) và tất cả chúng ta đều gặp khó khăn bởi những gì đã xảy ra. Chúng tôi đã thử chạy sp_updatestats và chuyển một số chỉ mục lớn sang các đĩa khác nhau, nhưng không có kết quả.

Tôi nghĩ rằng điều này phải có một cái gì đó để làm với bản vá - có vẻ như quá nhiều sự trùng hợp. Một đồng nghiệp bị thuyết phục rằng chính tải dữ liệu đã khiến kích thước của mdf tăng lên đến mức khiến cho các kế hoạch thực hiện trở nên không hiệu quả.

Điều gì trên trái đất đã gây ra điều này? Làm thế nào chúng ta có thể tìm ra, và chúng ta có thể làm gì để khắc phục nó?

BIÊN TẬP:

Sử dụng sp_WhoIsActivecho thấy không có gì khác thường. Nó đăng ký sử dụng sproc của riêng tôi và một số lệnh từ một đồng nghiệp hiện đang cố gắng di chuyển một chỉ mục khác. Điều đó có thể đang giữ DB ngay bây giờ nhưng nó vẫn chạy tồi tệ như trước đây.

Đây là phiên bản tiêu chuẩn của SQL Server 2008 R2. SELECT @@VERSIONcho:

Microsoft SQL Server 2008 R2 (SP2) - 10.50.4033.0 (X64)
Ngày 9 tháng 7 năm 2014 16:04:25
Bản quyền (c) Microsoft Corporation Standard Edition (64-bit) trên Windows NT 6.1 (Bản dựng 7601: Gói dịch vụ 1) (Hypervisor )

Máy chủ có 72GB RAM và ba bộ xử lý lõi tứ 2GHz.

Việc vá lỗi chỉ được áp dụng cho Windows. Không có thay đổi nào khác ngoài bản vá.

Cài đặt đã chọn:

_id     name                        value   minimum     maximum     value_in_use    description                                 is_dynamic  is_advanced
1540    min memory per query (KB)   1024    512         2147483647  1024            minimum memory per query (kBytes)           1           1
1541    query wait (s)              -1      -1          2147483647  -1              maximum time to wait for query memory (s)   1           1
1543    min server memory (MB)      0       0           2147483647  16              Minimum size of server memory (MB)          1           1
1544    max server memory (MB)      65536   16          2147483647  65536           Maximum size of server memory (MB)          1           1

CẬP NHẬT: Việc chuyển các chỉ mục và bảng sang các phân vùng đĩa khác nhau dường như đang cải thiện mọi thứ. Tôi vẫn còn bối rối về việc làm thế nào chúng ta có thể đạt đến điểm bùng phát đột ngột với kết quả quyết liệt như vậy.


Bạn có thể chạy sp_whoisactive trong 5 phút và ghi đầu ra vào bảng không. Bạn có thể tải xuống từ đâyđiều này sẽ cho thấy cách bạn có thể nắm bắt đầu ra vào bảng
Kin Shah

Chà, nếu bạn khởi động lại máy chủ, điều đó có nghĩa là tất cả dữ liệu được lưu trong bộ nhớ cache của bạn đã bị xóa khỏi nhóm bộ đệm và tất cả các kế hoạch thực hiện được lưu trong bộ nhớ cache của bạn cũng bị hủy. Điều này có nghĩa là SQL Server sẽ phải tăng cường cả hai - mọi kế hoạch thực hiện sẽ phải được biên dịch lại và nếu số liệu thống kê cũ, bạn có thể không có được các kế hoạch hiệu quả nhất. Điều đó cũng có nghĩa là dữ liệu sẽ phải được đọc vào bộ nhớ từ đĩa, trong khi trước khi khởi động lại, nó có thể đã ồn ào cùng với dữ liệu trong bộ nhớ. Điều này nên được ngắn hạn.
Aaron Bertrand

@AaronBertrand Cứ như thế trong tám giờ. Chúng tôi thường xuyên khởi động lại máy chủ để vá lỗi và chưa bao giờ nhận thấy bất cứ điều gì như thế này trước đây.
Bob Tway

1
Không sử dụng UI để kiểm tra cài đặt cấu hình. SELECT * FROM sys.configurations;- bạn muốn value, value_in_usecho những thứ như max server memory (MB). Ngoài ra, số bản dựng SELECT @@VERSION;sẽ hữu ích, cũng như liệu đây có phải là một trình ảo hóa hay không và nếu có bất cứ điều gì thay đổi trên máy chủ kể từ ngày hôm qua (hoặc kể từ lần cuối SQL Server được khởi động lại).
Aaron Bertrand

2
Bạn đang sử dụng loại hệ thống con IO nào? SAN, đĩa cục bộ, vv? Có bất kỳ cơ hội bạn tình cờ có một ổ đĩa xấu đi? Ngoài ra có bất kỳ DB nào của bạn được lưu trữ ở cùng một vị trí với bất kỳ tệp HĐH nào không? Và câu hỏi cuối cùng. Một phần trong quy trình của chúng tôi trước khi thực hiện nâng cấp hệ điều hành là chụp ảnh nhanh VM trước đó. Thật không may, người chịu trách nhiệm quên cam kết nó. Rất nhanh, toàn bộ hệ thống ngày càng chậm hơn. Bất kỳ cơ hội này xảy ra với bạn?
Kenneth Fisher

Câu trả lời:


3

Có thể xảy ra việc một lượng nhỏ dữ liệu đạt đến một giới hạn nhất định trong Máy chủ SQL để buộc một kế hoạch khác hoặc một cái gì đó tương tự. Điều này không phải là không thể. Nhưng thực tế là đĩa của bạn dường như đang chịu trách nhiệm nặng nề đưa tôi đến một kết luận khác.

Có 2 lý do cơ bản có thể khiến bạn chậm lại.

  1. Bạn đã nâng cấp hệ thống của mình và khởi động lại nó
  2. Bạn tải một loạt dữ liệu trong đó

Hãy xem phần 1

Có thể cấu hình SQL Server của bạn có thể bị hỏng. Điều này có thể gây ra vấn đề nghiêm trọng liên quan đến tốc độ Máy chủ của bạn và việc sử dụng đĩa.

Vui lòng kiểm tra trong trường hợp đầu tiên cài đặt máy chủ cơ bản của bạn. Những thiết lập cơ bản là max server memory, affinity I/O mask, affinity maskmax degree of parallelism. Bạn có thể cần phải kích hoạt các tùy chọn nâng cao bằng cách sử dụng show advanced options.

Đây là một kịch bản hoàn chỉnh:

-- enable advanced options
EXEC sp_configure 'show advanced options',1
-- apply configuration
RECONFIGURE
-- how much memory can the sql server allocate?
EXEC sp_configure 'max server memory'
-- which cpu is used to run I/O operations
EXEC sp_configure 'affinity I/O mask'
-- which cpus can run processes?
EXEC sp_configure 'affinity mask'
-- how many threads can work on one query part?
EXEC sp_configure 'max degree of parallelism'

So sánh kết quả với các giá trị tài liệu của bạn trong các bước cài đặt của bạn. Họ vẫn giống nhau chứ?

Nó có thể có nhiều lý do tại sao máy chủ của bạn hoạt động rất lạ. Tôi thường đặt cược, rằng bạn max server memorychỉ sai. Điều này sẽ khiến SQL Server của bạn hoán đổi vĩnh viễn các trang dữ liệu. Anh ta không thể giữ mọi thứ trong trí nhớ của mình. Điều này có nghĩa là anh ta cần phải đọc các trang từ đĩa, cập nhật nó, viết lại ngay lập tức. Nếu một bản cập nhật khác xuất hiện và sử dụng cùng một trang cho một bản cập nhật, nó không thể được đọc từ bộ nhớ. Thay vào đó, máy chủ cần đọc lại từ đĩa. Chỉ cần hoán đổi ...

Một vấn đề khác có thể là mối quan hệ cao đến đĩa hoặc quá trình. Nếu bạn đã sử dụng Máy chủ dùng chung (Máy chủ SQL + các dịch vụ khác) với đĩa dành riêng cho Máy chủ SQL (có thể là trường hợp hiếm gặp, nhưng có thể như vậy), đây có thể là vấn đề của bạn. Máy chủ của bạn thường được sử dụng để có 3 ví dụ cho các quy trình và một cho I / O. 12 cpus khác được sử dụng cho các dịch vụ khác. Trong trường hợp này, mặt nạ ái lực của bạn sai và sử dụng ví dụ cấu hình tự động. Điều này có nghĩa là Máy chủ của bạn sử dụng tất cả 16 lõi cho các quy trình và I / O một cách linh hoạt. Nếu bạn có các tiến trình lớn đang chạy, chúng có thể đặt một tải rất lớn lên đĩa mà nó có thể không xử lý được. Nhưng trên thực tế, tôi không tin rằng đây là trường hợp của bạn. Nó sẽ nhanh hơn (ngay cả khi chỉ một chút) nếu điều này được áp dụng, nhưng trường hợp của bạn là chậm lại.

Một vấn đề khác có thể là mức độ song song quá cao. Điều đó có nghĩa là bạn có quá nhiều luồng không hoạt động trên một phần của truy vấn. Điều này cũng có thể gây ra sự chậm lại rất lớn nếu song song không hoạt động như mong đợi. Nhưng điều này sẽ không mô tả tổng số I / O cao của bạn.

Bây giờ chúng ta hãy xem phần 2

Bạn tải một loạt các hàng vào hệ thống của bạn. Ngay cả khi đây là một công việc thông thường, nó có thể đưa ra một giới hạn trong đó các kế hoạch truy vấn của bạn leo thang. Thậm chí có thể là trường hợp chèn của bạn kết hợp với SQL Server tạo ra hành vi này.

Bạn đã đề cập rằng bạn đã cố gắng di chuyển các chỉ số của mình sang một đĩa khác, điều này có vẻ hữu ích. Điều này có thể xảy ra chỉ với thực tế là bạn chia tải trên hai đĩa khác nhau.

Nó có thể là các chỉ số của bạn đã bị phá vỡ, kế hoạch của bạn đã bị phá vỡ hoặc số liệu thống kê của bạn đã lỗi thời.

1. cho phép kiểm tra số liệu thống kê cập nhật mới nhất Bạn có thể thực hiện thủ công qua giao diện cho từng yếu tố thống kê. Đó sẽ là một nỗi đau. Hoặc bạn có thể thử mã này:

SELECT name AS indexname,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes

Điều này sẽ cung cấp cho bạn một thông tin đầy đủ qua từng chỉ số (và heap) và số liệu thống kê đằng sau chúng. Ngay cả khi bạn chạy, điều sp_updatestatsđó không có nghĩa là số liệu thống kê đã được cập nhật. Phần khi cập nhật khá phức tạp, ngay cả khi bạn chạy sp_updatestatshoặc ngay cả khi auto update statisticsđược bật, số liệu thống kê sẽ không được cập nhật kịp thời. Dưới đây là một số điểm cạnh, khi cần cập nhật / tạo:

  • Một bảng trống được một hoặc nhiều hàng
  • Một bảng có hơn 500 hàng cập nhật 20% + 500 hàng bổ sung và một lần chèn đã xảy ra sau đó
  • Khi 500 hàng được thay đổi trong một bảng chứa ít hơn 500 hàng

Điều này có nghĩa, số liệu thống kê của bạn có thể bị lỗi thời ngay cả khi bạn chạy bản cập nhật.

Bạn có thể xem các truy vấn ở trên. Nếu bạn tìm thấy một số thống kê khá cũ trong một số bảng, bạn có thể muốn chạy cập nhật thống kê thủ công cho bảng này:

UPDATE STATISTICS dbo.YourBadTable WITH FULLSCAN

Sau đó, bạn có thể muốn cho máy chủ của mình một cú đá vào mông để vứt bỏ tất cả các kế hoạch cũ.

DBCC FREEPROCCACHE 

Nếu bạn chỉ muốn xóa tất cả bộ nhớ cache, bạn có thể muốn chạy cái này thay thế:

DBCC FREESYSTEMCACHE ('ALL')

Điều này sẽ dọn sạch tất cả bộ nhớ cache, không chỉ bộ nhớ cache của gói. Tôi thường cảnh báo, để sử dụng điều này trên một máy chủ sản xuất trong giai đoạn sản xuất. Nhưng vì máy chủ của bạn hiện không hoạt động, bạn không thể làm hại họ quá nhiều. Nó có thể chậm lại trong vài giây có thể 1-2 phút vì anh ta cần xây dựng lại tất cả các bộ nhớ cache, nhưng sau đó anh ta nên chạy với các kế hoạch chính xác.

Một lý do khác có thể là các chỉ số hoàn toàn bị phân mảnh. Điều này có thể được kiểm tra trên toàn bộ máy chủ bằng cách sử dụng câu lệnh này:

SELECT * 
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL)

Nếu sự phân mảnh rất cao, bạn có thể cần phải sắp xếp lại (phân mảnh <20%) hoặc xây dựng lại hoàn toàn (> 20%) nó. Điều này có thể gây áp lực nhiều hơn cho đĩa của bạn và gây rắc rối. Mặt khác, nếu các chỉ số đó là xấu, có lẽ nó sẽ giúp ích nhiều hơn là có hại.

Bên cạnh hai lý do đó, vẫn có thể có một vấn đề thứ ba

Có lẽ máy chủ của bạn được cấu hình có thể, bạn đã không thay đổi bất kỳ mã nào trong thời gian này, chỉ cần thêm một vài hàng. Tất cả các số liệu thống kê được cập nhật và tất cả các bộ nhớ cache được xây dựng lại. Tất cả các chỉ số của bạn được sắp xếp lại theo cách bạn cần, nhưng vẫn vậy - không có gì hoạt động. Nó chỉ có thể là bạn đã đạt đến giới hạn của bộ nhớ có sẵn trong các quy trình của bạn. Có lẽ bạn cần nhiều hơn. Bạn có thể chỉ cần kiểm tra nếu có bất kỳ quá trình nào cố gắng để có được nhiều bộ nhớ hơn bạn có.

Bạn có thể kiểm tra điều này bằng lệnh này:

SELECT * FROM sys.dm_exec_query_memory_grants

Nó sẽ cung cấp cho bạn một danh sách tất cả các phiên sử dụng bộ nhớ. Có thể có một số truy vấn vẫn đang chờ để lấy bộ nhớ. Những truy vấn có thể dễ dàng được lọc. Tất cả các phiên ở đâu granted_memory_kb IS NULL. Đây là những phiên yêu cầu bộ nhớ nhưng không có được nó. Một điều nữa có thể là một bộ nhớ được cấp có thể thấp. Bạn có thể so sánh các cột requested_memory_kbvới granted_memory_kb. Yêu cầu hiển thị bao nhiêu bộ nhớ mà quá trình cần để chạy tối ưu trong khi được cấp sẽ hiển thị bộ nhớ được kích hoạt cho quy trình. Nếu một tiến trình cần 2GB để chạy nhưng chỉ nhận được 2 MB ... bạn có thể tự mình lấy nó. ;-)

Một cách khác là kiểm tra RESSOURCE_SEMAPHORE:

SELECT * FROM sys.dm_exec_query_resource_semaphore

Bạn có thể nhìn vào waiter_countgrantee_count. Nếu người phục vụ trên 0, bạn có áp lực lên bộ nhớ của mình, điều này có thể gây ra sự tráo đổi và có thể gây ra áp lực đĩa mà bạn nhìn thấy trong perfmon.


0

Ngoài các lỗi ổ đĩa có thể xảy ra, hãy kiểm tra trạng thái của hệ thống con RAID của bạn. Chúng tôi đã thấy một cái gì đó tương tự và hóa ra pin trên bộ điều khiển RAID không thành công nên không có bộ đệm ghi có sẵn - tất cả ghi phải được chuyển trực tiếp vào đĩa. Một mặt lưu ý - chúng ta có thể cảm thấy hệ thống tạm dừng trong khi RDC đang vào đó.

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.