Sao lưu bảng rất lớn


7

Tôi phải cập nhật một số giá trị nhất định của một bảng lớn (vì lợi ích của một ví dụ giả định, nó được gọi là 'Tài nguyên' và nó có hơn 5 triệu hàng) và do đó tôi phải tạo bản sao lưu trước khi thực hiện các thay đổi. Chúng tôi không có đủ không gian trống DB để lưu trữ bảng sao lưu đầy đủ.

Đó là cách tốt nhất? Có cách nào để làm điều này bằng các khối? Ý tôi là đại loại như: sao lưu các hàng 100K đầu tiên từ bảng gốc, cập nhật các hàng 100K đó trong bảng gốc, xóa các hàng 100K đó khỏi bảng sao lưu, sao lưu các hàng 100K sau từ bảng gốc và tiến hành tương tự . Điều này có khả thi không?


@George Ồ, tôi không biết về điều đó. Cảm ơn, George.
iL_Marto

Bạn đã có một bản sao lưu hiện có chưa?
Cougar9000

Phiên bản nào của SQL Server? Bạn có bật sao lưu nén không?
Cougar9000

@ Cougar9000, không có và không có bản sao lưu và tôi đang sử dụng SQL Server 2008 R2.
iL_Marto

8
Nếu cơ sở dữ liệu không đủ quan trọng để có bản sao lưu, tại sao nó đủ quan trọng để sao lưu trước khi thực hiện những thay đổi này? Cũng lưu ý rằng việc cập nhật 5M hàng trong bảng của bạn rất có thể sẽ gây ra một lượng sử dụng nhật ký nhất định và nếu bạn thiếu dung lượng trong cơ sở dữ liệu ...
Cade Roux

Câu trả lời:


4

Hai ý nghĩ nảy ra trong đầu.

  • Nếu bạn lo ngại rằng bản cập nhật này có thể không ảnh hưởng chính xác đến bảng theo cách bạn nghĩ, bạn đã nghĩ đến việc đưa bản cập nhật vào trong một giao dịch.
  • Bạn có thể thực hiện cập nhật, truy vấn dữ liệu và nếu tất cả đều ổn, Cam kết Giao dịch. Nếu thất bại, bạn có thể thực hiện Rollback.

Thay thế

Bạn có thể muốn xem tiện ích BCP để trích xuất bảng thành một tệp phẳng bên ngoài Máy chủ SQL.

Có lẽ, bạn có thể lưu trữ nội dung của bảng ở vị trí mà bạn không chịu nhiều áp lực lưu trữ. Nếu quá trình cập nhật thất bại, bạn có thể cố gắng khôi phục lại nội dung vào bảng của mình.


0

Không sao lưu một bảng duy nhất. Nó thường là một ý tưởng tồi. Luôn sao lưu toàn bộ cơ sở dữ liệu

Đầu tiên. Tôi giả định rằng cơ sở dữ liệu không sống. Nếu không, bạn có thể mất các hoạt động nếu bạn khôi phục một bản sao lưu.

Câu trả lời bạn muốn, giả sử bạn biết bạn đang làm gì:

Một cách đơn giản để tạo bản sao lưu của bảng là tạo một bảng khác có nội dung:

CREATE Table tableBackup as select * from tableToBackup;

nếu có lỗi xảy ra, hãy xóa các bộ dữ liệu khỏi bảng gốc và chèn các bộ dữ liệu từ cơ sở dữ liệu sao lưu.

Tất nhiên bạn phải rất ý thức rằng sao lưu một bảng duy nhất thường là một ý tưởng tồi. Thông thường tính toàn vẹn của cơ sở dữ liệu phụ thuộc vào các giá trị của toàn bộ cơ sở dữ liệu (ví dụ: một giá trị trong bảng khác có thể phụ thuộc vào sự tồn tại của bộ dữ liệu trong ví dụ này - ví dụ về mối quan hệ khóa ngoài).

Nếu có các ràng buộc tham chiếu giữa bảng bạn muốn sao lưu và các bảng khác, bạn có thể không thể khôi phục bảng gốc bằng phương pháp tôi đã đề xuất ở trên.

Vì vậy, trừ khi bạn biết những gì bạn đang làm, sao lưu toàn bộ cơ sở dữ liệu và không phải bảng duy nhất. Kiểm tra tài liệu của cơ sở dữ liệu bạn chọn để xem cách thực hiện.


2
CREATE TABLE ... AS SELECTkhông phải là cú pháp SQL Server hợp lệ.
Aaron Bertrand

Cú pháp cho SQL Server là select * into schema.backuptable from schema.table;. Như được chỉ ra dưới đây, điều này sao chép các định nghĩa cột và dữ liệu của schema.table- không phải là các ràng buộc hoặc chỉ mục hoặc trình kích hoạt.
Greenstone Walker

0

Để thêm vào những gì @dmg nói. Sao lưu một bảng duy nhất có thể có vấn đề. Bỏ qua một bên nếu ví dụ bảng "lớn" của bạn là 90% cơ sở dữ liệu thì chỉ cần sao lưu bảng sẽ không thực sự giúp bạn nhiều. Nếu bạn đang sử dụng SQL 2008, hãy chắc chắn rằng bạn đang có compressing your backups. Bạn có thể nhận được tỷ lệ phần trăm nén hợp lý và thực sự có thể sao lưu toàn bộ.

Một lựa chọn khác là transaction logsao lưu. Đây là những gì tôi thường làm khi tôi xử lý một cơ sở dữ liệu lớn trước khi thực hiện thay đổi. Chúng phải luôn nhỏ hơn nhiều (đặc biệt nếu bạn thường xuyên sao lưu) so với sao lưu toàn bộ. Và sẽ còn nhỏ hơn nữa nếu bạn nén chúng.

Bây giờ sẽ không hoạt động nếu cơ sở dữ liệu của bạn được đặt thành simple recovery. Trong trường hợp đó, chỉ có tùy chọn sao lưu truyền thống khác của bạn là xem xét differential backups. Chúng thực sự có thể nhận được khá lớn. Tuy nhiên, nếu bản sao lưu đầy đủ cuối cùng của bạn được thực hiện gần đây hoặc bạn chỉ thực hiện thay đổi đối với một tỷ lệ nhỏ của cơ sở dữ liệu thì đây có thể là một lựa chọn khả thi cho bạn. Mặt khác, nếu cơ sở dữ liệu của bạn được đặt thành simplethì bạn có thể không cần phải lo lắng về việc có thể phục hồi trước khi thay đổi.

Cuối cùng nhưng không kém phần quan trọng (SQL 2005 trở lên) có OUTPUTmệnh đề. Điều khoản nhỏ tiện dụng này cho phép bạn đưa ra những thay đổi bạn đã thực hiện trong khi thực hiện lệnh của mình. Chúng có thể được lưu trữ trong một biến bảng hoặc bảng. Về cơ bản họ cung cấp cho bạn quyền truy cập vào INSERTEDDELETEDcác bảng mà thông thường bạn chỉ thấy trong các kích hoạt. Tôi có hiệu lực bạn có thể sao lưu các thay đổi của mình (cả trước và sau) vào một bảng khác. Bằng cách này, bạn chỉ sao lưu các hàng và cột đã thay đổi. Hãy chắc chắn rằng bạn bao gồm khóa chính của bạn là tất nhiên. Đây là mục BOL . Và đây là một ví dụ từ BOL. Trong ví dụ cụ thể này, chỉ có 4 cột trong 10 hàng dữ liệu được lưu. Ngay cả khi bảng xảy ra là 5 hoặc thậm chí 10 triệu hàng.

USE AdventureWorks;
GO
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    OldVacationHours int,
    NewVacationHours int,
    ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 
OUTPUT INSERTED.EmployeeID,
       DELETED.VacationHours,
       INSERTED.VacationHours,
       INSERTED.ModifiedDate
INTO @MyTableVar;

0

Cú pháp tạo bảng được đăng sẽ không hoạt động, afaik.

Cách dễ dàng để sao lưu một bảng duy nhất là:

CHỌN * VÀO [bảng sao lưu] TỪ [bảng nguồn]

Sau đó, bạn có thể bỏ [bảng sao lưu] khi bạn không cần nó.

Bạn có thể thực hiện điều này qua một db khác (có thể nằm trên một bộ trục chính khác), v.v.


0

Cho đến nay bởi các câu trả lời đã cho, bạn đang sao lưu dữ liệu bảng cơ sở của mình, nhưng không phải chính bảng đó. Bảng này có nhiều thuộc tính khác, SELECT * INTOvề cơ bản chỉ cần lấy cho bạn các giá trị ô và cấu trúc cột. Mặc dù chưa hoàn thành, một số thuộc tính bổ sung cần xem xét:

  • Lược đồ phân vùng / Chức năng
  • Chỉ mục
  • Quan hệ đối ngoại
  • Cấp độ đối tượng
  • Thuộc tính -Extends
  • Vân vân.

Đây là một bảng rất lớn, vì vậy tôi sẽ không ngạc nhiên khi thấy phân vùng và lập chỉ mục nặng. Câu trả lời tốt nhất cho đến nay IMO là sao lưu toàn bộ cơ sở dữ liệu. Nếu đó không phải là một lựa chọn tốt, hãy viết ra toàn bộ lược đồ và lược đồ hỗ trợ (trong trường hợp các mục nằm bên ngoài bảng như trong phân vùng). Có một bản sao của nó, sau đó làm mộtSELECT INTO.

Tất nhiên, một số người rất am hiểu như Kim Tripp khuyên bạn nên thêm chỉ mục của mình và đôi khi phân vùng sau khi bạn đổ dữ liệu, đây có thể là lời khuyên hữu ích. Chỉ cần nhớ nếu bạn thực hiện phân vùng sau khi bạn đổ dữ liệu, bạn sẽ muốn sử dụng một ràng buộc kiểm tra để đảm bảo loại bỏ phân vùng xảy ra. Đó là một cái gì đó để xem xét nếu bạn thực sự thấy nó được cấu hình mặc dù.


0

Bạn có thể lấy một bản sao lưu của bảng hiện có một mình vào new_table và cập nhật bảng của bạn và nếu có gì sai, bạn luôn có bảng sao lưu để hoàn nguyên.

Ví dụ:

-- SCRIPT TO BACKUP A TABLE
SELECT * INTO <NEW_TABLE> FROM CURRENT_TABLE

Lấy bản sao lưu của bảng đơn ít hơn nhiều so với sao lưu cơ sở dữ liệu hoàn chỉnh.

Nếu mọi thứ suôn sẻ thì bạn có thể bỏ <NEW_TABLE>.


Câu hỏi nêu rõ: "Chúng tôi không có đủ dung lượng trống DB để lưu trữ bảng sao lưu đầy đủ". Vì vậy, những gì bạn đang đề xuất sẽ không làm việc ở đây.
Mat
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.