私のステップ:
pg_dumpall
を実行するprod-server-old
prod-server-old
を永久にシャットダウンします。prod-server-new
)prod-server-new
に今行きますpg_dumpall
(step1とstep2の間)の間にデータベースへの変更を回避して、この間の変更が失われないようにするにはどうすればよいですか?
私の場合、ダウンタイムが短いことは100%OKです。
「クラスター」にはいくつかのデータベースがあります(ところで、「クラスター」という言葉は好きではありません。「クラスター」は複数のコンピューターのグループだと思う人が多いと思いますが、この場合、1つのPostgresサーバーがいくつかのデータベース)。
私の質問は「Postgresデータベースを一時的に読み取り専用にする(ボリュームスナップショットを実行するため)」と重複する可能性があるとマークされました。一時的な読み取り専用の状態を要求しないため、私の場合は異なるため、それは重複しているとは思わない。
1つの回避策:
prod-server-old
でPostgreSQLのポートを変更します。この方法では、クライアントがpg_dumpall --port=OTHER_PORT
中にDBに接続することはほとんどありません。
それを行う2つの方法:
connect
グループに対するpublic
特権を取り消します。これにより、スーパーユーザー以外の全員が接続できなくなります。次に、サーバーを再起動するか、 すべての接続を終了 し、スーパーユーザーアカウントを使用してバックアップを続行します。
REVOKE CONNECT TO DATABASE (database) FROM public
データベースを読み取り専用モードにします。
ALTER DATABASE (database) SET default_transaction_read_only = true;
を進めます pg_dumpall
。再起動は必要なく、ダウンタイムもありません。
もちろん、「ロック」したいすべてのデータベースでこれを繰り返す必要があります。かなりの数のデータベースがある場合は、クラスター全体を読み取り専用にすることができます:set default_transaction_read_only = on;
postgresql.confで、postgresサービスをリロードします。
これらのコマンドはまだテストしていません。自己責任で進めてください。
私はSQL Server管理者(Postgresではありません)なので、100%確実ではありませんが、ダウンタイムが問題にならない場合は、次のことができます。
?
トリガーの使用:
create function __fn_db_readonly() returns event_trigger language plpgsql as $$
begin
raise exception '%', 'Database is in read-only mode';
end $$;
create function _fn_db_readonly() returns trigger language plpgsql as $$
begin
raise exception '%', TG_ARGV[0];
end $$;
create function set_db_readonly(amessage text) returns void language plpgsql as $$
declare
t record;
tbl_name text;
stm text;
begin
if coalesce(amessage, '') = '' then
-- Database
drop event trigger __tg_ro_database1;
drop event trigger __tg_ro_database2;
drop event trigger __tg_ro_database3;
-- Data
for t in (select * from pg_tables where not schemaname in ('pg_catalog', 'information_schema')) loop
tbl_name := format('%I.%I', t.schemaname, t.tablename);
stm := 'drop trigger if exists _tg_ro on ' || tbl_name;
execute stm;
end loop;
else
-- Data
for t in (select * from pg_tables where not schemaname in ('pg_catalog', 'information_schema')) loop
tbl_name := format('%I.%I', t.schemaname, t.tablename);
stm := format('create trigger _tg_ro before insert or update or delete on %s execute procedure _fn_db_readonly(%L)', tbl_name, amessage);
execute stm;
end loop;
-- Database
create event trigger __tg_ro_database1 on ddl_command_start execute procedure __fn_db_readonly();
create event trigger __tg_ro_database2 on table_rewrite execute procedure __fn_db_readonly();
create event trigger __tg_ro_database3 on sql_drop execute procedure __fn_db_readonly();
end if;
return;
end $$;
次に、データベースを読み取り専用にするには:
select set_db_readonly('Database is in read-only mode due to maintance.');
もう一度編集可能にするには:
select set_db_readonly('');