Cách giữ: sao lưu hàng ngày trong một tuần, hàng tuần trong một tháng, hàng tháng trong một năm và hàng năm sau đó


14

Tôi cần sao lưu dữ liệu và tập tin cấu hình trên máy chủ này, hàng ngày. Tôi cần giữ:

  • sao lưu hàng ngày trong một tuần
  • sao lưu hàng tuần trong một tháng
  • sao lưu hàng tháng trong một năm
  • sao lưu hàng năm sau đó

Tất cả điều này được thực hiện thông qua một tập lệnh shell chạy hàng ngày từ cron.

Đây là cách các tệp sao lưu sẽ trông sau 10 năm chạy:

blog-20050103.tar.bz2
blog-20060102.tar.bz2
blog-20070101.tar.bz2
blog-20080107.tar.bz2
blog-20090105.tar.bz2
blog-20100104.tar.bz2
blog-20110103.tar.bz2
blog-20120102.tar.bz2
blog-20130107.tar.bz2
blog-20130902.tar.bz2
blog-20131007.tar.bz2
blog-20131104.tar.bz2
blog-20131202.tar.bz2
blog-20140106.tar.bz2
blog-20140203.tar.bz2
blog-20140303.tar.bz2
blog-20140407.tar.bz2
blog-20140505.tar.bz2
blog-20140602.tar.bz2
blog-20140707.tar.bz2
blog-20140728.tar.bz2
blog-20140804.tar.bz2
blog-20140811.tar.bz2
blog-20140816.tar.bz2
blog-20140817.tar.bz2
blog-20140818.tar.bz2
blog-20140819.tar.bz2
blog-20140820.tar.bz2
blog-20140821.tar.bz2
blog-20140822.tar.bz2

9
... Đề xuất bình thường của tôi sẽ là "Sử dụng Bacula " (hoặc một số phần mềm sao lưu khác có thể xử lý việc giữ và xoay cho bạn) :-)
voretaq7

1
câu hỏi này khiến tôi viết cronicle < github.com/Kraymer/cronicle > vì câu trả lời được chấp nhận có khiếm khuyết rõ ràng là sao chép các bản sao lưu vào các thư mục hàng ngày / hàng tuần / vv. cronicle dựa vào symlink và đảm nhiệm việc xoay vòng, xóa các tập tin cơ bản khi không có thư mục nào chứa symlink trỏ đến nó.
kraymer

Câu trả lời:


29

Bạn đang nghiêm túc quá kỹ thuật này. Tệ.

Đây là một số mã giả:

  • Hằng ngày:
    • tạo một bản sao lưu, đưa vào daily thư mục
    • xóa mọi thứ trừ 7 dailybản sao lưu cuối cùng
  • Mỗi tuần:
    • tạo một bản sao lưu, đưa vào weekly thư mục
    • xóa tất cả mọi thứ trừ 5 weeklybản sao lưu cuối cùng
  • Mỗi tháng:
    • tạo một bản sao lưu, đưa vàomonthly thư mục
    • xóa mọi thứ trừ 12 monthlybản sao lưu cuối cùng
  • Mỗi năm:
    • tạo một bản sao lưu, đưa vàoyearly thư mục

Số lượng logic bạn phải thực hiện là như nhau, eh? HÔN.

Điều này có vẻ dễ dàng hơn:

s3cmd ls s3://backup-bucket/daily/ | \
    awk '$1 < "'$(date +%F -d '1 week ago')'" {print $4;}' | \
    xargs --no-run-if-empty s3cmd del

Hoặc, theo số lượng tập tin thay vì tuổi:

s3cmd ls s3://backup-bucket/daily/ | \
    awk '$1 != "DIR"' | \
    sort -r | \
    awk 'NR > 7 {print $4;}' | \
    xargs --no-run-if-empty s3cmd del

Tôi thực sự không có thư mục riêng. Nó được viết để kết xuất các tập tin vào một thùng S3. Khi mọi thứ ở một nơi, tổng số logic mà bạn cần triển khai là như nhau, bất kể bạn đi về nó như thế nào.
Florin Andrei

5
Rõ ràng là không.
MadHatter

6

Nếu bạn chỉ muốn giữ, ví dụ, 8 bản sao lưu hàng ngày và 5 bản sao lưu hàng tuần (mỗi chủ nhật), thì nó hoạt động như thế này:

for i in {0..7}; do ((keep[$(date +%Y%m%d -d "-$i day")]++)); done
for i in {0..4}; do ((keep[$(date +%Y%m%d -d "sunday-$((i+1)) week")]++)); done
echo ${!keep[@]}

Kể từ hôm nay (2014-11-10), điều này sẽ xuất ra:

20141012 20141019 20141026 20141102 20141103 20141104
20141105 20141106 20141107 20141108 20141109 20141110

Như một bài tập dành cho bạn, bạn chỉ cần xóa tất cả các tệp sao lưu có tên không xuất hiện trong keep -array.

Nếu bạn muốn giữ 13 bản sao lưu hàng tháng (chủ nhật đầu tiên của mỗi tháng) và 6 bản sao lưu hàng năm (chủ nhật đầu tiên của mỗi năm), mọi thứ sẽ phức tạp hơn một chút:

for i in {0..7}; do ((keep[$(date +%Y%m%d -d "-$i day")]++)); done
for i in {0..4}; do ((keep[$(date +%Y%m%d -d "sunday-$((i+1)) week")]++)); done
for i in {0..12}; do
        DW=$(($(date +%-W)-$(date -d $(date -d "$(date +%Y-%m-15) -$i month" +%Y-%m-01) +%-W)))
        for (( AY=$(date -d "$(date +%Y-%m-15) -$i month" +%Y); AY < $(date +%Y); AY++ )); do
                ((DW+=$(date -d $AY-12-31 +%W)))
        done
        ((keep[$(date +%Y%m%d -d "sunday-$DW weeks")]++))
done
for i in {0..5}; do
        DW=$(date +%-W)
        for (( AY=$(($(date +%Y)-i)); AY < $(date +%Y); AY++ )); do
                ((DW+=$(date -d $AY-12-31 +%W)))
        done
        ((keep[$(date +%Y%m%d -d "sunday-$DW weeks")]++))
done
echo ${!keep[@]}

Kể từ hôm nay (2014-11-10), điều này sẽ xuất ra:

20090104 20100103 20110102 20120101 20130106 20131103
20131201 20140105 20140202 20140302 20140406 20140504
20140601 20140706 20140803 20140907 20141005 20141012
20141019 20141026 20141102 20141103 20141104 20141105
20141106 20141107 20141108 20141109 20141110

Tương tự như trên, chỉ cần xóa tất cả các tập tin sao lưu không tìm thấy trong mảng này.


Đẹp, và tôi phải làm rm /dir/*.* except keep[@]thế nào?
takeshin

0

Như đã đề cập trong một bình luận, thông thường tốt nhất là ủy thác nhiệm vụ quản lý sao lưu cho một phần mềm quản lý sao lưu.

Nhưng đây là logic trong bash để xóa các bản sao lưu cũ hơn theo yêu cầu của bạn

#!/bin/sh

delete() {
    echo "Deleting $1"
}

DOW=$(date +%u)

if [ $DOW -eq 1 ]; then
    DATE_DAY=$(date -d "-28 days" +"%d")
    if [ $DATE_DAY -gt 7 ]; then
        DATE=$(date -d "-28 days" +"%Y-%m-%d")
        delete $DATE
    fi

    DATE_DAY=$(date -d "-364 days" +"%d")
    DATE_MONTH=$(date -d "-364 days" +"%m")
    if [ $DATE_DAY -le 7 ] && [ $DATE_MONTH -gt 1 ]; then
        DATE=$(date -d "-364 days" +"%Y-%m-%d")
        delete $DATE
    fi
else
    DATE=$(date -d "-7 days" +"%Y-%m-%d")
    delete $DATE
fi

Mã PHP hiển thị tệp nào sẽ tồn tại sau khi chạy trong 3520 ngày

https://ideone.com/n2ymQy

Array
(
    [0] => 2005-01-03
    [1] => 2006-01-02
    [2] => 2007-01-01
    [3] => 2008-01-07
    [4] => 2009-01-05
    [5] => 2010-01-04
    [6] => 2011-01-03
    [7] => 2012-01-02
    [8] => 2013-01-07
    [9] => 2013-09-02
    [10] => 2013-10-07
    [11] => 2013-11-04
    [12] => 2013-12-02
    [13] => 2014-01-06
    [14] => 2014-02-03
    [15] => 2014-03-03
    [16] => 2014-04-07
    [17] => 2014-05-05
    [18] => 2014-06-02
    [19] => 2014-07-07
    [20] => 2014-07-28
    [21] => 2014-08-04
    [22] => 2014-08-11
    [23] => 2014-08-16
    [24] => 2014-08-17
    [25] => 2014-08-18
    [26] => 2014-08-19
    [27] => 2014-08-20
    [28] => 2014-08-21
    [29] => 2014-08-22
)
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.