現在、本番環境でPostgreSQL 9.4を実行していますが、サーバーでOSのアップグレードを行っている最中なので、PostgreSQLのバージョンを最新(12)にアップグレードして、潜在的に利用可能な新機能のいくつかを利用する。ただし、さまざまなデータベースのテーブルのいくつかはかなり前に作成されました(2008年より前のように、少なくとも一部のケースでは2000年より前の可能性があります)。これらのデータベースには、OID(定義ではWITH OIDS=TRUE
)を使用する多くのテーブルが含まれています。
さらに、コードベースの大部分を検索して、テーブル内のOID列への参照を探し、いくつかのインスタンスを見つけました。=を明示的に呼び出すクエリがあります。 OID列。幸いにも、これらのケースの多くはtooなく、それらの大部分はシステムテーブルを参照しています。 (つまり、SELECT oid FROM pg_namespace
、...FROM pg_class
)。
プロセスのこの時点で、9.4データベースからダンプされたデータに対してpg_upgrade
を実行すると、データベースにOIDがなくなるまで続行されないことが明記されています。過去数回のリリースで徐々に段階的に廃止されており、12では基本的に重要ではなくなっていることを理解していますが、pg_upgrade
からの提案はOID列を削除することです先に進む前に、ほとんど関係のないコラムでは「やり過ぎ」だと思います。
この時点で-そして私はまだこれまでずっと考えていなかったことをすぐに認めます-影響を受けるテーブル定義のWITH OIDS
スイッチをFALSE
アップグレードを続行できるようにするには?これが反転しても、既存のOID列はデータベース構造の一部のままになりますか?(私はそう思うと思いますが、自動アップグレードによっていくつか面白いことができます)?
理想的な状況では、最終的にデータベースからOIDを完全に削除したいと思います。ただし、1人のIT部門であるため、後の評価のために「リストに載る」必要があります。とりあえず、最新のPostgreSQLバージョンでデータベースを稼働させたいのですが、すぐに操作に影響を与えることなくそうする機会があります。
テーブルのoid
sがコードで参照されている場合、単純にそれらを取り除くことはできません。おそらく古いコードは自動生成された識別子としてoid
に依存しています。これらの列に主キーまたは他のインデックスはありますか?
アップグレードでoid
sを保持する方法は次のとおりです。
アップグレード前の古いデータベース:
ALTER TABLE has_oids ADD newoid bigint NOT NULL;
UPDATE has_oids SET newoid = oid;
ALTER TABLE has_oids SET WITHOUT OIDS;
アップグレード後、新しいデータベースで:
ALTER TABLE has_oids RENAME newoid TO oid;
CREATE SEQUENCE has_oids_oid_seq OWNED BY has_oids.oid;
ALTER TABLE has_oids ALTER oid SET DEFAULT nextval('has_oids_oid_seq');
SELECT setval('has_oids_oid_seq', ???);
ここに、 ???
は、テーブルに存在する最高のoid
よりも大きい数値です。
また、oid
列のインデックスまたは制約にも注意する必要があります。
@LaurenzAlbeの回答からの提案を使用して、psql
コマンドライン(_pg_dump
_および_pg_restore
_を含む)を使用してデータベースに必要なすべての変更を行うバッチファイルを作成しました。また、プロセスの各ステップをテキストファイルに記録し、問題が発生した場合は個別のエラーログファイルを作成します。何かが失敗した場合は、現在のデータベースを更新前の状態に復元するように求められます(推奨されます)。
その答えが私の最終的な解決策の基礎を形成したので、私はそれを答えとして受け入れました。この回答は、既存のOIDが原因でPostgreSQL v12へのアップグレードで問題が発生している他のすべての人に役立つことを期待して、私が思いついたものを示すために提供します。
ここにはいくつかの注意点と「落とし穴」がありますが、このスクリプトを使用して、データベース内の_WITH OIDS=TRUE
_フラグが設定されたすべてのテーブルを更新し、PostgreSQLバージョン9.4からバージョン12への移行を完了しました。
pg_upgrade
_をすでに使用しており、OID
を使用する既存のテーブルが原因でアップグレードが失敗したことを前提としています。この場合、_pg_upgrade
_は_tables_with_oids.txt
_という名前のテキストファイルを生成しているはずです。すべての変更を「自動的に」行うには、バッチファイルがこのファイルにアクセスできる必要があります。OID
値を使用する代わりに、_1
_で各「新しいOID
」列のシーケンスを開始することにしました。特定のOID
値を明示的に参照していて何も見つからなかったものがないかどうかを確認するために、コードとデータベースを徹底的に調べました。私が見つけたのは、OID
への参照呼び出しを行ってテーブルから他の値を取得することだけだったので、呼び出しを行い、各テーブルのOID
。を再起動することにしました。OID
値を使用する場合(@LaurenzAlbeで推奨)、異なる方法でいくつかのことを行う必要があります。つまり、古いOID
列からデータが入力されるまで、新しいOID
列に_NOT NULL
_制約が設定されるのを待つ必要があります。また、_NOT NULL
_制約を追加する前に、nextval()
のデフォルト値を設定して、すべてのレコードにこの列が入力されていることを確認することもできます。:FINALIZE
_セクションに数行を追加することはそれほど難しくないはずです。このバッチファイルは、_tables_with_oids.txt
_によって生成された_pg_upgrade
_ファイルを1行ずつ読み取り、次のことを行います。
Database:
_で始まる行として識別されます)、問題が発生した場合に備えて、データベース全体の「バックアップ」ダンプファイルが作成されます。oid
に依存しているビューがいくつかあり、その列を削除できない場合があります。スクリプトは依存関係を照会し、見つかった定義をダンプしてから、依存ビューを削除します。Database:
_で始まる行)では、スキーマとテーブル名が分割されます。<schema>_<table>_oid_seq
_の形式で生成しますnewoid
)を作成します。newoid
列の定義を変更します(これに関する上記の私のメモを参照してください) 。WITHOUT OIDS
_(に変更します。これにより、既存のoid
列が自動的に削除されます)。oid
に変更します。oid
列に関連付けます。これは、新しいoid
列が将来データベースから削除された場合(すべての参照を根絶する方法がわかった)、新しく作成したシーケンスも削除する必要があります。さて、これで説明はすべて終了しました。バッチファイル用に作成したコードは次のとおりです。お役に立てれば幸いです。私はバッチファイル自体をかなり徹底的に文書化しようとしました。個々の環境に対して明示的に定義する必要がある値は、コード内の山括弧とすべて大文字で識別されます_<YOUR SETTING HERE>
_
_@ECHO OFF
CLS
:: --------------------------------------------------------------------
:: SETLOCAL to ensure that all variables are cleared from memory at the
:: end of the batch file's execution
:: --------------------------------------------------------------------
SETLOCAL EnableDelayedExpansion
SET "startTime=%time: =0%"
:: --------------------------------------------------------------------
:: >>>>>>> MAKE SURE TO SET THESE ACCORDING TO YOUR ENVIRONMENT <<<<<<<
:: PostgreSQL Variables
:: --------------------------------------------------------------------
SET PGPASSWORD=<SUPERUSER/ADMINISTRATIVE PASSWORD>
SET PGSQLHost=<HOSTNAME OF SERVER RUNNING THE "OLD" DATA>
SET PGSQLBin=<PATH TO THE POSTGRESQL bin DIRECTORY FOR THE "OLD" INSTANCE>
SET BackupPath=<PATH WHERE YOU WANT TO STORE BACKUPS AND LOGS>\%PGSQLHost%
:: CHECK FOR/CREATE THE BACKUP/LOG DIRECTORY
IF NOT EXIST %BackupPath%\ (
MD %BackupPath%\
)
FOR /f "tokens=*" %%a in ('powershell get-date -format "{yyyyMMdd}"') DO SET CURRDATE=%%a
SET TEMPLOG="%BackupPath%\pgsql%CURRDATE%.tmp"
SET ERRORLOG="%BackupPath%\pgsql_12_update_errors_%CURRDATE%.log"
SET SUCCESSLOG="%BackupPath%\pgsql_12_update_%CURRDATE%.log"
:: --------------------------------------------------------------------
:: THIS (PUSHD) IS USED TO AVOID UNC PATHS AS THE COMMAND Prompt CAN'T
:: USE THEM AS THE CURRENT DIRECTORY.
:: See https://docs.Microsoft.com/en-us/windows-server/administration/windows-commands/pushd
:: for more information on PUSHD/POPD
:: --------------------------------------------------------------------
PUSHD "%PGSQLBin%"
SET BinPath=%cd%
SET TableCount = 0
ECHO --------------------------------------------------------------------
ECHO Update started at %startTime%
ECHO Preparing list of PostgreSQL 9.4 tables to update...
ECHO --------------------------------------------------------------------
ECHO.
ECHO -------------------------------------------------------------------- > %SUCCESSLOG%
ECHO Removing OID references to facilitate upgrade from PostgreSQL 9.4 >> %SUCCESSLOG%
ECHO to PostgreSQL 12 >> %SUCCESSLOG%
ECHO. >> %SUCCESSLOG%
ECHO See official release announcement for details >> %SUCCESSLOG%
ECHO https://www.postgresql.org/docs/12/release-12.html >> %SUCCESSLOG%
ECHO. >> %SUCCESSLOG%
ECHO PostgreSQL 9.4 update started at %startTime% >> %SUCCESSLOG%
ECHO -------------------------------------------------------------------- >> %SUCCESSLOG%
ECHO. >> %SUCCESSLOG%
:: READ THE tables_with_oids.txt FILE LINE-BY-LINE
FOR /f "eol=; tokens=1 delims=," %%T IN (%BackupPath%\tables_with_oids.txt) DO (
SET oidbuffer=%%T
:: --------------------------------------------------------------------
:: LINES THAT DON'T BEGIN WITH `Database:` ARE THE INDIVIDUAL TABLES
:: WHICH CONTAIN OID'S AND NEED TO BE UPDATED
:: --------------------------------------------------------------------
IF NOT !oidbuffer:~0^,9!==Database: (
SET NameBuffer=%%T
:: SPLIT THE SCHEMA AND TABLE NAMES FROM THE CURRENT LINE
FOR /f "tokens=1,2 delims=." %%a IN ("!NameBuffer!") DO SET SchemaName=%%a&SET TableName=%%b
IF NOT [!DBName!]==[] (
IF NOT [!TableName!]==[] (
CALL :TRIM TableName
IF NOT [!SchemaName!]==[] (
CALL :TRIM SchemaName
ECHO Updating !SchemaName!.!TableName! in !DBName! on %PGSQLHost%
ECHO UPDATING !SchemaName!.!TableName! IN !DBName! ON %PGSQLHost% >> %SUCCESSLOG%
:: GET THE OWNER OF THE TABLE
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "SELECT tableowner FROM pg_tables WHERE schemaname = '!SchemaName!' AND tablename = '!TableName!';" > %BackupPath%\tblown.tmp
:: --------------------------------------------------------------------
:: CODE FROM STACKOVERFLOW FOR psql.exe ERROR HANDLING IN BATCH FILE
:: (USED REPEATEDLY)
:: https://stackoverflow.com/a/30775383/2569697
:: --------------------------------------------------------------------
IF NOT errorlevel 1 (
FOR /F "usebackq delims=" %%g IN (%BackupPath%\tblown.tmp) DO (
SET TABLEOWNER=%%g
ECHO - Table owner is %%g >> %SUCCESSLOG%
)
) ELSE (
ECHO Error retrieving table owner from !SchemaName!.!TableName!: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
:: DISABLE ALL TRIGGERS ON THE TABLE
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "ALTER TABLE \"!SchemaName!\".\"!TableName!\" DISABLE TRIGGER ALL;" > %TEMPLOG%
IF NOT errorlevel 1 (
ECHO - Triggers disabled >> %SUCCESSLOG%
) ELSE (
ECHO Error adding newoid column to !SchemaName!.!TableName!: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
:: CREATE A NEW SEQUENCE TO BE USED FOR THE NEW oid COLUMN
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "CREATE SEQUENCE \"!SchemaName!\".!SchemaName!_!TableName!_oid_seq;" > %TEMPLOG%
IF NOT errorlevel 1 (
ECHO - New sequence created for `oid` column: `!SchemaName!_!TableName!_oid_seq` >> %SUCCESSLOG%
) ELSE (
ECHO Error creating oid sequence for !SchemaName!.!TableName!: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
:: SET THE OWNER OF THE NEW SEQUENCE TO THE SAME AS THE TABLE (see above)
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "ALTER SEQUENCE \"!SchemaName!\".!SchemaName!_!TableName!_oid_seq OWNER TO \"!TABLEOWNER!\"" > %TEMPLOG%
IF NOT errorlevel 1 (
ECHO - Ownership of `!SchemaName!_!TableName!_oid_seq` sequence set to !TABLEOWNER! >> %SUCCESSLOG%
) ELSE (
ECHO Error altering ownership of oid sequence for !SchemaName!.!TableName!: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
:: GRANT USER/GROUP PERMISSIONS ON THE SEQUENCE
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "GRANT ALL ON SEQUENCE \"!SchemaName!\".!SchemaName!_!TableName!_oid_seq TO <USER/GROUP NAME>" > %TEMPLOG%
IF NOT errorlevel 1 (
ECHO - Permissions granted on `!SchemaName!_!TableName!_oid_seq` sequence for users/groups >> %SUCCESSLOG%
) ELSE (
ECHO Error granting permissions on oid sequence for !SchemaName!.!TableName!: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
:: CREATE THE newoid COLUMN IN TABLE
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "ALTER TABLE \"!SchemaName!\".\"!TableName!\" ADD newoid bigint NOT NULL DEFAULT nextval('\"!SchemaName!\".!SchemaName!_!TableName!_oid_seq');" > %TEMPLOG%
IF NOT errorlevel 1 (
ECHO - `newoid` column created >> %SUCCESSLOG%
) ELSE (
ECHO Error adding newoid column to !SchemaName!.!TableName!: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
:: REMOVE THE OID ASSOCIATION WITH THE TABLE - THIS ALSO REMOVES THE AUTO-CREATED oid COLUMN
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "ALTER TABLE \"!SchemaName!\".\"!TableName!\" SET WITHOUT OIDS;" > %TEMPLOG%
IF NOT errorlevel 1 (
ECHO - Table definition updated to remove OID association >> %SUCCESSLOG%
) ELSE (
ECHO Error altering table definition for !SchemaName!.!TableName!: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
:: RENAME THE newoid COLUMN TO REPLACE THE ORIGINAL oid COLUMN
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "ALTER TABLE \"!SchemaName!\".\"!TableName!\" RENAME newoid TO oid;" > %TEMPLOG%
IF NOT errorlevel 1 (
ECHO - `newoid` column renamed to `oid` >> %SUCCESSLOG%
) ELSE (
ECHO Error renaming newoid column in !SchemaName!.!TableName!: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
:: ASSOCIATE THE NEW SEQUENCE WITH THE NEW oid COLUMN
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "ALTER SEQUENCE \"!SchemaName!\".!SchemaName!_!TableName!_oid_seq OWNED BY \"!SchemaName!\".\"!TableName!\".oid;" > %TEMPLOG%
IF NOT errorlevel 1 (
ECHO - `!SchemaName!_!TableName!_oid_seq` sequence explicitly linked to `oid` column >> %SUCCESSLOG%
) ELSE (
ECHO Error altering column association of oid sequence for !SchemaName!.!TableName!: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
:: REENABLE ALL TRIGGERS ON THE TABLE
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "ALTER TABLE \"!SchemaName!\".\"!TableName!\" ENABLE TRIGGER ALL;" > %TEMPLOG%
IF NOT errorlevel 1 (
ECHO - All triggers reenabled on !SchemaName!.!TableName! table >> %SUCCESSLOG%
) ELSE (
ECHO Error reenabling triggers on !SchemaName!.!TableName!: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
)
SET /A TableCount=TableCount+1
ECHO -------------------------------------------------------------------- >> %SUCCESSLOG%
ECHO !DBName!.!SchemaName!.!TableName! on %PGSQLHost% >> %SUCCESSLOG%
ECHO was updated successfully. >> %SUCCESSLOG%
ECHO -------------------------------------------------------------------- >> %SUCCESSLOG%
ECHO. >> %SUCCESSLOG%
)
)
) ELSE (
:: --------------------------------------------------------------------
:: THE `DBName` VARIABLE WON'T BE SET IF THIS IS THE FIRST LINE, BUT
:: AFTER EACH DATABASE HAS BEEN UPDATED, WE NEED TO RESTORE ANY VIEWS
:: THAT WE DUMPED FROM THE PREVIOUS DATABASE.
:: --------------------------------------------------------------------
IF NOT [!DBName!]==[] (
FOR %%F IN (%BackupPath%\!DBName!\*.dmp) DO (
%BinPath%\pg_restore -h %PGSQLHost% -p 5432 -U <SUPERUSER/ADMINISTRATIVE USERNAME> -d !DBName! "%BackupPath%\!DBName!\%%~nF.dmp"
IF NOT errorlevel 1 (
ECHO - View restored to !DBName!.!SchemaName! from %%~nF.dmp >> %SUCCESSLOG%
) ELSE (
ECHO Error restoring view from %%~nF to !DBName!.!SchemaName!: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
)
)
SET DBName=%%T
SET DBName=!DBName:Database: =!
CALL :TRIM DBName
ECHO --------------------------------------------------------------------
ECHO Backing up !DBName! database on %PGSQLHost%
ECHO -------------------------------------------------------------------- >> %SUCCESSLOG%
ECHO BACKING UP `!DBName!` DATABASE ON %PGSQLHost% >> %SUCCESSLOG%
:: CHECK FOR/CREATE THE BACKUP PATH
IF NOT EXIST %BackupPath%\!DBName!\ (
MD %BackupPath%\!DBName!\
)
:: DUMP THE CURRENT DATABASE AS A BACKUP IN CASE SOMETHING FAILS
%BinPath%\pg_dump -h %PGSQLHost% -p 5432 -U <SUPERUSER/ADMINISTRATIVE USERNAME> -E UTF8 -Fc -f %BackupPath%\!DBName!\!DBName!.gz !DBName!
:: CHECK FOR ANY VIEWS THAT ARE DEPENDENT ON EXISTING `oid` COLUMNS
ECHO Getting oid dependencies in !DBName! database
ECHO GETTING OID DEPENDENCIES IN `!DBName!` DATABASE >> %SUCCESSLOG%
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "SELECT n.nspname || '.' || c.relname AS table_name FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace) LEFT JOIN pg_catalog.pg_attribute a ON (c.oid = a.attrelid AND a.attnum > 0 AND NOT a.attisdropped) LEFT JOIN pg_catalog.pg_stat_all_tables s ON (c.oid = s.relid) WHERE c.relkind = 'v' AND (pg_catalog.pg_get_viewdef(c.oid, true) ~* '.oid' OR pg_catalog.pg_get_viewdef(c.oid, true) ~* ',oid' OR pg_catalog.pg_get_viewdef(c.oid, true) ~* ' oid') AND n."nspname" NOT LIKE 'pg_%%' AND n."nspname" NOT LIKE 'information_%%' GROUP BY n.nspname, c.relowner, c.relkind, c.relname, s.n_live_tup, c.oid ORDER BY n.nspname, c.relname;" > %BackupPath%\!DBName!\!DBName!dep.txt
:: DUMP ANY DEPENDENT VIEWS TO SEPARATE FILES FOR RESTORATION LATER
FOR /F "usebackq delims=" %%V IN (%BackupPath%\!DBName!\!DBName!dep.txt) DO (
SET ViewNameBuffer=%%V
FOR /f "tokens=1,2 delims=." %%a IN ("!ViewNameBuffer!") DO SET ViewSchema=%%a&SET ViewName=%%b
%BinPath%\pg_dump -h %PGSQLHost% -p 5432 -U <SUPERUSER/ADMINISTRATIVE USERNAME> -E UTF8 -s -t \"!ViewSchema!\".\"!ViewName!\" -Ft -f %BackupPath%\!DBName!\!DBName!_!ViewSchema!_!ViewName!_def.dmp !DBName!
IF NOT errorlevel 1 (
ECHO - Dumped definition for !ViewSchema!.!ViewName! >> %SUCCESSLOG%
) ELSE (
ECHO Error dumping definition for `!ViewSchema!.!ViewName!` view: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
:: DROP THE DEPENDENT VIEW
%BinPath%\psql -qtAX -h %PGSQLHost% -p 5432 -d !DBName! -U <SUPERUSER/ADMINISTRATIVE USERNAME> -c "DROP VIEW \"!ViewSchema!\".\"!ViewName!\";" > %TEMPLOG%
IF NOT errorlevel 1 (
ECHO - Dropped !ViewSchema!.!ViewName! view >> %SUCCESSLOG%
) ELSE (
ECHO Error dropping `!ViewSchema!.!ViewName!` view: %errorlevel% >> %ERRORLOG%
GOTO :ERRORHANDLER
)
)
ECHO Updating tables in !DBName! database on %PGSQLHost%
ECHO --------------------------------------------------------------------
ECHO UPDATING TABLES IN `!DBName!` DATABASE ON %PGSQLHost% >> %SUCCESSLOG%
ECHO -------------------------------------------------------------------- >> %SUCCESSLOG%
)
)
ECHO.
ECHO --------------------------------------------------------------------
ECHO Cleaning up and finalizing the update
ECHO --------------------------------------------------------------------
GOTO :FINALIZE
:ERRORHANDLER
:: IF SOMETHING BREAKS, Prompt TO RESTORE THE DATABASE FROM THE BACKUP
(SET /P restore=Do you want to restore the !DBName! database on %PGSQLHost% from the backup? [Y/N]: )
:: --------------------------------------------------------------------
:: The /i switch allows the test to be case-insensitive (NT-based only)
:: --------------------------------------------------------------------
IF /i "%restore%"=="Y" GOTO RESTOREBACKUP
IF /i "%restore%"=="N" GOTO :FINALIZE
ECHO Invalid selection. Please type "Y" or "N".
ECHO.
GOTO :ERRORHANDLER
:RESTOREBACKUP
:: RESTORE THE DATABASE FROM THE BACKUP CREATED BEFORE CHANGES WERE MADE
ECHO Restoring !DBName!
%BinPath%\dropdb -h %PGSQLHost% -p 5432 -U <SUPERUSER/ADMINISTRATIVE USERNAME> !DBName!
%BinPath%\createdb -E UTF8 -T template0 -O Developers -h %PGSQLHost% -p 5432 -U <SUPERUSER/ADMINISTRATIVE USERNAME> !DBName!
%BinPath%\pg_restore -h %PGSQLHost% -p 5432 -U <SUPERUSER/ADMINISTRATIVE USERNAME> -d !DBName! "%BackupPath%\!DBName!\!DBName!.gz"
ECHO `!DBName!` on %PGSQLHost% restored from backup
ECHO `!DBName!` on %PGSQLHost% restored from backup >> %SUCCESSLOG%
:FINALIZE
:: RELEASE RESOURCES ALLOCATED BY PUSHD
POPD
SET "endTime=%time: =0%"
:: --------------------------------------------------------------------
:: CODE FROM STACKOVERFLOW FOR REPORTING ELAPSED TIME OF PROCESS
:: https://stackoverflow.com/a/9935540/2569697
:: --------------------------------------------------------------------
:: Get elapsed time:
:: --------------------------------------------------------------------
SET "end=!endTime:%time:~8,1%=%%100)*100+1!" & set "start=!startTime:%time:~8,1%=%%100)*100+1!"
SET /A "elap=((((10!end:%time:~2,1%=%%100)*60+1!%%100)-((((10!start:%time:~2,1%=%%100)*60+1!%%100)"
:: --------------------------------------------------------------------
:: Convert elapsed time to HH:MM:SS:CC format:
:: --------------------------------------------------------------------
SET /A "cc=elap%%100+100,elap/=100,ss=elap%%60+100,elap/=60,mm=elap%%60+100,hh=elap/60+100"
:: DISPLAY AND WRITE THE RESULTS OF THE UPDATE TO THE LOG FILE
ECHO.
ECHO --------------------------------------------------------------------
ECHO Update completed at %endTime%
ECHO --------------------------------------------------------------------
ECHO Elapsed Time: %hh:~1%%time:~2,1%%mm:~1%%time:~2,1%%ss:~1%%time:~8,1%%cc:~1%
ECHO.
ECHO %TableCount% tables were updated on %PGSQLHost%.
ECHO. >> %SUCCESSLOG%
ECHO -------------------------------------------------------------------- >> %SUCCESSLOG%
ECHO Update completed at %endTime% >> %SUCCESSLOG%
ECHO --------------------------------------------------------------------
ECHO Elapsed Time: %hh:~1%%time:~2,1%%mm:~1%%time:~2,1%%ss:~1%%time:~8,1%%cc:~1% >> %SUCCESSLOG%
ECHO. >> %SUCCESSLOG%
ECHO %TableCount% tables were successfully updated on %PGSQLHost%. >> %SUCCESSLOG%
:: DELETE THE TEMPORARY FILES USED
DEL /F /Q %TEMPLOG%
DEL /F /Q %BackupPath%\tblown.tmp
ENDLOCAL
GOTO :EOF
:: --------------------------------------------------------------------
:: CODE FROM STACKOVERFLOW FOR TRIMMING TRAILING/LEADING WHITESPACE
:: FROM A STRING VALUE
:: https://stackoverflow.com/a/19686956/2569697
:: --------------------------------------------------------------------
:TRIM
SETLOCAL EnableDelayedExpansion
CALL :TRIMSUB %%%1%%
ENDLOCAL & SET %1=%tempvar%
GOTO :EOF
:TRIMSUB
SET tempvar=%*
GOTO :EOF
_
これを書いているときに遭遇した特定の問題の解決策を見つけた場所を思い出すことができる場合に、クレジットを与えるために最善を尽くしました。私はそれらすべてを捕らえなかったと確信していますが、帰属のない貢献を認めた場合はご容赦ください。