Monday, July 27, 2015

Postgresql: Corruption: FATAL: invalid page header in block

VM crashed and took the postgresql with it. It failed to come back up when the VM restarted with the following error. There was no complete recent backup and unable to start the database. This does not leave a lot of room to wiggle around.

portgres postgres FATAL : the database system is starting up
portgres postgres FATAL : the database system is starting up
portgres postgres FATAL : the database system is starting up
       FATAL: invalid page header in block 903213 of relation pg_tblspc/16385/PG_9.0_201106101/16386/17694
       LOG: startup process (PID 27451) exited with exit code 1
       LOG: aborting startup due to startup process failure
       LOG: database system was interrupted while in recovery at 2015-07-20 21:00:01 UTC
       HINT: This is probably means that some data is corrupted and yo will have to use the last backup for recovery.
       LOG: database system was not properly shut down; automatic recovery in progress
       LOG: redo starts at 33E/D06C5FXX
       LOG: record with Zero length at 33E/D06C5FXX
       LOG: last completed transaction was at log time  ..........
 ... . .. .. . .. .


The file does exist but corrupted.
ls -as 17694

1349454 17694



Added zero_damaged_pages = on to postgresql.conf and was about to start up the database. Would suggest  to perform a VACUUM FULL and get a backup right after that.

Thursday, July 9, 2015

Postgresql: Recovering a single table in Postgresql when the database is backup with text format

As the subject stated, recovering a single when database was backup with text format.

1 - open the text format backup file.
2 - search for the table. In this example, I am using a fake table (vpx_version) to simulate this. 
3 - copy and paste them to excel spreadsheet. Remember to have the header.
4- save the excel spreadsheet in "CSV" format on DOS.
5- move the csv file to the location of where you want to load the data into.


  


  

Note: the table structure must already exist for COPY to work, it does not create the table. If you dropped the table instead of truncated or delete without where clause, you will need to create the table manually. The HEADER flag is when you actually have a header if you do not, it might bomb out depending on the type of data you have defined at the base table.

vcdb=> select * from vpx_version;
ver_id |       version_value
--------+----------------------------
    600 | VirtualCenter Database 6.0
(1 row)

vcdb=> truncate table vpx_version;
TRUNCATE TABLE


vcdb=> select * from vpx_version;
ver_id | version_value
--------+---------------
(0 rows)

vcdb=> \COPY vpx_version from test.csv CSV HEADER;

vcdb=> select * from vpx_version;
ver_id |       version_value
--------+----------------------------
    600 | VirtualCenter Database 6.0
    601 | VirtualCenter Database 6.0
    602 | VirtualCenter Database 6.0
    603 | VirtualCenter Database 6.0
    604 | VirtualCenter Database 6.0
    605 | VirtualCenter Database 6.0

(6 rows)


If there are options, I will urge user to do backup of the database with pg_dump -Fc or "create table" .. "from select all".

##################################


Well that's all .. ... restoring my vpx_version table to original state ...


postgres=# \c vcdb vc
You are now connected to database "vcdb" as user "vc".
vcdb=> select * from vpx_version;
 ver_id |       version_value
--------+----------------------------
    600 | VirtualCenter Database 6.0
    601 | VirtualCenter Database 6.0
    602 | VirtualCenter Database 6.0
    603 | VirtualCenter Database 6.0
    604 | VirtualCenter Database 6.0
    605 | VirtualCenter Database 6.0
(6 rows)

vcdb=> truncate table vpx_version;
TRUNCATE TABLE

vcdb=> select * from vpx_version;
 ver_id | version_value
--------+---------------
(0 rows)


vcdb=>

postgres@localhost:~> pg_restore -U vc -d vcdb -a -t vpx_version vcdb.Fc.backup

postgres@localhost:~> psql
psql.bin (9.3.6 (VMware Postgres 9.3.6.0-2686691 release))
Type "help" for help.

postgres=# \c vcdb vc

You are now connected to database "vcdb" as user "vc".

vcdb=> select * from vpx_version;
 ver_id |       version_value
--------+----------------------------
    600 | VirtualCenter Database 6.0

(1 row)