Trang này được dịch bằng máy. Đọc bản gốc tiếng Anh. English

Thư viện IBSurgeon

Hướng dẫn khôi phục InterBase và Firebird

LƯU Ý: Tài liệu này là chương trích từ cuốn sách “The InterBase World” được viết bởi Alexey Kovyazin và Serg Vostrikov.

Chương trích từ cuốn sách “The InterBase World” dành riêng cho việc sửa chữa cơ sở dữ liệu.

1. Lịch sử của tài liệu hướng dẫn này

Cuốn sách tiếng Nga “The InterBase World” được xuất bản vào tháng 9 năm 2002.

Số lượng in là 3000 bản. Sau 3 tháng, sách đã được bán hết và ấn bản thứ hai, được cải tiến, đã được xuất bản vào tháng 4 năm 2003 với số lượng in là 5000 bản.

Hiện nay, cuốn sách đang đứng đầu trong các cửa hàng sách trực tuyến lớn nhất của Nga và chúng tôi dự định rằng nó sẽ được bán hết rất sớm.

Các tác giả của cuốn sách là Alexey Kovyazin, nhà phát triển của IBSurgeon và

chuyên gia InterBase nổi tiếng của Nga, và Serg Vostrikov, CEO của công ty Devrace

www.devrace.com

Điều thú vị là, không một cuốn sách nào dành riêng cho InterBase được xuất bản bằng tiếng Anh!

Hàng ngàn và hàng ngàn nhà phát triển sử dụng InterBase và Firebird, thảo luận về

chủ đề này trong các hội nghị khác nhau (hãy xem tại đây: Liên kết).

Cộng đồng các nhà phát triển InterBase trung bình lên tới hàng chục ngàn

người. Nhu cầu mạnh mẽ về sách InterBase ở nhiều quốc gia khác nhau chứng minh rằng cộng đồng InterBase thực sự lớn.

Chúng tôi có thể đặt cược một thùng bia rằng ấn bản 10000 bản sẽ bị quét sạch khỏi Amazon.com trong một tháng. Nhưng những người trong các công ty xuất bản

“biết tất cả” và họ chắc chắn rằng không ai mua sách về InterBase. Đó là một điều đáng tiếc thực sự.

Tại đây, chúng tôi muốn giới thiệu cho bạn bản nháp của một chương trong cuốn sách này dành riêng cho việc khôi phục cơ sở dữ liệu InterBase/Firebird.

2. Cách khôi phục cơ sở dữ liệu InterBase/Firebird

2.1. Tổng quan về các nguyên nhân chính gây hỏng cơ sở dữ liệu

Thật không may, luôn có khả năng rằng bất kỳ kho lưu trữ thông tin nào cũng sẽ bị

hỏng và một số thông tin từ đó sẽ bị mất. Cơ sở dữ liệu không phải là ngoại lệ với quy tắc này. Trong chương này, chúng ta sẽ xem xét các nguyên nhân chính dẫn đến hỏng cơ sở dữ liệu InterBase, một số phương pháp sửa chữa cơ sở dữ liệu và trích xuất thông tin từ chúng. Ngoài ra, chúng ta sẽ tìm hiểu các khuyến nghị và biện pháp phòng ngừa sẽ giảm thiểu khả năng mất thông tin từ cơ sở dữ liệu.

Trước hết, nếu chúng ta nói về việc sửa chữa cơ sở dữ liệu, chúng ta nên làm rõ khái niệm “hỏng cơ sở dữ liệu”. Cơ sở dữ liệu thường được gọi là bị hỏng nếu khi cố gắng trích xuất hoặc sửa đổi một số thông tin, lỗi xuất hiện và/hoặc thông tin được trích xuất hóa ra bị mất, không đầy đủ hoặc hoàn toàn không đúng. Có những trường hợp hỏng cơ sở dữ liệu bị ẩn và chỉ được phát hiện khi kiểm tra bằng các công cụ đặc biệt, nhưng cũng có những trường hợp hỏng cơ sở dữ liệu thực sự khi không thể kết nối với cơ sở dữ liệu, khi các chương trình ứng dụng khách đã điều chỉnh hiển thị lỗi lạ (khi không có thao tác nào được thực hiện với cơ sở dữ liệu), hoặc khi không thể khôi phục cơ sở dữ liệu từ bản sao lưu.

2.2. Các nguyên nhân chính gây hỏng cơ sở dữ liệu là:

  • Tắt máy chủ bất thường, đặc biệt là mất điện. Đối với ngành CNTT, đây là một tai họa thực sự và do đó chúng tôi hy vọng không cần nhắc lại một lần nữa về sự cần thiết phải có nguồn điện liên tục trên máy chủ.
  • Khiếm khuyết và lỗi của máy chủ, đặc biệt là ổ cứng (HDD), bộ điều khiển đĩa, bộ nhớ chính của máy tính và bộ nhớ cache của bộ điều khiển Raid.
  • Chuỗi kết nối không đúng với cơ sở dữ liệu đa khách hàng của một hoặc nhiều người dùng (trong các phiên bản trước 6.x). Khi kết nối qua TCP/IP, đường dẫn đến cơ sở dữ liệu phải chỉ định tên máy chủ: ổ đĩa:/đường dẫn/tên cơ sở dữ liệu /đối với máy chủ trên nền tảng UNIX tên máy chủ: /đường dẫn/tên cơ sở dữ liệu /, theo giao thức NETBEUI \\tên máy chủ\ổ đĩa:\đường dẫn\tên cơ sở dữ liệu. Ngay cả khi kết nối cơ sở dữ liệu từ máy tính, nơi cơ sở dữ liệu được đặt và máy chủ đang chạy, người ta nên sử dụng cùng một dòng đổi tên tên máy chủ thành localhost. Không thể sử dụng ổ đĩa được ánh xạ trong dòng kết nối. Nếu bạn vi phạm một trong các quy tắc này, máy chủ coi rằng nó đang làm việc với các cơ sở dữ liệu khác nhau và việc hỏng cơ sở dữ liệu là chắc chắn.
  • Sao chép tệp hoặc truy cập tệp khác vào cơ sở dữ liệu khi máy chủ đang chạy. Việc thực hiện lệnh “shut-down” hoặc ngắt kết nối người dùng theo cách thông thường không đảm bảo rằng máy chủ không làm gì với cơ sở dữ liệu, nếu khoảng thời gian sweep không được đặt thành “0”, việc thu gom rác có thể được thực hiện. Thông thường, việc thu gom rác được thực hiện ngay sau khi người dùng cuối cùng ngắt kết nối khỏi cơ sở dữ liệu. Thường mất vài giây, nhưng nếu trước đó nhiều thao tác DELETE hoặc UPDATE đã được cam kết, quá trình này có thể lâu hơn.
  • Sử dụng các phiên bản máy chủ InterBase không ổn định 5.1-.5.5. Công ty Borland đã chính thức thừa nhận rằng có một số lỗi trong các máy chủ này và bản nâng cấp ổn định 5.6 chỉ được loại bỏ sau khi phát hành InterBase 6 được chứng nhận ở chế độ chạy tự do cho tất cả khách hàng của máy chủ 5.1-5.5 trên trang web của mình.
  • Vượt quá giới hạn kích thước của tệp cơ sở dữ liệu (không phải cơ sở dữ liệu!). Đối với các phiên bản trước InterBase 6 và một số bản beta InterBase 6, giới hạn tệp cơ sở dữ liệu là 4Gb, đối với InterBase 6.5 và tất cả các bản phát hành của Firebird (1.0, 1.5, 2.0, 2.1) - 32Tb. Khi kích thước cơ sở dữ liệu tiến gần đến giá trị giới hạn, phải tạo một tệp bổ sung.
  • Cạn kiệt dung lượng đĩa trống khi làm việc với cơ sở dữ liệu.
  • Đối với máy chủ Borland InterBase phiên bản dưới 6.0.1.6 - vượt quá giới hạn về số lượng generator theo định nghĩa của Borland InterBase R & D như sau (xem bảng 1).
Phiên bản Kích thước trang=1024 Kích thước trang=2048 Kích thước trang=4096 Kích thước trang=8192
Trước 6 248 504 1016 2040
6.0.x 124 257 508 102

Bảng 1: Số lượng generator tới hạn trong các phiên bản InterBase đầu

• Đối với tất cả máy chủ Borland InterBase - vượt quá số lượng giao dịch cho phép

mà không thực hiện backup/restore. Người ta có thể biết số lượng giao dịch đã xảy ra trong cơ sở dữ liệu kể từ lần tạo cuối cùng bằng cách gọi tiện ích gstat với khóa - h- tham số NEXT TRANSACTION ID sẽ là số lượng giao dịch mong muốn. Theo Ann W.Harrison, số lượng giao dịch tới hạn phụ thuộc vào kích thước trang và có các giá trị sau (xem bảng 2):

Kích thước trang cơ sở dữ liệu Số lượng giao dịch tới hạn
1024 byte 131 596 287
2048 byte 265 814 016
4096 byte 534 249 472
8192 byte 1 071 120 384

Bảng 2: Số lượng giao dịch tới hạn trong máy chủ Borland InterBase

Các ràng buộc của máy chủ Borland InterBase được liệt kê ở trên không áp dụng cho

máy chủ Firebird ngoại trừ các phiên bản sớm nhất 0.x., sự tồn tại của chúng đã trở thành lịch sử. Nếu bạn sử dụng phiên bản cuối cùng Firebird 1.0 hoặc InterBase 6.5-7.x, bạn không nên lo lắng về các điểm 5, 6, 8 và 9 và nên tập trung nỗ lực vào các nguyên nhân khác. Bây giờ chúng ta sẽ xem xét chi tiết những nguyên nhân thường gặp nhất trong số đó.

2.3. Sự cố nguồn điện

Khi tắt nguồn trên máy chủ, tất cả các hoạt động xử lý dữ liệu bị

gián đoạn ở những nơi bất ngờ nhất và (theo định luật Murphy) nguy hiểm nhất. Kết quả là thông tin trong cơ sở dữ liệu có thể bị sai lệch hoặc mất. Trường hợp đơn giản nhất là khi tất cả dữ liệu chưa cam kết từ các ứng dụng khách bị mất do máy chủ tắt khẩn cấp. Sau khi khởi động lại sau sự cố nguồn, máy chủ phân tích dữ liệu, nhận thấy các giao dịch không hoàn chỉnh không liên quan đến bất kỳ khách hàng nào và hủy bỏ tất cả các sửa đổi được thực hiện trong phạm vi các giao dịch “chết” này. Thực tế, hành vi như vậy là bình thường và được các nhà phát triển InterBase dự kiến từ đầu.

Tuy nhiên, sự gián đoạn nguồn điện không phải lúc nào cũng chỉ dẫn đến những tổn thất không đáng kể như vậy. Nếu máy chủ đang thực hiện việc mở rộng cơ sở dữ liệu tại thời điểm gián đoạn nguồn điện, có khả năng lớn sẽ có các trang mồ côi trong tệp cơ sở dữ liệu (các trang được phân bổ vật lý và được đăng ký trên trang kiểm kê trang (PIP), việc ghi dữ liệu vào đó là không thể). Nếu bạn muốn biết thêm về các trang mồ côi, hãy xem chương «Cấu trúc của cơ sở dữ liệu InterBase».

Chỉ có công cụ sửa chữa và sửa đổi gfix (chúng ta sẽ xem xét bên dưới) mới có thể chống lại các trang mồ côi trong tệp cơ sở dữ liệu. Thực tế, các trang mồ côi dẫn đến chi phí không cần thiết về dung lượng đĩa và như vậy không phải là nguyên nhân gây mất dữ liệu hoặc hỏng hóc.

Mất điện dẫn đến những hư hỏng nghiêm trọng hơn. Ví dụ, sau khi tắt

nguồn và khởi động lại, một lượng lớn dữ liệu, bao gồm cả dữ liệu đã cam kết, có thể bị mất (sau khi thêm hoặc sửa đổi mà lệnh «commit transaction» đã được thực hiện). Điều này xảy ra vì dữ liệu đã xác nhận không được ghi trực tiếp vào tệp cơ sở dữ liệu trên đĩa. Và bộ nhớ cache tệp của hệ điều hành (OS) được sử dụng cho mục đích này. Quá trình máy chủ đã đưa lệnh ghi dữ liệu cho OS. Sau đó OS đảm bảo với máy chủ rằng tất cả dữ liệu đã được lưu trên đĩa và trên thực tế dữ liệu được lưu trong bộ nhớ cache tệp. OS không vội ghi các dữ liệu này vào đĩa, vì nó cho rằng còn nhiều bộ nhớ chính và trì hoãn các thao tác ghi chậm vào đĩa cho đến khi bộ nhớ chính được lấp đầy.

2.4. Ghi cưỡng bức - con dao hai lưỡi

Để ảnh hưởng đến tình hình, việc điều chỉnh chế độ ghi dữ liệu được cung cấp trong InterBase 6. Tham số này được gọi là forced writes (FW) và có 2 chế độ - ON (đồng bộ) và OFF (không đồng bộ). Các chế độ FW xác định cách InterBase giao tiếp với đĩa. Nếu FW được bật, cài đặt ghi đồng bộ vào đĩa được bật, khi dữ liệu đã xác nhận được ghi vào đĩa ngay sau lệnh commit, máy chủ chờ hoàn tất việc ghi và chỉ sau đó tiếp tục xử lý. Nếu FW bị tắt, InterBase không vội ghi dữ liệu vào đĩa sau lệnh cam kết giao dịch và giao nhiệm vụ này cho luồng song song trong khi luồng chính tiếp tục xử lý dữ liệu mà không chờ việc ghi hoàn tất vào đĩa. Chế độ ghi đồng bộ là một trong những chế độ cẩn thận nhất và giảm thiểu mọi mất dữ liệu có thể xảy ra, tuy nhiên nó có thể gây ra một số mất hiệu suất. Chế độ ghi không đồng bộ làm tăng khả năng mất một lượng lớn dữ liệu. Để đạt được hiệu suất tối đa, chế độ FW Off thường được đặt. Nhưng kết quả của sự gián đoạn nguồn điện, lượng dữ liệu bị mất trong quá trình ghi không đồng bộ nhiều hơn nhiều so với ghi đồng bộ. Khi đặt chế độ ghi, bạn nên quyết định xem vài phần trăm hiệu suất có quan trọng hơn vài giờ làm việc nếu sự gián đoạn nguồn điện xảy ra bất ngờ hay không.

Rất thường xuyên, người dùng bất cẩn với InterBase. Các tổ chức nhỏ tiết kiệm từng thứ nhỏ nhặt, thường là trên máy tính-máy chủ nơi máy chủ DBMS và các chương trình máy chủ khác nhau (và không chỉ máy chủ) cũng được cài đặt. Nếu chúng bị treo, mọi người nghĩ không lâu rồi nhấn RESET (điều này xảy ra vài lần mỗi ngày). Mặc dù InterBase rất ổn định với các hoạt động như vậy so với các DBMS khác và cho phép bắt đầu làm việc với cơ sở dữ liệu ngay sau khi khởi động lại khẩn cấp, nhưng việc sử dụng như vậy là không mong muốn. Số lượng trang mồ côi tăng lên và dữ liệu mất kết nối với nhau do khởi động lại lỗi.

Điều này có thể tiếp tục trong một thời gian dài, nhưng sớm hay muộn nó sẽ kết thúc. Khi các trang bị hỏng xuất hiện giữa các trang PIP hoặc trang generator hoặc nếu trang tiêu đề cơ sở dữ liệu bị hỏng, cơ sở dữ liệu có thể không bao giờ mở lại được và trở thành một mảnh lớn dữ liệu riêng biệt mà từ đó không thể trích xuất một byte thông tin hữu ích nào.

2.5. Hỏng ổ cứng

Hỏng ổ cứng dẫn đến mất các trang hệ thống quan trọng của cơ sở dữ liệu và/hoặc hỏng các liên kết giữa các trang còn lại. Những hỏng hóc như vậy là một trong những trường hợp khó khăn nhất, vì hầu như luôn đòi hỏi can thiệp cấp thấp để khôi phục cơ sở dữ liệu.

2.6. Sai lầm trong thiết kế cơ sở dữ liệu

Bạn cần biết về một số sai lầm do các nhà phát triển cơ sở dữ liệu gây ra

có thể dẫn đến việc không thể khôi phục cơ sở dữ liệu từ bản sao lưu (các tệp *.gbk được tạo bởi chương trình gbak). Trước hết, đây là việc sử dụng bất cẩn các ràng buộc ở cấp độ cơ sở dữ liệu. Ví dụ điển hình là ràng buộc NOT NULL. Giả sử chúng ta có một bảng chứa một số lượng bản ghi. Bây giờ chúng ta sẽ thêm vào bảng này bằng lệnh ALTER TABLE một cột nữa và chỉ định rằng nó không được chứa các giá trị không xác định NULL. Một cái gì đó như thế này:

ALTER TABLE sometable Field/INTEGER NOT NULL

Và trong trường hợp này sẽ không có lỗi nào từ phía máy chủ như người ta có thể mong đợi. Việc sửa đổi metadata này sẽ được commit và chúng ta sẽ không nhận được bất kỳ thông báo lỗi hay cảnh báo nào, điều này tạo ra ảo giác về tính bình thường của tình huống này.

Tuy nhiên, nếu chúng ta sao lưu cơ sở dữ liệu và cố gắng khôi phục nó từ bản sao lưu, chúng ta sẽ nhận được thông báo lỗi ở giai đoạn khôi phục (vì các giá trị Null được chèn vào cột có ràng buộc NOT NULL, và quá trình khôi phục sẽ bị gián đoạn. (Lưu ý quan trọng được cung cấp bởi Craig Stuntz - với phiên bản InterBase 7.1, các ràng buộc được bỏ qua theo mặc định trong quá trình khôi phục (điều này có thể được kiểm soát bằng công tắc dòng lệnh) và gần như mọi bản sao lưu không bị hỏng đều có thể được khôi phục. Luôn luôn là một ý tưởng tốt để thực hiện khôi phục thử nghiệm sau khi tạo bản sao lưu, nhưng vấn đề này gần như sẽ biến mất trong phiên bản 7.1.) Bản sao lưu này không thể được khôi phục. Nếu việc khôi phục được hướng đến một tệp có cùng tên với cơ sở dữ liệu hiện có (trong quá trình khôi phục, tệp làm việc của cơ sở dữ liệu hiện có đang bị ghi đè), chúng ta sẽ mất toàn bộ thông tin.

Điều này liên quan đến thực tế là các ràng buộc NOT NULL được triển khai bởi các trigger hệ thống chỉ kiểm tra dữ liệu đến. Trong quá trình khôi phục, dữ liệu từ bản sao lưu được chèn vào các bảng trống vừa được tạo - ở đây chúng ta có thể tìm thấy các giá trị NULL không được chấp nhận trong cột có ràng buộc NOT NULL.

Một số nhà phát triển cho rằng hành vi như vậy của InterBase là không chính xác, nhưng những người khác sẽ không thể thêm một trường có ràng buộc NOT NULL vào bảng cơ sở dữ liệu.

Câu hỏi về giá trị mặc định bắt buộc và việc điền giá trị đó tại thời điểm tạo đã được các kiến trúc sư của Firebird thảo luận rộng rãi, nhưng không được chấp nhận vì thực tế là lập trình viên rõ ràng sẽ điền nó theo thuật toán khá phức tạp và có thể lặp lại. Nhưng không có gì đảm bảo liệu anh ta có thể phân biệt được các bản ghi bị bỏ qua bởi lần lặp trước với các bản ghi chưa được điền hay không.

Vấn đề tương tự có thể được gây ra bởi lỗi thu gom rác do thiết lập đường dẫn không chính xác đến cơ sở dữ liệu (nguyên nhân của hỏng hóc 3) tại thời điểm kết nối và truy cập tệp vào các tệp cơ sở dữ liệu khi máy chủ đang làm việc với nó (nguyên nhân của hỏng hóc 4) và các bản ghi được điền toàn bộ bằng Null có thể xuất hiện trong một số bảng. Rất khó để phát hiện các bản ghi này, vì chúng không tương ứng với các hạn chế kiểm soát toàn vẹn, và toán tử Select chỉ đơn giản là không nhìn thấy chúng, mặc dù chúng được đưa vào bản sao lưu. Nếu không thể khôi phục vì lý do này, người ta nên chạy chương trình gfix (xem bên dưới), tìm và xóa các bản ghi này bằng cách sử dụng các trường không được lập chỉ mục làm điều kiện tìm kiếm, sau đó thử lại để tạo bản sao lưu và khôi phục cơ sở dữ liệu từ nó. Kết luận, chúng ta có thể nói rằng có rất nhiều nguyên nhân gây hỏng hóc cơ sở dữ liệu và bạn phải luôn sẵn sàng cho điều tồi tệ nhất - rằng cơ sở dữ liệu của bạn sẽ bị hỏng vì lý do này hay lý do khác. Bạn cũng phải sẵn sàng khôi phục và lưu giữ thông tin có giá trị. Và bây giờ chúng ta sẽ xem xét các biện pháp phòng ngừa đảm bảo an toàn cho cơ sở dữ liệu InterBase, cũng như các phương pháp sửa chữa cơ sở dữ liệu bị hỏng.

2.7. Các biện pháp phòng ngừa hỏng hóc cơ sở dữ liệu InterBase

Để ngăn chặn hỏng hóc cơ sở dữ liệu, người ta nên luôn tạo các bản sao lưu (nếu bạn muốn biết thêm về sao lưu thì hãy xem chương “Sao lưu và khôi phục”). Đây là cách đáng tin cậy nhất chống lại hỏng hóc cơ sở dữ liệu. Chỉ có sao lưu mới đảm bảo 100% an toàn cho cơ sở dữ liệu. Như đã mô tả ở trên, kết quả của việc sao lưu chúng ta có thể nhận được một bản sao vô dụng (một bản sao không thể khôi phục), đó là lý do tại sao việc khôi phục cơ sở dữ liệu từ bản sao không được thực hiện bằng cách ghi đè lên script và việc sao lưu phải được thực hiện theo các quy tắc nhất định. Thứ nhất, sao lưu phải được thực hiện càng thường xuyên càng tốt, thứ hai nó phải tuần tự và thứ ba, các bản sao lưu phải được kiểm tra khả năng khôi phục.

Thường thì sao lưu có nghĩa là cần phải tạo bản sao lưu khá thường xuyên, ví dụ như mỗi hai mươi bốn giờ một lần. Khoảng thời gian dữ liệu giữa các lần sao lưu cơ sở dữ liệu càng ngắn thì càng ít dữ liệu bị mất do sự cố. Tính tuần tự của sao lưu có nghĩa là số lượng bản sao lưu phải tăng lên và phải được lưu trữ ít nhất trong một tuần. Nếu có khả năng, cần phải ghi các bản sao lưu vào các thiết bị đặc biệt như streamer, nhưng nếu không có - chỉ cần sao chép chúng sang máy tính khác. Lịch sử của các bản sao lưu sẽ giúp phát hiện các hỏng hóc ẩn và xử lý lỗi phát sinh từ lâu và xuất hiện bất ngờ. Người ta phải kiểm tra xem có thể khôi phục bản sao lưu nhận được mà không có lỗi hay không. Điều này chỉ có thể được kiểm tra bằng một cách - thông qua quá trình khôi phục thử nghiệm. Cần phải nói rằng quá trình khôi phục mất thời gian gấp 3 lần so với sao lưu, và rất khó để thực hiện xác nhận khôi phục mỗi ngày đối với các cơ sở dữ liệu lớn, vì nó có thể làm gián đoạn công việc của người dùng trong vài giờ (thời gian nghỉ đêm có thể không đủ).

Sẽ tốt hơn nếu các tổ chức lớn không tiết kiệm “diêm” và để lại một máy tính cho các mục đích này.

Trong trường hợp này, nếu máy chủ phải làm việc với tải nghiêm trọng 24 giờ 7 ngày một tuần, chúng ta có thể sử dụng cơ chế SHADOW để chụp ảnh nhanh từ cơ sở dữ liệu và các hoạt động sao lưu tiếp theo từ bản sao trực tiếp. Quá trình sao lưu và khôi phục cơ sở dữ liệu được mô tả chi tiết trong chương “Sao lưu và khôi phục”. Khi tạo bản sao lưu và sau đó khôi phục cơ sở dữ liệu từ nó, việc tái tạo tất cả dữ liệu trong cơ sở dữ liệu đang diễn ra. Quá trình này (sao lưu/khôi phục hoặc b/r) góp phần sửa chữa hầu hết các lỗi không nghiêm trọng trong cơ sở dữ liệu, liên quan đến hỏng hóc đĩa cứng, phát hiện các vấn đề về tính toàn vẹn trong cơ sở dữ liệu, làm sạch cơ sở dữ liệu khỏi rác (các phiên bản cũ và các mảnh của bản ghi, các giao dịch không hoàn chỉnh), giảm kích thước cơ sở dữ liệu đáng kể.

B/r thường xuyên là sự đảm bảo an toàn cho cơ sở dữ liệu InterBase. Nếu cơ sở dữ liệu đang hoạt động, thì nên thực hiện b/r mỗi tuần. Nói thật, có một số minh họa về các cơ sở dữ liệu InterBase được sử dụng tích cực trong nhiều năm mà không cần sao lưu/khôi phục.

Tuy nhiên, để an toàn, nên thực hiện quy trình này, đặc biệt là vì nó có thể dễ dàng được tự động hóa (xem chương “Sao lưu”)

Nếu không thể thực hiện sao lưu/khôi phục thường xuyên vì một số lý do, thì người ta có thể sử dụng công cụ gfix để kiểm tra và khôi phục cơ sở dữ liệu. gfix cho phép kiểm tra và loại bỏ nhiều lỗi mà không cần b/r.

2.8. Công cụ dòng lệnh gfix

Công cụ dòng lệnh gfix được sử dụng để kiểm tra và khôi phục cơ sở dữ liệu. Ngoài ra, gfix cũng có thể thực hiện các hoạt động khác nhau của việc kiểm soát cơ sở dữ liệu: thay đổi phương ngữ cơ sở dữ liệu, thiết lập và hủy chế độ “chỉ đọc”, thiết lập kích thước bộ nhớ cache cho một cơ sở dữ liệu cụ thể và cũng một số chức năng quan trọng (bạn có thể biết về chúng trong InterBase 6 Operations Guide [4.) gfix được thực hiện ở chế độ dòng lệnh và có cú pháp sau:

Gfix [ tùy chọn] tên db

Tùy chọn - là một tập hợp các tùy chọn để thực hiện gfix, tên db là tên của cơ sở dữ liệu mà các hoạt động sẽ được thực hiện, được xác định bởi tập hợp các tùy chọn. Bảng 3 trình bày các tùy chọn gfix liên quan đến việc sửa chữa cơ sở dữ liệu:

Tùy chọn Mô tả
-f[ull] Tùy chọn này được sử dụng kết hợp với -v và
có nghĩa là đã đến lúc kiểm tra tất cả các mảnh của bản ghi
-i[gnore] Tùy chọn làm cho gfix bỏ qua các lỗi checksum tại
thời điểm xác nhận hoặc làm sạch cơ sở dữ liệu
-m[end] Đánh dấu các bản ghi bị hỏng là không khả dụng, kết
quả là chúng sẽ bị xóa trong quá trình
sao lưu/khôi phục tiếp theo. Tùy chọn được sử dụng tại
thời điểm chuẩn bị cơ sở dữ liệu bị hỏng cho b/r.
-n[o_update] Tùy chọn được sử dụng kết hợp với -v để
xác nhận cơ sở dữ liệu chỉ đọc mà không sửa chữa
các hỏng hóc
-pas[sword] Tùy chọn cho phép thiết lập mật khẩu khi
kết nối cơ sở dữ liệu. (Lưu ý rằng đó là lỗi trong
tài liệu InterBase -pa[ssword], nhưng
phím tắt “-pa” sẽ không hoạt động - hãy sử dụng “-pas” )
-user Tùy chọn cho phép thiết lập tên người dùng kết nối
cơ sở dữ liệu
-v[alidate] Tùy chọn cài đặt trước việc xác nhận cơ sở dữ liệu theo
cách mà các lỗi được phát hiện
-m[ode] Tùy chọn thiết lập chế độ ghi cho cơ sở dữ liệu - cho
chỉ đọc hoặc đọc/ghi. Tham số này có thể
chấp nhận 2 giá trị - read write hoặc read only.
-w[rite] {sync | async} Tùy chọn bật và tắt chế độ
ghi cưỡng bức đồng bộ/không đồng bộ vào
cơ sở dữ liệu. sync - để bật ghi đồng bộ
(FW ON); async - để bật ghi không đồng bộ
(FW OFF);

Bảng 1: Các tùy chọn công cụ gfix để khôi phục cơ sở dữ liệu

Có một số ví dụ điển hình về việc sử dụng gfix:

gfix -w sync -user SYSDBA -pass masterkey firstbase.gdb

Trong ví dụ này, chúng ta thiết lập cho cơ sở dữ liệu thử nghiệm firstbase.gdb của mình chế độ ghi đồng bộ (FW ON). (Tất nhiên, điều này hữu ích trước khi hỏng hóc xảy ra). Và dưới đây là lệnh đầu tiên bạn nên sử dụng để kiểm tra cơ sở dữ liệu sau khi hỏng hóc xảy ra:

gfix -v -full -user SYSDBA -pass masterkey firstbase.gdb

Trong ví dụ này, chúng ta bắt đầu kiểm tra cơ sở dữ liệu thử nghiệm của mình (tùy chọn -v) và chỉ ra rằng các mảnh của bản ghi cũng phải được kiểm tra (tùy chọn -full). Tất nhiên, sẽ thuận tiện hơn khi thiết lập các tùy chọn khác nhau cho quá trình kiểm tra và khôi phục bằng bất kỳ GUI nào, nhưng chúng ta sẽ xem xét các chức năng khôi phục cơ sở dữ liệu bằng các công cụ dòng lệnh. Các công cụ này được bao gồm trong InterBase và bạn có thể chắc chắn rằng hành vi của chúng sẽ giống nhau trên tất cả các hệ điều hành chạy InterBase. Điều rất quan trọng là chúng luôn ở gần.

Ngoài ra, các công cụ hiện có, cho phép thực hiện quản trị cơ sở dữ liệu từ máy tính của khách hàng sử dụng Services API cho việc đó, điều này không được hỗ trợ bởi kiến trúc máy chủ Classic của InterBase. Điều đó có nghĩa là bạn có thể sử dụng các sản phẩm của bên thứ ba với kiến trúc máy chủ SuperServer.

2.9. Việc sửa chữa cơ sở dữ liệu bị hỏng

Giả sử có một số lỗi trong cơ sở dữ liệu của chúng ta. Thứ nhất, chúng ta phải kiểm tra sự tồn tại của các lỗi này; thứ hai, chúng ta phải cố gắng sửa chữa các lỗi này. Bạn nên tuân theo các hướng dẫn sau.

Bạn nên dừng máy chủ InterBase nếu nó vẫn đang hoạt động và tạo một bản sao của tệp hoặc các tệp cơ sở dữ liệu. Tất cả các hoạt động khôi phục chỉ nên được thực hiện với bản sao cơ sở dữ liệu, vì cách đã chọn có thể dẫn đến kết quả không may, và bạn sẽ phải khởi động lại quy trình khôi phục (từ điểm bắt đầu). Sau khi tạo bản sao, chúng ta sẽ thực hiện toàn bộ việc xác nhận cơ sở dữ liệu (kiểm tra các mảnh của bản ghi).

Chúng ta nên thực hiện lệnh sau cho việc đó:

gfix -v - full corruptbase gdb -user SYSDBA - password

Trong trường hợp này corruptbase.gdb - là một bản sao của cơ sở dữ liệu bị hỏng. Lệnh sẽ kiểm tra cơ sở dữ liệu để tìm bất kỳ hỏng hóc cấu trúc nào và đưa ra danh sách các vấn đề chưa được giải quyết. Nếu các lỗi như vậy được phát hiện, chúng ta sẽ phải xóa dữ liệu bị hỏng và sẵn sàng cho việc sao lưu/khôi phục bằng lệnh sau:

gfix -mend -user SYSDBA -password your_masterkey corruptbase gdb

Sau khi thực hiện lệnh, bạn nên kiểm tra xem có còn lỗi nào trong cơ sở dữ liệu không. Bạn phải chạy gfix với các tùy chọn -v -full cho việc đó, và khi quá trình kết thúc, thực hiện sao lưu cơ sở dữ liệu:

gbak -b -v -ig -user SYSDBA -password corruptbase.gdb corruptbase.gbk

Lệnh này sẽ thực hiện sao lưu cơ sở dữ liệu (tùy chọn - b cho biết điều đó) và chúng ta sẽ nhận được thông tin chi tiết về quá trình thực hiện sao lưu (tùy chọn -v). Lỗi liên quan đến checksums sẽ được bỏ qua (tùy chọn - ig) Nếu bạn muốn biết thêm thông tin về các tùy chọn của công cụ dòng lệnh gbak, bạn có thể tìm thấy trong chương “Sao lưu và khôi phục” Nếu có một số lỗi với việc sao lưu, bạn nên bắt đầu nó trong một cấu hình khác:

gbak -b -v -ig -g -user SYSDBA -password corruptbase.gdb

corruptbase.gbk

Trong đó tùy chọn - g sẽ tắt thu gom rác trong quá trình sao lưu. Điều này thường giúp giải quyết vấn đề với việc sao lưu.

Cũng có thể tạo một bản sao lưu của cơ sở dữ liệu, nếu trước đó chúng ta đặt cơ sở dữ liệu ở chế độ chỉ đọc. Chế độ này ngăn chặn việc ghi bất kỳ sửa đổi nào vào cơ sở dữ liệu và đôi khi giúp thực hiện sao lưu cơ sở dữ liệu bị hỏng. Để đặt cơ sở dữ liệu ở chế độ chỉ đọc, bạn nên sử dụng lệnh sau: gfix -m read _only

-user SYSDBA -password masterkey Disk:\Path\file.gdb

Sau đó, bạn nên thử lại việc sao lưu cơ sở dữ liệu bằng các tham số đã nêu ở trên.

Nếu sao lưu thành công, bạn nên khôi phục cơ sở dữ liệu từ bản sao lưu. Bạn nên sử dụng lệnh sau:

gbak -c -user SYSDBA -password masterkey Disk:\Path\backup.gbk

Disk:\Path\newbase,gdb

Khi khôi phục cơ sở dữ liệu, bạn có thể gặp một số vấn đề, đặc biệt là khi tạo chỉ mục. Trong trường hợp này, các tùy chọn -inactive và -one_at_a_time nên được thêm vào lệnh khôi phục. Các tùy chọn này vô hiệu hóa chỉ mục trong quá trình tạo từ bản sao lưu cơ sở dữ liệu và xác nhận dữ liệu cho từng bảng.

2.10. Làm thế nào bạn có thể thử trích xuất dữ liệu từ cơ sở dữ liệu bị hỏng

Có thể các thao tác nêu trên sẽ không dẫn đến việc khôi phục cơ sở dữ liệu. Điều đó có nghĩa là cơ sở dữ liệu bị hỏng nghiêm trọng hoặc không thể khôi phục như một tổng thể duy nhất, hoặc phải tốn rất nhiều công sức để khôi phục. Ví dụ, bạn có thể thực hiện sửa đổi siêu dữ liệu hệ thống, sử dụng các hàm không được tài liệu hóa, v.v. Đây là một công việc rất khó khăn, kéo dài và không mang lại kết quả với cơ hội thành công mong manh. Và nếu có thể, hãy cố gắng tránh điều đó và sử dụng các phương pháp khác. Nếu cơ sở dữ liệu bị hỏng mở được và cho phép thực hiện các thao tác đọc và sửa đổi với một số dữ liệu, bạn nên tận dụng khả năng này và lưu dữ liệu bằng cách sao chép chúng vào một cơ sở dữ liệu mới, và “nói lời tạm biệt” với cơ sở dữ liệu cũ vĩnh viễn.

Vì vậy, trước khi chuyển dữ liệu từ cơ sở dữ liệu cũ, cần phải tạo một cơ sở dữ liệu đích. Nếu cơ sở dữ liệu đã không được thay đổi trong một thời gian dài, bạn có thể sử dụng bản sao lưu cũ, từ đó có thể trích xuất siêu dữ liệu để tạo cơ sở dữ liệu đích. Trên cơ sở siêu dữ liệu này, bạn phải tạo một cơ sở dữ liệu đích và bắt đầu sao chép dữ liệu. Nhiệm vụ chính là trích xuất dữ liệu từ cơ sở dữ liệu bị hỏng. Sau đó, chúng ta sẽ phải phân bổ dữ liệu vào một cơ sở dữ liệu mới, nhưng điều đó không quá khó khăn, ngay cả khi chúng ta phải khôi phục cấu trúc cơ sở dữ liệu từ trí nhớ. Khi trích xuất dữ liệu từ các bảng, bạn nên sử dụng thuật toán thao tác sau:

  • Trước tiên, bạn nên thử thực hiện SELECT* từ bảng N. Nếu nó diễn ra bình thường, bạn có thể lưu dữ liệu nhận được vào nguồn bên ngoài. Tốt hơn là lưu dữ liệu dưới dạng script (hầu hết các GUI đều cung cấp chức năng này), nếu bảng không chứa các trường BLOB. Nếu có các trường BLOB trong bảng, thì dữ liệu từ chúng nên được lưu vào một cơ sở dữ liệu khác bằng chương trình khách đóng vai trò trung gian. Có thể bạn sẽ phải viết chương trình đơn giản này đặc biệt cho mục đích khôi phục dữ liệu.
  • Nếu bạn không thể truy xuất tất cả dữ liệu, bạn nên xóa tất cả các chỉ mục và thử lại. Thực tế, các chỉ mục có thể được xóa khỏi tất cả các bảng ngay từ đầu quá trình khôi phục, vì chúng sẽ không còn cần thiết nữa. Tất nhiên, nếu bạn không có cấu trúc siêu dữ liệu giống với cấu trúc bị hỏng, cần phải ghi lại nhật ký tất cả các thao tác bạn đang thực hiện với cơ sở dữ liệu nguồn bị hỏng.
  • Nếu bạn không thể đọc tất cả dữ liệu từ bảng sau khi xóa các chỉ mục, bạn có thể thử truy vấn phạm vi theo khóa chính. Điều đó có nghĩa là chọn một phạm vi dữ liệu cụ thể. Ví dụ:

SELECT * FROM table N WHERE field_PK >=0 and field_PK <=10000 Field_PK

ở đây là khóa chính. InterBase có tổ chức dữ liệu theo trang và do đó truy vấn phạm vi giá trị có thể khá hiệu quả, mặc dù nó có vẻ giống như một kiểu pháp thuật. Tuy nhiên, nó vẫn hoạt động vì chúng ta có thể loại bỏ dữ liệu từ các trang bị hỏng trong truy vấn và đọc được các trang khác một cách may mắn. Bạn có thể nhớ lại luận điểm của chúng tôi rằng không có thứ tự xác định nào trong việc lưu trữ các bản ghi trong SQL. Thực sự, không ai đảm bảo rằng một truy vấn không có thứ tự trong các lần chạy lại sẽ trả về các bản ghi theo cùng một thứ tự, nhưng tuy nhiên, các bản ghi vật lý được lưu trữ trong cơ sở dữ liệu theo một thứ tự nội bộ xác định. Rõ ràng là máy chủ sẽ không trộn lẫn các bản ghi chỉ để tuân theo chuẩn SQL. Bạn có thể thử sử dụng thứ tự nội bộ này để trích xuất dữ liệu từ cơ sở dữ liệu bị hỏng (nếu bạn muốn biết thêm thông tin về các trang dữ liệu và mối tương quan của chúng, hãy xem chương “Cấu trúc cơ sở dữ liệu InterBase”).

Vitaliy Barmin, một trong những nhà phát triển InterBase giàu kinh nghiệm của Nga, đã báo cáo rằng bằng cách này, ông đã khôi phục được tới 98% thông tin từ cơ sở dữ liệu không thể khôi phục (có rất nhiều trang bị hỏng). Do đó, dữ liệu từ cơ sở dữ liệu bị hỏng phải được chuyển sang cơ sở dữ liệu mới hoặc vào các nguồn bên ngoài như script SQL. Khi sao chép dữ liệu, hãy chú ý đến các giá trị generator trong cơ sở dữ liệu bị hỏng (chúng phải được lưu lại để khởi động lại hoạt động đúng trong cơ sở dữ liệu mới. Nếu bạn không có bản sao đầy đủ của siêu dữ liệu, bạn nên trích xuất văn bản của các stored procedure, trigger, ràng buộc và định nghĩa chỉ mục.

2.11. Khôi phục cơ sở dữ liệu vô vọng

Nói chung, việc khôi phục cơ sở dữ liệu có thể rất rắc rối và khó khăn, và do đó tốt hơn là tạo bản sao lưu cơ sở dữ liệu hơn là khôi phục dữ liệu bị hỏng, và dù điều gì xảy ra, bạn cũng không nên tuyệt vọng vì một giải pháp có thể được tìm thấy trong những tình huống khó khăn nhất. Và bây giờ chúng ta sẽ xem xét 2 trường hợp.

Trường hợp đầu tiên (một vấn đề kinh điển). Một bản sao lưu không thể khôi phục vì có các giá trị NULL trong cột có ràng buộc NOT NULL (quá trình khôi phục được chạy trên tệp đang hoạt động). Tệp đang hoạt động đã bị xóa và quá trình khôi phục bị gián đoạn do lỗi. Và kết quả của những hành động thiếu suy nghĩ, chúng ta có một lượng lớn dữ liệu vô dụng (không thể khôi phục) thay vì bản sao lưu. Nhưng giải pháp đã được tìm thấy. Lập trình viên đã nhớ lại bảng nào và cột nào có ràng buộc NOT NULL. Tệp sao lưu được nạp vào trình soạn thảo thập lục phân. Và một tổ hợp byte tương ứng với định nghĩa của cột này đã được tìm thấy ở đó bằng cách tìm kiếm. Sau vô số thử nghiệm, hóa ra ràng buộc NOT NULL thêm 1 ở đâu đó gần tên cột. Trong trình soạn thảo HEX, “1” này đã được sửa thành “0” và bản sao lưu đã được khôi phục. Sau trường hợp đó, lập trình viên đã ghi nhớ mãi mãi cách thực hiện quá trình sao lưu và khôi phục.

Trường hợp thứ hai. Tình huống thảm khốc. Cơ sở dữ liệu bị hỏng ở giai đoạn mở rộng do thiếu dung lượng đĩa. Khi tăng kích thước cơ sở dữ liệu, máy chủ tạo ra một loạt các trang quan trọng (ví dụ: trang kiểm kê giao dịch và trang kiểm kê trang, các trang bổ sung cho quan hệ RDB$Pages) và ghi chúng vào cuối cơ sở dữ liệu. Kết quả là cơ sở dữ liệu không mở được bằng các công cụ quản trị hoặc tiện ích GBAK. Và khi chúng tôi cố gắng kết nối với cơ sở dữ liệu, thông báo lỗi (“Unexpected end of file”) xuất hiện.

Khi chúng tôi chạy tiện ích gfix, những điều kỳ lạ đã xảy ra: Chương trình hoạt động trong một vòng lặp vô tận. Khi gfix hoạt động, máy chủ ghi lỗi vào nhật ký (tệp InterBase log) với tốc độ cao (khoảng 100 Kb mỗi giây). Kết quả là, tệp nhật ký nhanh chóng lấp đầy toàn bộ dung lượng đĩa trống. Chúng tôi thậm chí phải viết một chương trình xóa nhật ký này theo bộ hẹn giờ. Quá trình này kéo dài trong một thời gian dài - gfix hoạt động hơn 16 giờ mà không có kết quả. Nhật ký được lấp đầy với các lỗi có dạng sau: “Page XXX doubly allocated”. Trong mã nguồn InterBase (trong tệp val.#) có một mô tả ngắn về lỗi này. Nó nói rằng lỗi này xuất hiện khi cùng một trang dữ liệu được sử dụng hai lần. Rõ ràng là lỗi này là kết quả của việc hỏng các trang quan trọng.

Kết quả là, sau vài ngày thử nghiệm không thành công, các nỗ lực khôi phục dữ liệu bằng các phương pháp tiêu chuẩn đã bị bỏ dở. Và đó là lý do tại sao chúng tôi phải sử dụng phân tích cấp thấp của dữ liệu được lưu trữ trong cơ sở dữ liệu bị hỏng.

Alexander Kozelskiy, trưởng phòng công nghệ thông tin của East View Publications Inc, là tác giả của ý tưởng trích xuất thông tin từ các cơ sở dữ liệu không thể khôi phục tương tự.

Phương pháp khôi phục mà chúng tôi có được từ kết quả nghiên cứu dựa trên thực tế rằng cơ sở dữ liệu có tổ chức trang và dữ liệu từ mỗi bảng được thu thập bởi các trang dữ liệu. Mỗi trang dữ liệu chứa định danh của bảng mà nó lưu trữ dữ liệu. Điều đặc biệt quan trọng là khôi phục dữ liệu từ một số bảng quan trọng. Có dữ liệu từ các bảng tương tự, nhận được từ một bản sao lưu cũ hoạt động hoàn hảo và có thể là một mẫu. Cơ sở dữ liệu mẫu được nạp vào trình soạn thảo mã thập lục phân và sau đó chúng tôi tìm kiếm các mẫu của dữ liệu mà chúng tôi quan tâm. Các dữ liệu này được sao chép vào bộ đệm ở định dạng thập lục phân và sau đó phần còn lại của cơ sở dữ liệu bị hỏng được nạp vào trình soạn thảo. Một chuỗi byte tương ứng với mẫu đã được tìm thấy trong cơ sở dữ liệu bị hỏng, và trang (nơi chuỗi này được tìm thấy) đã được phân tích.

Lúc đầu, chúng tôi xác định trang bắt đầu, nhưng điều đó không khó vì kích thước của tệp cơ sở dữ liệu chia hết cho kích thước trang dữ liệu. Số byte hiện tại chia cho kích thước trang - 8192 byte, làm tròn kết quả thành số nguyên (và có được số trang hiện tại). Sau đó nhân số trang hiện tại với kích thước trang và có được số byte tương ứng với phần đầu của trang hiện tại. Sau khi phân tích tiêu đề, chúng tôi xác định loại trang (đối với các trang có dữ liệu, loại là 5 - xem tệp ods.h từ bộ mã nguồn InterBase và cả chương “Cấu trúc cơ sở dữ liệu InterBase”) cũng như định danh của bảng cần thiết.

Sau đó, một chương trình đã được viết, phân tích toàn bộ cơ sở dữ liệu, thu thập tất cả các trang cho bảng cần thiết thành một mảnh duy nhất và chuyển nó vào tệp.

Vì vậy, khi chúng tôi có được dữ liệu cần thiết trước tiên, chúng tôi bắt đầu phân tích nội dung của các trang đã chọn. InterBase sử dụng rộng rãi việc nén dữ liệu để tiết kiệm không gian. Ví dụ, một chuỗi VARCHAR chứa chuỗi “ABC”, nó lưu trữ chuỗi các giá trị sau: độ dài chuỗi (2 byte), trong trường hợp của chúng tôi là 0003, và sau đó là các ký tự và sau đó là checksum. Chúng tôi phải viết trình phân tích chuỗi cũng như các loại cơ sở dữ liệu khác chuyển đổi dữ liệu từ định dạng thập lục phân sang dạng thông thường. Chúng tôi đã trích xuất được tới 80% thông tin từ một số bảng quan trọng bằng phương pháp “thủ công” phân tích nội dung cơ sở dữ liệu. Sau đó, dựa trên kinh nghiệm, Oleg Kulkov và Alexey Kovyazin, một trong những tác giả của cuốn sách này, đã phát triển tiện ích InterBase Surgeon thực hiện truy cập trực tiếp vào cơ sở dữ liệu, bỏ qua engine InterBase và cho phép đọc trực tiếp và diễn giải dữ liệu trong cơ sở dữ liệu InterBase một cách chính xác.

Sử dụng InterBase Surgeon, chúng tôi quản lý để phát hiện nguyên nhân hỏng hóc và khôi phục tới 90% các cơ sở dữ liệu hoàn toàn không thể khôi phục mà InterBase không thể mở và các phương pháp tiêu chuẩn không thể khôi phục.

Bạn có thể tải chương trình này từ trang web chính thức của chương trình www.ib-aid.com.

3. Lời cảm ơn

Tôi muốn gửi lời cảm ơn đến tất cả những người đã giúp tôi tạo ra hướng dẫn này:

Craig Stuntz, Alexander Nevsky, Konstantin Sipachev, Tatjana Sipacheva và tất cả những người tốt bụng và hiểu biết khác trong cộng đồng InterBase và Firebird.

Nếu bạn có bất kỳ gợi ý hoặc câu hỏi nào về chương này, xin vui lòng gửi email.

© 2002 AIexey Kovyazin, Serge Vostrikov.

Bản quyền © 2004 IBSurgeon Team. Mọi quyền được bảo lưu.