greenplum數據庫中mirror的做用就是做爲primary的備份存在。那麼恢復down掉的mirror或primary時,是否能夠直接複製文件從primary或mirror到對應的mirror或primary來啓動數據庫,而不採用gprecoverseg呢?答案是確定的。下面將討論其中須要涉及的相關文件以及會出現的問題。
1,最簡單的狀況-某個mirror在down掉後,數據庫沒有出現數據修改操做的狀況,此時進行恢復。
此時,該mirror和對應的primary記錄數據的文件base是同樣的。
pg_xlog是PostgreSQL的事務日誌,包含幾個二進制文件,每一個文件固定大小爲64MB,並不斷重複使用,記錄關於最近事務的數據。
greenplum在啓動時正是經過對比primary和mirror的pg_xlog來判斷它們是否處於同步狀態,那麼能夠經過複製down掉的mirror對應的primary上的pg_xlog到該mirror上來"騙"過數據庫啓動時,master對他們的對比檢查。另外還須要修改gp_segment_configuration中這一對實例的狀態到正常,不然master仍是會判斷該mirror就是down掉了。
操做示例說明:--如今content=0的mirror是'd'。
testDB=# select * from gp_segment_configuration;
dbid | content | role | preferred_role | mode | status | port | hostname | address | replication_port | san_mounts
------+---------+------+----------------+------+--------+-------+----------+---------+------------------+------------
1 | -1 | p | p | s | u | 5432 | mdw | mdw | |
3 | 1 | p | p | s | u | 40000 | sdw2 | sdw2 | 41000 |
5 | 1 | m | m | s | u | 50000 | sdw1 | sdw1 | 51000 |
2 | 0 | p | p | c | u | 40000 | sdw1 | sdw1 | 41000 |
4 | 0 | m | m | s | d | 50000 | sdw2 | sdw2 | 51000 |
--停掉數據庫。
[gpadmin@mdw ~]$ gpstop -a
--將content=0的primary上的pg_xlog傳輸到目標節點機上。
[gpadmin@sdw1 gpseg0]$ scp -r pg_xlog/ gpadmin@sdw2:/data1/mirror
000000010000000200000014 100% 64MB 64.0MB/s 00:01
000000010000000200000015 100% 64MB 64.0MB/s 00:01
000000010000000200000016 100% 64MB 32.0MB/s 00:02
000000010000000200000017 100% 64MB 64.0MB/s 00:01
000000010000000200000018 100% 64MB 64.0MB/s 00:01
000000010000000200000019 100% 64MB 64.0MB/s 00:01
00000001000000020000001A 100% 64MB 64.0MB/s 00:01
00000001000000020000001B 100% 64MB 64.0MB/s 00:01
00000001000000020000001C 100% 64MB 32.0MB/s 00:02
00000001000000020000001D 100% 64MB 64.0MB/s 00:00
--用傳輸過來的pg_xlog覆蓋該mirror上的pg_xlog。
[gpadmin@sdw2 mirror]$ cp -r pg_xlog/ gpseg0/
[gpadmin@sdw2 mirror]$ rm -rf pg_xlog/
--修改gp_segment_configuration中這一對實例的狀態到正常。
[gpadmin@mdw ~]$ gpstart -m
[gpadmin@mdw ~]$ PGOPTIONS="-cgp_session_role=utility" psql
psql (8.2.15)
Type "help" for help.
testDB=# set allow_system_table_mods='dml';
testDB=# update gp_segment_configuration set mode='s' where dbid=2;
UPDATE 1
testDB=# update gp_segment_configuration set status='u' where dbid=4;
UPDATE 1
testDB=# select * from gp_segment_configuration ;
dbid | content | role | preferred_role | mode | status | port | hostname | address | replication_port | san_mounts
------+---------+------+----------------+------+--------+-------+----------+---------+------------------+------------
1 | -1 | p | p | s | u | 5432 | mdw | mdw | |
3 | 1 | p | p | s | u | 40000 | sdw2 | sdw2 | 41000 |
5 | 1 | m | m | s | u | 50000 | sdw1 | sdw1 | 51000 |
2 | 0 | p | p | s | u | 40000 | sdw1 | sdw1 | 41000 |
4 | 0 | m | m | s | u | 50000 | sdw2 | sdw2 | 51000 |
(5 rows)
[gpadmin@mdw ~]$ gpstop -m
[gpadmin@mdw ~]$ gpstart -a
20150907:23:19:24:013031 gpstart:mdw:gpadmin-[INFO]:-Starting gpstart with args: -a
20150907:23:19:24:013031 gpstart:mdw:gpadmin-[INFO]:-Gathering information and validating the environment...
20150907:23:19:24:013031 gpstart:mdw:gpadmin-[INFO]:-Greenplum Binary Version: 'postgres (Greenplum Database) 4.3.5.1 build 1'
20150907:23:19:24:013031 gpstart:mdw:gpadmin-[INFO]:-Greenplum Catalog Version: '201310150'
20150907:23:19:24:013031 gpstart:mdw:gpadmin-[INFO]:-Starting Master instance in admin mode
20150907:23:19:25:013031 gpstart:mdw:gpadmin-[INFO]:-Obtaining Greenplum Master catalog information
20150907:23:19:25:013031 gpstart:mdw:gpadmin-[INFO]:-Obtaining Segment details from master...
20150907:23:19:25:013031 gpstart:mdw:gpadmin-[INFO]:-Setting new master era
20150907:23:19:25:013031 gpstart:mdw:gpadmin-[INFO]:-Master Started...
20150907:23:19:25:013031 gpstart:mdw:gpadmin-[INFO]:-Shutting down master
20150907:23:19:27:013031 gpstart:mdw:gpadmin-[INFO]:-Commencing parallel primary and mirror segment instance startup, please wait...
.......
20150907:23:19:34:013031 gpstart:mdw:gpadmin-[INFO]:-Process results...
20150907:23:19:34:013031 gpstart:mdw:gpadmin-[INFO]:-----------------------------------------------------
20150907:23:19:34:013031 gpstart:mdw:gpadmin-[INFO]:- Successful segment starts = 4
20150907:23:19:34:013031 gpstart:mdw:gpadmin-[INFO]:- Failed segment starts = 0
20150907:23:19:34:013031 gpstart:mdw:gpadmin-[INFO]:- Skipped segment starts (segments are marked down in configuration) = 0
20150907:23:19:34:013031 gpstart:mdw:gpadmin-[INFO]:-----------------------------------------------------
20150907:23:19:34:013031 gpstart:mdw:gpadmin-[INFO]:-
20150907:23:19:34:013031 gpstart:mdw:gpadmin-[INFO]:-Successfully started 4 of 4 segment instances
20150907:23:19:34:013031 gpstart:mdw:gpadmin-[INFO]:-----------------------------------------------------
20150907:23:19:34:013031 gpstart:mdw:gpadmin-[INFO]:-Starting Master instance mdw directory /data/master/gpseg-1
20150907:23:19:35:013031 gpstart:mdw:gpadmin-[INFO]:-Command pg_ctl reports Master mdw instance active
20150907:23:19:35:013031 gpstart:mdw:gpadmin-[INFO]:-No standby master configured. skipping...
20150907:23:19:35:013031 gpstart:mdw:gpadmin-[INFO]:-Database successfully started
--說明直接複製primary的文件pg_xlog至mirror,而不用gprecoverseg來恢復的方法是可行。
2, 某個mirror在down掉後,數據庫出現了數據修改操做的狀況,此時進行恢復。
若是此時還想用複製文件的方法進行恢復,就須要複製記錄數據的base文件夾中的內容,若是不清楚具體那些文件不同,能夠複製覆蓋整個base文件夾。
這裏我主要想說明,數據庫出現了數據修改操做,而沒有複製base中的相應文件,只是複製pg_xlog來恢復啓動數據庫後引發的錯誤後果。
若是在content=0的mirror down掉後,建立了一個表syn_test,並插入了數據。
testDB=# create table syn_test(id int,name varchar(10)) distributed by (id);
CREATE TABLE
testDB=# insert into syn_test values(1,'ab'),(2,'dc'),(3,'dfs'),(4,'sfs');
INSERT 0 4
--該表的oid爲890432,能夠content=0的primary的base下找到剛創建的該文件,但在content=0的mirror的base下是沒有該文件的。
testDB=# select oid,relname from pg_class where relname='syn_test';
oid | relname
--------+---------
890432 | syn_test
(1 row)此時數據庫出現了數據修改操做,但按上面第一節的方法,僅複製pg_xlog,並修改gp_segment_configuration來啓動數據庫。
此時增刪改查都是正常的。
testDB=# select * from syn_test;
id | name
----+------
1 | ab
3 | dfs
2 | dc
4 | sfs
(4 rows)
testDB=# insert into syn_test values (5,'asfd'),(6,'fjdslj');
INSERT 0 2
testDB=# delete from syn_test where id in (5,6);
DELETE 2
testDB=# alter table syn_test alter name type char(10);
ALTER TABLE但kill掉content=0的primary, 讓content=0的mirror擔當primary的角色時,任何操做都會出錯。
testDB=# select * from syn_test;
ERROR: relation with OID 890432 does not exist (seg0 slice1 sdw2:50000 pid=10501)--說明改表在該mirror中根本就不存在。
--在進行此種非正常操做時需謹慎判斷數據的變化。
3,創建一個全新的gpseg0文件夾。還有個問題就是將primary的整個gpseg0複製到對應的mirror的文件位置,創建一個全新的gpseg0文件夾,是否可行呢?
其實,直接複製文件夾也是能夠的,但須要修改文件夾中記錄關於實例信息的兩個文件gp_dbid 和postmaster.opts,另外修改gp_segment_configuration中這一對實例的狀態到正常仍是必須的。
下面的對比能夠看出primary和mirror中這兩個文件的不一樣之處。
primary的gp_dbid
[gpadmin@sdw1 gpseg0]$ cat gp_dbid
# Greenplum Database identifier for this master/segment.
# Do not change the contents of this file.
dbid = 2
mirror的gp_dbid
[gpadmin@sdw2 gpseg0]$ cat gp_dbid
# Greenplum Database identifier for this master/segment.
# Do not change the contents of this file.
dbid = 4
primary的postmaster.opts
[gpadmin@sdw1 gpseg0]$ cat postmaster.opts
/usr/local/greenplum-db-4.3.5.1/bin/postgres "-D" "/data1/primary/gpseg0" "-p" "40000" "-b" "2" "-z" "2" "--silent-mode=true" "-i" "-M" "quiescent" "-C" "0"
mirror的postmaster.opts,需修改3 處
[gpadmin@sdw2 gpseg0]$ cat postmaster.opts
/usr/local/greenplum-db-4.3.5.1/bin/postgres "-D" "/data1/mirror/gpseg0" "-p" "50000" "-b" "4" "-z" "2" "--silent-mode=true" "-i" "-M" "quiescent" "-C" "0"
這裏主要是理解pg_xlog的做用,爲恢復數據庫打開新的思路。 原文:https://blog.csdn.net/aabc012/article/details/48280983