sql >> データベース >  >> RDS >> PostgreSQL

pg_dumpとpg_dumpallを使用してPostgreSQLをバックアップする

    ビジネスとサービスは、データに基づいて価値を提供します。可用性、一貫した状態、および耐久性は、顧客とエンドユーザーを満足させるための最優先事項です。データが失われたりアクセスできなくなったりすると、顧客が失われる可能性があります。

    データベースのバックアップは、日常の運用とタスクの最前線にある必要があります。

    データが破損または失われた場合に備えておく必要があります。

    私は、聞いたことがある古いことわざを固く信じています。「 必要でなくてもよいよりも、必要でなくてもよい "

    これはデータベースのバックアップにも当てはまります。それらがなければ、基本的に何もありません。データに何も起こり得ないという考えに基づいて行動することは誤りです。

    ほとんどのDBMSは、組み込みのバックアップユーティリティのいくつかの手段を提供します。 PostgreSQLにはすぐに使えるpg_dumpとpg_dumpallがあります。

    どちらも、多数のカスタマイズと構造化のオプションを提供します。それらすべてを1つのブログ投稿で個別にカバーすることはほぼ不可能です。代わりに、自己啓発/学習環境に最もよく適用できる例を見ていきます。

    そうは言っても、このブログ投稿は本番環境を対象としていません。ほとんどの場合、単一のワークステーション/開発環境が最もメリットがあります。

    pg_dumpおよびpg_dumpallとは何ですか?

    ドキュメントでは、pg_dumpを次のように説明しています。「pg_dumpはPostgreSQLデータベースをバックアップするためのユーティリティです」

    また、pg_dumpallのドキュメント:「pg_dumpallは、クラスターのすべてのPostgreSQLデータベースを1つのスクリプトファイルに書き出す(「ダンプする」)ためのユーティリティです。」

    データベースやテーブルのバックアップ

    まず、以下のSQLを使用して使用する練習用データベースといくつかのテーブルを作成します。

    postgres=# CREATE DATABASE example_backups;
    CREATE DATABASE
    example_backups=# CREATE TABLE students(id INTEGER,
    example_backups(# f_name VARCHAR(20),
    example_backups(# l_name VARCHAR(20));
    CREATE TABLE
    example_backups=# CREATE TABLE classes(id INTEGER,
    example_backups(# subject VARCHAR(20));
    CREATE TABLE
    example_backups=# INSERT INTO students(id, f_name, l_name)
    example_backups-# VALUES (1, 'John', 'Thorn'), (2, 'Phil', 'Hampt'),
    example_backups-# (3, 'Sue', 'Dean'), (4, 'Johnny', 'Rames');
    INSERT 0 4
    example_backups=# INSERT INTO classes(id, subject)
    example_backups-# VALUES (1, 'Math'), (2, 'Science'),
    example_backups-# (3, 'Biology');
    INSERT 0 3
    example_backups=# \dt;
             List of relations
    Schema |   Name | Type  | Owner
    --------+----------+-------+----------
    public | classes  | table | postgres
    public | students | table | postgres
    (2 rows)
    example_backups=# SELECT * FROM students;
    id | f_name | l_name
    ----+--------+--------
     1 | John   | Thorn
     2 | Phil   | Hampt
     3 | Sue    | Dean
     4 | Johnny | Rames
    (4 rows)
    example_backups=# SELECT * FROM classes;
    id | subject
    ----+---------
     1 | Math
     2 | Science
     3 | Biology
    (3 rows)

    データベースとテーブルがすべてセットアップされました。

    注:

    これらの例の多くでは、psqlの\!を利用します。メタコマンド。シェル(コマンドライン)にドロップするか、後続のシェルコマンドを実行できます。

    ターミナルまたはコマンドラインセッション(このブログ投稿では先頭の「$」で示されています)では、\! meta-commandは、pg_dumpまたはpg_dumpallコマンドのいずれにも含めないでください。繰り返しになりますが、これはpsql内の便利なメタコマンドです。

    単一のテーブルのバックアップ

    この最初の例では、studentsテーブルのみをダンプします:

    example_backups=# \! pg_dump -U postgres -t students example_backups > ~/Example_Dumps/students.sql.

    ディレクトリの内容を一覧表示すると、ファイルがそこにあることがわかります:

    example_backups=# \! ls -a ~/Example_Dumps
    .  .. students.sql

    この個々のコマンドのコマンドラインオプションは次のとおりです。

    • -U postgres:指定されたユーザー名
    • -tの学生:ダンプするテーブル
    • example_backups:データベース

    Student.sqlファイルには何が含まれていますか?

    $ cat students.sql
    --
    -- PostgreSQL database dump
    --
    -- Dumped from database version 10.4 (Ubuntu 10.4-2.pgdg16.04+1)
    -- Dumped by pg_dump version 10.4 (Ubuntu 10.4-2.pgdg16.04+1)
    SET statement_timeout = 0;
    SET lock_timeout = 0;
    SET idle_in_transaction_session_timeout = 0;
    SET client_encoding = 'UTF8';
    SET standard_conforming_strings = on;
    SELECT pg_catalog.set_config('search_path', '', false);
    SET check_function_bodies = false;
    SET client_min_messages = warning;
    SET row_security = off;
     
    SET default_tablespace = '';
     
    SET default_with_oids = false;
     
    --
    -- Name: students; Type: TABLE; Schema: public; Owner: postgres
    --
    CREATE TABLE public.students (
       id integer,
       f_name character varying(20),
       l_name character varying(20)
    );
     
    ALTER TABLE public.students OWNER TO postgres;
     
    --
    -- Data for Name: students; Type: TABLE DATA; Schema: public; Owner: postgres
    --
    COPY public.students (id, f_name, l_name) FROM stdin;
    1 John Thorn
    2 Phil Hampt
    3 Sue Dean
    4 Johnny Rames
    \.
    --
    -- PostgreSQL database dump complete

    テーブルの生徒を再作成して再入力するために必要なSQLコマンドがファイルに含まれていることがわかります。

    しかし、バックアップは良いですか?信頼性が高く、機能していますか?

    テストして確認します。

    example_backups=# DROP TABLE students;
    DROP TABLE
    example_backups=# \dt;
             List of relations
    Schema |  Name | Type  | Owner
    --------+---------+-------+----------
    public | classes | table | postgres
    (1 row)

    なくなった。

    次に、コマンドラインから保存したバックアップをpsqlに渡します。

    $ psql -U postgres -W -d example_backups -f ~/Example_Dumps/students.sql
    Password for user postgres:
    SET
    SET
    SET
    SET
    SET
    set_config
    ------------
    (1 row)
     
    SET
    SET
    SET
    SET
    SET
    CREATE TABLE
    ALTER TABLE
    COPY 4

    データベースで確認しましょう:

    example_backups=# \dt;
             List of relations
    Schema |   Name | Type  | Owner
    --------+----------+-------+----------
    public | classes  | table | postgres
    public | students | table | postgres
    (2 rows)
    example_backups=# SELECT * FROM students;
    id | f_name | l_name
    ----+--------+--------
     1 | John   | Thorn
     2 | Phil   | Hampt
     3 | Sue    | Dean
     4 | Johnny | Rames
    (4 rows)

    テーブルとデータが復元されました。

    複数のテーブルのバックアップ

    次の例では、次のコマンドを使用して両方のテーブルをバックアップします。

    example_backups=# \! pg_dump -U postgres -W -t classes -t students -d example_backups > ~/Example_Dumps/all_tables.sql
    Password:

    (最初の例では指定しなかった-Wオプションのため、このコマンドでパスワードを指定する必要があることに注意してください。これについては後で詳しく説明します。)

    ディレクトリの内容を一覧表示して、ファイルが作成されたことをもう一度確認しましょう。

    example_backups=# \! ls -a ~/Example_Dumps
    .  .. all_tables.sql  students.sql

    次に、テーブルを削除します:

    example_backups=# DROP TABLE classes;
    DROP TABLE
    example_backups=# DROP TABLE students;
    DROP TABLE
    example_backups=# \dt;
    Did not find any relations.

    次に、all_tables.sqlバックアップファイルを使用して復元します。

    $ psql -U postgres -W -d example_backups -f ~/Example_Dumps/all_tables.sql
    Password for user postgres:
    SET
    SET
    SET
    SET
    SET
    set_config
    ------------
    (1 row)
     
    SET
    SET
    SET
    SET
    SET
    CREATE TABLE
    ALTER TABLE
    CREATE TABLE
    ALTER TABLE
    COPY 3
    COPY 4
    example_backups=# \dt;
             List of relations
    Schema |   Name | Type  | Owner
    --------+----------+-------+----------
    public | classes  | table | postgres
    public | students | table | postgres
    (2 rows)

    両方のテーブルが復元されました。

    pg_dumpでわかるように、特定のデータベース内の1つまたは複数のテーブルをバックアップできます。

    データベースのバックアップ

    ここで、example_backupsデータベース全体をpg_dumpでバックアップする方法を見てみましょう。

    example_backups=# \! pg_dump -U postgres -W -d example_backups > ~/Example_Dumps/ex_back_db.sql
    Password:
     
    example_backups=# \! ls -a ~/Example_Dumps
    .  .. all_tables.sql  ex_back_db.sql students.sql

    ex_back_db.sqlファイルがあります。

    example_backupsデータベースを削除するためにpostgresデータベースに接続します。

    postgres=# DROP DATABASE example_backups;
    DROP DATABASE

    次に、コマンドラインから復元します:

    $ psql -U postgres -W -d example_backups -f ~/Example_Dumps/ex_back_db.sql
    Password for user postgres:
    psql: FATAL:  database "example_backups" does not exist

    ありません。なぜだめですか?そして、それはどこにありますか?

    最初に作成する必要があります。

    postgres=# CREATE DATABASE example_backups;
    CREATE DATABASE

    次に、同じコマンドで復元します:

    $ psql -U postgres -W -d example_backups -f ~/Example_Dumps/ex_back_db.sql
    Password for user postgres:
    SET
    SET
    SET
    SET
    SET
    set_config
    ------------
    (1 row)
     
    SET
    SET
    SET
    CREATE EXTENSION
    COMMENT
    SET
    SET
    CREATE TABLE
    ALTER TABLE
    CREATE TABLE
    ALTER TABLE
    COPY 3
    COPY 4
    postgres=# \c example_backups;
    You are now connected to database "example_backups" as user "postgres".
    example_backups=# \dt;
             List of relations
    Schema |   Name | Type  | Owner
    --------+----------+-------+----------
    public | classes  | table | postgres
    public | students | table | postgres
    (2 rows)

    データベースとすべてのテーブルが存在し、説明されています。

    バックアップを取るときに-Cオプションを含めることで、最初にターゲットデータベースを作成する必要があるというこのシナリオを回避できます。

    example_backups=# \! pg_dump -U postgres -W -C -d example_backups > ~/Example_Dumps/ex_back2_db.sql
    Password:

    postgresデータベースに再接続し、example_backupsデータベースを削除して、復元がどのように機能するかを確認します(簡潔にするために、これらのconnectコマンドとDROPコマンドは表示されていません)。

    次に、コマンドラインで(-d dbnameオプションが含まれていないことに注意してください):

    $ psql -U postgres -W -f ~/Example_Dumps/ex_back2_db.sql
    Password for user postgres:
    ……………..
    (And partway through the output...)
    CREATE DATABASE
    ALTER DATABASE
    Password for user postgres:
    You are now connected to database "example_backups" as user "postgres".
    SET
    SET
    SET
    SET
    SET
    set_config
    ------------
    (1 row)
     
    SET
    SET
    SET
    CREATE EXTENSION
    COMMENT
    SET
    SET
    CREATE TABLE
    ALTER TABLE
    CREATE TABLE
    ALTER TABLE
    COPY 3
    COPY 4

    -Cオプションを使用すると、-Cフラグに関するドキュメントに記載されているように、接続を確立するためのパスワードの入力を求められます。

    「データベース自体を作成し、作成されたデータベースに再接続するコマンドで出力を開始します。」

    次に、psqlセッションで:

    postgres=# \c example_backups;
    You are now connected to database "example_backups" as user "postgres".

    すべてが復元され、準備が整い、復元前にターゲットデータベースを作成する必要がなくなります。

    クラスター全体のpg_dumpall

    これまでに、単一のテーブル、複数のテーブル、および単一のデータベースをバックアップしてきました。

    ただし、それ以上のことが必要な場合、たとえばPostgreSQLクラスター全体をバックアップする場合は、ここでpg_dumpallを使用する必要があります。

    では、pg_dumpとpg_dumpallの注目すべき違いは何ですか?

    手始めに、ドキュメントとの重要な違いは次のとおりです。

    「pg_dumpallはすべてのデータベースからテーブルを読み取るため、完全なダンプを生成するには、データベースのスーパーユーザーとして接続する必要があります。また、ユーザーとグループを追加したりデータベースを作成したりするには、保存したスクリプトを実行するためのスーパーユーザー権限が必要です。」

    以下のコマンドを使用して、PostgreSQLクラスター全体をバックアップし、whole_cluster.sqlファイルに保存します。

    $ pg_dumpall -U postgres -W -f ~/Example_Dumps/Cluster_Dumps/entire_cluster.sql
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:
    Password:

    一体全体?プロンプトごとにパスワードを入力する必要があったのでしょうか?

    うん、確かにそうだった。 24回。

    '日を数えます。 (ねえ、私は学びながらさまざまなデータベースを探索して掘り下げるのが好きですか?私は何を言うことができますか?)

    しかし、なぜすべてのプロンプトですか?

    まず第一に、その大変な作業の後、pg_dumpallはバックアップファイルを作成しましたか?

    postgres=# \! ls -a ~/Example_Dumps/Cluster_Dumps
    .  .. entire_cluster.sql

    はい、バックアップファイルがあります。

    そのすべてに光を当てましょう'タイピングの練習 ’ドキュメントからこの一節を見てください:

    「pg_dumpallはPostgreSQLサーバーに数回接続する必要があります(データベースごとに1回)。パスワード認証を使用すると、毎回パスワードが要求されます。」

    私はあなたが何を考えているか知っています。

    これは理想的ではないか、実現可能ではないかもしれません。深夜に実行されるプロセス、スクリプト、またはcronジョブはどうですか?

    誰かがキーボードにカーソルを合わせて入力を待っていますか?

    おそらくそうではありません。

    これらの繰り返しのパスワードプロンプトに直面しないようにするための効果的な対策の1つは、〜/.pgpassファイルです。

    〜/ .pgpassファイルが機能するために必要な構文は次のとおりです(ドキュメントから提供された例は上記のリンクを参照してください):

    hostname:port:database:username:password

    開発環境に〜/ .pgpassファイルがあり、postgresロールに必要な資格情報が含まれているので、-W(-w)オプションを省略して、パスワードで手動で認証せずにpg_dumpallを実行できます。

    $ pg_dumpall -U postgres -f ~/Example_Dumps/Cluster_Dumps/entire_cluster2nd.sql

    ディレクトリの内容を一覧表示する:

    postgres=# \! ls -a ~/Example_Dumps/Cluster_Dumps
    .  .. entire_cluster2nd.sql  entire_cluster.sql

    ファイルが作成され、パスワードの繰り返しプロンプトは表示されません。

    保存されたファイルは、pg_dumpと同様にpsqlで再ロードできます。

    ドキュメントのこの一節によると、接続データベースもそれほど重要ではありません。「pg_dumpallによって作成されたスクリプトファイルには、保存されたデータベースを作成して接続するための適切なコマンドが含まれているため、ここで接続するデータベースは重要ではありません。」

    今日のホワイトペーパーをダウンロードするClusterControlを使用したPostgreSQLの管理と自動化PostgreSQLの導入、監視、管理、スケーリングを行うために知っておくべきことについて学ぶホワイトペーパーをダウンロードする

    pg_dump、pg_dumpall、およびシェルスクリプト-便利な組み合わせ

    このセクションでは、pg_dumpとpg_dumpallを単純なシェルスクリプトに組み込む例をいくつか紹介します。

    はっきり言って、これはシェルスクリプトのチュートリアルではありません。私はシェルスクリプトの第一人者でもありません。主に、ローカルの開発/学習環境で使用するいくつかの例を紹介します。

    まず、単一のデータベースのバックアップに使用できる簡単なシェルスクリプトを見てみましょう。

    #!/bin/bash
    # This script performs a pg_dump, saving the file the specified dir.
    # The first arg ($1) is the database user to connect with.
    # The second arg ($2) is the database to backup and is included in the file name.
    # $(date +"%Y_%m_%d") includes the current system date into the actual file name.
    
    pg_dump -U $1 -W -C -d $2 > ~/PG_dumps/Dump_Scripts/$(date +"%Y_%m_%d")_$2.sql

    ご覧のとおり、このスクリプトは2つの引数を受け入れます。最初の引数はバックアップのために接続するユーザー(またはロール)であり、2番目の引数はバックアップするデータベースの名前です。

    コマンドの-Cオプションに注意してください。これにより、データベースが存在しない場合でも、事前に手動で作成しなくても復元できます。

    example_backupsデータベースのpostgresロールを使用してスクリプトを呼び出しましょう(初めて呼び出す前に、少なくともchmod + xでスクリプトを実行可能にすることを忘れないでください):

    $ ~/My_Scripts/pgd.sh postgres example_backups
    Password:

    そして、そこにあることを確認します:

    $ ls -a ~/PG_dumps/Dump_Scripts/
    .  .. 2018_06_06_example_backups.sql

    前の例と同様に、このバックアップスクリプトを使用して復元が実行されます。

    同様のシェルスクリプトをpg_dumpallで使用して、PostgreSQLクラスター全体をバックアップできます。

    このシェルスクリプトは、pg_dumpallをgzipにパイプ(|)し、指定されたファイルの場所に転送します:

    #!/bin/bash
    # This shell script calls pg_dumpall and pipes into the gzip utility, then directs to
    # a directory for storage.
    # $(date +"%Y_%m_%d") incorporates the current system date into the file name.
     
    pg_dumpall -U postgres | gzip > ~/PG_dumps/Cluster_Dumps/$(date +"%Y_%m_%d")_pg_bck.gz

    前のサンプルスクリプトとは異なり、これは引数を受け入れません。

    このスクリプトをコマンドラインで呼び出します(postgresロールは〜/ .pgpassファイルを利用するためパスワードプロンプトは表示されません-上記のセクションを参照してください)。

    $ ~/My_Scripts/pgalldmp.sh

    完了したら、.sqlファイルとgzファイルを比較するためのファイルサイズも示すディレクトリの内容を一覧表示します。

    postgres=# \! ls -sh ~/PG_dumps/Cluster_Dumps
    total 957M
    37M 2018_05_22_pg_bck.gz   32M 2018_06_06_pg_bck.gz 445M entire_cluster2nd.sql  445M entire_cluster.sql

    ドキュメントからのgzアーカイブ形式に関する注記:

    「データベースを再構築するには、pg_restoreで代替のアーカイブファイル形式を使用する必要があります。」

    概要

    このブログ投稿を締めくくるために、pg_dumpとpg_dumpallのドキュメントから重要なポイントをまとめ、観察結果をまとめました。

    注:ドキュメントから提供されるポイントは引用符で囲まれています。

    • 「pg_dumpは単一のデータベースのみをダンプします」
    • プレーンテキストのSQLファイル形式は、pg_dumpのデフォルトの出力です。
    • ドキュメントの次の行に従ってpg_dumpを実行するには、ロールにSELECT権限が必要です。「pg_dumpは内部でSELECTステートメントを実行します。 pg_dumpの実行に問題がある場合は、たとえばpsqlを使用してデータベースから情報を選択できることを確認してください。
    • 必要なDDLCREATEDATABASEコマンドと接続をバッ​​クアップファイルに含めるには、-Cオプションを含めます。
    • -W:このオプションは、pg_dumpにパスワードの入力を強制します。サーバーがパスワードを必要とする場合、とにかくプロンプトが表示されるため、このフラグは必要ありません。それでも、ドキュメントのこの箇所が私の目に留まったので、ここに含めることを考えました。「ただし、pg_dumpは、サーバーがパスワードを必要としていることを確認するための接続試行を無駄にします。場合によっては、余分な接続の試行を避けるために-Wと入力する価値があります。」
    • -d:接続するデータベースを指定します。また、ドキュメントには次のように記載されています。「これは、コマンドラインで最初の非オプション引数としてdbnameを指定することと同じです。」
    • -t(テーブル)などのフラグを使用すると、ユーザーはデータベースの一部、つまりテーブルをバックアップできます。ユーザーにはアクセス権限があります。
    • バックアップファイルの形式はさまざまです。ただし、.sqlファイルはとりわけ優れた選択肢です。バックアップファイルは、復元のためにpsqlによって読み込まれます。
    • pg_dumpは、他の操作(つまり、他のリーダーとライター)に干渉することなく、実行中のアクティブなデータベースをバックアップできます。
    • 1つの注意点:pg_dumpは、ロールやテーブルスペースを含む他のデータベースオブジェクトをダンプせず、単一のデータベースのみをダンプします。
    • PostgreSQLクラスター全体のバックアップを作成するには、pg_dumpallの方が適しています。
    • pg_dumpallはクラスター全体を処理し、役割、テーブルスペース、ユーザー、権限などに関する情報をバックアップできますが、pg_dumpでは処理できません。
    • おそらく、SUPERUSER権限を持つロールは、ダンプを実行し、ファイルがpsqlを介して読み戻されるときにファイルを復元/再作成する必要があります。これは、復元中に、すべてのデータベースのすべてのテーブルを読み取る権限が必要になるためです。

    私の希望は、このブログ投稿を通じて、単一の開発/学習PostgreSQL環境のpg_dumpおよびpg_dumpallに関する初心者レベルの概要の適切な例と詳細を提供したことです。

    利用可能なすべてのオプションが検討されたわけではありませんが、公式ドキュメントには両方のユーティリティの例を含む豊富な情報が含まれているため、詳細な調査、質問、および読書については、必ずそのリソースを参照してください。


    1. SQLiteで日付順に並べ替える方法

    2. 列を指定せずにSQLINSERTを実行します。何が起こるのですか?

    3. 実行中のPostgresバージョンを表示する方法

    4. データベースでのユーザーアクセスを制限することが重要な理由