Bản sao không phải là bản sao lưu. Hay không? Đây là cách chúng tôi sử dụng bản sao trì hoãn để khôi phục sau khi vô tình xóa các phím tắt.
Bản sao không phải là phương tiện sao lưu cơ sở dữ liệu (gitlab-ce
Với bản sao trả chậm, chúng tôi đã khôi phục dữ liệu chỉ trong 1,5 giờ. Hãy nhìn xem nó đã xảy ra như thế nào.
Phục hồi tại thời điểm với PostgreSQL
PostgreSQL có chức năng tích hợp sẵn để khôi phục trạng thái của cơ sở dữ liệu về một thời điểm cụ thể. Nó được gọi là
Để sử dụng tính năng này cho việc sao lưu nguội, chúng tôi thường xuyên tạo bản sao lưu cơ sở dữ liệu cơ bản và lưu trữ nó trong kho lưu trữ (kho lưu trữ GitLab nằm trong
Sao chép trì hoãn là gì?
Sao chép lười biếng là việc áp dụng các thay đổi từ WAL với độ trễ. Tức là giao dịch diễn ra trong một giờ X
, nhưng nó sẽ xuất hiện trong bản sao với độ trễ d
trong một tiếng nữa X + d
.
PostgreSQL có 2 cách để thiết lập bản sao cơ sở dữ liệu vật lý: khôi phục bản sao lưu và sao chép trực tuyến.
Cách thiết lập khôi phục bị trì hoãn từ kho lưu trữ
recovery.conf
. Thí dụ:
standby_mode = 'on'
restore_command = '/usr/bin/envdir /etc/wal-e.d/env /opt/wal-e/bin/wal-e wal-fetch -p 4 "%f" "%p"'
recovery_min_apply_delay = '8h'
recovery_target_timeline = 'latest'
Với các tham số này, chúng tôi đã định cấu hình một bản sao bị trì hoãn với tính năng khôi phục bản sao lưu. Ở đây nó được sử dụng restore_command
) từ kho lưu trữ và các thay đổi sẽ được áp dụng sau tám giờ (recovery_min_apply_delay
). Bản sao sẽ theo dõi các thay đổi về dòng thời gian trong kho lưu trữ, chẳng hạn như do chuyển đổi dự phòng cụm (recovery_target_timeline
).
С recovery_min_apply_delay
Bạn có thể thiết lập sao chép phát trực tuyến với độ trễ, nhưng có một số cạm bẫy ở đây liên quan đến các khe sao chép, phản hồi ở chế độ chờ nóng, v.v. Kho lưu trữ WAL cho phép bạn tránh chúng.
Thông số recovery_min_apply_delay
chỉ xuất hiện trong PostgreSQL 9.3. Ở các phiên bản trước, để sao chép hoãn lại, bạn cần định cấu hình tổ hợp pg_xlog_replay_pause(), pg_xlog_replay_resume()
) hoặc giữ các phân đoạn WAL trong kho lưu trữ trong suốt thời gian trì hoãn.
PostgreSQL làm điều này như thế nào?
Thật thú vị khi xem PostgreSQL triển khai phục hồi lười biếng như thế nào. Chúng ta hãy nhìn vào recoveryApplyDelay(XlogReaderState)
static bool
recoveryApplyDelay(XLogReaderState *record)
{
uint8 xact_info;
TimestampTz xtime;
long secs;
int microsecs;
/* nothing to do if no delay configured */
if (recovery_min_apply_delay <= 0)
return false;
/* no delay is applied on a database not yet consistent */
if (!reachedConsistency)
return false;
/*
* Is it a COMMIT record?
*
* We deliberately choose not to delay aborts since they have no effect on
* MVCC. We already allow replay of records that don't have a timestamp,
* so there is already opportunity for issues caused by early conflicts on
* standbys.
*/
if (XLogRecGetRmid(record) != RM_XACT_ID)
return false;
xact_info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
if (xact_info != XLOG_XACT_COMMIT &&
xact_info != XLOG_XACT_COMMIT_PREPARED)
return false;
if (!getRecordTimestamp(record, &xtime))
return false;
recoveryDelayUntilTime =
TimestampTzPlusMilliseconds(xtime, recovery_min_apply_delay);
/*
* Exit without arming the latch if it's already past time to apply this
* record
*/
TimestampDifference(GetCurrentTimestamp(), recoveryDelayUntilTime,
&secs, µsecs);
if (secs <= 0 && microsecs <= 0)
return false;
while (true)
{
// Shortened:
// Use WaitLatch until we reached recoveryDelayUntilTime
// and then
break;
}
return true;
}
Điểm mấu chốt là độ trễ dựa trên thời gian vật lý được ghi trong dấu thời gian cam kết giao dịch (xtime
). Như bạn có thể thấy, độ trễ chỉ áp dụng cho các cam kết và không ảnh hưởng đến các mục khác - tất cả các thay đổi đều được áp dụng trực tiếp và cam kết bị trì hoãn, vì vậy chúng ta sẽ chỉ thấy các thay đổi sau độ trễ được định cấu hình.
Cách sử dụng bản sao bị trì hoãn để khôi phục dữ liệu
Giả sử chúng ta có một cụm cơ sở dữ liệu và một bản sao bị chậm trễ XNUMX giờ trong quá trình sản xuất. Hãy xem cách khôi phục dữ liệu bằng một ví dụ
Khi tìm hiểu vấn đề, chúng tôi
SELECT pg_xlog_replay_pause();
Khi tạm dừng, chúng tôi không gặp rủi ro rằng bản sao sẽ lặp lại yêu cầu DELETE
. Một điều hữu ích nếu bạn cần thời gian để tìm hiểu mọi thứ.
Vấn đề là bản sao bị trì hoãn phải đến thời điểm trước khi có yêu cầu DELETE
. Chúng tôi đã biết gần đúng thời gian thực tế của việc loại bỏ. Chúng tôi đã xóa recovery_min_apply_delay
và thêm recovery_target_time
в recovery.conf
. Đây là cách bản sao đến đúng thời điểm mà không bị chậm trễ:
recovery_target_time = '2018-10-12 09:25:00+00'
Với dấu thời gian, tốt hơn hết bạn nên giảm bớt phần thừa để không bỏ sót. Đúng, mức giảm càng lớn thì chúng ta càng mất nhiều dữ liệu. Một lần nữa, nếu chúng ta bỏ lỡ yêu cầu DELETE
, mọi thứ sẽ bị xóa một lần nữa và bạn sẽ phải bắt đầu lại (hoặc thậm chí sao lưu nguội cho PITR).
Chúng tôi đã khởi động lại phiên bản Postgres bị trì hoãn và các phân đoạn WAL được lặp lại cho đến thời gian được chỉ định. Bạn có thể theo dõi tiến trình ở giai đoạn này bằng cách hỏi:
SELECT
-- current location in WAL
pg_last_xlog_replay_location(),
-- current transaction timestamp (state of the replica)
pg_last_xact_replay_timestamp(),
-- current physical time
now(),
-- the amount of time still to be applied until recovery_target_time has been reached
'2018-10-12 09:25:00+00'::timestamptz - pg_last_xact_replay_timestamp() as delay;
Nếu dấu thời gian không còn thay đổi thì quá trình khôi phục đã hoàn tất. Hành động có thể được tùy chỉnh recovery_target_action
Cơ sở dữ liệu đã trở lại trạng thái trước yêu cầu đáng tiếc đó. Ví dụ: bây giờ bạn có thể xuất dữ liệu. Chúng tôi đã xuất dữ liệu nhãn đã xóa và tất cả các liên kết đến các vấn đề cũng như các yêu cầu hợp nhất rồi chuyển chúng vào cơ sở dữ liệu sản xuất. Nếu tổn thất quy mô lớn, bạn chỉ cần quảng bá bản sao và sử dụng nó làm bản chính. Nhưng sau đó tất cả những thay đổi sau thời điểm mà chúng ta đã phục hồi sẽ bị mất.
Thay vì sử dụng dấu thời gian, tốt hơn nên sử dụng ID giao dịch. Sẽ rất hữu ích khi ghi lại các ID này, ví dụ: cho các câu lệnh DDL (chẳng hạn như DROP TABLE
), bằng cách sử dụng log_statements = 'ddl'
. Nếu chúng tôi có ID giao dịch, chúng tôi sẽ lấy recovery_target_xid
và chạy mọi thứ đến giao dịch trước khi có yêu cầu DELETE
.
Quay lại làm việc rất đơn giản: xóa tất cả thay đổi khỏi recovery.conf
và khởi động lại Postgres. Bản sao sẽ sớm bị trễ tám giờ và chúng tôi đã chuẩn bị cho những rắc rối trong tương lai.
Quyền lợi phục hồi
Với bản sao trả chậm thay vì bản sao lưu nguội, bạn không phải mất hàng giờ để khôi phục toàn bộ hình ảnh từ kho lưu trữ. Ví dụ: chúng tôi phải mất 2 giờ để có được toàn bộ bản sao lưu cơ bản XNUMX TB. Và sau đó bạn vẫn phải áp dụng toàn bộ WAL hàng ngày để khôi phục về trạng thái mong muốn (trong trường hợp xấu nhất).
Bản sao hoãn lại tốt hơn bản sao lưu nguội theo hai cách:
- Không cần phải xóa toàn bộ bản sao lưu cơ bản khỏi kho lưu trữ.
- Có một khoảng thời gian tám giờ cố định cho các phân đoạn WAL phải được lặp lại.
Chúng tôi cũng liên tục kiểm tra xem liệu có thể tạo PITR từ WAL hay không và chúng tôi sẽ nhanh chóng nhận thấy lỗi hỏng hoặc các vấn đề khác với kho lưu trữ WAL bằng cách theo dõi độ trễ của bản sao bị trì hoãn.
Trong ví dụ này, chúng tôi mất 50 phút để khôi phục, nghĩa là tốc độ là 110 GB dữ liệu WAL mỗi giờ (bản lưu trữ vẫn bật
Kết quả: nơi mà bản sao hoãn lại hữu ích (và nơi nào không)
Sử dụng bản sao bị trì hoãn làm cách sơ cứu nếu bạn vô tình làm mất dữ liệu và nhận thấy sự cố này trong độ trễ đã định cấu hình.
Nhưng hãy nhớ: bản sao không phải là bản sao lưu.
Sao lưu và sao chép có các mục đích khác nhau. Một bản sao lưu lạnh sẽ có ích nếu bạn vô tình thực hiện DELETE
hoặc DROP TABLE
. Chúng tôi tạo bản sao lưu từ kho lưu trữ lạnh và khôi phục trạng thái trước đó của bảng hoặc toàn bộ cơ sở dữ liệu. Nhưng đồng thời yêu cầu DROP TABLE
gần như được sao chép ngay lập tức trong tất cả các bản sao trên cụm làm việc, vì vậy việc sao chép thông thường sẽ không giúp ích được gì ở đây. Bản thân bản sao giữ cho cơ sở dữ liệu luôn sẵn sàng khi các máy chủ riêng lẻ được thuê và phân phối tải.
Ngay cả với bản sao trả chậm, đôi khi chúng tôi thực sự cần một bản sao lưu lạnh ở một nơi an toàn nếu xảy ra lỗi trung tâm dữ liệu, hư hỏng tiềm ẩn hoặc các sự kiện khác không thể nhận thấy ngay lập tức. Bản sao một mình là không sử dụng ở đây.
Ghi. Trên
Nguồn: www.habr.com