Cơ sở dữ liệu trong quá trình chuyển đổi


11

Hôm nay tôi đã cố gắng khôi phục cơ sở dữ liệu qua cơ sở dữ liệu đã có sẵn, tôi chỉ cần nhấp chuột phải vào cơ sở dữ liệu trong SSMS -> Nhiệm vụ -> Ngoại tuyến để tôi có thể khôi phục cơ sở dữ liệu.

Một cửa sổ bật lên nhỏ xuất hiện và Query Executing.....thỉnh thoảng xuất hiện và sau đó đưa ra một lỗi nói Database is in use cannot take it offline. Từ đó tôi thu thập được có một số kết nối hoạt động đến cơ sở dữ liệu đó vì vậy tôi đã cố gắng thực hiện truy vấn sau

USE master
GO
ALTER DATABASE My_DatabaseName
SET OFFLINE WITH ROLLBACK IMMEDIATE
GO

Một lần nữa, tại thời điểm này, SSMS đã hiển thị Query Executing.....một lúc và sau đó đã đưa ra lỗi sau:

Msg 5061, Level 16, State 1, Line 1
ALTER DATABASE failed because a lock could not be placed on database 'My_DatabaseName'. Try again later.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.

Sau này tôi không thể kết nối với cơ sở dữ liệu thông qua SSMS. và khi tôi cố gắng đưa nó ngoại tuyến bằng SSMS, nó đã báo lỗi:

Database is in Transition. Try later .....

Tại thời điểm này, tôi chỉ đơn giản là không thể chạm vào cơ sở dữ liệu bất cứ điều gì tôi đã thử nó trả về cùng một thông báo lỗi Database is in Transition.

Tôi đã lên google đọc một số câu hỏi mà mọi người đã gặp phải vấn đề tương tự và họ đề nghị đóng SSMS và mở lại, Tôi cũng vậy và vì đó chỉ là một máy chủ dev nên tôi đã xóa cơ sở dữ liệu bằng SSMS và khôi phục trên cơ sở dữ liệu mới.

Câu hỏi của tôi là những gì có thể có thể gây ra điều này ?? và làm thế nào tôi có thể tránh điều này xảy ra trong tương lai và nếu tôi gặp phải tình huống tương tự trong tương lai thì có cách nào khác để khắc phục nó sau đó xóa toàn bộ cơ sở dữ liệu không ???

Cảm ơn bạn

Câu trả lời:


23

Repro

  1. Mở SSMS
  2. Nhập nội dung sau vào cửa sổ truy vấn mới

    use <YourDatabase>;
    go
  3. Chuyển đến Object Explorer (SSMS) và nhấp chuột phải vào <YourDatabase>-> Tasks->Take Offline
  4. Mở một cửa sổ truy vấn mới thứ hai và gõ như sau:

    use <YourDatabase>;
    go

Bạn sẽ được nhắc với thông báo sau:

Msg 952, Cấp 16, Trạng thái 1,
Cơ sở dữ liệu Dòng 1 'TestDb1' đang trong quá trình chuyển đổi. Hãy thử tuyên bố sau.

Lý do điều này xảy ra có thể được tìm thấy từ một truy vấn chẩn đoán tương tự với truy vấn dưới đây:

select
    l.resource_type,
    l.request_mode,
    l.request_status,
    l.request_session_id,
    r.command,
    r.status,
    r.blocking_session_id,
    r.wait_type,
    r.wait_time,
    r.wait_resource,
    request_sql_text = st.text,
    s.program_name,
    most_recent_sql_text = stc.text
from sys.dm_tran_locks l
left join sys.dm_exec_requests r
on l.request_session_id = r.session_id
left join sys.dm_exec_sessions s
on l.request_session_id = s.session_id
left join sys.dm_exec_connections c
on s.session_id = c.session_id
outer apply sys.dm_exec_sql_text(r.sql_handle) st
outer apply sys.dm_exec_sql_text(c.most_recent_sql_handle) stc
where l.resource_database_id = db_id('<YourDatabase>')
order by request_session_id;

Để biết giá trị của nó, bạn không cần Object Explorer để tái tạo lỗi này. Bạn chỉ cần một yêu cầu bị chặn đang cố thực hiện thao tác tương tự (trong trường hợp này, hãy lấy cơ sở dữ liệu ngoại tuyến). Xem ảnh chụp màn hình bên dưới để biết ba bước trong T-SQL:

nhập mô tả hình ảnh ở đây

Những gì bạn rất có thể sẽ thấy là phiên Object Explorer của bạn bị chặn bởi một phiên khác (được hiển thị bởi blocking_session_id). Phiên Object Explorer đó sẽ cố lấy khóa độc quyền ( X) trên cơ sở dữ liệu. Trong trường hợp của repro ở trên, phiên Object Explorer đã được cấp khóa cập nhật ( U) và cố gắng chuyển đổi thành khóa độc quyền ( X). Nó có một Wait_type của LCK_M_X, bị chặn bởi phiên của chúng tôi được đại diện bởi cửa sổ truy vấn đầu tiên ( use <YourDatabase>lấy khóa chia sẻ ( S) trên cơ sở dữ liệu).

Và sau đó, lỗi này xuất phát từ một phiên khác đang cố khóa và thông báo lỗi này dẫn đến việc từ chối phiên để có quyền truy cập vào cơ sở dữ liệu đang cố chuyển sang trạng thái khác (trong trường hợp này là trạng thái trực tuyến để chuyển đổi ngoại tuyến).

Lần sau bạn nên làm gì?

Trước hết, đừng hoảng sợđừng bắt đầu bỏ cơ sở dữ liệu . Bạn cần thực hiện một phương pháp khắc phục sự cố (với một truy vấn chẩn đoán tương tự như ở trên) để tìm hiểu lý do tại sao bạn nhìn thấy những gì bạn đang thấy. Với một thông báo như vậy hoặc khi một cái gì đó xuất hiện "treo", bạn sẽ tự động cho rằng thiếu đồng thời và bắt đầu đào sâu vào việc chặn ( sys.dm_tran_lockslà một khởi đầu tốt).

Là một lưu ý phụ, tôi thực sự tin rằng bạn là tốt nhất để tìm ra gốc rễ của một vấn đề trước khi thực hiện bất kỳ hành động ngẫu nhiên. Không chỉ với thao tác này, mà còn phù hợp với mọi hành vi mà bạn không mong đợi. Biết những gì thực sự gây ra vấn đề của bạn, rõ ràng nó thực sự không phải là vấn đề lớn. Về cơ bản, bạn đã có một chuỗi chặn và trình chặn cha mẹ là thứ mà rất có thể bạn đã đưa ra KILLhoặc nếu đó là yêu cầu của phiên mà bạn không muốn KILLthì bạn có thể đợi cho đến khi hoàn thành. Dù bằng cách nào, bạn sẽ có kiến ​​thức để đưa ra quyết định đúng đắn và thận trọng dựa trên kịch bản cụ thể của bạn (khôi phục hoặc chờ cam kết).

Một điều đáng chú ý khác, đây là một trong những lý do tại sao tôi luôn chọn phương án thay thế T-SQL thay vì GUI. Bạn biết chính xác những gì bạn đang thực hiện với T-SQL và SQL Server đang làm gì. Rốt cuộc, bạn đã ban hành lệnh rõ ràng. Khi bạn sử dụng GUI, T-SQL thực tế sẽ là một sự trừu tượng hóa. Trong trường hợp này, tôi đã xem xét nỗ lực của Object Explorer bị chặn để lấy cơ sở dữ liệu ngoại tuyến và nó đã được ALTER DATABASE <YourDatabase> SET OFFLINE. Không có nỗ lực để quay trở lại, đó là lý do tại sao nó đã chờ đợi vô thời hạn. Trong trường hợp của bạn, nếu bạn muốn quay lại các phiên có khóa trên cơ sở dữ liệu đó, ALTER DATABASE ... SET OFFLINE WITH ROLLBACK IMMEDIATEthì rất có thể bạn sẽ bị thiếu khả năng nếu bạn đã xác định ban đầu rằng rollback là ổn.


1

Chỉ cần đóng SQL Server Management Studio (SSMS) và mở lại đã khắc phục sự cố cho tôi.


0

Không cần làm gì cả, chỉ cần giết tiến trình SqLWB.exetừ Trình quản lý tác vụ, mở SQL Server, nhấp chuột phải vào cơ sở dữ liệu và đưa nó ngoại tuyến. Nếu nó không hoạt động, sau khi phiên bị giết, hãy gõ lệnh

ALTER DATABASE [Test4] SET OFFLINE WITH ROLLBACK IMMEDIATE

rồi ngoại tuyến. Nó sẽ làm việc như nó làm việc cho tôi là tốt.

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.