Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

ROLLBACK TRUNCATE trong SQL Server

Bạn đã bao giờ vô tình thực hiện TRUNCATE lệnh trên một bảng sai? Điều này sẽ dẫn đến mất toàn bộ dữ liệu. Điều tồi tệ nhất là bạn sẽ không có cơ hội lấy lại dữ liệu của mình. Trong bài viết này, chúng ta sẽ biết cách tránh những trường hợp như vậy và có cơ hội ROLLBACK TRUNCATE .

Bạn không thể ROLLBACK TRUNCATE

Đơn giản, bạn không thể khôi phục một giao dịch nếu nó đã được cam kết nhưng bạn có thể làm điều gì đó khác để lấy lại dữ liệu (hoặc ít nhất là một số phần của nó).

Khi bạn thực hiện TRUNCATE tuyên bố, dữ liệu của bạn vẫn còn trong tệp MDF. Tuy nhiên, nó không hiển thị vì SQL Server đang coi đây là dung lượng trống ( TRUNCATE đang yêu cầu SQL Server phân bổ các trang dữ liệu).

Cách duy nhất để lấy lại dữ liệu là bằng cách nào đó đọc các trang dữ liệu đã được phân bổ và chuyển đổi chúng thành dữ liệu có thể đọc được.

Bạn phải hành động nhanh chóng vì dung lượng trống sẽ bị ghi đè bằng dữ liệu mới nếu chưa có. Nếu bạn có thể dừng phiên bản SQL Server của mình và tạo một bản sao của các tệp MDF và LDF sẽ giúp bạn có thêm thời gian.

Có một số công cụ có thể thực hiện loại khôi phục này.

Bạn có thể QUAY LẠI TRUNCATE

TRUNCATE là một hoạt động được ghi lại, nhưng SQL Server không ghi lại từng hàng đơn lẻ vì nó TRUNCATE bảng. SQL Server chỉ ghi lại thực tế là TRUNCATE hoạt động đã xảy ra. Nó cũng ghi lại thông tin về các trang và phạm vi đã được phân bổ. Tuy nhiên, có đủ thông tin để quay trở lại, chỉ cần phân bổ lại các trang đó. Bản sao lưu nhật ký chỉ cần thông tin mà BẢNG TRUNCATE xảy ra. Để khôi phục BẢNG TRUNCATE , hoạt động chỉ được áp dụng lại. Dữ liệu liên quan không cần thiết trong quá trình KHÔI PHỤC (giống như đối với hoạt động 'ghi nhật ký tối thiểu' thực sự như CHÈN SỐ LƯỢNG LỚN ).

SQL Server biết những trang nào thuộc về bảng cho đến khi chúng được khóa bằng một khóa riêng và cũng giống như tất cả các khóa X, chúng được giữ cho đến khi kết thúc giao dịch. Đó là lý do tại sao các trang hoặc phạm vi không thể được phân bổ và chắc chắn, không thể được sử dụng lại.

Đây là một ví dụ:

Chúng tôi đã đếm được 504 hàng và một số trang. Bây giờ chúng ta sẽ xem xét số lượng hàng và số trang thuộc về bảng.

BEGIN TRAN
TRUNCATE TABLE dbo.Products;
SELECT COUNT(*) FROM dbo.Products;
 
DBCC IND('AdventureWorks', 'Products', -1);
DBCC EXTENTINFO('AdventureWorks', 'Products', -1);
 
SELECT resource_type, resource_description,
        request_mode FROM sys.dm_tran_locks
WHERE  resource_type IN ('EXTENT', 'PAGE')
AND   resource_database_id = DB_ID('AdventureWorks');

Bạn sẽ không thấy hàng nào từ DBCC IND , và 0 hàng từ số đếm (*). Thông tin ổ khóa trả về như sau:

resource_type resource_description request_mode
————- ——————– ————
EXTENT 1:33352 X
PAGE 1:42486 X
EXTENT 1:42488 X
TRANG 1:42487 X
TRANG 1:42488 X
TRANG 1:42489 X
TRANG 1:23027 X
TRANG 1:23030 X
TRANG 1:23029 X
TRANG 1:26992 X
TRANG 1:26993 X

Phạm vi và số lần khóa trang bao gồm tất cả các trang mà chúng tôi đã thấy trong DBCC IND đầu ra. Chỉ sau khi bạn ROLLBACK giao dịch sẽ mở khóa và bạn sẽ thấy lại tất cả các hàng và trang trên bảng.

ROLLBACK TRAN;
GO
SELECT COUNT(*) FROM dbo.Products;
DBCC IND('AdventureWorks', 'Products', -1);
GO

Hãy cẩn thận và luôn đặt câu lệnh bảng TRUNCATE trong giao dịch.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sử dụng SQL Server làm kho lưu trữ hình ảnh

  2. Cách đổi tên tên cột hoặc tên bảng trong SQL Server - Hướng dẫn SQL Server / T-SQL Phần 36

  3. Cách lấy thông tin thống kê của máy chủ SQL bằng chức năng thống kê hệ thống

  4. Cải thiện điều chỉnh hiệu suất SQL Server với 3 mẹo sau

  5. Tại sao tham gia bên trái t-sql của tôi không hoạt động?