Sao lưu / Khôi phục cơ sở dữ liệu PostgreSQL được neo


155

Tôi đang cố gắng sao lưu / khôi phục cơ sở dữ liệu PostgreQuery như được giải thích trên trang web Docker, nhưng dữ liệu không được khôi phục.

Các khối lượng được sử dụng bởi hình ảnh cơ sở dữ liệu là:

VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]

và CMD là:

CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]

Tôi tạo bộ chứa DB bằng lệnh này:

docker run -it --name "$DB_CONTAINER_NAME" -d "$DB_IMAGE_NAME"

Sau đó, tôi kết nối một container khác để chèn một số dữ liệu theo cách thủ công:

docker run -it --rm --link "$DB_CONTAINER_NAME":db "$DB_IMAGE_NAME" sh -c 'exec bash'
psql -d test -h $DB_PORT_5432_TCP_ADDR
# insert some data in the db
<CTRL-D>
<CTRL-D>

Lưu trữ tar sau đó được tạo:

$ sudo docker run --volumes-from "$DB_CONTAINER_NAME" --rm -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /etc/postgresql /var/log/postgresql /var/lib/postgresql

Bây giờ tôi loại bỏ bộ chứa được sử dụng cho db và tạo một cái khác, có cùng tên và cố gắng khôi phục dữ liệu được chèn trước đó:

$ sudo docker run --volumes-from "$DB_CONTAINER_NAME" --rm -v $(pwd):/backup ubuntu tar xvf /backup/backup.tar 

Nhưng các bảng trống, tại sao dữ liệu không được khôi phục đúng cách?


Câu trả lời:


457

Sao lưu cơ sở dữ liệu của bạn

docker exec -t your-db-container pg_dumpall -c -U postgres > dump_`date +%d-%m-%Y"_"%H_%M_%S`.sql

Khôi phục cơ sở dữ liệu của bạn

cat your_dump.sql | docker exec -i your-db-container psql -U postgres

2
Đúng, đó là cách hậu kỳ để làm điều đó, nhưng tôi nghĩ rằng cách docker nên luôn luôn được ưa thích khi bạn sử dụng nó
Carl Levasseur

42
Để tiết kiệm dung lượng trên đĩa, bạn có thể muốn chuyển kết xuất sang gzip: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > /var/data/postgres/backups/dump_ngày +% d-% m-% Y "_"% H_% M_% S.gz
Tarion

1
Chỉ cần giải nén dữ liệu trước khi bạn khôi phục nó. Để làm điều đó như là một lớp lót, bạn sẽ phải thay thế cat your_dump.sqlbằng lệnh giải nén và đường ống thay vì catkết quả cho docker exec.
Tarion

2
Định dạng ngày bị rối, vì vậy hãy kiểm tra kỹ trước khi sao chép và dán.
vidstige

1
Đối với những người không thể tìm ra cách để định dạng ngày hoạt động: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > ./tmp/dump_$(date +"%Y-%m-%d_%H_%M_%S").gz
user1230795

18

Tôi nghĩ bạn cũng có thể sử dụng một thùng chứa dự phòng potgres để sao lưu cơ sở dữ liệu của bạn trong một khoảng thời gian nhất định.

  pgbackups:
    container_name: Backup
    image: prodrigestivill/postgres-backup-local
    restart: always
    volumes:
      - ./backup:/backups
    links:
      - db:db
    depends_on:
      - db
    environment:
      - POSTGRES_HOST=db
      - POSTGRES_DB=${DB_NAME} 
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_EXTRA_OPTS=-Z9 --schema=public --blobs
      - SCHEDULE=@every 0h30m00s
      - BACKUP_KEEP_DAYS=7
      - BACKUP_KEEP_WEEKS=4
      - BACKUP_KEEP_MONTHS=6
      - HEALTHCHECK_PORT=81

1
Hoạt động hoàn hảo! Cảm ơn
CaM2091

15

Được rồi, tôi đã tìm ra điều này. Postgresql không phát hiện các thay đổi đối với thư mục / var / lib / postgresql sau khi được khởi chạy, ít nhất không phải là loại thay đổi tôi muốn nó phát hiện.

Giải pháp đầu tiên là khởi động một container bằng bash thay vì khởi động trực tiếp máy chủ postgres, khôi phục dữ liệu và sau đó khởi động máy chủ theo cách thủ công.

Giải pháp thứ hai là sử dụng một thùng chứa dữ liệu. Tôi đã không nhận được điểm của nó trước đây, bây giờ tôi làm. Bộ chứa dữ liệu này cho phép khôi phục dữ liệu trước khi bắt đầu bộ chứa postgres. Do đó, khi máy chủ postgres khởi động, dữ liệu đã ở đó.


1
flocker hoặc đoàn xe có thể giúp xử lý container dữ liệu.
Forth

24
Vui lòng điền thêm chi tiết. Điều này nghe có vẻ giống như một bản phác thảo của một giải pháp hơn là một giải pháp thực tế
nafg

5

Một cách tiếp cận khác (dựa trên luồng công việc docker-postgresql )

Cơ sở dữ liệu đang chạy cục bộ (không phải trong docker, nhưng cách tiếp cận tương tự sẽ hoạt động) để xuất:

pg_dump -F c -h localhost mydb -U postgres export.dmp

Cơ sở dữ liệu container để nhập:

docker run -d -v /local/path/to/postgres:/var/lib/postgresql/data postgres #ex runs container as `CONTAINERNAME` #find via `docker ps`
docker run -it --link CONTAINERNAME:postgres  --volume $PWD/:/tmp/  postgres  bash -c 'exec pg_restore -h postgres -U postgres -d mydb -F c /tmp/sonar.dmp'

1
điều này làm việc cho tôi: pg_dump mydb -U postgres > export.psqltrong bash container docker
Sepultura

3

Tôi đã gặp vấn đề này trong khi cố gắng sử dụng db_dump để khôi phục db. Tôi thường sử dụng dbeaver để khôi phục - tuy nhiên đã nhận được kết xuất psql, vì vậy phải tìm ra một phương thức để khôi phục bằng cách sử dụng bộ chứa docker.

Phương pháp được đề xuất bởi Forth và được chỉnh sửa bởi Soviut đã làm việc cho tôi:

cat your_dump.sql | docker exec -i your-db-container psql -U postgres -d dbname

(vì đây là một kết xuất db duy nhất và không bao gồm nhiều db. Tôi đã bao gồm tên)

Tuy nhiên, để làm cho nó hoạt động, tôi cũng phải truy cập vào virtualenv mà container và dự án docker. Điều này đã lảng tránh tôi một chút trước khi nhận ra - vì tôi đã nhận được lỗi docker sau.

read unix @->/var/run/docker.sock: read: connection reset by peer

Điều này có thể được gây ra bởi tệp /var/lib/docker/network/files/local-kv.db. Tôi không biết tính chính xác của tuyên bố này: nhưng tôi tin rằng tôi đã thấy điều này vì tôi không sử dụng docker cục bộ, do đó, không có tệp này, mà nó đang tìm kiếm, sử dụng câu trả lời của Forth.

Sau đó tôi đã điều hướng đến đúng thư mục (với dự án) kích hoạt virtualenv và sau đó chạy câu trả lời được chấp nhận. Boom, làm việc như một đỉnh. Hy vọng điều này sẽ giúp người khác ngoài kia!


1

Đây là lệnh làm việc cho tôi.

cat your_dump.sql | sudo docker exec -i {docker-postgres-container} psql -U {user} -d {database_name}

ví dụ

cat table_backup.sql | docker exec -i 03b366004090 psql -U postgres -d postgres

Tham khảo : Giải pháp được đưa ra bởi GMartinez-Sisti trong cuộc thảo luận này. https://gist.github.com/gilyes/525cc0f471aafae18c3857c27519fc4b


1

cat db.dump | docker exec ...cách không hoạt động cho bãi chứa của tôi (~ 2Gb). Phải mất vài giờ và kết thúc với lỗi hết bộ nhớ.

Thay vào đó, tôi đã đổ rác vào container và pg_restore'ed từ bên trong.

Giả sử rằng id container là CONTAINER_IDvà tên db là DB_NAME:

# copy dump into container
docker cp local/path/to/db.dump CONTAINER_ID:/db.dump

# shell into container
docker exec -it CONTAINER_ID bash

# restore it from within
pg_restore -U postgres -d DB_NAME --no-owner -1 /db.dump

0

dksnap( https://github.com/kelda/dksnap ) tự động hóa quá trình chạy pg_dumpallvà tải bãi chứa thông qua /docker-entrypoint-initdb.d.

Nó hiển thị cho bạn một danh sách các container đang chạy và bạn chọn cái nào bạn muốn sao lưu. Hiện vật kết quả là một hình ảnh Docker thông thường, do đó bạn có thể sau đó docker runhoặc chia sẻ nó bằng cách đẩy nó vào một đăng ký Docker.

(từ chối trách nhiệm: Tôi là người duy trì dự án)


0

Lệnh dưới đây có thể được sử dụng để lấy kết xuất từ ​​thùng chứa sau docker

docker exec -t <postgres-container-name> pg_dump --no-owner -U <db-username> <db-name> > file-name-to-backup-to.sql
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.