Compare commits

..

705 Commits
v1.0.0 ... v3.0

Author SHA1 Message Date
Ian Barwick
372f4f7d3d Bump specfile version number 2015-03-27 11:47:23 +09:00
Ian Barwick
c4505248b0 doc: Minor README/FAQ rewording 2015-03-27 11:34:52 +09:00
Ian Barwick
5774d86ac7 Remove not-yet-existent 2.0.3 release items 2015-03-27 11:05:40 +09:00
Ian Barwick
29e7733152 Prepare devel branch for promotion to master 2015-03-26 11:50:22 +09:00
Ian Barwick
b64385bee8 Fix HISTORY item 2015-03-26 11:46:28 +09:00
Ian Barwick
419ce28d3d Remove old README 2015-03-26 11:44:09 +09:00
Ian Barwick
90cc6a5cb4 Add note about --initdb-no-pwprompt 2015-03-26 11:43:24 +09:00
Ian Barwick
1b175ddfcf Update FAILOVER.rst 2015-03-26 11:40:51 +09:00
Ian Barwick
eabe618738 FAQ fixes and updates 2015-03-26 11:07:18 +09:00
Ian Barwick
3e621f43d1 Use 100 as the default priority; 0 or less means node will never be promoted 2015-03-26 10:38:20 +09:00
Ian Barwick
15a531fed8 Update function description 2015-03-24 19:36:31 +09:00
Ian Barwick
96255b988a Remove unused function
And standardized nomenclature on "master" rather than "primary".
2015-03-24 14:29:54 +09:00
Ian Barwick
8de0deddf9 Change "primary" to "master"
Personally I prefer "primary", but repmgr uses "master" so let's consolidate
on one version of the terminology for clarity.
2015-03-24 14:06:39 +09:00
Ian Barwick
bd19a2c868 Improve handling of event logging in rempgrd
Provide the master connection if available, and if not enable
create_event_record() to skip trying to write to the database,
but execute the notification program if defined.
2015-03-24 13:40:39 +09:00
Ian Barwick
2cadb3424d Don't try and log events when no master connection available 2015-03-24 12:48:02 +09:00
Ian Barwick
bfe4585b91 rempgr -> repmgr 2015-03-24 11:32:50 +09:00
Ian Barwick
230773d626 Merge pull request #52 from centromere/repmgr
Fix typo in README.rst
2015-03-24 10:45:02 +09:00
John Galt
81b7b3bae7 Fixed typo 2015-03-23 21:08:48 -04:00
Germ van Ek
8cfc26d3ea Added postgresql-9.4 to debian control file 2015-03-24 10:03:56 +09:00
Ian Barwick
5b1a4d0ef1 Merge pull request #51 from gerben-van-eck/repmgr
Added postgresql-9.4 to debian control file
2015-03-24 09:59:57 +09:00
Germ van Ek
22423aa51a Added postgresql-9.4 to debian control file 2015-03-23 16:53:04 +01:00
Ian Barwick
98df2a5891 Fix recovery_min_apply_delay handling
- rename --min-recovery-apply-delay to --recovery-min-apply-delay
- ensure server version is 9.4 or later before writing
  recovery_min_apply_delay to recovery.conf.

This fixes changes introduced in 653e11c2a7
(the parameter was subsequently renamed).

Also reallocate the '-r' parameter to --rsync-only, which is probably
more useful.
2015-03-23 17:50:51 +09:00
Ian Barwick
6f61c8285b Add note about pg_basebackup -X s
We already provide a facility to pass arbitrary options to pg_basebackup.
2015-03-23 15:56:50 +09:00
Ian Barwick
0875b2aafa Change 'ignore_external_config_files' to a command line option
It's only used when cloning a standby and has more in common with
--fast-checkpoint
2015-03-23 15:24:01 +09:00
Ian Barwick
3e2c9ed410 Support --fast-checkpoint 2015-03-23 12:18:17 +09:00
Ian Barwick
5b4f832f3b Only allow --rsync-only option in combination with STANDBY CLONE 2015-03-20 15:16:55 +09:00
Ian Barwick
66844d057a Rename 'need_a_node' to 'config_file_required' 2015-03-20 14:56:02 +09:00
Ian Barwick
f096cca84f Fix parameter checking for STANDBY CLONE
Previous check for the master host was ineffective. We'd be better off explicitly
requiring at least hostname, database and usernames for the master rather
than relying on whatever defaults were in place when STANDBY CLONE is
run, especially as dbname and username are used in recovery.conf.
2015-03-20 14:47:04 +09:00
Ian Barwick
0fbb83262f Rename t_configuration_options member 'pgctl_options' to 'pg_ctl_options'
Change is to make it match the actual configuration item.
2015-03-20 11:02:32 +09:00
Ian Barwick
a0a3ef58b0 Remove item "Timeline increases when promoting a standby"
Covered by `pg_ctl promote`.
2015-03-20 10:42:07 +09:00
Ian Barwick
b007fc8b39 3.0rc4 2015-03-19 23:28:40 +09:00
Ian Barwick
ae19c9bd5d Only execute pg_stop_backup() if pg_start_backup() was previously executed
It's not a problem per-se but produces some unnecessary and possibly
confusing errors.
2015-03-19 23:19:34 +09:00
Ian Barwick
1b4a8917ca Transfer hint in error message to its own log notice 2015-03-19 23:12:39 +09:00
Ian Barwick
ce66a7c2d2 We shouldn't terminate with an error if no event record could be created
Event records are advisory and non-critical; there may be paths
where we're not able to connect to a valid master and hence unable
to write a record. (If an 'event_notification_command' is defined,
this should serve as a backup notification of the event).
2015-03-19 23:09:29 +09:00
Ian Barwick
9a3196b671 Add a hint if 'standby register' fails due to insert error 2015-03-19 23:01:31 +09:00
Ian Barwick
46a3082055 No need for log_event() function 2015-03-19 22:49:50 +09:00
Ian Barwick
ebabc68f8a Add recovery.conf file location and contents to debugging output 2015-03-19 22:15:45 +09:00
Ian Barwick
c757985640 primary -> master
For consistency
2015-03-19 11:26:47 +09:00
Ian Barwick
172a3d90cf Terminate rather than destroy 2015-03-19 09:55:20 +09:00
Ian Barwick
86d24759a0 In configuration check, check that 'archive_command' is not empty 2015-03-18 16:07:34 +09:00
Ian Barwick
7bd54b5a70 3.0rc3 2015-03-17 23:16:18 +09:00
Ian Barwick
3e04c8e720 Event logging and notifications 2015-03-17 20:10:00 +09:00
Ian Barwick
7f98bb7aec Create event record for rempgrd termination
Also fix a few incorrect exit codes.
2015-03-17 19:08:59 +09:00
Ian Barwick
9e2736be4c Remove superfluous configuration check
Also add note about configuration parsing failure and event logging.
2015-03-17 18:41:17 +09:00
Ian Barwick
4b3966d6a7 Update HISTORY 2015-03-17 16:07:04 +09:00
Ian Barwick
5a1036cea2 Update and rework repmgr.conf.sample 2015-03-17 14:13:46 +09:00
Ian Barwick
e21448831d Standardize configuration error messages for 'failover' parameter.
Better to fail with an error than assume a default value if an
unrecognized value is detected.
2015-03-17 08:19:29 +09:00
Ian Barwick
155f5075cb Improve configuration error and warning messages 2015-03-17 08:14:27 +09:00
Ian Barwick
9cfd6680b3 Remove superfluous comment 2015-03-17 08:01:09 +09:00
Ian Barwick
874616f149 Add %n/node id format option for 'event_notification_command' 2015-03-16 18:04:50 +09:00
Ian Barwick
61ce18ebbe Add configuration parameter 'event_notifications' 2015-03-16 17:31:26 +09:00
Ian Barwick
922dfd88e5 Add configuration option 'event_notification_command'
Command to be executed each time an event is logged.

Following formatting sequences will be interpolated:

      %e - event type
      %d - description
      %s - success (1 or 0)
      %t - timestamp
2015-03-16 13:41:13 +09:00
Ian Barwick
b41235b896 Tweak code comments 2015-03-16 09:31:08 +09:00
Ian Barwick
0307c51d4b Add initial event logging code 2015-03-16 07:44:54 +09:00
Abhijit Menon-Sen
6d608aea7f Merge pull request #50 from wking/autofailover-quick-setup-copy-edits
autofailover_quick_setup.rst: Assorted copy edits
2015-03-15 23:13:28 +05:30
W. Trevor King
5d26e27b48 autofailover_quick_setup.rst: '$(...)' for command substitution
Both are in POSIX [1], but the dollar-paren form is nicer [2].

[1]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_03
[2]: http://mywiki.wooledge.org/BashFAQ/082
2015-03-14 12:13:22 -07:00
W. Trevor King
2fa2dfff95 autofailover_quick_setup.rst: Double-colon before literal block 2015-03-14 12:00:30 -07:00
W. Trevor King
9e5b3e0a2d autofailover_quick_setup.rst: Replace tabs with spaces
Before this commit there was inconsistency over the indentation.  This
commit consolidates around two spaces.
2015-03-14 11:59:46 -07:00
W. Trevor King
e0b82393b0 autofailover_quick_setup.rst: Restructure notes about witness server information
Avoid repeating "it needs", and explain that the superuser password it
needs is for the witness database (and not a sudo password, or a
superuser on the production database).
2015-03-14 11:56:36 -07:00
W. Trevor King
5c64f09889 autofailover_quick_setup.rst: 'failover procedure' -> 'the failover procedure' 2015-03-14 11:50:47 -07:00
W. Trevor King
af7dee05a4 autofailover_quick_setup.rst: 'it is needed' -> 'you need'
Drop the passive voice.
2015-03-14 11:49:10 -07:00
W. Trevor King
bdb8ee1a6f autofailover_quick_setup.rst: 'Clone the node1' -> 'Clone node1'
This sounds better to me, but maybe that's just my American dialect
:p.  The issue of what name get articles is complicated [1].

[1]: http://english.stackexchange.com/questions/59271/why-there-is-the-before-some-names-but-not-others
2015-03-14 11:43:54 -07:00
W. Trevor King
3799d089a1 autofailover_quick_setup.rst: 'Log in' -> 'Log in to'
For some discussion, see [1].

[1]: http://english.stackexchange.com/questions/5302/log-in-to-or-log-into-or-login-to
2015-03-14 11:40:37 -07:00
W. Trevor King
d06bd0ddea autofailover_quick_setup.rst: 'allows setups' -> 'allows for' 2015-03-14 11:34:42 -07:00
W. Trevor King
7fed433df1 autofailover_quick_setup.rst: 'hostname fully qualified' -> FQDN
This is the usual terminology [1].

[1]: http://en.wikipedia.org/wiki/Fully_qualified_domain_name
2015-03-14 11:33:54 -07:00
W. Trevor King
9517624297 autofailover_quick_setup.rst: Replace 'server used for witness'
With 'witness server' in most places.

When defining the nodes, I went with 'server used as a witness', since
'**witness** is the hostname ... of the witness server' sounded like a
tautology.  The longer phrasing isn't really any different, but it
sounds better to me ;).
2015-03-14 11:33:53 -07:00
W. Trevor King
25ea635689 autofailover_quick_setup.rst: Reword 'failover need to vote'
And some other minor tweaks to this paragraph.  I split the
witness-repmgrd bit off into its own sentence, since that's pretty
independent of the voting business.
2015-03-14 11:33:53 -07:00
W. Trevor King
0d971d9009 autofailover_quick_setup.rst: Reword name-with-status caution
Fix the 'recommanded' typo and reword to drop the passive voice and
some awkward phrasing.
2015-03-14 11:32:11 -07:00
W. Trevor King
5bba37cebd autofailover_quick_setup.rst: Replace 'fail-over' with 'failover'
Use the more common spelling.  Before this commit:

  $ git grep -i failover | wc -l
  67
  $ git grep -i fail-over | wc -l
  2
2015-03-14 11:17:46 -07:00
Abhijit Menon-Sen
886a9fd036 A couple of items for later 2015-03-13 16:15:53 +05:30
Abhijit Menon-Sen
94d0d119f6 Fix typo 2015-03-13 16:15:53 +05:30
Ian Barwick
96c8cd4148 Update code comments 2015-03-13 16:43:12 +09:00
Ian Barwick
619f95d85c Update code comments 2015-03-13 12:49:06 +09:00
Ian Barwick
97ae6dbf57 Remove superfluous configuration check
This is already done in parse_config()
2015-03-13 12:04:08 +09:00
Ian Barwick
2929ed9be0 Make parameters 'conninfo' and 'node_name' mandatory
There's no reason why they need to be absent; if absent they're
likely to cause confusion.
2015-03-13 11:57:34 +09:00
Ian Barwick
33037dd7fb Explicitly specify problematic parameter names in error messages. 2015-03-13 11:47:28 +09:00
Ian Barwick
36db199882 Retrieve node's active status too 2015-03-13 11:31:01 +09:00
Ian Barwick
728b71c700 Clarify error message
"Node information" is too vague.
2015-03-13 08:26:11 +09:00
Abhijit Menon-Sen
97c9525479 Note what to do with the names 2015-03-12 20:34:08 +05:30
Abhijit Menon-Sen
bf957ac173 Note 9.4 above wal_keep_segments 2015-03-12 20:33:07 +05:30
Abhijit Menon-Sen
e358c20b84 Oops, it's .rst not .md; also typeset filenames properly 2015-03-12 20:21:17 +05:30
Abhijit Menon-Sen
aaf219a694 Even more clear 2015-03-12 20:15:23 +05:30
Abhijit Menon-Sen
c69e4e93f2 Be very clear about conninfo's host= 2015-03-12 20:14:27 +05:30
Abhijit Menon-Sen
8a4f4bbd83 Shorten the title; we don't need to say cluster 2015-03-12 20:11:29 +05:30
Abhijit Menon-Sen
36a9e17bd3 More feedback is good 2015-03-12 20:09:03 +05:30
Abhijit Menon-Sen
95ac7e889b Tweak and add a reference to .sample 2015-03-12 20:07:46 +05:30
Abhijit Menon-Sen
0a5457efb2 Rewrite the repmgr configuration section 2015-03-12 20:04:31 +05:30
Abhijit Menon-Sen
aa67a4b7e9 Add missing newline 2015-03-12 19:46:40 +05:30
Abhijit Menon-Sen
f8a0e45f5b Rewrite the server configuration section 2015-03-12 19:39:10 +05:30
Abhijit Menon-Sen
6b8f96b590 Split out packaging notes too 2015-03-12 18:34:55 +05:30
Abhijit Menon-Sen
e01807ea20 Split out SSH configuration bits from the old README 2015-03-12 18:22:53 +05:30
Abhijit Menon-Sen
080bb81aeb A last little tweak 2015-03-12 18:07:58 +05:30
Abhijit Menon-Sen
d8fe1ebf47 Minor .md tweaking 2015-03-12 18:01:15 +05:30
Abhijit Menon-Sen
9b7cb5b0c0 Rewrite installation and move things around a bit 2015-03-12 17:58:27 +05:30
Abhijit Menon-Sen
2c69119eff Don't say 'standbies', especially when we don't actually do anything 2015-03-12 17:49:27 +05:30
Abhijit Menon-Sen
cc1e285d90 Rewrite requirements 2015-03-12 17:37:05 +05:30
Abhijit Menon-Sen
4ee84f4f05 Rewrite the introduction and overview 2015-03-12 16:54:33 +05:30
Abhijit Menon-Sen
ad83f8f12e Fix typo 2015-03-12 14:14:30 +05:30
Ian Barwick
ce254ccde3 Add instructions for upgrading from repmgr2 to repmgr3 2015-03-12 14:15:00 +09:00
Ian Barwick
c833dd65f9 rempgr -> repmgr
The rampager strikes again.
2015-03-12 11:42:50 +09:00
Ian Barwick
7e615c5e0d Add witness server information 2015-03-12 11:42:28 +09:00
Ian Barwick
a0a2f87d32 Fix format and typos 2015-03-12 10:50:02 +09:00
Ian Barwick
dce16d794c Update README - add witness create section 2015-03-12 10:44:38 +09:00
Ian Barwick
60b14ab107 Update README 2015-03-12 10:34:00 +09:00
Ian Barwick
65afc42afa Remove superfluous comment 2015-03-12 10:16:46 +09:00
Ian Barwick
0bba5ad792 3.0rc2 2015-03-11 22:54:29 +09:00
Ian Barwick
f3d5a4a7b0 Clarify pg_basebackup vs rsync 2015-03-11 21:35:42 +09:00
Ian Barwick
6597a03559 Remove accidentally added file 2015-03-11 21:34:46 +09:00
Ian Barwick
78dad4fc52 Add note about replication slots 2015-03-11 21:33:34 +09:00
Ian Barwick
b152cccd69 Events table removed for now
Was very experimental.
2015-03-11 21:26:43 +09:00
Ian Barwick
6e5d4e0235 Add repmgr command reference 2015-03-11 18:13:45 +09:00
Ian Barwick
5ade2a1f2d Clarify that slots won't work with 9.3 and add useful links 2015-03-11 17:43:09 +09:00
Ian Barwick
cd2f74a840 Update README with replication slot information 2015-03-11 17:40:27 +09:00
Ian Barwick
fb28ee6f1c Update README 2015-03-11 15:48:01 +09:00
Ian Barwick
c02d226d2f Clarify error message 2015-03-11 15:31:19 +09:00
Ian Barwick
fe1bd5fb91 Clarify reason for defaulting to port 5499 for the witness server 2015-03-11 15:02:13 +09:00
Ian Barwick
bc63099dcf Add missing \n 2015-03-11 14:52:01 +09:00
Ian Barwick
ef5ef9c13f Update README 2015-03-11 13:53:17 +09:00
Ian Barwick
02646165be No need to keep 2.x spec files hanging around
Per suggestion from Martín.
2015-03-11 09:15:18 +09:00
Ian Barwick
d08bd352c1 Use pg_malloc0() instead of malloc() 2015-03-10 23:37:18 +09:00
Ian Barwick
53b990c65d Initialize cli_errors 2015-03-10 15:59:53 +09:00
Ian Barwick
1979fe63ca Rename variable for consistency 2015-03-10 15:56:53 +09:00
Ian Barwick
b0ce1fc801 Fix release numbers 2015-03-10 14:51:31 +09:00
Ian Barwick
28c2652580 Put files back where expected in Makefile
They'll be common between releases anyway.
2015-03-10 14:41:15 +09:00
Ian Barwick
e3b8a8fc3a Initial spec file for 3.x/9.3 2015-03-10 14:09:05 +09:00
Ian Barwick
74d925475e Separate specfiles by major version 2015-03-10 11:07:59 +09:00
Ian Barwick
bd96e0ca72 Remove various temporary debugging output, comments 2015-03-10 09:55:16 +09:00
Ian Barwick
918ee3811f Improve error message 2015-03-10 08:42:46 +09:00
Ian Barwick
606d0afabc primary -> master
For consistency.
2015-03-09 15:48:46 +09:00
Ian Barwick
e16c3b2c9a Improve -?/--help output 2015-03-09 15:16:24 +09:00
Ian Barwick
4e6c250830 Remove experimental event logging code
Needs more bikeshedding.
2015-03-09 14:39:04 +09:00
Ian Barwick
29110a6e11 Consolidate version checking code 2015-03-09 14:19:13 +09:00
Ian Barwick
abf92883a8 Clean up log output
No need to prefix each line with the program name; this was pretty
inconsistent anyway. The only place where log output needs to identify
the outputting program is when syslog is being used, which is done
anyway.
2015-03-09 12:00:05 +09:00
Ian Barwick
bdf1696b58 Fix WAL level check for 9.4 and later 2015-03-09 10:07:31 +09:00
Ian Barwick
7ad001e0c5 Parse config file before daemonizing
Daemonizing changes the current working directory to '/',
which breaks configuration file parsing if the file is in
the previous working directory and provided without an
explicit path.

Also it makes general sense to parse the configuration file
before daemonizing.
2015-03-09 08:26:33 +09:00
Ian Barwick
fb8296644d Canonicalize configuration file path 2015-03-09 08:25:35 +09:00
Ian Barwick
e603498f43 Parse config file before daemonizing
Daemonizing changes the current working directory to '/',
which breaks configuration file parsing if the file is in
the previous working directory and provided without an
explicit path.

Also it makes general sense to parse the configuration file
before daemonizing.
2015-03-09 08:21:54 +09:00
Ian Barwick
d7365535ab Reject parameters with empty values. 2015-03-08 00:12:33 +09:00
Ian Barwick
a55587d75a Initialise upstream_node value 2015-03-07 23:54:54 +09:00
Ian Barwick
5a9b6eea1f Prevent trim() from segfaulting on an empty string 2015-03-07 23:47:07 +09:00
Ian Barwick
a572efe929 No need to destroy buffer here 2015-03-07 23:46:24 +09:00
Ian Barwick
c6b0f77923 Prevent trim() from segfaulting on an empty string 2015-03-07 23:45:07 +09:00
Martín Marqués
66b399b886 Add check for wal_level = logical so we don't fail on 9.4
On 9.4 we have logical decoding, which introduced a new wal_level called
logical. This level includes all the previous ones, so you can run a
hot_standby if wal_level = logical, because the relevant information for
hot_standby will be there, plus other information needed for logical
decoding.

We fix this be adding a second check when wal_level is not hot_standby.
2015-03-06 10:37:43 -03:00
Ian Barwick
2339adba6c Fix event logging when cloning from another standby
We can only write to the primary, which we'll need to find seperately
when cloning from a standby.
2015-03-06 18:39:36 +09:00
Ian Barwick
ff63954c68 do_standby_clone(): primary_conn -> upstream_conn
We could be cloning from a standby.
2015-03-06 17:44:06 +09:00
Ian Barwick
1a9fbd623f Fix log message 2015-03-06 16:10:53 +09:00
Ian Barwick
491309f4ba Write events of note to a log table
This makes keeping track of events such as failovers
much easier. Note that this is for convenience and is
not a foolproof auditing log.

Sample output:

repmgr_db=# SELECT * from repmgr_test.repl_events ;
 node_id |          event           | successful |        event_timestamp        |                         details
---------+--------------------------+------------+-------------------------------+----------------------------------------------------------
       1 | master_register          | t          | 2015-03-06 14:14:08.196636+09 |
       2 | standby_clone            | t          | 2015-03-06 14:14:17.660768+09 | Backup method: pg_basebackup; --force: N
       2 | standby_register         | t          | 2015-03-06 14:14:18.762222+09 |
       4 | witness_create           | t          | 2015-03-06 14:14:22.072815+09 |
       3 | standby_clone            | t          | 2015-03-06 14:14:23.524673+09 | Backup method: pg_basebackup; --force: N
       3 | standby_register         | t          | 2015-03-06 14:14:24.620161+09 |
       2 | repmgrd_start            | t          | 2015-03-06 14:14:29.639096+09 |
       3 | repmgrd_start            | t          | 2015-03-06 14:14:29.641489+09 |
       4 | repmgrd_start            | t          | 2015-03-06 14:14:29.648002+09 |
       2 | standby_promote          | t          | 2015-03-06 14:15:01.956737+09 | Node 2 was successfully be promoted to master
       2 | repmgrd_failover_promote | t          | 2015-03-06 14:15:01.964771+09 | Node 2 promoted to master; old master 1 marked as failed
       3 | repmgrd_failover_follow  | t          | 2015-03-06 14:15:07.228493+09 | Node 3 now following new upstream node 2
(12 rows)
2015-03-06 14:35:41 +09:00
Ian Barwick
072c2d70ff Reformat comment for legibility 2015-03-05 17:54:34 +09:00
Ian Barwick
1f9b19f3ff Add configuration option ignore_external_config_files 2015-03-05 13:46:55 +09:00
Ian Barwick
04fe820aff Note where compatibility check for replication slots is carried out
Scanning the source code gives the impression there's no check.
2015-03-05 10:12:36 +09:00
Ian Barwick
0f8759d316 Consolidate duplicated code 2015-03-04 17:27:51 +09:00
Ian Barwick
2b6415b339 Update README.md 2015-03-04 15:54:14 +09:00
Ian Barwick
defb1e819b Add some annotations 2015-03-04 10:36:19 +09:00
Ian Barwick
7ae4434f6e Add new quickstart guide with annotated examples only.
The other content will become the new README.
2015-03-03 19:03:52 +09:00
Ian Barwick
e3b734f177 Check for max_replication_slots > 0 2015-03-03 18:51:58 +09:00
Ian Barwick
187a6b6d23 Fix slot name 2015-03-03 18:50:48 +09:00
Ian Barwick
238fc589a1 Improve logging of configuration file operations 2015-03-03 18:14:26 +09:00
Ian Barwick
63b9254be4 Change log notice to log debug 2015-03-03 17:49:40 +09:00
Ian Barwick
44196de2f4 Add initial FAQ file 2015-03-03 16:21:57 +09:00
Ian Barwick
46888de77f Improve configuration file handling
Put logic in config.c so it can be shared between repmgr and repmgrd.
2015-03-03 15:39:56 +09:00
Ian Barwick
6b1f55ff1b Improve command line error handling
Per e.g. this complaint:

 https://groups.google.com/d/msg/repmgr/a-SMIQFGDBs/rgRH3p4ZPgYJ

Before:

    $ repmgr -f /etc/postgres/repmgr.conf cluster status

    repmgr: Replicator manager
    Try "repmgr --help" for more information.

after:

    $ repmgr -f /etc/postgres/repmgr.conf cluster status
    repmgr: Replication manager
    [ERROR] Unknown server command 'status'
    Try "repmgr --help" for more information.
2015-03-03 11:13:37 +09:00
Ian Barwick
3d3f082617 Ensure witness server updates its node records following a failover
This involves mainly abstracting the functions which copy
and create records from repmgr.c to dbutils.c, as they need
to be shared between repmgr and repmgrd.

Per issue noted here:

  https://groups.google.com/forum/#!topic/repmgr/v5nu1Xwf6X0
2015-03-03 08:57:20 +09:00
Ian Barwick
db5db06244 Retire old README
Keep it around for reference for now.
2015-03-03 07:43:02 +09:00
Ian Barwick
dd7193715c Gracefully fail when node has not been registered 2015-03-02 10:38:44 +09:00
Ian Barwick
f8f81f4bf1 Update HISTORY file with items included in 2.0.2
Also standardize on spaces instead of tabs
2015-03-02 08:04:18 +09:00
Ian Barwick
27a4780cc3 Update HISTORY 2015-03-02 07:58:06 +09:00
Ian Barwick
b79bce5821 Support tablespace mapping in --rsync-only mode
This makes it practical to take a back with rsync where tablespaces
require remapping. It also makes tablespace remapping possible for
9.3, where pg_basebackup does not support this option.
2015-03-01 14:10:17 +09:00
Ian Barwick
a69176fc1b tablespace_dirs -> tablespace_mapping
For consistency with the parameter name.
2015-02-28 11:03:03 +09:00
Ian Barwick
65dcce55e8 Remove redundant comment
Issue already addressed.
2015-02-28 10:54:42 +09:00
Ian Barwick
ff30df3d96 In rsync mode, move pg_control last
Emulate the backup protocol as much as possible.
2015-02-27 19:27:46 +09:00
Ian Barwick
74e4b6aa3c Refactor rsync file/directory exclusion
Better simulate what goes on in 'src/backend/replication/basebackup.c';
avoid copying some files/directories introduced in 9.4.
2015-02-27 15:59:47 +09:00
Ian Barwick
22dd164cbb Clarify intent 2015-02-27 13:29:21 +09:00
Ian Barwick
63c416bb76 Set synchronous_commit to off for current session
Forward-ported from 2.x; need to verify it makes sense.
2015-02-27 11:40:57 +09:00
Ian Barwick
e2c2f97307 Clarify repmgr.conf usage 2015-02-27 10:02:42 +09:00
Ian Barwick
41e9a370af Clarify repmgr.conf usage 2015-02-27 10:01:38 +09:00
Ian Barwick
2eb242553a Fix log message 2015-02-27 09:57:18 +09:00
Ian Barwick
e3ecd3cdc5 Move cluster size check to an earlier point
Seems to make more sense that way.
2015-02-25 14:28:42 +09:00
Ian Barwick
32611f5f04 Add --rsync-only option
Sometimes it's desirable to re-sync a "stale" data directory
on a standby, rather than start from scratch with pg_basebackup().

This re-adds the rsync code from the 2.x series, with some
modifications.

TODO: tablespace support.
2015-02-25 14:17:09 +09:00
Ian Barwick
ba254d2f06 Clarify comment 2015-02-24 16:00:28 +09:00
Magnus Hagander
69f842bbc2 Fix markup
This was broken in commit  8faf41dd94,
most likely because of a runaway search/replace.
2015-02-24 09:43:54 +09:00
Magnus Hagander
99e1c33668 Fix markup
This was broken in commit  8faf41dd94,
most likely because of a runaway search/replace.
2015-02-24 08:47:34 +09:00
Ian Barwick
6791bd9ad3 Clean up rempgr debugging output 2015-02-23 15:17:06 +09:00
Ian Barwick
3e6659dda0 Modify log message for consistency and testing
Pre-3.0: 'repmgr standby clone complete'
3.0: 'repmgr standby clone (using pg_basebackup) complete' or
     'repmgr standby clone (using rsync) complete'
2015-02-20 12:29:15 +09:00
Ian Barwick
ce498e4d1e Update devel version string 2015-02-20 10:10:17 +09:00
Ian Barwick
0762b28679 Update HISTORY file with items included in 2.0.2
Also standardize on spaces instead of tabs
2015-02-17 16:12:37 +09:00
Ian Barwick
5dff3017c8 Update HISTORY file 2015-02-12 17:22:34 +09:00
Ian Barwick
b453c6a533 Fix master port check
Check introduced in dc0dfe9b56
was comparing the provided database name instead of the port.
2015-02-12 14:44:05 +09:00
Ian Barwick
09c7ba95ac Update HISTORY notes 2015-02-12 14:42:23 +09:00
Ian Barwick
e213f3b99d Fix master port check
Check introduced in dc0dfe9b56
was comparing the provided database name instead of the port.
2015-02-12 14:39:05 +09:00
Jaime Casanova
eabb3cb1ab Add "--checksum" in rsync when using "--force"
If the user don't put that option in rsync_options using of "--force"
could be unsafe.
While the probability of failures because of this are low they aren't
zero.
2015-02-11 10:38:35 +09:00
Jaime Casanova
e886e72f14 Add "--checksum" in rsync when using "--force"
If the user don't put that option in rsync_options using of "--force"
could be unsafe.
While the probability of failures because of this are low they aren't
zero.
2015-02-10 20:15:40 -05:00
Ian Barwick
1803a16c7e Detect changes to configuration file
This will prevent unnecessary reconnects to the upstream and
updates of the node record on the primary.
2015-02-10 12:35:19 +09:00
Ian Barwick
4f36b2c085 Probably needed. 2015-02-10 11:07:18 +09:00
Ian Barwick
19aba38327 Handle DB error when updating upstream node 2015-02-10 10:32:20 +09:00
Ian Barwick
2d82ade170 Clarify error message 2015-02-10 10:21:17 +09:00
Ian Barwick
21730899da Clarify error message.
Avoid implying there's a configuration file if none was provided.
2015-02-10 10:08:49 +09:00
Ian Barwick
94bc5bdf80 Remove unneeded function 2015-02-09 18:31:18 +09:00
Ian Barwick
1369fe5c79 Rename 'test_mode' to 'target_directory_provided'
Which describes its meaning more accurately.

Also update some comments.
2015-02-09 16:32:21 +09:00
Ian Barwick
e71dd4945e Remove duplicated error message 2015-02-09 13:42:51 +09:00
Ian Barwick
49d1abf130 rempgr: adapt tablespace handling for 9.4 and later
See note in code about 9.3.

Also ensure that no empty parameters are passed to pg_basebackup.
2015-02-09 13:39:18 +09:00
Ian Barwick
01a33198fd Add configuration file parameter for pg_basebackup
"pg_basebackup_options"
  Enable custom options to be passed to pg_basebackup
  (e.g. --max-rate, --checkpoint, --xlogdir)

"tablespace_mapping"
  Analogue to pg_basebackup's (9.4 and later) -T/--tablespace-mapping
  option.

  Tablespace mapping could also be passed via "pg_basebackup_options",
  however by providing a separate parameter it makes the configuration
  file easier to read and allows us to verify the specified tablespaces
  exist (pg_basebackup won't do this, which can lead to undesired
  behaviour, i.e. attempting to create the tablespace in the original
  path).
2015-02-09 10:31:06 +09:00
Ian Barwick
1d28a2d08e runtime_options.wal_keep_segments is prepopulated with default value
Explicitly track if setting came from command line parameter.
2015-02-05 11:55:52 +09:00
Ian Barwick
d4578e023e Mention use_replication_slots in sample config file 2015-02-05 11:19:54 +09:00
Ian Barwick
9ceef937eb Emit warning if -w/--wal-keep-segments used when use_replication_slots set 2015-02-05 11:17:23 +09:00
Ian Barwick
f047ec9526 Use DEFAULT_WAL_KEEP_SEGMENTS in help output instead of hard-coded number 2015-02-04 14:08:55 +09:00
Ian Barwick
a3f0e89a05 Improve pg_bindir parameter handling
Previously, the pg_bindir parameter was mandatory and could only be
provided in the repmgr.conf file, which was leading to the slightly
bizarre situation that e.g. for "clone standby", repmgr was complaining
that it didn't want the configuration file when it actually did.

pg_bindir is now optional - if not provided, it will use the default
path. It can be provided in the repmgr.conf file, or as a command
line parameter; the latter overrides the former.
2015-02-04 14:04:04 +09:00
Ian Barwick
3d9d0d98af Improve repmgr configuration file handling
Previous behaviour was somewhat counterintuitive, with an error
message being logged if no configuration file provided or found,
even though this is not actually an error.

Configuration files now handled like this:

- if a configuration file is explicitly provided (-f), error out
  if not found.

- if no configuration file explicitly provided, attempt to open
  default configuration file; if this does not exist, log
  notice and continue with default values.

Also, for 9.4 and later add a hint about replication slot usage
if 'use_replication_slots' not set.
2015-02-04 09:57:51 +09:00
Ian Barwick
49debcdf92 Add version check if replication slot usage requested
Replication slots require 9.4 or greater
2015-02-02 22:16:04 +09:00
Ian Barwick
7a760c32ff Store slot name in repl_nodes table 2015-02-02 17:57:15 +09:00
Ian Barwick
b4b5e6cd30 do_standby_clone(): rename conn to primary_conn
For clarity.
2015-02-02 16:53:35 +09:00
Ian Barwick
2ece014952 Initial support for physical replication slots
Todo:
 - if slots specified in repmgr.conf, verify server version
 - store generated slot name in `repl_nodes` table
2015-02-02 15:53:53 +09:00
Ian Barwick
01360c3d39 Improve repl_status view. 2015-01-29 15:08:37 +09:00
Ian Barwick
031a726f04 Enable get_master_connection() to accept a null value for master_id
Saves worrying about the purpose of various superfluous ints
2015-01-29 11:25:01 +09:00
Ian Barwick
5c67d47881 Add query result tests 2015-01-28 18:05:19 +09:00
Ian Barwick
f40b3ac48a Consolidate node type parsing 2015-01-28 11:57:34 +09:00
Ian Barwick
109269f7fb When writing monitoring info, ensure standby connects to current primary
If the node is a cascaded standby and the primary fails, `primary_conn`
will not be updated automatically; when writing monitoring info,
ensure we connect to the current primary.
2015-01-27 21:19:25 +09:00
Ian Barwick
36d94c88ac Handle empty result set
Should never happen, but just in case.`
2015-01-27 16:28:17 +09:00
Ian Barwick
23ef305afb After promotion or follow, update internal node metadata record 2015-01-27 16:25:58 +09:00
Ian Barwick
99dae5cdcb Function is_witness() no longer required
Node type can be extracted directly from the metadata
2015-01-27 15:32:13 +09:00
Ian Barwick
b552710767 Remove global variable my_local_mode
Information now contained in metadata`x
2015-01-27 13:53:36 +09:00
Ian Barwick
7e4c26b8a0 Clarify upstream role in log messages 2015-01-27 12:39:39 +09:00
Ian Barwick
f8639a7878 Add TODO note 2015-01-26 22:11:54 +09:00
Ian Barwick
f2309bd0a9 Remove redundant comments 2015-01-26 21:25:37 +09:00
Ian Barwick
061e72d7cd Rename connection variable for clarity
Connection will always be the primary
2015-01-26 20:12:34 +09:00
Ian Barwick
0a19bf1e23 Reword notice to make more sense in log output context 2015-01-24 05:03:57 +09:00
Ian Barwick
84a4766f13 Basic failover for cascaded standby nodes
Attempt to attach to the next available upstream node, otherwise
quit monitoring. We'll need to add further options for failover
scenarios, including attempting to attach to another node,
shutting down the server completely etc.
2015-01-24 04:22:40 +09:00
Ian Barwick
3be8bf8e4c Check primary connection
Verify that existing primary connection is valid, and if not
attempt to find and connect to the current primary node.
2015-01-22 12:20:23 +09:00
Ian Barwick
1e6f1a88b0 On local node failure, attempt to update record on primary server 2015-01-22 11:45:01 +09:00
Ian Barwick
4a8912c2b4 Update comments and debugging output 2015-01-22 10:59:33 +09:00
Ian Barwick
3279e9e47e Separate functions for primary and cascading standby failover 2015-01-22 10:12:03 +09:00
Ian Barwick
5c4e77f8e2 do_failover() -> do_primary_failover() 2015-01-16 17:28:51 +09:00
Ian Barwick
b09f987341 Add note 2015-01-16 16:59:44 +09:00
Ian Barwick
fe758eda9f Update repl_nodes following failover
repl_nodes table updated by each node following failover to
show that either it is the primary, or which primary it has
started to follow.
2015-01-16 16:28:09 +09:00
Ian Barwick
c413cff461 Function to update node records 2015-01-16 14:14:04 +09:00
Ian Barwick
609453a848 Handle failover of top-level standby
Cascaded standbys will not go into failover so we need to ignore
these when looking for candidates for promotion.
2015-01-16 12:35:01 +09:00
Ian Barwick
a82d37e48a Improve node metadata and upstream connecting mechanism
To handle cascaded replication we're going to have to keep track
of each node's upstream node. Also enumerate the node type
("primary", "standby" or "witness") and mark if active.
2015-01-16 10:28:02 +09:00
Ian Barwick
4b6c097a3e Use AS for consistency 2015-01-16 08:46:28 +09:00
Ian Barwick
3dfa33d01d Store upstream node ID if set
Required to manage cascaded standbys
2015-01-16 00:29:43 +09:00
Ian Barwick
a20afe28ec Add upstream_node_id to repl_nodes table 2015-01-15 23:54:07 +09:00
Ian Barwick
692204e381 Consolidate duplicated schema check code 2015-01-15 18:34:51 +09:00
Ian Barwick
2ae27521a3 Some infrastructure for supporting cascading replication
Does not fully work yet.
2015-01-15 15:37:09 +09:00
Ian Barwick
d141d2a8aa Remove unused variable 2015-01-14 16:25:24 +09:00
Ian Barwick
fc6f5ddaa7 Add function repmgr_get_primary_conninfo() 2015-01-14 16:23:08 +09:00
Ian Barwick
4b7fb70de3 Add current year to copyright 2015-01-14 15:50:42 +09:00
Ian Barwick
5db6489ae5 Initial support for cascaded standbys 2015-01-14 14:18:57 +09:00
Ian Barwick
96f6695a52 Clean up repmgr_get_last_standby_location() polling loop
No need to reconnect on every iteration of the loop. Move conditions
which break out of the loop straight away out of the loop.
2015-01-13 16:08:36 +09:00
Ian Barwick
f006a79af9 Clean up log messages for invalid LSNs 2015-01-13 14:53:55 +09:00
Ian Barwick
3a8aa86e0c Remove pointless check 2015-01-13 14:25:58 +09:00
Ian Barwick
9cbac64ad4 Remove pointless check
Witness server can never be considered as a promotion candidate.
2015-01-13 14:24:19 +09:00
Ian Barwick
242fc8416c Consolidate disconnection calls 2015-01-13 13:59:27 +09:00
Ian Barwick
355d8b8f01 Use InvalidXLogRecPtr for pedantic correctness 2015-01-13 13:47:22 +09:00
Ian Barwick
8df7966540 Rename variable
"find_best" sounds like an imperative.
2015-01-13 13:42:30 +09:00
Ian Barwick
1a790549ea Refactor if-statement 2015-01-13 13:40:47 +09:00
Ian Barwick
b80d25ad33 Add some hopefully correct comments for future reference
Also some debugging output which will need to be removed later.
2015-01-13 11:12:20 +09:00
Ian Barwick
a1a61e5ec3 Remove unneeded include 2015-01-13 07:57:54 +09:00
Ian Barwick
1221b73293 repmgrd: explicitly state INSERT statement target columns 2015-01-12 20:47:22 +09:00
Ian Barwick
93d5d7905f Remove "XL*" macros and rationalize XLogRecPtr handling
As of 9.3, XLogRecPtr is a uint64, which makes it much easier to
handle, so we can retire the legacy macros and work directly
with the values.
2015-01-12 17:18:57 +09:00
Ian Barwick
41a5274b44 Comment for consistency 2015-01-12 15:30:17 +09:00
Ian Barwick
d9f83cf620 Replace hard-coded value with local_options.reconnect_attempts; 2015-01-12 14:09:44 +09:00
Ian Barwick
905a2d0a5e Have witness server retry determining the new master
Loop a few times before giving up
2015-01-12 14:05:37 +09:00
Ian Barwick
526803c5e0 Witness server should always try to re-connect to primary
Standbys will try to reconnect even in MANUAL_FAILOVER mode,
so it's consistent to have the witness server do that too.
2015-01-12 13:32:04 +09:00
Ian Barwick
2ff24fecf2 Remove redundant constant 2015-01-12 13:16:13 +09:00
Ian Barwick
a5ead16d6f Change query to use COUNT(*)
No point implying we're fetching the entire record
2015-01-12 12:28:06 +09:00
Ian Barwick
5fb84b9627 Witness server: on failover attempt to reconnect to new master
Previously it was just quitting.
2015-01-12 11:23:20 +09:00
Ian Barwick
437485bf6a Fix debugging output 2015-01-12 09:47:13 +09:00
Ian Barwick
822867ec24 Fix thinko 2015-01-12 09:40:47 +09:00
Ian Barwick
5b88a980b8 Add some debugging output 2015-01-12 07:57:42 +09:00
Ian Barwick
e958b8f2d7 Fix typo 2015-01-09 18:44:31 +09:00
Ian Barwick
74a963a10e Fix schema quoting
There was a lot of duplicated/unused related to handling the
schema name; consolidated and rationalised.
2015-01-09 15:51:34 +09:00
Ian Barwick
dd064cb47c res1 -> res 2015-01-09 11:20:07 +09:00
Ian Barwick
17de82493a Consolidate repl_node insert statements 2015-01-09 11:14:47 +09:00
Ian Barwick
f2fa60f5cf Tidy up SQL statements
Improves readability
2015-01-09 09:46:41 +09:00
Ian Barwick
acf2744ed7 Replace magic number with defined constant
And use it to restrict the number of rows retrieved to avoid
overflowing the array.
2015-01-08 17:19:02 +09:00
Ian Barwick
7bafd490c1 Remove #define for pre-9.3 versions 2015-01-08 16:59:10 +09:00
Ian Barwick
7c15176646 Clean up comments 2015-01-08 14:04:43 +09:00
Ian Barwick
97cbd7d557 Remove superfluous variable 2015-01-08 13:23:33 +09:00
Ian Barwick
5798241205 Add 'recovery_target_timeline = latest' to recovery.conf
Also revert to generating our own recovery.conf rather than using
pg_basebackup's minimal file.
2015-01-08 10:46:49 +09:00
Ian Barwick
5b5b4cd4cd Remove redundant comment 2015-01-08 09:51:53 +09:00
Ian Barwick
9dd78f34db Add missing short options to --help output 2015-01-07 08:56:05 +09:00
Ian Barwick
a5b5e3d384 No need to store master version number here 2015-01-07 08:55:17 +09:00
Ian Barwick
241622694d Remove support for pre-9.3 servers 2015-01-06 14:53:26 +09:00
Ian Barwick
687872e979 get_data_directory() -> get_pg_setting()
More code consolidation
2015-01-06 13:47:31 +09:00
Ian Barwick
3033f2dfaf Fix get_cluster_size()
Was returning a pointer to a cleared PQresult
2015-01-06 10:30:33 +09:00
Ian Barwick
718024454e Add function get_data_directory()
Consolidate duplicate code
2015-01-06 10:06:58 +09:00
Ian Barwick
e3379c0fbf Bump minimum supported version to 9.3
We need to assume the existence of timeline switch following by
standbys.
2015-01-06 08:29:57 +09:00
Ian Barwick
ba4413ce91 Change any log messages using 'master' to 'primary'
For consistency, as 'master' is the preferred terminology in repmgr
2015-01-06 08:19:48 +09:00
Ian Barwick
e85e0732ef Nope, no real point doing that here 2015-01-05 22:55:58 +09:00
Ian Barwick
97fb3dbb14 Have 'standby promote' use 'pg_ctl promote' 2015-01-05 21:28:11 +09:00
Ian Barwick
8e09e7b57c Fix error code handling 2015-01-05 10:49:21 +09:00
Ian Barwick
4f37515113 Pass username to pg_basebackup 2015-01-05 10:29:02 +09:00
Ian Barwick
413cc6eb54 Add todo comment 2015-01-05 09:37:30 +09:00
Ian Barwick
f23c43b986 Clean up exit error codes 2015-01-05 09:36:48 +09:00
Ian Barwick
38de150436 Fix spelling 2015-01-05 09:23:26 +09:00
Ian Barwick
a80da61203 Remove unneeded parameters 2015-01-04 17:10:29 +09:00
Ian Barwick
4fbe8ca70e copy_remote_files() now only needs to copy individual files
In which case rsync should be an atomic operation
2015-01-04 16:03:27 +09:00
Ian Barwick
1aa12a122f Selectively copy configuration files if not in master data directory 2015-01-04 15:59:07 +09:00
Ian Barwick
c54d5f9a9c Add check for max_wal_senders > 0 on master 2015-01-04 08:31:52 +09:00
Ian Barwick
db49206fc5 Clean up logging output 2015-01-04 08:25:50 +09:00
Ian Barwick
017f66e15e Make --check-master-config state no problems found 2015-01-04 08:15:11 +09:00
Ian Barwick
e06949db87 Add option --check-master-config
Consolidate the configuration checks carried out when cloning
a standby, and enable them to be run separately to check the
required configuration without running STANDBY CLONE multiple times.
2015-01-03 11:29:00 +09:00
Ian Barwick
2f6ce44cab Consolidate server version checks in repmgr
Merge basically identical checks in multiple places into a single
function. Only doing this in repmgr, as repmgrd only performs
the version check in one place and we'd need to somehow pass progname
to the function as well, which isn't worth the effort.
2015-01-03 09:25:08 +09:00
Ian Barwick
1f21040fb3 Fix help output formatting 2015-01-03 08:12:13 +09:00
Ian Barwick
4e9c58c7db Update copyright to 2015 2015-01-03 08:12:13 +09:00
Ian Barwick
3e983b258c Fix help output formatting 2015-01-03 08:08:47 +09:00
Ian Barwick
9093a9d1ce Update copyright to 2015 2015-01-03 08:06:09 +09:00
Ian Barwick
4305f76fa9 Remove unused code 2015-01-02 08:27:20 +09:00
Ian Barwick
7700086703 Use pg_basebackup 2014-12-31 11:04:01 +09:00
Ian Barwick
8b69b1e16f Optionally retrieve server_version string as well
In a couple of places we'll need to report the human-readable
version number
2014-12-29 15:52:53 +09:00
Ian Barwick
f94626bf7b Refactor version number detection
Use the reported `server_version_num` integer for version number
detection and comparison. This makes it easier to set an arbitrary
minimum supported version (rather than "9.0 or later") as well
as future-proofing for 10.x and later.
2014-12-29 14:54:04 +09:00
Ian Barwick
4c64d52afb Update repmgrd usage examples and help output 2014-12-25 10:52:50 +09:00
Ian Barwick
6f80cd5441 Add option "--initdb-no-pwprompt"
Previously repmgr passed the -W flag to initdb, which forced
manual input of a password; this option removes the -W flag
to make repetitive testing easier.
2014-12-24 19:07:08 +09:00
Ian Barwick
ee69730f8b Error message correction 2014-12-24 15:36:03 +09:00
Ian Barwick
9306726e06 Add note about repmgr.conf.sample 2014-12-24 13:15:45 +09:00
Ian Barwick
44fa98f828 Add links to relevant blog posts 2014-12-23 09:12:29 +09:00
Ian Barwick
28fd9d5aeb Spelling 2014-12-22 16:21:08 +09:00
Ian Barwick
24b2ee09b3 Add -S/--superuser option for witness database creation
Previously the witness database creation code was hard-coding the
username 'postgres' when accessing the previously initialised database.
However initdb was not passed any explicit username, meaning the
default database superuser name was the same as the user running
repmgr.

With this patch, a superuser user name (default: postgres) will
be passed to initdb.

Per report by eggyknap [1]

[1] https://github.com/2ndQuadrant/repmgr/issues/38
2014-12-22 16:01:58 +09:00
Ian Barwick
8faf41dd94 Fix markup 2014-12-18 16:42:09 +09:00
Ian Barwick
763881b1ed Whitespace cleanup 2014-12-18 10:52:20 +09:00
Ian Barwick
94f520e1de Fix variable name 2014-12-09 15:14:41 +09:00
Marco Nenciarini
f72bb2f093 Fix syntax errors in repmgr.c 2014-10-30 12:09:55 +01:00
Jaime Casanova
927667905e Code review: Do not use psql on do_witness_create,
use createdb and createuser binaries instead
2014-10-29 19:25:14 -05:00
Jaime2ndQuadrant
684d66f48e Merge pull request #27 from Nexperteam/witness-fixes
Witness fixes: create a db and user to avoid using postgres

This is so, we can create the appropiate user and database on the witness.
2014-10-29 19:05:38 -05:00
Jaime2ndQuadrant
406c325ccb Merge pull request #23 from wamonite/fix_witness
fix: witness creation and monitoring. 

On copy_configuration() we are using the res variable when is still used on the loop.
2014-10-29 18:44:53 -05:00
Martín Marqués
c23ee3830b errcode.h is a local header. 2014-09-29 16:09:55 -03:00
Martín Marqués
dc0dfe9b56 If the user doesn't pass the port on which the primary server is listening
we have to assume it's the DEFAULT_MASTER_PORT.

This was not done, so we added a check to see if it has a value that is
usable, else we use DEFAULT_MASTER_PORT.
2014-09-29 16:06:05 -03:00
Ian Barwick
313d787ebf Clarify repmgr database role 2014-07-16 14:10:18 +09:00
Ian Barwick
253992c5ec Fix pg_hba.conf example 2014-07-16 13:51:05 +09:00
Ian Barwick
47b7c4ce06 Update HISTORY for minor release 2.0.1 2014-07-16 11:00:58 +09:00
Ian Barwick
99ed9a065e Formatting fixes 2014-07-16 10:58:05 +09:00
Ian Barwick
a87d859e56 Correct year in specfile changelog 2014-07-16 09:58:51 +09:00
Ian Barwick
7350a8bf57 Fix code block formatting 2014-07-16 08:07:07 +09:00
Ian Barwick
75baed233b Convert QUICKSTART file to markdown format
Less effort for more consistent formatting (at least the way
github renders it).
2014-07-16 07:57:00 +09:00
Ian Barwick
5b9ac4585b Formatting fixes 2014-07-07 14:10:00 +09:00
Ian Barwick
2cbee90f35 Fix formatting 2014-07-07 11:51:10 +09:00
Ian Barwick
fa7d8df534 Add a "quickstart" guide
Provides a succinct overview of the steps needed to get repmgr
up and running as.
2014-07-07 11:39:26 +09:00
Ian Barwick
0cbd5d3933 Fix log messages in do_standby_promote()
Initial connection is to current standby, before attempting to
connect to old master.
2014-07-07 11:30:29 +09:00
Ian Barwick
a0e4c99ab4 Typo fixes 2014-07-07 11:10:32 +09:00
Ian Barwick
98c5215871 Change successful standby promotion message to log level 'NOTICE'
Was previously 'ERROR'.
2014-07-07 11:09:07 +09:00
Ian Barwick
e40b9db0a6 Properly specify rsync --exclude directories
Using '--exclude=dirname/*' to explicitly specify directories whose contents
should not be copied. This will result in empty directories being created
on the destination if they exist on the source, but that's not a problem as
they are needed anyway.

Previously the generated rsync command contained '--exclude=pg_log*', which
will break replication on 9.5 as the wildcard expansion prevents the
'pg_logical' directory from being copied.
2014-07-07 10:42:45 +09:00
Ian Barwick
54e62c3d65 Typo fixes and minor wording tweaks for clarity 2014-07-03 15:41:51 +09:00
Abhijit Menon-Sen
bfd482bebc Merge pull request #28 from Nexperteam/rhel-scripts
adapt makefile for RHEL + RHEL specific files
2014-06-26 22:55:56 +05:30
Abhijit Menon-Sen
6a0fc43086 Merge pull request #26 from Nexperteam/master
Makefile: create bindir before instal + force dir
2014-06-26 22:54:09 +05:30
Abhijit Menon-Sen
8f47111072 Merge pull request #31 from riegie/patch-1
Update README.rst
2014-06-26 22:51:52 +05:30
Riegie Godwin Jeyaranchen
0b5b3aaa4b Update README.rst
Fixing a grammar mistake.
2014-06-19 20:53:42 -04:00
Nathan Van Overloop
d8bba0de03 init script: make status call return proper return code 2014-06-06 15:47:33 +02:00
Nathan Van Overloop
a11bb60fd5 re-add comment full debug of log.c 2014-06-06 14:45:27 +02:00
Nathan Van Overloop
4f810aee2c on init of witness server create db and user to avoid using postgres 2014-06-06 14:36:12 +02:00
Nathan Van Overloop
73d352b2a2 adapt makefile for RHEL + RHEL specific files 2014-06-06 14:30:37 +02:00
brynhood
143aa57bb8 Makefile: create bindir before instal + force dir
in order to facilitate building of an rpm I've added an / to the end of the dirs.
2014-04-28 14:27:52 +02:00
Abhijit Menon-Sen
5b15fcff5c Merge pull request #24 from PriceChild/patch-1
Typo in example command.
2014-04-08 11:04:09 +05:30
PriceChild
4469de533e Typo in example command. 2014-04-01 16:31:33 +01:00
Warren Moore
30045f3bec keep naming consistent 2014-03-24 15:18:37 +00:00
Warren Moore
d93d42fadb fix: witness creation and monitoring
While reading node entries from master use a separate PGresult when inserting into witness.
Witness monitoring supplies a null value for 'last_apply_time'.
2014-03-24 14:19:29 +00:00
Christian Kruse
7c89a4d762 Merge pull request #20 from kjoe/master
debian init script and config file documentation fixes
2014-03-24 07:46:56 +01:00
József Kószó
b3c68dead8 debian init script and config file documentation fixes 2014-03-22 22:23:15 +01:00
József Kószó
b9ab9010c0 debian init script and config file documentation fixes 2014-03-22 22:13:33 +01:00
József Kószó
2a6c835a5a debian init script and config file documentation fixes 2014-03-21 14:18:07 +01:00
Christian Kruse
2d48d5aee4 fixing some documentation errors 2014-03-10 15:48:44 +01:00
Christian Kruse
653e11c2a7 basic min_recovery_apply_delay support 2014-03-10 15:41:38 +01:00
Christian Kruse
91c29fe2a2 removed old comment 2014-03-06 18:34:41 +01:00
Christian Kruse
573f1d3b2e no longer use global variable for SQL query buffer 2014-03-06 18:34:41 +01:00
Christian Kruse
0a6ff7faec removed no-longer used variable 2014-03-06 18:34:41 +01:00
Christian Kruse
98b1f8d28a rather big refactoring: use a naming scheme
In the past naming of functions, variables and such didn't really have a
naming scheme. Now they should have.
2014-03-06 18:34:40 +01:00
Christian Kruse
9eba986833 avoid usage of snprintf()
We have a nice little abstraction for snprintf with covering the case
that a string is too big for the target buffer – let's use that!
2014-03-06 18:34:40 +01:00
Christian Kruse
164cf9d08f completely avoid usage of strnlen() 2014-03-06 18:34:40 +01:00
Christian Kruse
d8b8bf0e2a pg_indent'ing all files… 2014-03-06 18:34:40 +01:00
Christian Kruse
fed5c77653 various improvements and bugfixes in the init script 2014-03-06 15:23:22 +01:00
Christian Kruse
8429b43edf Merge pull request #14 from wamonite/fix_follow_user
fix: store the master connection user name on standby follow
2014-03-06 15:20:02 +01:00
Warren Moore
7e55ce737d fix: store the master connection user name on standby follow 2014-03-05 16:49:56 +00:00
Christian Kruse
98c7635fb5 fixing more compiler warnings 2014-03-04 17:58:36 +01:00
Christian Kruse
90ecb2b107 fix: check return values of freopen()
Some compiles complain about not checking the return value of freopen(),
so we check it
2014-03-04 15:32:48 +01:00
Christian Kruse
50b9022a41 fix: don't use Windows newlines 2014-03-04 12:59:23 +01:00
Christian Kruse
150ccc0662 add option to avoid repmgrd started upon installation
Now repmgr.repmgrd.default has another option: REPMGRD_ENABLED. Valid
values are either yes or no.
2014-03-04 12:46:05 +01:00
Christian Kruse
0ff14a2aa1 avoid compiler warnings 2014-02-21 13:47:29 +01:00
Christian Kruse
5215265694 fix: now CloseConnections() is much more safe 2014-02-18 17:06:36 +01:00
Christian Kruse
e45ac25348 fix: progname is const, do not free it
The leak is irrelevant
2014-02-18 16:45:35 +01:00
Christian Kruse
a1ce01f033 fix: fixed some leaks 2014-02-18 16:35:29 +01:00
Christian Kruse
516cde621a fix: strcpy() on overlapping memory regions is invalid 2014-02-18 15:42:20 +01:00
Christian Kruse
f0807923a3 fix: gettimeofday() expects two arguments 2014-02-18 15:33:56 +01:00
Christian Kruse
10ca8037f8 added some more log messages
Now we should be able to distinguish different events more easily
2014-02-18 14:10:12 +01:00
Christian Kruse
0dc46f0dc8 fix: set connection to NULL when finishing it
This will avoid CloseConnections() to try to close an already closed connection.
2014-02-18 13:42:49 +01:00
Christian Kruse
c3b58658ad fixing repmgr repl_status columns
repmgr repl_status had the column time_lag which was documented to be
the time a standby is behind master. In fact it only works like this
when viewed on the standby and not on the master: there it only was the
time of the last status update. We dropped that column and replaced it
by a new column „communication_time_lag“ which is the content of the
repl_status column on the master. On the standby we contain the time of
the last update in shared mem though refer always to the correct time
nonetheless where repl_status is queried. We also added a new column,
„replication_time_lag“, which refers to the apply delay.
2014-02-15 01:35:27 +01:00
Christian Kruse
18f1fed77f fixing wait_connection_availability()
wait_connection_availability() did take at least 2 seconds per call in
the old incarnation. Now we may finish a call without any sleep at all
when the result is already ready at the time called
2014-02-15 01:31:12 +01:00
Christian Kruse
d58fd080ca flush stderr after a log message appears
We had the problem that the log file appeared empty for a long time due
to file buffers. Thus we call fflush() after every log message so the
log file gets written out to disk quickly
2014-02-15 01:29:12 +01:00
Christian Kruse
c4ac2d3343 fixing PQexec() calls
fixing several calls where we did not check the result status but only
the return value; the query may fail nonetheless
2014-02-15 01:27:53 +01:00
Christian Kruse
5ff1beeea7 do not enable autofailover by default
Autofailover is an experimental feature which should not be enabled by
default. The user has to be aware of what he is doing when enabling it.
2014-02-11 09:27:31 +01:00
Christian Kruse
ca470647cb cleanup of usage text
Now it properly aligns and breaks at 78 characters.
2014-01-30 14:26:17 +01:00
Christian Kruse
62ee287e3f updated TODO 2014-01-30 14:10:14 +01:00
Christian Kruse
729a1b848a release notes for 2.0 stable 2014-01-30 13:59:17 +01:00
Christian Kruse
701cf043fd fix: seems as if I missread -hackers 2014-01-23 16:46:49 +01:00
Christian Kruse
bbb67c55f6 simple past of set is set 2014-01-23 10:50:37 +01:00
Christian Kruse
c2c48a9fe6 removed already finished TODO tasks 2014-01-23 10:48:04 +01:00
Christian Kruse
9d6ac2ebf9 fixed documentation and line endings 2014-01-23 10:39:21 +01:00
Christian Kruse
680f23fb1d copyright push 2014-01-23 10:37:49 +01:00
Christian Kruse
1159113c58 ignore the dynamic shared memory directory, too 2014-01-23 10:02:32 +01:00
Christian Kruse
f25a709454 added an explicit type cast to avoid compiler warnings 2014-01-22 15:17:47 +01:00
Christian Kruse
897daddcc7 removed not needed arguments to avoid compiler warnings 2014-01-22 15:17:28 +01:00
Christian Kruse
0fdcce0477 use if instead of switch and avoid a warning 2014-01-22 15:12:29 +01:00
Christian Kruse
de58eff7c1 added a chdir() for proper daemonizing 2014-01-22 14:30:38 +01:00
Christian Kruse
f2a0b31a20 more log format fixes 2014-01-22 14:30:24 +01:00
Christian Kruse
e007a55967 fix: do not use fsync()
We do not need fsync(), the fflush() is enough to avoid concurrent
logs.
2014-01-22 11:47:50 +01:00
Christian Kruse
d235c696af fix: do not newline at the start of a log line
This breaks the log file format since it will have a line break directly
after the timestamp
2014-01-22 11:47:02 +01:00
Christian Kruse
4ef6fbb5fe do not close stderr but reopen it to /dev/null
We want stderr to be always a valid file descriptor
2014-01-21 16:25:57 +01:00
Christian Kruse
2e61d7b156 refactoring: daemonizing is now a function 2014-01-21 16:19:49 +01:00
Christian Kruse
4496a0761e we now use a function and are more sophisticated
Refactoring part: we now use a function to generate the PID
file. Sophistication: we now check if the PID contained in the file is a
valid PID. We ignore the file if it doesn't.
2014-01-21 16:18:15 +01:00
Christian Kruse
3978ead184 use a second fork to avoid a terminal
after the setsid() we are the process leader. And as a process leader we
are able to open a new terminal, even if we currently don't own one. So
we do another fork and do not call setsid() and not become a process
leader to avoid that.
2014-01-21 15:51:33 +01:00
Christian Kruse
b36dbf61fe reopening stdin and stdout to /dev/null now
stdin, stdout and stderr should always be valid file handles. Thus we
don't close them but reopen them to /dev/null
2014-01-21 15:31:38 +01:00
Christian Kruse
84466ecca5 log_crit() is more appropriate 2014-01-21 15:23:20 +01:00
Christian Kruse
649086e5e4 use unlink() instead of remove()
`remove()` will do a rmdir if necessary - we don't want that. So we use `unlink()`
2014-01-21 15:22:31 +01:00
Christian Kruse
7cf2eb440d renamed config options to a much more descriptive name 2014-01-21 15:19:50 +01:00
Christian Kruse
388bbfb773 split install target into install_prog and install_ext
Patch by Marco Nenciarini <mnencia@debian.org>
2014-01-21 14:23:33 +01:00
Christian Kruse
a89aa02c68 fix: make pg_config be settable from outside the makefile
Patch by Marco Nenciarini <mnencia@debian.org>
2014-01-21 14:22:59 +01:00
Christian Kruse
c81793b63f fix: added forgotten options.priority value
Patch by Marco Nenciarini <mnencia@debian.org>
2014-01-21 14:18:12 +01:00
Christian Kruse
b4e83cf188 Add format attribute checking for printf() like functions
Patch by Marco Nenciarini <mnencia@debian.org>
2014-01-21 14:14:36 +01:00
Christian Kruse
1db61ce277 fix: fail when repmgr_funcs is not pre-loaded
when repmgr_funcs is not pre-loaded `repmgr_update_standby_location()`
will return false and `repmgr_get_last_standby_location()` will return
an empty string. Thus we may end in an endless loop. To avoid that we fail.
2014-01-21 13:54:10 +01:00
Christian Kruse
41abf9a7ef fix: flushing and fsync()ing the log file
When not flushing and fsync()ing it the output may be garbled due to
concurrent writes to the file (system() spawns a child process with
stdin/stdout/stderr inherited from it's parent)
2014-01-21 13:52:27 +01:00
Christian Kruse
abebc53ddc fix: sscanf() does not set variables to 0 on error 2014-01-21 13:48:41 +01:00
Christian Kruse
5fc4a0382f added config options sleep_delay and sleep_monitor
sleep_monitor replaces the old SLEEP_MONITOR define and makes it
configurable; this is the interval in which we monitor

sleep_delay replaces the old sleep(300) when waiting for the master to
recover.
2014-01-17 14:35:50 +01:00
Christian Kruse
a7d3c9b93a fix: also close stderr when using syslog logging 2014-01-17 12:14:26 +01:00
Christian Kruse
ee9dc9e247 do not use exit()
We avoid using exit() to be able to clean up when we have to
terminate. This includes removal of the PID file as well as closing
database connections.
2014-01-17 11:28:55 +01:00
Christian Kruse
94cb5b94e7 fix: reopen log file on SIGHUP 2014-01-16 17:16:45 +01:00
Christian Kruse
a08aa50f92 fix: close stdin and stdout only in repmgrd
closing stdin and stdout might cause problems when using system(), so we
avoid it.
2014-01-16 16:01:58 +01:00
Christian Kruse
9563877fbb new config option, stdout/stdin closed
Now stdin and stdout get closed. Additionally stderr gets closed and
reopened to the new config option „logfile“ if specified
2014-01-16 15:22:34 +01:00
Christian Kruse
4f3bd6612c do not exit in getMasterConnection() 2014-01-16 15:07:15 +01:00
Christian Kruse
192ee3cdb0 do not exit in get_cluster_size 2014-01-16 15:07:06 +01:00
Christian Kruse
6f149ead8f do not exit in guc_setted and guc_setted_typed 2014-01-16 14:48:46 +01:00
Christian Kruse
77aa6aa326 do not exit in pg_version 2014-01-16 14:48:42 +01:00
Christian Kruse
18206b3a64 do not exit() in is_witness 2014-01-16 14:28:56 +01:00
Christian Kruse
91446bcf93 fix: do not try to reconnect infinitely 2014-01-10 17:26:02 +01:00
Christian Kruse
dcdf8788ae fix: handle connection loss to standby
We do basically the same as we do for the master since connections drop
from time to time
2014-01-10 17:12:03 +01:00
Christian Kruse
4fabfbbbd0 fix: do not exit in is_standby()
Instead we now return an int with 0 meaning „not a standby,“ 1 meaning
„is a standby“ and -1 meaning „connection dropped“
2014-01-10 17:11:16 +01:00
Christian Kruse
c41030b40e Merge branch 'REL2_0_STABLE'
Conflicts:
	HISTORY
	dbutils.h
	repmgr.c
	repmgrd.c
	version.h
2014-01-10 16:07:33 +01:00
Christian Kruse
a0fdadd5d2 this way it is much cleaner 2014-01-09 15:35:44 +01:00
Christian Kruse
4c3d7f80ed now code compiles with -ansi -pedantic and has less warnings 2014-01-09 14:45:07 +01:00
Christian Kruse
6e3fe059d8 added config options pg_bindir and pg_ctl_options 2014-01-09 14:44:34 +01:00
Christian Kruse
9f26254ac3 fix: added some missing initializers to avoid compiler warning 2014-01-09 13:33:22 +01:00
Christian Kruse
0e8ff1730e added handling of a PID file 2014-01-09 13:04:40 +01:00
Christian Kruse
634fdff303 fix: do not call setup_event_handlers() on WIN32
If we put setup_event_handlers() in #ifdef WIN32, we have to do it for
the call and the declaration, too
2014-01-09 12:57:16 +01:00
Christian Kruse
cbce29f009 fixed typos 2014-01-08 11:55:03 +01:00
Christian Kruse
920f925e4b added a new cli option --daemonize
This option forks the process and generates a new session. This
effectively detaches it from the shell. Don't forget to redirect stderr
or use syslog for logging!
2014-01-08 11:53:15 +01:00
Christian Kruse
9fe2d6886e white space cleanup 2014-01-07 16:42:06 +01:00
Christian Kruse
0068dd573a fix: do not compare pointers but the strings 2014-01-07 15:52:29 +01:00
Christian Kruse
d0f3cb59c7 fix: create data directory after sanity check 2014-01-07 14:42:55 +01:00
Christian Kruse
7428e92e10 fix: correctly check the return value of PQexec()
not only check if return value is not NULL but also check that the
returned result is a PGRES_COMMAND_OK (e.g. the INSERT was successful)
2014-01-07 14:27:31 +01:00
Christian Kruse
a97065113d fix: remove own node earlier if force is set
We have to remove our own node before we check for a new master if force
is set; else master register would fail on the second time since there
already is a master (ourselves), even if we specify -F
2014-01-07 14:16:58 +01:00
Christian Kruse
9e2f276fcf fix: do not exit after pg_start_backup() w/o pg_stop_backup() 2014-01-07 14:02:29 +01:00
Christian Kruse
b0cd2b5e43 fix: do not exit() in create_pgdir()
This could leave the database in a locked state (pg_start_backup()).
And since all calls to create_pgdir() handle the return value correctly
we simply replace the exit() by a return false
2014-01-07 14:01:46 +01:00
Jaime Casanova
9209248420 Fix oversight in the header of guc_setted_typed() 2013-12-19 11:09:08 -05:00
Jaime Casanova
6693b99288 Files to create the debian package
Patch by: Christian Kruse
2013-12-19 01:43:12 -05:00
Jaime Casanova
8e7b487838 Update debian control file 2013-12-19 01:41:24 -05:00
Jaime Casanova
7f796e2d15 Update history and credit files 2013-12-19 01:40:00 -05:00
Jaime Casanova
5e04ab6eae Add a ssh_options parameter to allow ssh checking
to consider non-default values (ie: a different port)

Patch by Jay Taylor
2013-12-19 01:22:55 -05:00
Jaime Casanova
a1f4285e2b Add guc_setted_typed() function to allow
wal_keep_segmeents to be checked as an integer instead
of text

Patch by Jay Taylor
2013-12-19 01:22:42 -05:00
Jaime Casanova
493133986d Add timestamps to log line in stderr
Patch by Christian Kruse
2013-12-19 01:15:28 -05:00
Jaime Casanova
8b370dc581 Fix some typos
Patch by Krzysztof Gajdemski
2013-12-07 13:25:46 -05:00
Jaime Casanova
43af00aa12 Ignore pg_log when cloning, just like we ignore pg_xlog 2013-12-04 01:23:48 -05:00
Jaime Casanova
3c8df59eb9 Make repmgr compile in 9.3.
Patch provided by Shawn Ellis with some fixes by me.
2013-11-14 00:43:35 -05:00
Jaime Casanova
b410772627 Rework algorithm to coordinate voting
Make this by waiting for all nodes to finish a step, before starting
a new one. So everyone starts promoting or following in a coordinated
fashion.
Also make a few fixes.
2013-09-26 13:24:31 -05:00
Jaime Casanova
d99024ba11 Make repmgrd survive to the failover
To do this it needs to reconnect to the new master
2013-09-26 11:58:59 -05:00
Jaime Casanova
1afaa3a26f Rearrange the logic in do_failover() for further improvements.
Specially, make this a more coordinated process by making all
nodes waiting for the others before going to the next step.

This is one step further in following Andres Freund advices
but there is still a lot to do in order to complete that,
specially it could be needed to add more fields to repl_nodes
and to the shm area.
2013-09-23 18:28:58 -05:00
Jaime Casanova
079a7c9f16 In a failover situation get the nodes in a well defined order.
When deciding which node will be the new master, we should get the
nodes in a well defined order otherwise two standbys could process
nodes with the same priority in different order and end up with
a two master situation.
2013-07-26 00:59:50 -05:00
Jaime Casanova
3b66a31ac9 In a failover situation get the nodes in a well defined order.
When deciding which node will be the new master, we should get the
nodes in a well defined order otherwise two standbys could process
nodes with the same priority in different order and end up with
a two master situation.
2013-07-26 00:52:31 -05:00
Jaime Casanova
bdf957ca52 Add a missing ')'. This is a typo introduced in commit
2bc8044fda

Per complaint from Carlos Chapi when compiling for a customer.
2013-07-13 12:39:13 -05:00
Jaime Casanova
ad3630e7a9 Add a missing ')'. This is a typo introduced in commit
2bc8044fda

Per complaint from Carlos Chapi when compiling for a customer.
2013-07-13 12:37:15 -05:00
Jaime Casanova
67b451aa45 If PQgetCancel() returns NULL we should also return false.
Noted by Andres Freund.
2013-07-12 08:03:36 -05:00
Jaime Casanova
0a70d907ae Improve messages in wait_connection_availability, so we know what
error makes the failover procedure to start

By gripe from Andres Freund
2013-07-12 08:03:25 -05:00
Jaime Casanova
2e7acf03c4 If PQgetCancel() returns NULL we should also return false.
Noted by Andres Freund.
2013-07-12 08:01:01 -05:00
Jaime Casanova
2bc8044fda Improve messages in wait_connection_availability, so we know what
error makes the failover procedure to start

By gripe from Andres Freund
2013-07-10 19:25:58 -05:00
Jaime Casanova
ab1d380843 If PQcancel() fails, consider it as if the master is failing.
Because PQcancel() establish a new synchronous connection to the
database, if it fails it means something wrong has happenned with
master. So instead of just ignore the failure, CancelQuery() now
reports a failure condition so we can detect master's death in
that situation.

This is very important specially when only postmaster crashes but
other children/backend connections are still there. Because the
children connection won't fail and CancelQuery() failure is our
only indication of something wrong happenning.
Currently we just ignore the PQcancel() failure which leads us to
a situation in which we just loop forever
trying to cancel the async query.

Reported by: Martin Euser <martin.euser@nl.abnamro.com>
Problem analyzed and bug spotted by: Andres Freund <andres@2ndquadrant.com>
Patch by: Jaime Casanova <jaime@2ndquadrant.com>
2013-07-10 10:21:51 -05:00
Jaime Casanova
b0b44a157f If PQcancel() fails, consider it as if the master is failing.
Because PQcancel() establish a new synchronous connection to the
database, if it fails it means something wrong has happenned with
master. So instead of just ignore the failure, CancelQuery() now
reports a failure condition so we can detect master's death in
that situation.

This is very important specially when only postmaster crashes but
other children/backend connections are still there. Because the
children connection won't fail and CancelQuery() failure is our
only indication of something wrong happenning.
Currently we just ignore the PQcancel() failure which leads us to
a situation in which we just loop forever
trying to cancel the async query.

Reported by: Martin Euser <martin.euser@nl.abnamro.com>
Problem analyzed and bug spotted by: Andres Freund <andres@2ndquadrant.com>
Patch by: Jaime Casanova <jaime@2ndquadrant.com>
2013-07-10 09:53:45 -05:00
Jaime Casanova
49a2531930 Options -F -W -I -v doesn't accept arguments, which means that on
getopt_long shouldn't be marked with the colon (:) character.

This has been wrong since day one, so backpatching all the way until
1.1
2013-01-13 16:37:39 -05:00
Jaime Casanova
672b237c4e Options -F -W -I -v doesn't accept arguments, which means that on
getopt_long shouldn't be marked with the colon (:) character.

This has been wrong since day one, so backpatching all the way until
1.1
2013-01-13 16:32:56 -05:00
Jaime Casanova
7d94151494 If the node is a witness don't bother asking its position, it always
will be 0/0. We just need to check that we can connect to it to determine
if we are in the majority.
2013-01-11 03:44:50 -05:00
Jaime Casanova
4191b77e70 If the node is a witness don't bother asking its position, it always
will be 0/0. We just need to check that we can connect to it to determine
if we are in the majority.
2013-01-11 03:42:08 -05:00
Jaime Casanova
2a5d431481 Fix a problem that caused a standby to promote itself without going to
voting procedure.

This is because of a race condition inside CheckPrimaryConnection().

This has independently reported by Alex Railean and Dumitru, and Frank Jördens.
Analyzed and fixed by Cédric Villemain.

The fix have been verified to work by Frank
2012-12-19 12:01:27 -05:00
Jaime Casanova
81b8a944de Fix a problem that caused a standby to promote itself without going to
voting procedure.

This is because of a race condition inside CheckPrimaryConnection().

This has independently reported by Alex Railean and Dumitru, and Frank Jördens.
Analyzed and fixed by Cédric Villemain.

The fix have been verified to work by Frank
2012-12-19 11:45:58 -05:00
Jaime Casanova
93a999adc7 Formatting code using astyle 2012-12-11 11:49:07 -05:00
Jaime Casanova
1b69282df9 Formatting code using astyle 2012-12-11 11:47:59 -05:00
Jaime Casanova
06dd252f69 To select new master it needs to know which standby has received more
xlog records from master, so it standby should use pg_last_xlog_receive_location()
to report their positions. This solves a possible situation in which
a standby that is considered as new master when promoted is no longer
the best option.
2012-12-03 09:27:12 -05:00
Jaime Casanova
088ca29fe3 To select new master it needs to know which standby has received more
xlog records from master, so it standby should use pg_last_xlog_receive_location()
to report their positions. This solves a possible situation in which
a standby that is considered as new master when promoted is no longer
the best option.
2012-12-03 09:18:08 -05:00
Jaime Casanova
30e9d06172 Add an option for STANDBY FOLLOW to wait for a master to appear.
This is important for autofailover to do the right thing when
standbys detected master death at different times.

While this is a new option, seems important for the autofailover
to work properly so i will consider the lack of it a bug and
will backpatch to 2.0 where autofailover was introduced.

For gripe from Alex Railean, about a standby not finding the new
master because the new master hasn't finish promoting.
2012-11-14 15:09:26 -05:00
Jaime Casanova
d6bd5aa381 Add an option for STANDBY FOLLOW to wait for a master to appear.
This is important for autofailover to do the right thing when
standbys detected master death at different times.

While this is a new option, seems important for the autofailover
to work properly so i will consider the lack of it a bug and
will backpatch to 2.0 where autofailover was introduced.

For gripe from Alex Railean, about a standby not finding the new
master because the new master hasn't finish promoting.
2012-11-14 15:07:59 -05:00
Gabriele Bartolini
bbdcffa813 Fixed typos notified by lintian 2012-11-09 18:09:43 +01:00
Jaime Casanova
cd1a84252e Fix node decision logic when priorities are involved. Currently if
two nodes with different prorities are equally good to be promoted
the second one (with a lower priority, considering them
in descending order) will win.

Per report from Brailean Dumitru
2012-09-16 02:47:02 -05:00
Jaime Casanova
5f33d9d715 Fix node decision logic when priorities are involved. Currently if
two nodes with different prorities are equally good to be promoted
the second one (with a lower priority, considering them
in descending order) will win.

Per report from Brailean Dumitru
2012-09-16 02:38:28 -05:00
Jaime Casanova
2e19b3688b Add a comment 2012-09-16 02:26:18 -05:00
Jaime Casanova
877f4cf82e Add a comment 2012-09-16 02:23:16 -05:00
Jaime Casanova
de883a4c84 Keep compiler quiet. Noted when compiling in FreeBSD in which i
get a warning for an uninitialized variable.

Also, define InvalidXLogRecPtr. We don't really need it but using
it make the initialization future proof (considering that in 9.3
XLogRecPtr will change its structure).
2012-09-16 02:21:18 -05:00
Jaime Casanova
949f5ee498 Keep compiler quiet. Noted when compiling in FreeBSD in which i
get a warning for an uninitialized variable.

Also, define InvalidXLogRecPtr. We don't really need it but using
it make the initialization future proof (considering that in 9.3
XLogRecPtr will change its structure).
2012-09-16 02:10:02 -05:00
Jaime Casanova
eb2f7efb4a When we have more command-line arguments than we should have we
need to show that last value and we should use only optind for that
instead of optind+1
2012-09-15 17:39:10 -05:00
Jaime Casanova
85ff3ec286 Fix documentation to always use -h sintax to refer to the node we
want to clone or connect to, instead of relying on the fact that
for some time putting that argument at last worked.
2012-09-15 17:38:42 -05:00
Jaime Casanova
499a501afd Make repmgr compatible with FreeBSD.
We need to add an #include and make it use a different path for the
"true" binary.

Maybe we need to make this changes for all BSD systems but having no
evidence of that i prefer to make this only for systems with __FreeBSD__
2012-09-15 17:37:59 -05:00
Jaime Casanova
0a9107d76d Improve sample of commands for promote and follow 2012-09-15 17:37:43 -05:00
Jaime Casanova
2803bb92a8 Make repmgr compatible with FreeBSD.
We need to add an #include and make it use a different path for the
"true" binary.

Maybe we need to make this changes for all BSD systems but having no
evidence of that i prefer to make this only for systems with __FreeBSD__
2012-09-15 17:32:38 -05:00
Jaime Casanova
16fe41eecf Improve sample of commands for promote and follow 2012-09-11 15:53:57 -05:00
Jaime Casanova
95ec0450da When we have more command-line arguments than we should have we
need to show that last value and we should use only optind for that
instead of optind+1
2012-08-30 02:11:48 -05:00
Jaime Casanova
57aa95f674 Fix documentation to always use -h sintax to refer to the node we
want to clone or connect to, instead of relying on the fact that
for some time putting that argument at last worked.
2012-08-30 02:10:10 -05:00
Jaime Casanova
d365a309fc Fix HISTORY to show from newest to oldest 2012-07-27 11:29:07 -05:00
Jaime Casanova
56d2ae4e81 Fix HISTORY to show from newest to oldest 2012-07-27 11:26:18 -05:00
Jaime Casanova
d5a41bb587 Fix tabs in HISTORY 2012-07-27 11:22:04 -05:00
Jaime Casanova
474d3217b4 Fix typos in RELEASE NOTES 2012-07-27 11:21:49 -05:00
Jaime Casanova
3edd87a041 Fix tabs in HISTORY 2012-07-27 11:20:56 -05:00
Jaime Casanova
740208da1c Fix typos in RELEASE NOTES 2012-07-27 11:15:50 -05:00
Jaime Casanova
7a00d5a9a4 Now that we can have no monitoring we need to check all nodes at failover
not only those in repl_monitor
2012-07-21 17:53:15 -05:00
Jaime Casanova
664e1a8321 Now that we can have no monitoring we need to check all nodes at failover
not only those in repl_monitor
2012-07-21 17:49:38 -05:00
Jaime Casanova
5683b905dd New development branch is 2.1dev 2012-07-21 12:22:04 -05:00
Jaime Casanova
d43c6334da Prepare HISTORY and release notes for release 2012-07-21 12:06:33 -05:00
Jaime Casanova
f984b3fd33 Document tunables added in aaf35947ed 2012-07-21 11:10:59 -05:00
Jaime Casanova
aaf35947ed Add tunables for connection retries to master and interval between
connection retries, these parameters along with master_response_timeout
determines the amount of time since failure to failover
2012-07-21 11:01:00 -05:00
Jaime Casanova
08ed0aa987 Commit 2d24518d9d added an additional
'}' at the end of parse_config(). removing.
2012-07-21 10:42:58 -05:00
Jaime Casanova
2d24518d9d If master_response_timeout hasn't been set in repmgr.conf it defaults
to zero, which was causing to a false positive in the failure detection
logic in wait_connection_availability(). So, change that to defaults to 60s
and add a check to avoid it being set to zero or negative.

Problem reported and analyzed by Andrew Newman
2012-07-21 09:49:05 -05:00
Jaime Casanova
a6c94b29de Change release notes because of commit bf241ba1d6 2012-07-06 02:00:46 -05:00
Jaime Casanova
bf241ba1d6 Make the monitoring history capabilities of repmgr be optional and
turned off by default. Most of it has been superseeded by
pg_stat_replication view, we can still start it by using the switch
--monitoring-history
2012-07-06 01:51:22 -05:00
Jaime Casanova
41dbc39527 Add release notes 2012-07-05 09:35:23 -05:00
Jaime Casanova
50b7147f15 Change Copyright date to cover 2012 2012-07-04 10:47:26 -05:00
Jaime Casanova
f5e57aa433 Add an option for "no-history" mode, where repmgrd just checks the
conectivity of master but don't INSERT any data into it
2012-07-04 10:07:31 -05:00
Jaime Casanova
ac5a9d1fd6 The release changed, just wait a little before setting it.
Also make well known names in HISTORY be only names, without
last name
2012-07-02 00:06:57 -05:00
Jaime Casanova
cb740b68be Add a check of the connection inside the CancelQuery() so it check
that before trying to cancel a query, which can block.
2012-06-26 11:29:02 -05:00
Jaime Casanova
d58ea77798 Add a quick setup for autofailover 2012-06-26 07:49:43 -05:00
Jaime Casanova
e3c3c22b6e Improve the version message to actually show the repmgr version not
only postgresql's one
2012-06-25 22:54:48 -05:00
Jaime Casanova
861a3c8f22 Fix CLUSTER CLEANUP, it needs to establish a local connection in order
to look for the master
2012-06-16 01:32:59 -05:00
Jaime Casanova
e51870b504 Force to enter a password for the superuser in the witness, this is
in case we need to send a password to connect as stated in
master's pg_hba.conf.
2012-06-15 13:51:45 -05:00
Jaime Casanova
5651720560 Remove a variable left in last commit 2012-06-15 09:46:01 -05:00
Jaime Casanova
d32a6cdb24 Remove kludge added to create user and db for witness.
It's too fragile, almost always cause a "segment violation" and
don't seems to be very useful.
2012-06-15 09:41:54 -05:00
Jaime Casanova
9e10987b90 Fix a few bugs introduced when merging features 2012-06-15 09:40:09 -05:00
Jaime Casanova
64fce88e99 Add a CLUSTER CLEANUP command to clean monitor's history,
also include a --keep-history (-k) option to indicate how many
days of history to keep
2012-06-13 00:39:54 -05:00
Jaime Casanova
7a76f1998c getMasterConnection() cannot avoid checking the same node that asks
to find the master.
This was a micro optimization based on the fact that all commands that
needed to detect the master were executed from the standby but now that
we have CLUSTER level commands that is not true anymore
2012-06-12 23:28:24 -05:00
Jaime Casanova
4db046a8ea Allow repmgr to obtain tablespace's locations from pg 9.2 and later
in which we no longer have a spclocation column in pg_tablespaces
2012-06-12 11:08:15 -05:00
Jaime Casanova
331eca447a STANDBY CLONE should be run by a SUPERUSER, otherwise we won't be able
to retrieve data_directory and the other parameters we need by
querying the database.
2012-06-12 09:42:50 -05:00
Jaime Casanova
b5b2f93f7e Merge branches 'master' and 'async' 2011-12-02 00:28:17 -05:00
Jaime Casanova
9d03d4a254 After checking that master is alive, is_pgup() should return not keep
checking forever.
2011-12-01 23:58:12 -05:00
Jaime Casanova
3b2ccc5b78 Add a master_response_timeout parameter and use it to limit the amount
of time we spent a reponse from master before declaring the failure.
Also, change is_pgup() so it use PQsendQuery() instead of PQexec to
execute the check of master
2011-12-01 01:20:33 -05:00
Jaime Casanova
89a1e2bcbd Not even consider old master as an option in failover 2011-11-27 19:17:59 -05:00
Jaime Casanova
7077a7c68f Add -w option to pg_ctl commands so we wait until command is finish.
Or at least, we try. By default, after 60 seconds pg_ctl just return.
This make useless to wait ourselves after pg_ctl start of witness so
remove the sleep
2011-11-27 18:38:53 -05:00
Jaime Casanova
9b8fb7e960 Remove last argument from log_err, left in commit 55c7ea4b5e.
Also rephrase the sentence

Reported by Jeroen Dekkers
2011-11-25 14:59:29 -05:00
Jaime Casanova
55c7ea4b5e Fix a wrong message.
It was saying the problem is the version of the PostgreSQL server while
it actually is because the MASTER REGISTER command was running on a
standby node
2011-11-10 09:38:12 -05:00
Jaime Casanova
0240cb2bfb Fix a typo introduced in commit cb764b180d 2011-11-03 12:50:51 -05:00
Jaime Casanova
2e64028f26 Add the improvement of the view repl_status to the history 2011-10-20 23:26:41 -05:00
Greg Smith
27396f462a Add strnlen on platforms that don't have it, such as OS X 2011-10-20 23:23:31 -05:00
Jaime Casanova
cb764b180d Let the clone happen in a session with synchronous_commit off. This
is because in pg 9.1 the default configuration can easily allow sync
rep to be activated even if no standby is present and will block
pg_start_backup() and pg_stop_backup() in that case.
2011-10-03 14:04:27 -05:00
Jaime Casanova
65cf045a63 Fix a few problems introduced in 020e17b059
while adding standby_name
2011-08-09 02:01:00 -05:00
Jaime Casanova
3d53661d97 Fix a typo introduced in the commit about standby_name
(020e17b059)
2011-08-09 01:14:50 -05:00
Jaime Casanova
7b3a9cbbe4 Rename standby_name configuration option as node_name
per gripe by Cedric
2011-08-09 01:01:37 -05:00
Jaime Casanova
276c947202 Add name to nodes and show it for the standby in repl_status. 2011-08-09 00:58:01 -05:00
Jaime Casanova
020e17b059 Add a new standby_name parameter that, when provided in repmgr.conf,
is included in the primary_conninfo as application_name... This is
a simple first step towards making repmgr works fine with 9.1 and
sync standbys
2011-08-09 00:57:23 -05:00
Jaime Casanova
10817ecffc Add "witness" as a node role in CLUSTER SHOW 2011-08-08 13:29:26 -05:00
Jaime2ndQuadrant
f26e37c087 Merge pull request #2 from 2ndquadrant-it/master
Add function to show nodes with actual roles: repmgr cluster show
2011-08-08 11:10:13 -07:00
Carlo Ascani
61c31eeb0c Added function to show nodes with actual roles: repmgr cluster show 2011-08-08 19:32:32 +02:00
Jaime2ndQuadrant
0b5d2418df Merge pull request #1 from 2ndquadrant-it/master
Added function "write_primary_conninfo" which now adds the username to the primary_conninfo parameter in recovery.conf

Author: Gabriele and Marco
2011-08-05 11:03:54 -07:00
Gabriele Bartolini
f44037088b Added function "write_primary_conninfo" which now adds the username to the primary_conninfo parameter in recovery.conf
Signed-off-by: Gabriele Bartolini <gabriele.bartolini@2ndquadrant.it>
Signed-off-by: Marco Nenciarini <marco.nenciarini@2ndquadrant.it>
2011-08-05 17:41:18 +02:00
Carlo Ascani
e05dd729f8 Fix a typo in documentation 2011-08-05 00:15:13 -05:00
Jaime Casanova
ab8d2673dc Remove useless second parameter from create_recovery_file()
per gripe by Gabriele
2011-08-04 17:45:28 -05:00
Jaime Casanova
28c5ac3d91 Make is_standby() and is_witness() work the same way, actually
is_standby() can show the segmentation fault problem but for code
clearity
2011-07-26 18:36:27 -05:00
Carlo Ascani
c983fdf83c Fix a possible double free that would cause a segfault in
checkNodeConfiguration()
2011-07-26 18:22:06 -05:00
Carlo Ascani
158214acae Only log that we have restored the connection when that already happens,
this fix a flood in logs that make them unnecessarily big
2011-07-26 18:16:22 -05:00
Jaime Casanova
04290c1f60 Another pass reviewing code:
- remove a duplicate check for ssh connection and just exit if
  we can't connect to the remote host.
  stop_backup is only needed if pg_start_backup() has been
  already called
- remove a new connection to master in stop_backup label, AFAIC
  we hadn't close the one we already opened
- add a lot of PQfinish(), a few PQclear() and adjust code to what
  we used to do in 1.x
2011-07-26 16:14:44 -05:00
Jaime Casanova
cedc5e20fb Add a check to ensure 'hot_standby=on' on master. While this parameter
doesn't have an effect here it will be a reminder for users, besides
will reduce things user have to do on the standby
2011-07-26 16:12:51 -05:00
Jaime Casanova
b61ac86b5f Move repmgr_update_standby_location() and
repmgr_get_last_standby_location() functions to repmgr schema.
This will be important when we want to create this as an
extension, so better make it be in the right place from day 1.
2011-07-26 16:12:11 -05:00
Jaime Casanova
64da72b48b repl_monitor.last_wal_standby_location should accept nulls because
of the witness
2011-07-26 16:11:26 -05:00
Jaime Casanova
c4778a83c5 Be consistent in the use of sqlquery_snprintf() for query strings,
which was not used in the new code.
Also add a few "newline" characters in some messages, and other
minutia.
2011-07-19 05:02:51 -05:00
Jaime Casanova
4d26e4d21e Redefining repl_status view to improve performance, also add an
index on repl_monitor to speed up even more the view.
2011-06-13 11:58:43 -05:00
Jaime Casanova
3f4ff5a862 A "HEAD" word remaining from a merge conflict was accidentally left
in... removing it
2011-06-10 21:16:07 -05:00
Simon Riggs
1d05467df1 README additions and improvements 2011-06-07 11:37:09 +01:00
Simon Riggs
15ba3342aa Remove whitespace 2011-06-07 11:12:58 +01:00
Greg Smith
3a950c9f8b Squashed commit of the following:
commit e7ef17117efe6679e154a4905d587c808b48df50
Merge: cd3a280... 43268f2...
Author: Greg Smith <greg@2ndQuadrant.com>
Date:   Tue Jun 7 01:40:08 2011 -0400

    Merge commit 'origin/master' into autofailover

    Conflicts:
    	repmgr.c

commit cd3a280804a01c5270c5c743e5822c7beb9ac77a
Merge: 72ad378... 8200b68...
Author: Greg Smith <greg@2ndQuadrant.com>
Date:   Tue Jun 7 00:52:42 2011 -0400

    Merge commit 'origin/master' into autofailover

    Conflicts:
    	config.c

commit 72ad378bed21d74dab743fec411fe10b19007481
Merge: 17bafa1... 367d0b1...
Author: Greg Smith <greg@2ndQuadrant.com>
Date:   Tue Jun 7 00:38:01 2011 -0400

    Merge commit 'origin/master' into autofailover

    Conflicts:
    	config.c
    	dbutils.c
    	repmgr.c
    	repmgrd.c

commit 17bafa1ca509c1f6614810bab2538e570ebc599e
Author: Greg Smith <greg@2ndQuadrant.com>
Date:   Tue Jun 7 00:31:28 2011 -0400

    Run astyle to fix recent changes

commit a5fbbaecce8fe86bc17c0ebeb1324f9262967316
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Tue May 10 00:46:58 2011 +0200

    Fix a crititcal bug in the decision process

    If the postgresql on the first node returned by the query to find
    candidates in do_failover is down then the initialization of the
    bestCandidate is done with non assigned variables.

    Fix the situation by moving the initialization in the loop above.
    And loop until we have a find_best. Added a log message if no candidate
    is found

commit 42b21475ac248db8f0e50f5956ef96808e92c68c
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Mon May 9 22:39:21 2011 +0200

    Add test_ssh_connection

    The feature was written by Jaime and reworked to fix
    https://github.com/greg2ndQuadrant/repmgr/issues/5

commit 86f01afae631e9541600af6578e649d88c3ece98
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Mon May 9 21:39:42 2011 +0200

    Improve log output

commit db2f29fc1c8ea03a8ff85717873f8a876846b844
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Mon May 9 01:41:34 2011 -0500

    Only compare getenv("USER") when it's actually set, otherwise it
    will segfault

commit ea4f3f20747e2e0294551d5e61869bdde6d3cd7b
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Mon May 9 01:03:39 2011 -0500

    Fix a message to only show when log_info is requested and the verbose
    flag is set.
    This is because it needs a calculation that is only done when the
    verbose flag is set, so if i have requested log INFO level but haven't
    set the flag it shows a null

commit 35a53bac7e341cfdbb64d2c15fa77c9c4e18bd40
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Mon May 9 01:00:54 2011 -0500

    Use log_* functions in do_witness_create()

commit 8c526f758a46ad53b4d391fc76360561d4ff8bdd
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Sun May 8 19:30:34 2011 -0500

    Add a fallback_application_name parameter to the conninfo identify
    the connection if application_name is not set

commit 01057fc12cbc1fb656d619f483044f28a5f08d37
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri May 6 23:57:27 2011 +0200

    Fix the best_candidate loop

    there was an overflow in the loop, already fixed but loosed during merge.

commit e80effa3daf56f08005704fc1a5bbe69c1324212
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri May 6 23:55:15 2011 +0200

    Fix check in do_failover (merge faillure)

    And also remove an unused variable as I was here.

commit 79ba37e2933f4e87523a77375dfda1d96150e7d3
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Thu May 5 21:15:46 2011 +0200

    Fix compile error

commit 67c7b5d68c95a60bb4cd0cfb750b4c8d047fa2a0
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Sun Apr 24 23:27:57 2011 +0200

    And apply astyle  ....

commit 9a321722537d96983b8162227ff629a267b6ed67
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Sun Apr 24 23:27:09 2011 +0200

    Cosmetic change to reduce diff with master

commit 09037efea3fa2c31896b5dc78b0340516a743ba6
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Sun Apr 24 22:26:03 2011 +0200

    Apply astyle

commit 7c4786f662943558be967be4a8dad976f52155dd
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Sun Apr 24 02:22:12 2011 +0200

    Improve the standby clone action

    By default, all config files and directories are cloned from the master in the
    same place in the slave.
    If a destination directory is provided (-D), everything is copied in the
    provided dir, and if the master have tablespaces repmgr exit without cloning.

commit a6d7f765b9403a2cff7e2e1df8ae45a5a7ee1665
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Apr 22 23:31:09 2011 +0200

    Add success message for repmgr standby register

commit 26bf3b08e661137dd3f3c0d3c00fd6b3b90b08b3
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Apr 22 22:51:28 2011 +0200

    Change the exit to a return in config.c

commit 1bd8f4c119e1dbf9a94b2eaec884abce96eeb174
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Apr 22 22:32:57 2011 +0200

    Reduce duplicate code

commit db553fab45ca075f95f09bdb2147de68948b60c8
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Apr 22 22:24:04 2011 +0200

    Some cosmetic

commit f19d0ad714ebcf7df7726772e887c873d005d350
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Apr 22 22:23:06 2011 +0200

    Move a function declaration into header file

commit 1f328bc438c896a9f2067069d756f901b58d41f2
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Mon Apr 11 00:38:30 2011 -0500

    We don't use conninfo as a separate variable anymore

commit f6ade0d63b8a5dd43377f546f5311b4a151b2bfb
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Sun Apr 10 20:53:22 2011 -0500

    Fix a few typos

commit ceca9fa983c8dbde61a7a78da29a1e1871756d8c
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Sun Apr 10 19:32:57 2011 -0500

    Fix code to allow the code to compile:
    - some log_* had problems with parenthesis
    - some uses of variables without the runtime_options prefix

commit 73431f955afd77560bca5370924e09329566c4b7
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Sun Apr 10 23:21:37 2011 +0200

    Fix the debian package name

commit 688eab371110083ae8715b35f414e29c6d87e1ac
Merge: 5c23375... 7995c42...
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Sun Apr 10 23:17:58 2011 +0200

    Merge branch 'autofailover' of git.2ndquadrant.it:repmgr into autofailover

commit 5c23375f88a53ed469e9d13934d618f7a74669be
Merge: cc3315c... c4ae574...
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Sun Apr 10 23:08:36 2011 +0200

    Merge branch 'master' into autofailover

    Conflicts:
    	repmgr.c

commit 7995c428161566cfc54a67eb16f9134c859e7381
Merge: 788ff98... 1303e49...
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Sun Apr 10 16:14:30 2011 -0500

    Merge branch 'autofailover' of git+ssh://git.2ndquadrant.it/git/repmgr into autofailover

commit cc3315ce235b898711c34fd1f2fa1116dbee4e16
Merge: 1303e49... d77186c...
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Sun Apr 10 23:03:11 2011 +0200

    Merge commit 'd77186c90444b9c5ca2de201651841f56a7ded02' into autofailover

commit 1303e49852705046e15ef64f5f7ab739a1689431
Merge: 7ff621b... 4c792c8...
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Sun Apr 10 22:28:08 2011 +0200

    Merge commit '4c792c8013f5713589f53dbdb47721febf139a85' into autofailover

commit 788ff98e94311a33e3e6f7d85a303cbc61288e5f
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Tue Mar 15 19:00:56 2011 -0500

    A few fixes after merge to unbroke what the merge broke, and to make
    the new logging system more consistent through the system

commit 7ff621b96784dfaf40baab4f0f8e7857b4aed6ce
Author: Dan Farina <drfarina@acm.org>
Date:   Tue Dec 7 21:30:44 2010 -0800

    Install install/uninstall SQL also.

    Signed-off-by: Dan Farina <drfarina@acm.org>
    Signed-off-by: Peter van Hardenberg <pvh@heroku.com>

commit c9147dad8223eff20bf5d52ced8a35eed6d82110
Author: Dan Farina <drfarina@acm.org>
Date:   Tue Dec 7 21:30:20 2010 -0800

    Split up install/uninstall actions more like a standard contrib

    Signed-off-by: Dan Farina <drfarina@acm.org>
    Signed-off-by: Peter van Hardenberg <pvh@heroku.com>

commit c8028780b50f2c7fb4384cb9891796647f356e19
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Sat Feb 12 13:29:32 2011 +0100

    Fixing SLEEP times and RETRY

commit 39a1bf3d29f3e33fbf0e1b066a311e8a72f2dc38
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Sat Feb 12 01:17:37 2011 +0100

    Add a pause after update_shared_memory() in do_failover

    we pause for SLEEP_MONITOR+1 to let other nodes update themselves.

commit 527af2baa945e3b640352c01c6dd181d93c9529a
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Feb 11 21:14:22 2011 +0100

    change the debian package filename too

commit c8cb27c7039b2b3a838554187a8add850a42027a
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Feb 11 15:14:40 2011 +0100

    Change package name for the automatic fail-over branch of repmgr

commit 7427988628f754e57069453d65a71f79117c3a3d
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Feb 11 14:28:03 2011 +0100

    Exit 1 when SIGINT

commit af366fe731b70e24ead056e50b69269392bd15a1
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Feb 11 14:27:46 2011 +0100

    Improve log output when reloading configuration

commit 6cc18ce081d7bf55ba9993e9d87567879da35c4d
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Feb 11 14:20:36 2011 +0100

    Add reload conf on (re)start

commit 4259e2c410fd0ef1273c7d1b4ab8fcf1e778e968
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Feb 11 14:01:37 2011 +0100

    avoid double free on repmgrd exit as master
    Per commit from Charles Duffy <charles@tippr.com>
    and faillure to cherry-pick it correctly.

    Conflicts:

    	repmgrd.c

commit 431e27b1c005e000f9a346d982419979b4363d77
Author: Greg Smith <greg@2ndQuadrant.com>
Date:   Thu Feb 10 15:09:18 2011 -0500

    Tweak .gitignore to ignore more doc build artifacts

commit b725fa9ae65c7bd5fea7a4e944db5685dee2e8bd
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Sun Mar 13 15:16:27 2011 -0500

    Delete a paragraph that appears twice, because a merge problem

commit d990c77b327a282c1903b7a339f35a22b6a89958
Author: trbs <trbs@trbs.net>
Date:   Tue Jan 11 18:24:17 2011 +0100

    added note about postgresql-server-dev-9.0 and use libxslt-dev instead of version specific package name

commit 69bc1cd3772103b529598978160327e1f9025157
Author: trbs <trbs@trbs.net>
Date:   Fri Jan 7 01:32:31 2011 +0100

    fix line

commit f7b1d1e5e3764c85cec7afa81c164fac3679e1ea
Author: trbs <trbs@trbs.net>
Date:   Thu Dec 23 15:02:23 2010 +0100

    Updated README with Debian/Ubuntu install information

commit 77d28960ff78c3936be0e1029305b0b578e260a9
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Feb 11 13:34:49 2011 +0100

    Create the function used for shared memory access in create_schema, note that this is incompatible with current master

commit 4a73043f232f0a143ede898841530f4d7442c95b
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Fri Feb 11 10:00:34 2011 +0100

    improve log output

commit 62c90a4e86b2cd56ec14255adcfef564945d0769
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Fri Feb 11 00:40:05 2011 -0500

    Close local connection on witness before exit on error of primary

commit e5156865e05670fa9944d74d472127082556d0a0
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Fri Feb 11 00:34:25 2011 -0500

    Remove a semicolon which is just a typo

commit 7586a09bc321241932adacf6a1431029964dc46f
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Fri Feb 11 00:07:02 2011 -0500

    Fix the computation of quorum, we need to count master and the
    division should not be an integer division

commit a19c0ad2059a00e9e7415fc6ea280c109c809c9c
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Thu Feb 10 23:54:35 2011 +0100

    move the functions back into public schema

commit 19fc8ffb1dc0fd9acddad5d22bf5c01704687474
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Thu Feb 10 00:48:00 2011 -0500

    A few more fixes.
    Make repmgr functions exists in repmgr schema and fix a typo that
    caused a seg fault.

commit c6d2b8c6421f93074d7d616980feb0175ee4ef36
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Wed Feb 9 17:56:44 2011 -0500

    A few places where i forgot to update the priority field

commit 0ff0bb8d981b868693c6a751e7e80473b25f2399
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Wed Feb 9 14:24:43 2011 -0500

    Fix a few bugs from last commit and make reload configuration also
    update registration on repl_nodes

commit 508c34e9dfb2bfb7e47d5c6836ead7992e6112fe
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Wed Feb 9 13:45:20 2011 -0500

    Add a way for the user to indicate it's preference about which node
    should be promoted in case of a conflict (ie: two nodes with the
    same wal location).

    This will be provided as a parameter in repmgr.conf called priority,
    andd will be registered in the repl_nodes table.

commit 6005f1bbf90de61b4c5ebc34302307fa05b019a7
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Wed Feb 9 11:15:30 2011 -0500

    Add a heartbeat for the witness, this should write to repl_monitor
    table so we can see the witness in repl_status and monitor if it
    is working.

    Also close connection at the end of do_witness_create in repmgr.c

commit ac1c6367ab689aeae2eff3dda22db42337f300c1
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Wed Feb 9 01:26:41 2011 -0500

    Add a sighup handler to reload the configuration

commit 7df2fb7b74a3c5287319e56112840d9c2a3e7d5b
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Thu Feb 3 18:42:36 2011 +0100

    Change the is_pgup () check test

    remove spurious 'return'

commit 7e58e6aa91ab3f681854a44fe282b44da81768fa
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Thu Feb 3 16:53:17 2011 +0100

    Add constant for the sleep times and retry, rework monitor functions

    Rename MonitorExecute() to StandbyMonitor()
    Add    WitnessMonitor() # very simple version to start service mode isolation

commit 1b270dab2e2c3c60527b86a33cd0fc9c0d11c08c
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Thu Feb 3 16:23:01 2011 +0100

    Improve PrimaryCheck

    add a function "bool is_pgup()"

    Now, repmgrd-master can work.

commit c6f07229713c8f2b77596459c06184edddd8d77e
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Wed Feb 2 19:31:06 2011 +0100

    Fix strcmp in config parser, now failover parameter should be set correctly

commit 0b690698a0d9aa87d3e8f1e462ee0771aa2ae9e8
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Wed Feb 2 16:23:50 2011 +0100

    fix sprintf extra param

commit 6050da315824048661be9c425ae6005576e5870f
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Wed Feb 2 13:53:29 2011 +0100

    Add some other files to ignore

commit a146dd581b46ea0e26b7b56b087d6b0d4ae15d44
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Wed Feb 2 13:53:04 2011 +0100

    Fix SQL query

commit 8f5db0f9c0f68ce2519afda72b6a778536427eab
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Wed Feb 2 00:51:54 2011 +0100

    Some more minor fix and remove TODO

commit c9299ad74e8f929bdc24804a6a834f24b66b7074
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Wed Feb 2 00:39:18 2011 +0100

    fix some memory leak and fix testlogic for is_standby is_witness

    * is_standby() must be tested *after* is_witness else we think we are in a master
    * remove SELECT * in favor of SELECT witness

commit cc5d06ea8bf1dcde4c264e95eb90f7fb1e821af3
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Tue Feb 1 23:40:15 2011 +0100

    Forgot to remove a param from fprintf

commit 426e22fa8dfd78f0c256bda1b166a31807de9ec6
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Tue Feb 1 22:47:58 2011 +0100

    Restore previous usage of --force and rsync tablespace before data_dir

    The --force option is used to reduce the time needed to restore a failed
    node: it will overwrite existing files thanks to rsync --delete option

    The tablespaces need to be coyed first, because there are symlinks to
    them from the data_directory

commit 1937973fced703d14159e6aae1cbdabb5619accb
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Tue Feb 1 21:09:12 2011 +0100

    Improve message of repmgrd

commit 035a9bcc1eea55cd95790bc72276727cc492694a
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Tue Feb 1 21:08:38 2011 +0100

    Fix (bool *)PQgetval

commit bf9181654213f898949e9c8f094b974915f82258
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Tue Feb 1 01:54:49 2011 +0100

    Fix pg_hba on witness and connection

    * Copy the pg_hba.conf file from master to witness server
    * createdb and createuser in witness if they are different from getenv(USER)

commit a2d8dcb2fd105d8f02bd76856969aca6605c66fa
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Tue Feb 1 01:01:43 2011 +0100

    Improve initialization of repmgr (+ critical bug and minor fixes)

    * standby clone now *clone* the master files and dir to the *same*
      place on the standby if destination_directory is not provided
    * add preload library to the witness configuration
    * sleep 2 seconds after starting the witness postgresql to let it
      start enough to be able to connect to it.
    * Fix rsync files
    * Fix insert configuration into witness

commit bc1a265d272e4805ac7859c208b51b57edd10fc7
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Mon Jan 31 12:25:20 2011 +0100

    Fix some error message new line

commit e087bd5de5ab43ffac90c6a20df6ef3fb19eed6d
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Mon Jan 31 11:37:08 2011 +0100

    Guess data_directory from master in 'standby clone' and remove --force for dir

    --force does not overwrite directories anymore (it was not working very well anyway)
    dest_dir is the same as the master's one by default.
    Move down the tablespace check directories process

commit 0a961e7ef05f26c87af1946b8141a639076fc488
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Mon Jan 31 11:21:40 2011 +0100

    Add new function: create_pgdir (and fix 2 bugs in the process).
    It also fix function create_schema.

    Reduce repmgr code

commit 7e5958dcc1daa9b54cb6f295af96fbef750c7952
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Mon Jan 31 10:34:58 2011 +0100

    Improve an ERROR message

commit f3a66a65a361f919727fc2d0ff9bf9544a10a822
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Mon Jan 31 10:25:45 2011 +0100

    Improve error message about 'wal_keep_segments'

commit 150dbcc0fe53ce4eff08797210fd2e9e4dd0e17a
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Sat Jan 29 23:35:00 2011 -0500

    Add witness server support

commit 6281e22a9c467da883ad960567f8ab6bdbc155ba
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Thu Jan 27 21:32:11 2011 +0100

    Build all at once and update debian makefile to include the sql/

commit 50d752bf1ead7c9343900d4b494844284b7aac6c
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Thu Jan 27 02:10:31 2011 +0100

    Adding information for debian and --version test

commit 16d56dbfa05314eea69869ee2a7a705636432ad9
Author: Cédric Villemain <cedric@2ndQuadrant.fr>
Date:   Thu Jan 27 02:03:20 2011 +0100

    Add a hint at the end of the standby clone
    and minor typo and message shuffle

commit 6404ba247de1e2e3b995f30b6e7626e459849136
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Wed Jan 26 06:13:30 2011 -0500

    Fix compiler warning about variables beign used unintialized

commit a4f48993d5fe3b22bdd2aaefcff315115f8764b7
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Fri Jan 21 21:09:03 2011 -0500

    Fix a new typo

commit 904e61c9edcbbce6b1027c80ff77317d7cbd4919
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Fri Jan 21 19:30:56 2011 -0500

    Use a function to make the call to repmgr_update_standby_location()
    so i avoid typos like the one i fixed in a previous commit. It also
    makes the code cleaner.

commit 4ed388726f4bc0a52cc88d044d1f81697f348a7c
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Wed Jan 19 09:17:16 2011 -0500

    Fix a typo when calling the sql function that writes shared memory

commit d9232266561306eabef90e13c084c051a0e7f458
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Tue Jan 18 01:25:23 2011 -0500

    Define the variable that we are using to test the result status of
    the system() call.

commit 4d131c212b91e40ca027f76637c182456ab12514
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Tue Jan 18 01:04:12 2011 -0500

    Makes repmgrd warn if promote_command or follow_command fails, add
    a "still alive" check for primary.
    Add a few messages and fix a bug in do_failover() in which we were
    using a closed PGresult.

commit a5189e68cf4c8cf84259ea667a35e96de56fa4c9
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Thu Jan 13 15:45:50 2011 -0500

    Initial attempt to get autofailover

commit d0e09010a9d4610997c900b62ea1df2a71b01015
Author: Jaime Casanova <jaime@2ndQuadrant.com>
Date:   Wed Jan 12 14:40:29 2011 -0500

    Add options failover, promote_command and follow_command
    to repmgr.conf, in pass also rename sample repmgr.conf to
    repmgr.conf.sample
    promote_command and follow_command allows to use a custom script
    for those actions.
2011-06-07 01:42:15 -04:00
Greg Smith
43268f2345 Refactor more log messages to use "_" form 2011-06-07 01:17:41 -04:00
Greg Smith
8200b68cf7 Convert some remaining fprintf messages to logger 2011-06-07 00:50:46 -04:00
Greg Smith
06aecbf58a Fix copyright date on repmgr.sql 2011-06-07 00:46:16 -04:00
Greg Smith
367d0b1afa astyle fixes on logging change 2011-06-07 00:30:35 -04:00
Greg Smith
e52f2e88a5 Update use of paranthesis in logging messages.
Extracted portion of what was originally
ceca9fa983c8dbde61a7a78da29a1e1871756d8c , due to be
applied later.
2011-06-07 00:19:11 -04:00
Cédric Villemain
620f8090a3 Add test_ssh_connection
The feature was written by Jaime and reworked by me to fix
https://github.com/greg2ndQuadrant/repmgr/issues/5
2011-05-09 22:52:29 +02:00
Jaime Casanova
534649eb03 Fix a message to only show when log_info is requested and the verbose
flag is set.
This is because it needs a calculation that is only done when the
verbose flag is set, so if i have requested log INFO level but haven't
set the flag it shows a null
2011-05-09 01:07:54 -05:00
Jaime Casanova
1e8b9e8960 Add a fallback_application_name parameter to conninfo to identify
the connection if application_name is not set
2011-05-08 19:26:59 -05:00
Cédric Villemain
c4ae5741a3 Fix getopt for ignore-rsync-warning
The change was loosed during merge and not checked in master/
2011-04-10 22:42:38 +02:00
Greg Smith
f824189692 Cleanup new ignore rsync warning feature. Closes gh-22. 2011-04-05 17:52:39 -04:00
Greg Smith
68b42d16c9 Merge commit '3ca0f2db06c9114c59e0846dda487cca9b1e85ff' 2011-04-05 17:26:33 -04:00
Greg Smith
3ca0f2db06 Fix unapplied astyle. Closes gh-26. 2011-04-05 17:21:48 -04:00
Cédric Villemain
235903e517 Fix rsync return code test 2011-03-28 18:42:20 +02:00
Cédric Villemain
bf29601218 remove the exit on rsync error because it is handle by the caller 2011-03-28 17:08:22 +02:00
Cédric Villemain
02a3fbb303 Add --ignore-rsync-warning to README 2011-03-28 16:46:47 +02:00
Cédric Villemain
b30398bf2a Add --ignore-rsync-warning command line option
This fix the rsync return code in case there are vanished files.

Common situation are DROPed tables and TEMPorary object deletion and
are handled by PostgreSQL.
But as it may exist situation where an external process delete files in
the PGDATA the flag is off by default.

XXX 2 items :

 * is -I a good choice ? maybe we need to prevent future --ignore-foo and
   add something like : --ignore=rsync_warning -I rsync_warning
 * the warning message is not enough explicit with the risk involved by
   --force usage
2011-03-28 16:38:55 +02:00
Cédric Villemain
e74e319e7a Applying indent style 2011-03-28 16:05:09 +02:00
Jaime Casanova
d77186c904 Ignore error 24 from rsync (that could happen if we use a lot of
temp tables for example).
It only ignores that error if we are copying a directory (which means
we are in pg_start_backup() and then ignore changes that happen
due to concurrent access is fine).
2011-03-28 16:02:32 +02:00
Greg Smith
4c792c8013 Add TODO, update history for 1.1.0 release 2011-03-09 15:27:29 -05:00
Greg Smith
e7903a7971 Merge branch 'master' of git+ssh://git@git.2ndquadrant.it/git/repmgr 2011-03-03 09:27:18 -05:00
Greg Smith
f372793114 Merge correction commit 2011-03-03 09:26:22 -05:00
trbs
295a183d0b removing old code which is made invalid after merging the different branches by upstream 2011-03-03 09:25:27 -05:00
trbs
c6693340c1 cleanup help and usage 2011-03-03 09:21:46 -05:00
trbs
cc0c516810 added new lines to log messages 2011-03-03 09:21:38 -05:00
Jaime Casanova
58ec43106e Options -U, -R and -p shouldn't be mandatory. Fix by checking if the string
is empty before use.
2011-03-02 02:44:01 -05:00
Greg Smith
3e960286c7 Update history for 1.1.0-beta1 2011-02-24 19:25:40 -05:00
Greg Smith
bf0bbd747b Fix typos in some logging messages 2011-02-24 19:05:03 -05:00
Greg Smith
459f14b594 Document repmgrd's role on each type of node. Add
logging (when run in verbose mode) showing what
decisions repmgrd is making after it determines
what type of node it is.
2011-02-24 18:58:03 -05:00
Greg Smith
f928edf897 Improve parameter validation, logging, and error
handling in repmgrd
2011-02-24 18:13:16 -05:00
Greg Smith
c7b62003b2 Reorganize README to be easier to follow 2011-02-23 09:50:07 -05:00
Greg Smith
59b7b90169 Update README with better two-node example output 2011-02-23 09:08:08 -05:00
Greg Smith
3cdd6a57fd Add more info level logging around database activity 2011-02-23 08:42:49 -05:00
Greg Smith
5dcec5818f Update README with standard two-host examples 2011-02-23 08:42:06 -05:00
Greg Smith
9c6288993b Fix double free in standby clone 2011-02-23 07:26:39 -05:00
Greg Smith
2675101330 Make PGPASSWORD substitution in recovery.conf optional 2011-02-23 07:19:36 -05:00
Greg Smith
02daccd6e7 Wrap use of PQconnectdbParams, add proper error
checking and logging when the connection fails.
2011-02-23 06:44:10 -05:00
Greg Smith
18ef5b3cf3 Convert more uses of fprintf to use logger 2011-02-23 05:59:09 -05:00
Greg Smith
3b2203c38c Make verbose command line option useful on top of
the new logging infrastructure.
2011-02-23 05:29:29 -05:00
Greg Smith
fee7da1ba7 Fix cast on WAL lag computation to (long long) 2011-02-22 07:43:02 -05:00
Greg Smith
a98aec12e1 And one more round of astyle work 2011-02-15 00:57:12 -05:00
Greg Smith
757457ad85 Fix merge error that removed setting keywords 2011-02-15 00:55:50 -05:00
Greg Smith
45022debc6 Break out error codes, cleanup header files and HISTORY 2011-02-15 00:43:36 -05:00
Greg Smith
f6618a01c7 Post-merge astyle run 2011-02-15 00:14:13 -05:00
Greg Smith
20af4ffc2c Merge commit '3ef1fa126d9c9b9ba3b29deab7f67218cdf7ce10'
Conflicts:
	.gitignore
	Makefile
	README.rst
	check_dir.c
	config.c
	config.h
	dbutils.h
	repmgr.c
	repmgr.conf
	repmgr.h
	repmgrd.c
2011-02-15 00:06:01 -05:00
Greg Smith
3ef1fa126d astyle run against Heroku code 2011-02-14 21:51:14 -05:00
Greg Smith
ce06e6c8e0 Fix some mistakes in the history file 2011-02-10 19:34:50 -05:00
Greg Smith
0ad3d91e9c Cleanup history and credits 2011-02-10 18:57:50 -05:00
Greg Smith
0130420947 astyle cleanup run after recent merges 2011-02-10 18:55:51 -05:00
Greg Smith
c3af4274ae Document astyle command line used to standardize
code formatting
2011-02-10 18:55:17 -05:00
Greg Smith
5460517a43 Protect against duplicate header inclusion 2011-02-10 18:35:56 -05:00
Greg Smith
1d32133d49 Update all the copyrights to add 2011 2011-02-10 18:33:02 -05:00
Greg Smith
1be62fa6b2 Fix use of "options" broken by recent merging 2011-02-10 18:26:44 -05:00
Charles Duffy
b62ad056f1 repmgrd: log restored connection only after a break 2011-02-10 17:57:13 -05:00
Greg Smith
ec30caef0f Merge commit '78b925ea54bb7a131e97c2f5d0a63f54ca58e26f' 2011-02-10 17:52:50 -05:00
Greg Smith
78b925ea54 Unify use of error codes across all exit statements 2011-02-10 17:49:34 -05:00
Charles Duffy
7e7c45c61d exit with status 2 if manual work is needed during standby_clone 2011-02-10 17:08:43 -05:00
Charles Duffy
a02cd43115 repmgr: treat directory access errors during standby clone as failure 2011-02-10 17:03:00 -05:00
Charles Duffy
a67688f198 minor format string and comment fixes (add missing newlines, fix english usage, format string argument order) 2011-02-10 17:01:59 -05:00
Charles Duffy
f74b806e4f repmgr: exit with nonzero status on obvious errors 2011-02-10 17:00:33 -05:00
Charles Duffy
657aa3013b avoid double free on repmgrd exit as master 2011-02-10 16:40:00 -05:00
Greg Smith
8d2aff558d Update history with recent merges 2011-02-10 16:19:35 -05:00
Gabriele Bartolini
6e1306cfb2 Uses a switch to detect the log level 2011-02-10 16:09:46 -05:00
Gabriele Bartolini
308efba95e added explanations about logging 2011-02-10 16:09:46 -05:00
Gabriele Bartolini
556f256bb6 Now standby clone command accepts configuration file - for logging purposes only 2011-02-10 16:08:07 -05:00
Gabriele Bartolini
83eee2ed96 added some messages to the clone command 2011-02-10 16:08:07 -05:00
Gabriele Bartolini
cb36aaddff - Added \n 2011-02-10 16:08:07 -05:00
Gabriele Bartolini
3146d2c676 fixed some bugs with standby clone 2011-02-10 16:08:07 -05:00
Gabriele Bartolini
3f1c6a5852 Removed any sprintf/strcpy call and use snprintf/strncpy - Fixed bug with tblspc_dir - added debug messages after every query 2011-02-10 16:08:07 -05:00
Gabriele Bartolini
716a0ae9d3 removed any malloc operation, added t_runtime_options struct 2011-02-10 16:05:03 -05:00
Gabriele Bartolini
7a3be3a2f9 Cleaned log messages (\n at the end of every line) 2011-02-10 15:58:55 -05:00
Gabriele Bartolini
f6a6632169 Added new log system to both repmgr and repmgrd. Needs cleaning, but it is a good starting point 2011-02-10 15:58:55 -05:00
Gabriele Bartolini
2c1eafd7a9 first alpha version for syslog support 2011-02-10 15:56:10 -05:00
Greg Smith
1787cf1c21 Update credits and history to reflect recent merges 2011-02-10 15:19:00 -05:00
Greg Smith
287e2c1a67 Tweak .gitignore to ignore more doc build artifacts 2011-02-10 15:09:18 -05:00
trbs
b487772b84 added note about postgresql-server-dev-9.0 and use libxslt-dev instead of version specific package name 2011-02-10 15:06:09 -05:00
trbs
52313a2d6e made rsync_options configurable 2011-02-10 15:06:09 -05:00
trbs
814863edf2 use struct for config file information 2011-02-10 15:06:09 -05:00
trbs
e4f431c355 fix line 2011-02-10 15:06:09 -05:00
trbs
c3816d8586 added readme.html to gitignore 2011-02-10 15:05:07 -05:00
trbs
4ea0fc4214 Updated README with Debian/Ubuntu install information 2011-02-10 15:05:07 -05:00
trbs
03ed0e692a fix strformat order reversal in error message 2011-02-10 15:00:44 -05:00
Daniel Farina
ce21291418 Issue a message when a configuration file is passed unnecessarily
Simply intends to set expectations around the fact that a config file
is not used *and* doesn't affect anything material about the standby
clone command.

This uses a notion of "logging level" (like NOTICE) that is not yet
seen this program, but I'll probably introduce that soon.

Signed-off-by: Daniel Farina <daniel@heroku.com>
2011-02-10 03:19:36 -08:00
Daniel Farina
4b007bf4bc Use a better check for when to issue an error message
This patch changes raising the error "You need to use connection
parameters to the master when issuing a STANDBY CLONE command." to
only occur when no host (a global variable, that is abused for at
least two purposes, but is okay in this case) is passed, rather than
when no config file is passed, which is fine for standby clone (which
itself is a wrapper for rsync)

Signed-off-by: Daniel Farina <daniel@heroku.com>
2011-02-10 03:19:30 -08:00
Daniel Farina
da82829659 Avoid checking config file when performing standby clone action
Signed-off-by: Daniel Farina <daniel@heroku.com>
2011-02-10 02:10:58 -08:00
Dan Farina
ebbb7c3a47 Fix more quoting: used an overly-quoted copy
Signed-off-by: Dan Farina <daniel@heroku.com>
2011-02-07 03:59:18 -08:00
Dan Farina
630d716819 Use the proper freeing method
As according to
http://www.postgresql.org/docs/9.0/static/libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING

Signed-off-by: Dan Farina <daniel@heroku.com>
2011-02-07 03:59:18 -08:00
Dan Farina
c1b84fe9fc Make some fast hacks to quote schema names
Signed-off-by: Dan Farina <drfarina@acm.org>
2011-02-07 03:59:18 -08:00
Dan Farina
bfd3aed33b Fix a myriad of problems introduced by merging
Signed-off-by: Dan Farina <drfarina@acm.org>
2011-02-06 18:32:49 -08:00
Dan Farina
c356f9e97f Merge remote-tracking branch 'tbrs/master' into heroku
Grab the configuration struct changes. It was expeditious to un-do
some of my by-hand line-wrapping that avoids 80 character limit,
though.

Conflicts:
	config.c
	config.h
	repmgr.c
	repmgr.h
	repmgrd.c
2011-02-04 18:35:56 -08:00
Dan Farina
a52ebc412c Merge remote-tracking branch 'origin/master' into heroku
The Great Whitespace Reconciliation

Conflicts:
	check_dir.c
	config.c
	dbutils.c
	repmgr.c
	repmgr.h
	repmgrd.c

Signed-off-by: Dan Farina <drfarina@acm.org>
2011-02-04 18:27:28 -08:00
Cédric Villemain
fbf97807b8 Remove spurious file 2011-01-27 21:33:09 +01:00
Hannu Krosing
3cce9efac0 Merge branch 'master' of git+ssh://git.2ndquadrant.it/git/repmgr 2011-01-27 10:04:25 +02:00
Hannu Krosing
ec8678379f Makefile changes for building debian packages, left out of previous commit 2011-01-27 10:02:59 +02:00
Cédric Villemain
d017edbe47 Adding information for debian and --version test 2011-01-27 02:11:05 +01:00
Hannu Krosing
f41ba482eb dded section on building on Debian and Ubuntu 2011-01-27 01:09:18 +02:00
Hannu Krosing
4c5fad2070 simple support for creating deb file 2011-01-27 00:32:52 +02:00
Greg Smith
0dd31b09dd Additional notes on 32 vs. 64 build issues 2011-01-22 09:59:43 -05:00
Greg Smith
943dda0ad0 Document potential build issues on RPM 2011-01-22 09:09:37 -05:00
Greg Smith
d4de19bc78 Doc warning: need server restart after config change 2011-01-17 15:38:44 -05:00
trbs
1999b534fd added note about postgresql-server-dev-9.0 and use libxslt-dev instead of version specific package name 2011-01-11 18:24:17 +01:00
trbs
57169f51cf made rsync_options configurable 2011-01-08 01:46:39 +01:00
trbs
fc2405f17d use struct for config file information 2011-01-07 01:36:46 +01:00
trbs
4a0e827464 fix line 2011-01-07 01:32:31 +01:00
trbs
745392e3a2 added readme.html to gitignore 2011-01-06 23:46:21 +01:00
Jaime Casanova
170f519d84 Fixing a message, shouldn't show progname in the middle of a line.
Is one message not two.
2010-12-29 00:45:33 -05:00
trbs
cf5717ad59 Updated README with Debian/Ubuntu install information 2010-12-23 15:02:23 +01:00
trbs
cb1192b912 fix strformat order reversal in error message 2010-12-23 15:02:02 +01:00
Dan Farina
156714f3f1 Fix quoting misbehavior
Move the single quote in the formatting string to the end of the line.

Signed-off-by: Dan Farina <drfarina@acm.org>
2010-12-23 01:04:05 -08:00
Dan Farina
dd5ac660bf Comments and cleanup
Signed-off-by: Dan Farina <drfarina@acm.org>
2010-12-23 00:55:39 -08:00
Dan Farina
3a430397dc Avoid overwriting the new password-in-recovery.conf formatting
Previously: did that work, then threw it away/overwrote it.

Signed-off-by: Dan Farina <drfarina@acm.org>
2010-12-23 00:55:39 -08:00
Dan Farina
1f098c60ac Remove dead-ish code
This is a leftover after having fixed various problems in the verbose
output here.

Signed-off-by: Dan Farina <drfarina@acm.org>
2010-12-23 00:55:39 -08:00
Dan Farina
0bae682a0d Fix off-by-one in passing buffer size to xsnprintf
This would cause a consistent panic (exit() call) without reason.
This should not enable any overruns (but check my work).

Signed-off-by: Dan Farina <drfarina@acm.org>
2010-12-23 00:55:32 -08:00
Dan Farina
f969dca821 Hack to get passwords in recovery.conf
Signed-off-by: Dan Farina <drfarina@acm.org>
2010-12-22 20:10:32 -08:00
Dan Farina
29c39c21f6 Avoid a use-after-free in verbose logging (again)
Previously, this print would use memory freed by PQClear previously.

Also allocate/free memory to prevent this tiny memory leak.

Signed-off-by: Dan Farina <drfarina@acm.org>
2010-12-22 20:10:15 -08:00
Dan Farina
620974ba04 Fix unsafe string handling
It looks like the old code would overflow in some cases.

Signed-off-by: Dan Farina <drfarina@acm.org>
2010-12-22 19:00:21 -08:00
Greg Smith
9843205a4f Reformat all source code using astyle
astyle --style=ansi --indent=tab
2010-12-22 19:07:01 -05:00
Greg Smith
1ddb78ddd8 Merge branch 'license' of https://github.com/gbartolini/repmgr into gbartolini-license 2010-12-22 19:02:50 -05:00
Greg Smith
b0e1428caa Add contribution information 2010-12-22 19:01:58 -05:00
Greg Smith
47349b01e0 Merge branch 'gabriele-2010-12' of https://github.com/gbartolini/repmgr into gbartolini-gabriele-2010-12 2010-12-22 18:43:14 -05:00
Greg Smith
e5d886d651 Add CREDITS file 2010-12-22 18:42:24 -05:00
Greg Smith
91a304e3ee Add HISTORY file. Ignore build artifacts in git. 2010-12-22 18:34:29 -05:00
Dan Farina
faddaed316 Avoid a use-after-free in verbose logging
Previously, this print would use memory freed by PQClear previously.

Signed-off-by: Dan Farina <drfarina@acm.org>
2010-12-22 15:03:05 -08:00
Dan Farina
7b0a142075 Merge remote branch 'gbartolini/gabriele-2010-12' into heroku
Conflicts:
	config.c
	dbutils.c
	dbutils.h
	repmgrd.c

Signed-off-by: Dan Farina <drfarina@acm.org>
2010-12-21 16:08:07 -08:00
Dan Farina
ec73a07e2f Make various buffers larger
MAXLEN definitely needed to be bigger to properly format fairly common
connection strings.  In addition, the reliance on xsnprintf helps
detect cases where even this buffer is not long enough.

the buffer in parse_config has been made bigger in a bit of sloppy
programming, but what really needs to happen is reporting when a line
cannot be properly parsed/is too big for the buffer.  That is just a
kludge.

Signed-off-by: Dan Farina <drfarina@acm.org>
Signed-off-by: Peter van Hardenberg <pvh@heroku.com>
2010-12-21 15:19:28 -08:00
Dan Farina
fc13d50e37 Canonicalize whitespace
Signed-off-by: Dan Farina <drfarina@acm.org>
Signed-off-by: Peter van Hardenberg <pvh@heroku.com>
2010-12-21 15:19:28 -08:00
Dan Farina
309bb92d95 Prevent a double-free
This can occur because prior to this, there is a code path that looks
like this:

    primaryConn = myLocalConn

CloseConnections will subsequently try to free both with PQFinish.
I'm not sure if this is the right fix -- it's more of hack -- without
more information about design intention.

One reasonable alternative would be to have CloseConnections perform
this check itself. As-is I am pretty sure that this fix leaves a
signal-race (when CloseConnections is called, without the check, in
the interrupt handler) unfixed.

Signed-off-by: Dan Farina <drfarina@acm.org>
Signed-off-by: Peter van Hardenberg <pvh@heroku.com>
2010-12-21 15:19:28 -08:00
Dan Farina
6cea339697 Fix a use-after-free
A result is being cleared while there are still pointers that
refer to datums in it.

Signed-off-by: Dan Farina <drfarina@acm.org>
Signed-off-by: Peter van Hardenberg <pvh@heroku.com>
2010-12-21 15:19:28 -08:00
Dan Farina
3f2094a242 Initialize connection pointers to NULL
This makes some bugs easier to find.

Signed-off-by: Dan Farina <drfarina@acm.org>
Signed-off-by: Peter van Hardenberg <pvh@heroku.com>
2010-12-21 15:19:28 -08:00
Dan Farina
84b69b3bd4 Whitespace to adjust for longer snprintf identifier
This is done in a separate patch to try and reduce the sound and fury
of the patch that actually did the conversion from sprintf to
snprintf-alikes.

Signed-off-by: Dan Farina <drfarina@acm.org>
Signed-off-by: Peter van Hardenberg <pvh@heroku.com>
2010-12-21 15:19:28 -08:00
Dan Farina
916c0492fb sprintf to snprintf conversion
Move out string operations to another file, and introduce a frontend
to snprintf for various situations.  This change is important for
catching and eliminating sprintf overflows, which are as of now many
times silently corrupting memory.

Signed-off-by: Dan Farina <drfarina@acm.org>
Signed-off-by: Peter van Hardenberg <pvh@heroku.com>
2010-12-21 15:19:28 -08:00
Dan Farina
846c0b92e8 Install install/uninstall SQL also.
Signed-off-by: Dan Farina <drfarina@acm.org>
Signed-off-by: Peter van Hardenberg <pvh@heroku.com>
2010-12-21 15:19:28 -08:00
Dan Farina
778303bb6e Split up install/uninstall actions more like a standard contrib
Signed-off-by: Dan Farina <drfarina@acm.org>
Signed-off-by: Peter van Hardenberg <pvh@heroku.com>
2010-12-21 15:19:28 -08:00
Dan Farina
af2edf10a0 Attack of whitespace pedantry
pgsql conventions (tabs, four-spaces-wide, etc) applied all around.

Also tried to fix some very tiny capitalization errors, auto-fill
problems, and some inter-block vertical whitespacing issues.

Long strings in repmgr.c were left intact, though. They are rather
numerous and are less of a problem than tiny bits of function calls
and comments wrapping over a line; the latter kind of problem has been
mostly fixed.

Signed-off-by: Dan Farina <drfarina@acm.org>
Signed-off-by: Peter van Hardenberg <pvh@heroku.com>
2010-12-21 15:19:28 -08:00
Gabriele Bartolini
d88783a4d9 Changed pg_version() prototype in order to remove the small memory leak 2010-12-16 22:48:19 +01:00
Gabriele Bartolini
f2bec9a08f Some cosmetic changes 2010-12-16 22:31:26 +01:00
Gabriele Bartolini
05e88a2cc8 removed strncmp improper usage, initialise values asap 2010-12-16 22:21:27 +01:00
Gabriele Bartolini
763a1e8b3d Reviewed the code, fixed a small bug with option name detection 2010-12-16 22:14:18 +01:00
Gabriele Bartolini
c687d0d670 Reviewed the code, fixed a small bug with option name detection 2010-12-16 22:13:30 +01:00
Gabriele Bartolini
9b7a078e0e Added license information in every source file 2010-12-16 21:50:15 +01:00
Greg Smith
56c65acd99 Add force option to help and docs on help 2010-12-06 00:33:02 -05:00
43 changed files with 10361 additions and 2285 deletions

9
.gitignore vendored
View File

@@ -0,0 +1,9 @@
*~
*.o
*.so
repmgr
repmgrd
README.htm*
README.pdf
sql/repmgr_funcs.so
sql/repmgr_funcs.sql

View File

@@ -1,4 +1,4 @@
Copyright (c) 2009-2010, 2ndQuadrant Limited
Copyright (c) 2010-2015, 2ndQuadrant Limited
All rights reserved.
This program is free software: you can redistribute it and/or modify

16
CREDITS Normal file
View File

@@ -0,0 +1,16 @@
Code and documentation contributors to repmgr include:
Jaime Casanova <jaime@2ndQuadrant.com>
Simon Riggs <simon@2ndQuadrant.com>
Greg Smith <greg@2ndQuadrant.com>
Robert J. Noles <rj@2ndQuadrant.com>
Gabriele Bartolini <gabriele@2ndQuadrant.com>
Bas van Oostveen <v.oostveen@gmail.com>
Hannu Krosing <hannu@2ndQuadrant.com>
Cédric Villemain <cedric@2ndquadrant.com>
Charles Duffy <charles@dyfis.net>
Daniel Farina <daniel@heroku.com>
Shawn Ellis <shawn.ellis17@gmail.com>
Jay Taylor <jay@jaytaylor.com>
Christian Kruse <christian@2ndQuadrant.com>
Krzysztof Gajdemski <songo@debian.org.pl>

231
FAILOVER.rst Normal file
View File

@@ -0,0 +1,231 @@
====================================================
PostgreSQL Automatic Failover - User Documentation
====================================================
Automatic Failover
==================
repmgr allows for automatic failover when it detects the failure of the master node.
Following is a quick setup for this.
Installation
============
For convenience, we define:
**node1**
is the fully qualified domain name of the Master server, IP 192.168.1.10
**node2**
is the fully qualified domain name of the Standby server, IP 192.168.1.11
**witness**
is the fully qualified domain name of the server used as a witness, IP 192.168.1.12
**Note:** We don't recommend using names with the status of a server like «masterserver»,
because it would be confusing once a failover takes place and the Master is
now on the «standbyserver».
Summary
-------
2 PostgreSQL servers are involved in the replication. Automatic failover needs
a vote to decide what server it should promote, so an odd number is required.
A witness-repmgrd is installed in a third server where it uses a PostgreSQL
cluster to communicate with other repmgrd daemons.
1. Install PostgreSQL in all the servers involved (including the witness server)
2. Install repmgr in all the servers involved (including the witness server)
3. Configure the Master PostreSQL
4. Clone the Master to the Standby using "repmgr standby clone" command
5. Configure repmgr in all the servers involved (including the witness server)
6. Register Master and Standby nodes
7. Initiate witness server
8. Start the repmgrd daemons in all nodes
**Note** A complete High-Availability design needs at least 3 servers to still have
a backup node after a first failure.
Install PostgreSQL
------------------
You can install PostgreSQL using any of the recommended methods. You should ensure
it's 9.0 or later.
Install repmgr
--------------
Install repmgr following the steps in the README file.
Configure PostreSQL
-------------------
Log in to node1.
Edit the file postgresql.conf and modify the parameters::
listen_addresses='*'
wal_level = 'hot_standby'
archive_mode = on
archive_command = 'cd .' # we can also use exit 0, anything that
# just does nothing
max_wal_senders = 10
wal_keep_segments = 5000 # 80 GB required on pg_xlog
hot_standby = on
shared_preload_libraries = 'repmgr_funcs'
Edit the file pg_hba.conf and add lines for the replication::
host repmgr repmgr 127.0.0.1/32 trust
host repmgr repmgr 192.168.1.10/30 trust
host replication all 192.168.1.10/30 trust
**Note:** It is also possible to use a password authentication (md5), .pgpass file
should be edited to allow connection between each node.
Create the user and database to manage replication::
su - postgres
createuser -s repmgr
createdb -O repmgr repmgr
psql -f /usr/share/postgresql/9.0/contrib/repmgr_funcs.sql repmgr
Restart the PostgreSQL server::
pg_ctl -D $PGDATA restart
And check everything is fine in the server log.
Create the ssh-key for the postgres user and copy it to other servers::
su - postgres
ssh-keygen # /!\ do not use a passphrase /!\
cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
exit
rsync -avz ~postgres/.ssh/authorized_keys node2:~postgres/.ssh/
rsync -avz ~postgres/.ssh/authorized_keys witness:~postgres/.ssh/
rsync -avz ~postgres/.ssh/id_rsa* node2:~postgres/.ssh/
rsync -avz ~postgres/.ssh/id_rsa* witness:~postgres/.ssh/
Clone Master
------------
Log in to node2.
Clone node1 (the current Master)::
su - postgres
repmgr -d repmgr -U repmgr -h node1 standby clone
Start the PostgreSQL server::
pg_ctl -D $PGDATA start
And check everything is fine in the server log.
Configure repmgr
----------------
Log in to each server and configure repmgr by editing the file
/etc/repmgr/repmgr.conf::
cluster=my_cluster
node=1
node_name=earth
conninfo='host=192.168.1.10 dbname=repmgr user=repmgr'
master_response_timeout=60
reconnect_attempts=6
reconnect_interval=10
failover=automatic
promote_command='promote_command.sh'
follow_command='repmgr standby follow -f /etc/repmgr/repmgr.conf'
**cluster**
is the name of the current replication.
**node**
is the number of the current node (1, 2 or 3 in the current example).
**node_name**
is an identifier for every node.
**conninfo**
is used to connect to the local PostgreSQL server (where the configuration file is) from any node. In the witness server configuration you need to add a 'port=5499' to the conninfo.
**master_response_timeout**
is the maximum amount of time we are going to wait before deciding the master has died and start the failover procedure.
**reconnect_attempts**
is the number of times we will try to reconnect to master after a failure has been detected and before start the failover procedure.
**reconnect_interval**
is the amount of time between retries to reconnect to master after a failure has been detected and before start the failover procedure.
**failover**
configure behavior: *manual* or *automatic*.
**promote_command**
the command executed to do the failover (including the PostgreSQL failover itself). The command must return 0 on success.
**follow_command**
the command executed to address the current standby to another Master. The command must return 0 on success.
Register Master and Standby
---------------------------
Log in to node1.
Register the node as Master::
su - postgres
repmgr -f /etc/repmgr/repmgr.conf master register
Log in to node2. Register it as a standby::
su - postgres
repmgr -f /etc/repmgr/repmgr.conf standby register
Initialize witness server
-------------------------
Log in to witness.
Initialize the witness server::
su - postgres
repmgr -d repmgr -U repmgr -h 192.168.1.10 -D $WITNESS_PGDATA -f /etc/repmgr/repmgr.conf witness create
The witness server needs the following information from the command
line:
* Connection details for the current master, to copy the cluster
configuration.
* A location for initializing its own $PGDATA.
repmgr will also ask for the superuser password on the witness database so
it can reconnect when needed (the command line option --initdb-no-pwprompt
will set up a password-less superuser).
Start the repmgrd daemons
-------------------------
Log in to node2 and witness::
su - postgres
repmgrd -f /etc/repmgr/repmgr.conf --daemonize -> /var/log/postgresql/repmgr.log 2>&1
**Note:** The Master does not need a repmgrd daemon.
Suspend Automatic behavior
==========================
Edit the repmgr.conf of the node to remove from automatic processing and change::
failover=manual
Then, signal repmgrd daemon::
su - postgres
kill -HUP $(pidof repmgrd)
Usage
=====
The repmgr documentation is in the README file (how to build, options, etc.)

119
FAQ.md Normal file
View File

@@ -0,0 +1,119 @@
FAQ - Frequently Asked Questions about repmgr
=============================================
This FAQ applies to `repmgr` 3.0 and later.
General
-------
- What's the difference between the repmgr versions?
repmgr 3.x builds on the improved replication facilities added
in PostgreSQL 9.3, as well as improved automated failover support
via `repmgrd`, and is not compatible with PostgreSQL 9.2 and earlier.
repmgr 2.x supports PostgreSQL 9.0 onwards. While it is compatible
with PostgreSQL 9.3 and later, we recommend repmgr v3.
- What's the advantage of using replication slots?
Replication slots, introduced in PostgreSQL 9.4, ensure that the
master server will retain WAL files until they have been consumed
by all standby servers. This makes WAL file management much easier,
and if used `repmgr` will no longer insist on a fixed number (default: 5000)
of WAL files being preserved.
(However this does mean that if a standby is no longer connected to the
master, the master will retain WAL files indefinitely).
- How many replication slots should I define in `max_replication_slots`?
Normally at least same number as the number of standbys which will connect
to the node. Note that changes to `max_replication_slots` require a server
restart to take effect, and as there is no particular penalty for unused
replication slots, setting a higher figure will make adding new nodes
easier.
`repmgr`
--------
- When should I use the --rsync-only option?
By default, `repmgr` uses `pg_basebackup` to clone a standby from
a master. However, `pg_basebackup` copies the entire data directory, which
can take some time depending on installation size. If you have an
existing but "stale" standby, `repmgr` can use `rsync` instead,
which means only changed or added files need to be copied.
- Can I register an existing master/standby?
Yes, this is no problem.
- How can a failed master be re-added as a standby?
This is a two-stage process. First, the failed master's data directory
must be re-synced with the current master; secondly the failed master
needs to be re-registered as a standby. The section "Converting a failed
master to a standby" in the `README.md` file contains more detailed
information on this process.
- Is there an easy way to check my master server is correctly configured
for use with `repmgr`?
Yes - execute `repmgr` with the `--check-upstream-config` option, and it
will let you know which items in `postgresql.conf` need to be modified.
- Even though I specified custom `rsync` options, `repmgr` appends
the `--checksum` - why?
When syncing a stale data directory from an active server, it's
essential that `rsync` compares the content of files rather than
just timestamp and size, to ensure that all changed files are
copied and prevent corruption.
- When cloning a standby, how can I prevent `repmgr` from copying
`postgresql.conf` and `pg_hba.conf` from the PostgreSQL configuration
directory in `/etc`?
Use the command line option `--ignore-external-config-files`
- How can I prevent `repmgr` from copying local configuration files
in the data directory?
If you're updating an existing but stale data directory which
contains e.g. configuration files you don't want to be overwritten
with the same file from the master, specify the files in the
`rsync_options` configuration option, e.g.
rsync_options=--exclude=postgresql.local.conf
This option is only available when using the `--rsync-only` option.
`repmgrd`
---------
- Do I need a witness server?
Not necessarily. However if you have an uneven number of nodes spread
over more than one network segment, a witness server will enable
better handling of a 'split brain' situation by providing a "casting
vote" on the preferred network segment.
- How can I prevent a node from ever being promoted to master?
In `rempgr.conf`, set its priority to a value of 0 or less.
- Does `repmgrd` support delayed standbys?
`repmgrd` can monitor delayed standbys - those set up with
`recovery_min_apply_delay` set to a non-zero value in `recovery.conf` -
but as it's not currently possible to directly examine the value
applied to the standby, `repmgrd` may not be able to properly evaluate
the node as a promotion candidate.
We recommend that delayed standbys are explicitly excluded from promotion
by setting `priority` to 0 in `repmgr.conf`.
Note that after registering a delayed standby, `repmgrd` will only start
once the metadata added in the master node has been replicated.

103
HISTORY Normal file
View File

@@ -0,0 +1,103 @@
3.0
Require PostgreSQL 9.3 or later (Ian)
Use `pg_basebackup` by default (instead of `rsync`) to clone standby servers (Ian)
Use `pg_ctl promote` to promote a standby to primary
Enable tablespace remapping using `pg_basebackup` (in PostgreSQL 9.3 with `rsync`) (Ian)
Support cascaded standbys (Ian)
"pg_bindir" no longer required as a configuration parameter (Ian)
Enable replication slots to be used (PostgreSQL 9.4 and later (Ian)
Command line option "--check-upstream-config" (Ian)
Add event logging table and option to execute an external program when an event occurs (Ian)
General usability and logging message improvements (Ian)
Code consolidation and cleanup (Ian)
2.0.2 2015-02-17
Add "--checksum" in rsync when using "--force" (Jaime)
Use createdb/createuser instead of psql (Jaime)
Fixes to witness creation and monitoring (wamonite)
Use default master port if none supplied (Martín)
Documentation fixes and improvements (Ian)
2.0.1 2014-07-16
Documentation fixes and new QUICKSTART file (Ian)
Explicitly specify directories to ignore when cloning (Ian)
Fix log level for some log messages (Ian)
RHEL/CentOS specfile, init script and Makefile fixes (Nathan Van Overloop)
Debian init script and config file documentation fixes (József Kószó)
Typo fixes (Riegie Godwin Jeyaranchen, PriceChild)
2.0stable 2014-01-30
Documentation fixes (Christian)
General refactoring, code quality improvements and stabilization work (Christian)
Added proper daemonizing (-d/--daemonize) (Christian)
Added PID file handling (-p/--pid-file) (Christian)
New config option: monitor_interval_secs (Christian)
New config option: retry_promote_interval (Christian)
New config option: logfile (Christian)
New config option: pg_bindir (Christian)
New config option: pgctl_options (Christian)
2.0beta2 2013-12-19
Improve autofailover logic and algorithms (Jaime, Andres)
Ignore pg_log when cloning (Jaime)
Add timestamps to log line in stderr (Christian)
Correctly check wal_keep_segments (Jay Taylor)
Add a ssh_options parameter (Jay Taylor)
2.0beta1 2012-07-27
Make CLONE command try to make an exact copy including $PGDATA location (Cedric)
Add detection of master failure (Jaime)
Add the notion of a witness server (Jaime)
Add autofailover capabilities (Jaime)
Add a configuration parameter to indicate the script to execute on failover or follow (Jaime)
Make the monitoring optional and turned off by default, it can be turned on with --monitoring-history switch (Jaime)
Add tunables to specify number of retries to reconnect to master and the time between them (Jaime)
1.2.0 2012-07-27
Test ssh connection before trying to rsync (Cédric)
Add CLUSTER SHOW command (Carlo)
Add CLUSTER CLEANUP command (Jaime)
Add function write_primary_conninfo (Marco)
Teach repmgr how to get tablespace's location in different pg version (Jaime)
Improve version message (Carlo)
1.1.1 2012-04-18
Add --ignore-rsync-warning (Cédric)
Add strnlen for compatibility with OS X (Greg)
Improve performance of the repl_status view (Jaime)
Remove last argument from log_err (Jaime, Reported by Jeroen Dekkers)
Complete documentation about possible error conditions (Jaime)
Document how to clean history (Jaime)
1.1.0 2011-03-09
Make options -U, -R and -p not mandatory (Jaime)
1.1.0b1 2011-02-24
Fix missing "--force" option in help (Greg Smith)
Correct warning message for wal_keep_segments (Bas van Oostveen)
Add Debian build/usage docs (Bas, Hannu Krosing, Cedric Villemain)
Add Debian .deb packaging (Hannu)
Move configuration data into a structure (Bas, Gabriele Bartolini)
Make rsync options configurable (Bas)
Add syslog as alternate logging destination (Gabriele)
Change from using malloc to static memory allocations (Gabriele)
Add debugging messages after every query (Gabriele)
Parameterize schema name used for repmgr (Gabriele)
Avoid buffer overruns by using snprintf etc. (Gabriele)
Fix use of database query after close (Gabriele)
Add information about progress during "standby clone" (Gabriele)
Fix double free errors in repmgrd (Charles Duffy, Greg)
Make repmgr exit with an error code when encountering an error (Charles)
Standardize on error return codes, use in repmgrd too (Greg)
Add [un]install actions/SQL like most contrib modules (Daniel Farina)
Wrap all string construction and produce error on overflow (Daniel)
Correct freeing of memory from first_wal_segment (Daniel)
Allow creating recovery.conf file with a password (Daniel)
Inform when STANDBY CLONE sees an unused config file (Daniel)
Use 64-bit computation for WAL apply_lag (Greg)
Add info messages for database and general work done (Greg)
Map old verbose flag into a useful setting for the new logger (Greg)
Document repmgrd startup restrictions and log info about them (Greg)
1.0.0 2010-12-05
First public release

View File

@@ -1,23 +1,28 @@
#
# Makefile
# Copyright (c) 2ndQuadrant, 2010
# Copyright (c) 2ndQuadrant, 2010-2015
repmgrd_OBJS = dbutils.o config.o repmgrd.o
repmgr_OBJS = dbutils.o check_dir.o config.o repmgr.o
repmgrd_OBJS = dbutils.o config.o repmgrd.o log.o strutil.o
repmgr_OBJS = dbutils.o check_dir.o config.o repmgr.o log.o strutil.o
DATA = repmgr.sql uninstall_repmgr.sql
PG_CPPFLAGS = -I$(libpq_srcdir)
PG_LIBS = $(libpq_pgport)
all: repmgrd repmgr
$(MAKE) -C sql
repmgrd: $(repmgrd_OBJS)
$(CC) $(CFLAGS) $(repmgrd_OBJS) $(PG_LIBS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o repmgrd
$(MAKE) -C sql
repmgr: $(repmgr_OBJS)
$(CC) $(CFLAGS) $(repmgr_OBJS) $(PG_LIBS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o repmgr
ifdef USE_PGXS
PGXS := $(shell pg_config --pgxs)
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/repmgr
@@ -26,11 +31,52 @@ include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
install:
$(INSTALL_PROGRAM) repmgrd$(X) '$(DESTDIR)$(bindir)'
$(INSTALL_PROGRAM) repmgr$(X) '$(DESTDIR)$(bindir)'
# XXX: Try to use PROGRAM construct (see pgxs.mk) someday. Right now
# is overriding pgxs install.
install: install_prog install_ext
install_prog:
mkdir -p '$(DESTDIR)$(bindir)'
$(INSTALL_PROGRAM) repmgrd$(X) '$(DESTDIR)$(bindir)/'
$(INSTALL_PROGRAM) repmgr$(X) '$(DESTDIR)$(bindir)/'
install_ext:
$(MAKE) -C sql install
install_rhel:
mkdir -p '$(DESTDIR)/etc/init.d/'
$(INSTALL_PROGRAM) RHEL/repmgrd.init '$(DESTDIR)/etc/init.d/repmgrd'
mkdir -p '$(DESTDIR)/etc/sysconfig/'
$(INSTALL_PROGRAM) RHEL/repmgrd.sysconfig '$(DESTDIR)/etc/sysconfig/repmgrd'
mkdir -p '$(DESTDIR)/etc/repmgr/'
$(INSTALL_PROGRAM) repmgr.conf.sample '$(DESTDIR)/etc/repmgr/'
mkdir -p '$(DESTDIR)/usr/bin/'
$(INSTALL_PROGRAM) repmgrd$(X) '$(DESTDIR)/usr/bin/'
$(INSTALL_PROGRAM) repmgr$(X) '$(DESTDIR)/usr/bin/'
ifneq (,$(DATA)$(DATA_built))
@for file in $(addprefix $(srcdir)/, $(DATA)) $(DATA_built); do \
echo "$(INSTALL_DATA) $$file '$(DESTDIR)$(datadir)/$(datamoduledir)'"; \
$(INSTALL_DATA) $$file '$(DESTDIR)$(datadir)/$(datamoduledir)'; \
done
endif
clean:
rm -f *.o
rm -f repmgrd
rm -f repmgr
$(MAKE) -C sql clean
deb: repmgrd repmgr
mkdir -p ./debian/usr/bin
cp repmgrd repmgr ./debian/usr/bin/
mkdir -p ./debian/usr/share/postgresql/9.0/contrib/
cp sql/repmgr_funcs.sql ./debian/usr/share/postgresql/9.0/contrib/
cp sql/uninstall_repmgr_funcs.sql ./debian/usr/share/postgresql/9.0/contrib/
mkdir -p ./debian/usr/lib/postgresql/9.0/lib/
cp sql/repmgr_funcs.so ./debian/usr/lib/postgresql/9.0/lib/
dpkg-deb --build debian
mv debian.deb ../postgresql-repmgr-9.0_1.0.0.deb
rm -rf ./debian/usr

123
PACKAGES.md Normal file
View File

@@ -0,0 +1,123 @@
Packaging
=========
Notes on RedHat Linux, Fedora, and CentOS Builds
------------------------------------------------
The RPM packages of PostgreSQL put ``pg_config`` into the ``postgresql-devel``
package, not the main server one. And if you have a RPM install of PostgreSQL
9.0, the entire PostgreSQL binary directory will not be in your PATH by default
either. Individual utilities are made available via the ``alternatives``
mechanism, but not all commands will be wrapped that way. The files installed
by repmgr will certainly not be in the default PATH for the postgres user
on such a system. They will instead be in /usr/pgsql-9.0/bin/ on this
type of system.
When building repmgr against a RPM packaged build, you may discover that some
development packages are needed as well. The following build errors can
occur::
/usr/bin/ld: cannot find -lxslt
/usr/bin/ld: cannot find -lpam
Install the following packages to correct those::
yum install libxslt-devel
yum install pam-devel
If building repmgr as a regular user, then doing the install into the system
directories using sudo, the syntax is hard. ``pg_config`` won't be in root's
path either. The following recipe should work::
sudo PATH="/usr/pgsql-9.0/bin:$PATH" make USE_PGXS=1 install
Issues with 32 and 64 bit RPMs
------------------------------
If when building, you receive a series of errors of this form::
/usr/bin/ld: skipping incompatible /usr/pgsql-9.0/lib/libpq.so when searching for -lpq
This is likely because you have both the 32 and 64 bit versions of the
``postgresql90-devel`` package installed. You can check that like this::
rpm -qa --queryformat '%{NAME}\t%{ARCH}\n' | grep postgresql90-devel
And if two packages appear, one for i386 and one for x86_64, that's not supposed
to be allowed.
This can happen when using the PGDG repo to install that package;
here is an example sessions demonstrating the problem case appearing::
# yum install postgresql-devel
..
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package postgresql90-devel.i386 0:9.0.2-2PGDG.rhel5 set to be updated
---> Package postgresql90-devel.x86_64 0:9.0.2-2PGDG.rhel5 set to be updated
--> Finished Dependency Resolution
Dependencies Resolved
=========================================================================
Package Arch Version Repository Size
=========================================================================
Installing:
postgresql90-devel i386 9.0.2-2PGDG.rhel5 pgdg90 1.5 M
postgresql90-devel x86_64 9.0.2-2PGDG.rhel5 pgdg90 1.6 M
Note how both the i386 and x86_64 platform architectures are selected for
installation. Your main PostgreSQL package will only be compatible with one of
those, and if the repmgr build finds the wrong postgresql90-devel these
"skipping incompatible" messages appear.
In this case, you can temporarily remove both packages, then just install the
correct one for your architecture. Example::
rpm -e postgresql90-devel --allmatches
yum install postgresql90-devel-9.0.2-2PGDG.rhel5.x86_64
Instead just deleting the package from the wrong platform might not leave behind
the correct files, due to the way in which these accidentally happen to interact.
If you already tried to build repmgr before doing this, you'll need to do::
make USE_PGXS=1 clean
to get rid of leftover files from the wrong architecture.
Notes on Ubuntu, Debian or other Debian-based Builds
----------------------------------------------------
The Debian packages of PostgreSQL put ``pg_config`` into the development package
called ``postgresql-server-dev-$version``.
When building repmgr against a Debian packages build, you may discover that some
development packages are needed as well. You will need the following development
packages installed::
sudo apt-get install libxslt-dev libxml2-dev libpam-dev libedit-dev
If your using Debian packages for PostgreSQL and are building repmgr with the
USE_PGXS option you also need to install the corresponding development package::
sudo apt-get install postgresql-server-dev-9.0
If you build and install repmgr manually it will not be on the system path. The
binaries will be installed in /usr/lib/postgresql/$version/bin/ which is not on
the default path. The reason behind this is that Ubuntu/Debian systems manage
multiple installed versions of PostgreSQL on the same system through a wrapper
called pg_wrapper and repmgr is not (yet) known to this wrapper.
You can solve this in many different ways, the most Debian like is to make an
alternate for repmgr and repmgrd::
sudo update-alternatives --install /usr/bin/repmgr repmgr /usr/lib/postgresql/9.0/bin/repmgr 10
sudo update-alternatives --install /usr/bin/repmgrd repmgrd /usr/lib/postgresql/9.0/bin/repmgrd 10
You can also make a deb package of repmgr using::
make USE_PGXS=1 deb
This will build a Debian package one level up from where you build, normally the
same directory that you have your repmgr/ directory in.

114
QUICKSTART.md Normal file
View File

@@ -0,0 +1,114 @@
repmgr quickstart guide
=======================
This quickstart guide provides some annotated examples on basic
`repmgr` setup. It assumes you are familiar with PostgreSQL replication
concepts setup and Linux/UNIX system administration.
For the purposes of this guide, we'll assume the database user will be
`repmgr_usr` and the database will be `repmgr_db`.
Master setup
------------
1. Configure PostgreSQL
- create user and database:
```
CREATE ROLE repmgr_usr LOGIN SUPERUSER;
CREATE DATABASE repmgr_db OWNER repmgr_usr;
```
- configure `postgresql.conf` for replication (see above)
- update `pg_hba.conf`, e.g.:
```
host repmgr_db repmgr_usr 192.168.1.0/24 trust
host replication repmgr_usr 192.168.1.0/24 trust
```
Restart the PostgreSQL server after making these changes.
2. Create the `repmgr` configuration file:
$ cat /path/to/repmgr/node1/repmgr.conf
cluster=test
node=1
node_name=node1
conninfo='host=repmgr_node1 user=repmgr_usr dbname=repmgr_db'
pg_bindir=/path/to/postgres/bin
(For an annotated `repmgr.conf` file, see `repmgr.conf.sample` in the
repository's root directory).
3. Register the master node with `repmgr`:
$ repmgr -f /path/to/repmgr/node1/repmgr.conf --verbose master register
[2015-03-03 17:45:53] [INFO] repmgr connecting to master database
[2015-03-03 17:45:53] [INFO] repmgr connected to master, checking its state
[2015-03-03 17:45:53] [INFO] master register: creating database objects inside the repmgr_test schema
[2015-03-03 17:45:53] [NOTICE] Master node correctly registered for cluster test with id 1 (conninfo: host=localhost user=repmgr_usr dbname=repmgr_db)
Standby setup
-------------
1. Use `repmgr standby clone` to clone a standby from the master:
repmgr -D /path/to/standby/data -d repmgr_db -U repmgr_usr --verbose standby clone 192.168.1.2
[2015-03-03 18:18:21] [NOTICE] No configuration file provided and default file './repmgr.conf' not found - continuing with default values
[2015-03-03 18:18:21] [NOTICE] repmgr Destination directory ' /path/to/standby/data' provided
[2015-03-03 18:18:21] [INFO] repmgr connecting to upstream node
[2015-03-03 18:18:21] [INFO] repmgr connected to upstream node, checking its state
[2015-03-03 18:18:21] [INFO] Successfully connected to upstream node. Current installation size is 27 MB
[2015-03-03 18:18:21] [NOTICE] Starting backup...
[2015-03-03 18:18:21] [INFO] creating directory " /path/to/standby/data"...
[2015-03-03 18:18:21] [INFO] Executing: 'pg_basebackup -l "repmgr base backup" -h localhost -p 9595 -U repmgr_usr -D /path/to/standby/data '
NOTICE: pg_stop_backup complete, all required WAL segments have been archived
[2015-03-03 18:18:23] [NOTICE] repmgr standby clone (using pg_basebackup) complete
[2015-03-03 18:18:23] [NOTICE] HINT: You can now start your postgresql server
[2015-03-03 18:18:23] [NOTICE] for example : pg_ctl -D /path/to/standby/data start
Note that at this point it does not matter if the `repmgr.conf` file is not found.
This will clone the PostgreSQL database files from the master, including its
`postgresql.conf` and `pg_hba.conf` files, and additionally automatically create
the `recovery.conf` file containing the correct parameters to start streaming
from the primary node.
2. Start the PostgreSQL server
3. Create the `repmgr` configuration file:
$ cat /path/node2/repmgr/repmgr.conf
cluster=test
node=2
node_name=node2
conninfo='host=repmgr_node2 user=repmgr_usr dbname=repmgr_db'
pg_bindir=/path/to/postgres/bin
4. Register the standby node with `repmgr`:
$ repmgr -f /path/to/repmgr/node2/repmgr.conf --verbose standby register
[2015-03-03 18:24:34] [NOTICE] Opening configuration file: /path/to/repmgr/node2/repmgr.conf
[2015-03-03 18:24:34] [INFO] repmgr connecting to standby database
[2015-03-03 18:24:34] [INFO] repmgr connecting to master database
[2015-03-03 18:24:34] [INFO] finding node list for cluster 'test'
[2015-03-03 18:24:34] [INFO] checking role of cluster node '1'
[2015-03-03 18:24:34] [INFO] repmgr connected to master, checking its state
[2015-03-03 18:24:34] [INFO] repmgr registering the standby
[2015-03-03 18:24:34] [INFO] repmgr registering the standby complete
[2015-03-03 18:24:34] [NOTICE] Standby node correctly registered for cluster test with id 2 (conninfo: host=localhost user=repmgr_usr dbname=repmgr_db)
This concludes the basic `repmgr` setup of master and standby. The records
created in the `repl_nodes` table should look something like this:
repmgr_db=# SELECT * from repmgr_test.repl_nodes;
id | type | upstream_node_id | cluster | name | conninfo | slot_name | priority | active
----+---------+------------------+---------+-------+-------------------------------------------------+-----------+----------+--------
1 | primary | | test | node1 | host=localhost user=repmgr_usr dbname=repmgr_db | | 0 | t
2 | standby | 1 | test | node2 | host=localhost user=repmgr_usr dbname=repmgr_db | | 0 | t
(2 rows)

619
README.md Normal file
View File

@@ -0,0 +1,619 @@
repmgr: Replication Manager for PostgreSQL
==========================================
`repmgr` is an open-source tool to manage replication and failover
between multiple PostgreSQL servers. It enhances PostgreSQL's built-in
hot-standby capabilities with tools to set up standby servers, monitor
replication, and perform administrative tasks such as failover or manual
switchover operations.
This document covers `repmgr 3`, which supports PostgreSQL 9.4 and 9.3.
This version can use `pg_basebackup` to clone standby servers, supports
replication slots and cascading replication, doesn't require a restart
after promotion, and has many usability improvements.
Please continue to use `repmgr 2` with earlier PostgreSQL 9.x versions.
For a list of changes since `repmgr 2` and instructions on upgrading to
`repmgr 3`, see the "Upgrading from repmgr 2" section below.
Overview
--------
The `repmgr` command-line tool is used to perform administrative tasks,
and the `repmgrd` daemon is used to optionally monitor replication and
manage automatic failover.
To get started, each PostgreSQL node in your cluster must have a
`repmgr.conf` file. The current master node must be registered using
`repmgr master register`. Existing standby servers can be registered
using `repmgr standby register`. A new standby server can be created
using `repmgr standby clone` followed by `repmgr standby register`.
See the `QUICKSTART.md` file for examples of how to use these commands.
Once the cluster is in operation, run `repmgr cluster show` to see the
status of the registered primary and standby nodes. Any standby can be
manually promoted using `repmgr standby promote`. Other standby nodes
can be told to follow the new master using `repmgr standby follow`. We
show examples of these commands below.
Next, for detailed monitoring, you must run `repmgrd` (with the same
configuration file) on all your nodes. Replication status information is
stored in a custom schema along with information about registered nodes.
You also need `repmgrd` to configure automatic failover in your cluster.
See the `FAILOVER.rst` file for an explanation of how to set up
automatic failover.
Requirements
------------
`repmgr` is developed and tested on Linux and OS X, but it should work
on any UNIX-like system which PostgreSQL itself supports.
All nodes must be running the same major version of PostgreSQL, and we
recommend that they also run the same minor version. This version of
`repmgr` (v3) supports PostgreSQL 9.3 and 9.4.
Earlier versions of `repmgr` needed password-less SSH access between
nodes in order to clone standby servers using `rsync`. `repmgr 3` can
use `pg_basebackup` instead in most circumstances; ssh is not required.
You will need to use rsync only if your PostgreSQL configuration files
are outside your data directory (as on Debian) and you wish these to
be copied by `repmgr`. See the `SSH-RSYNC.md` file for details on
configuring password-less SSH between your nodes.
Installation
------------
`repmgr` must be installed on each PostgreSQL server node.
* Packages
- PGDG publishes RPM packages for RedHat-based distributions
- Debian/Ubuntu provide .deb packages.
- See `PACKAGES.md` for details on building .deb and .rpm packages
from the `repmgr` source code.
* Source installation
- `git clone https://github.com/2ndQuadrant/repmgr`
- Or download tar.gz files from
https://github.com/2ndQuadrant/repmgr/releases
- To install from source, run `sudo make USE_PGXS=1 install`
After installation, you should be able to run `repmgr --version` and
`repmgrd --version`. These binaries should be installed in the same
directory as other PostgreSQL binaries, such as `psql`.
Configuration
-------------
### Server configuration
By default, `repmgr` uses PostgreSQL's built-in replication protocol to
clone a primary and create a standby server. If your configuration files
live outside your data directory, however, you will still need to set up
password-less SSH so that rsync can be used. See the `SSH-RSYNC.md` file
for details.
### PostgreSQL configuration
The primary server needs to be configured for replication with the
following settings in `postgresql.conf`:
# Allow read-only queries on standby servers. The number of WAL
# senders should be larger than the number of standby servers.
hot_standby = on
wal_level = 'hot_standby'
max_wal_senders = 10
# How much WAL to retain on the primary to allow a temporarily
# disconnected standby to catch up again. The larger this is, the
# longer the standby can be disconnected. This is needed only in
# 9.3; in 9.4, replication slots can be used instead (see below).
wal_keep_segments = 5000
# Enable archiving, but leave it unconfigured (so that it can be
# configured without a restart later). Recommended, not required.
archive_mode = on
archive_command = 'cd .'
# You can also set additional replication parameters here, such as
# hot_standby_feedback or synchronous_standby_names.
PostgreSQL 9.4 makes it possible to use replication slots, which means
the value of wal_keep_segments need no longer be set. With 9.3, `repmgr`
expects it to be set to at least 5000 (= 80GB of WAL) by default, though
this can be overriden with the `-w N` argument.
A dedicated PostgreSQL superuser account and a database in which to
store monitoring and replication data are required. Create them by
running the following commands:
createuser -s repmgr
createdb repmgr -O repmgr
We recommend using the name `repmgr` for both, but you can use whatever
name you like (and you need to set the names you chose in the `conninfo`
string in `repmgr.conf`; see below). `repmgr` will create the schema and
objects it needs when it connects to the server.
### repmgr configuration
Create a `repmgr.conf` file on each server. Here's a minimal sample:
cluster=test
node=1
node_name=node1
conninfo='host=repmgr_node1 user=repmgr dbname=repmgr'
The `cluster` name must be the same on all nodes. The `node` (an
integer) and `node_name` must be unique to each node.
The `conninfo` string must point to repmgr's database *on this node*.
The host must be an IP or a name that all the nodes in the cluster can
resolve (not `localhost`!). All nodes must use the same username and
database name, but other parameters, such as the port, can vary between
nodes.
Your `repmgr.conf` should not be stored inside the PostgreSQL data
directory. We recommend `/etc/repmgr/repmgr.conf`, but you can place it
anywhere and use the `-f /path/to/repmgr.conf` option to tell `repmgr`
where it is. If not specified, `repmgr` will search for `repmgr.conf` in
the current working directory.
If your PostgreSQL binaries (`pg_ctl`, `pg_basebackup`) are not in your
`PATH`, you can specify an alternate location in `repmgr.conf`:
pg_bindir=/path/to/postgres/bin
See `repmgr.conf.sample` for an example configuration file with all
available configuration settings annotated.
### Starting up
The master node must be registered first using `repmgr master register`,
and standby servers must be registered using `repmgr standby register`;
this inserts details about each node into the control database. Use
`repmgr cluster show` to see the result.
See the `QUICKSTART.md` file for examples of how to use these commands.
Failover
--------
To promote a standby to master, on the standby execute e.g.:
repmgr -f /etc/repmgr/repmgr.conf --verbose standby promote
`repmgr` will attempt to connect to the current master to verify that it
is not available (if it is, `repmgr` will not promote the standby).
Other standby servers need to be told to follow the new master with e.g.:
repmgr -f /etc/repmgr/repmgr.conf --verbose standby follow
See file `FAILOVER.rst` for details on setting up automated failover.
Converting a failed master to a standby
---------------------------------------
Often it's desirable to bring a failed master back into replication
as a standby. First, ensure that the master's PostgreSQL server is
no longer running; then use `repmgr standby clone` to re-sync its
data directory with the current master, e.g.:
repmgr -f /etc/repmgr/repmgr.conf \
--force --rsync-only \
-h node2 -d repmgr -U repmgr --verbose \
standby clone
Here it's essential to use the command line options `--force`, to
ensure `repmgr` will re-use the existing data directory, and
`--rsync-only`, which causes `repmgr` to use `rsync` rather than
`pg_basebackup`, as the latter can only be used to clone a fresh
standby.
The node can then be restarted.
The node will then need to be re-registered with `repmgr`; again
the `--force` option is required to update the existing record:
repmgr -f /etc/repmgr/repmgr.conf
--force \
standby register
Replication management with repmgrd
-----------------------------------
`repmgrd` is a management and monitoring daemon which runs on standby nodes
and which can automate actions such as failover and updating standbys to
follow the new master.`repmgrd` can be started simply with e.g.:
repmgrd -f /etc/repmgr/repmgr.conf --verbose > $HOME/repmgr/repmgr.log 2>&1
or alternatively:
repmgrd -f /etc/repmgr/repmgr.conf --verbose --monitoring-history > $HOME/repmgr/repmgrd.log 2>&1
which will track replication advance or lag on all registered standbys.
For permanent operation, we recommend using the options `-d/--daemonize` to
detach the `repmgrd` process, and `-p/--pid-file` to write the process PID
to a file.
Example log output (at default log level):
[2015-03-11 13:15:40] [INFO] checking cluster configuration with schema 'repmgr_test'
[2015-03-11 13:15:40] [INFO] checking node 2 in cluster 'test'
[2015-03-11 13:15:40] [INFO] reloading configuration file and updating repmgr tables
[2015-03-11 13:15:40] [INFO] starting continuous standby node monitoring
Witness server
--------------
In a situation caused e.g. by a network interruption between two
data centres, it's important to avoid a "split-brain" situation where
both sides of the network assume they are the active segment and the
side without an active master unilaterally promotes one of its standbys.
To prevent this situation happening, it's essential to ensure that one
network segment has a "voting majority", so other segments will know
they're in the minority and not attempt to promote a new master. Where
an odd number of servers exists, this is not an issue. However, if each
network has an even number of nodes, it's necessary to provide some way
of ensuring a majority, which is where the witness server becomes useful.
This is not a fully-fledged standby node and is not integrated into
replication, but it effectively represents the "casting vote" when
deciding which network segment has a majority. A witness server can
be set up using `repmgr witness create` (see below for details) and
can run on a dedicated server or an existing node. Note that it only
makes sense to create a witness server in conjunction with running
`repmgrd`; the witness server will require its own `repmgrd` instance.
Monitoring
----------
When `repmgrd` is running with the option `-m/--monitoring-history`, it will
constantly write node status information to the `repl_monitor` table, which can
be queried easily using the view `repl_status`:
repmgr=# SELECT * FROM repmgr_test.repl_status;
-[ RECORD 1 ]-------------+-----------------------------
primary_node | 1
standby_node | 2
standby_name | node2
node_type | standby
active | t
last_monitor_time | 2015-03-11 14:02:34.51713+09
last_wal_primary_location | 0/3012AF0
last_wal_standby_location | 0/3012AF0
replication_lag | 0 bytes
replication_time_lag | 00:00:03.463085
apply_lag | 0 bytes
communication_time_lag | 00:00:00.955385
Event logging and notifications
-------------------------------
To help understand what significant events (e.g. failure of a node) happened
when and for what reason, `repmgr` logs such events into the `repl_events`
table, e.g.:
repmgr_db=# SELECT * from repmgr_test.repl_events ;
node_id | event | successful | event_timestamp | details
---------+------------------+------------+-------------------------------+-----------------------------------------------------------------------------------
1 | master_register | t | 2015-03-16 17:36:21.711796+09 |
2 | standby_clone | t | 2015-03-16 17:36:31.286934+09 | Cloned from host 'localhost', port 5500; backup method: pg_basebackup; --force: N
2 | standby_register | t | 2015-03-16 17:36:32.391567+09 |
(3 rows)
Additionally `repmgr` can execute an external program each time an event is
logged. This program is defined with the configuration variable
`event_notification_command`; the command string can contain the following
placeholders, which will be replaced with the same content which is
written to the `repl_events` table:
%n - node id
%e - event type
%s - success (1 or 0)
%t - timestamp
%d - description
Example:
event_notification_command=/path/to/some-script %n %e %s "%t" "%d"
By default the program defined with `event_notification_command` will be
executed for every event; to restrict execution to certain events, list
these in the parameter `event_notifications`
event_notifications=master_register,standby_register
Following event types currently exist:
master_register
standby_register
standby_clone
standby_promote
witness_create
repmgrd_start
repmgrd_failover_promote
repmgrd_failover_follow
Cascading replication
---------------------
Cascading replication - where a standby can connect to an upstream node and not
the master server itself - was introduced in PostgreSQL 9.2. `repmgr` and
`repmgrd` support cascading replication by keeping track of the relationship
between standby servers - each node record is stored with the node id of its
upstream ("parent") server (except of course the master server).
In a failover situation where the master node fails and a top-level standby
is promoted, a standby connected to another standby will not be affected
and continue working as normal (even if the upstream standby it's connected
to becomes the master node). If however the node's direct upstream fails,
the "cascaded standby" will attempt to reconnect to that node's parent.
To configure standby servers for cascading replication, add the parameter
`upstream_node` to `repmgr.conf` and set it to the id of the node it should
connect to, e.g.:
cluster=test
node=2
node_name=node2
upstream_node=1
Replication slots
-----------------
Replication slots were introduced with PostgreSQL 9.4 and enable standbys to
notify the master of their WAL consumption, ensuring that the master will
not remove any WAL files until they have been received by all standbys.
This mitigates the requirement to manage WAL file retention using
`wal_keep_segments` etc., with the caveat that if a standby fails, no WAL
files will be removed until the standby's replication slot is deleted.
To enable replication slots, set the boolean parameter `use_replication_slots`
in `repmgr.conf`:
use_replication_slots=1
`repmgr` will automatically generate an appropriate slot name, which is
stored in the `repl_nodes` table.
Note that `repmgr` will fail with an error if this option is specified when
working with PostgreSQL 9.3.
Further reading:
* http://www.postgresql.org/docs/current/interactive/warm-standby.html#STREAMING-REPLICATION-SLOTS
* http://blog.2ndquadrant.com/postgresql-9-4-slots/
Upgrading from repmgr 2
-----------------------
`repmgr 3` is largely compatible with `repmgr 2`; the only step required
to upgrade is to update the `repl_nodes` table to the definition needed
by `repmgr 3`. See the file `sql/repmgr2_repmgr3.sql` for details on how
to do this.
`repmgrd` must *not* be running while `repl_nodes` is being updated.
Existing `repmgr.conf` files can be retained as-is.
---------------------------------------
Reference
---------
### repmgr command reference
Not all of these commands need the ``repmgr.conf`` file, but they need to be able to
connect to the remote and local databases.
You can teach it which is the remote database by using the -h parameter or
as a last parameter in standby clone and standby follow. If you need to specify
a port different then the default 5432 you can specify a -p parameter.
Standby is always considered as localhost and a second -p parameter will indicate
its port if is different from the default one.
* `master register`
Registers a master in a cluster. This command needs to be executed before any
standby nodes are registered.
* `standby register`
Registers a standby with `repmgr`. This command needs to be executed to enable
promote/follow operations and to allow `repmgrd` to work with the node.
An existing standby can be registered using this command.
* `standby clone [node to be cloned]`
Clones a new standby node from the data directory of the master (or
an upstream cascading standby) using `pg_basebackup` or `rsync`.
Additionally it will create the `recovery.conf` file required to
start the server as a standby. This command does not require
`repmgr.conf` to be provided, but does require connection details
of the master or upstream server as command line parameters.
Provide the `-D/--data-dir` option to specify the destination data
directory; if not, the same directory path as on the source server
will be used. By default, `pg_basebackup` will be used to copy data
from the master or upstream node but this can only be used for
bootstrapping new installations. To update an existing but 'stale'
data directory (for example belonging to a failed master), `rsync`
must be used by specifying `--rsync-only`. In this case,
password-less SSH connections between servers are required.
* `standby promote`
Promotes a standby to a master if the current master has failed. This
command requires a valid `repmgr.conf` file for the standby, either
specified explicitly with `-f/--config-file` or located in the current
working directory; no additional arguments are required.
If the standby promotion succeeds, the server will not need to be
restarted. However any other standbys will need to follow the new server,
by using `standby follow` (see below); if `repmgrd` is active, it will
handle this.
This command will not function if the current master is still running.
* `witness create`
Creates a witness server as a separate PostgreSQL instance. This instance
can be on a separate server or a server running an existing node. The
witness server contain a copy of the repmgr metadata tables but will not
be set up as a standby; instead it will update its metadata copy each
time a failover occurs.
Note that it only makes sense to create a witness server if `repmgrd`
is in use; see section "witness server" above.
By default the witness server will use port 5499 to facilitate easier setup
on a server running an existing node.
* `standby follow`
Attaches the standby to a new master. This command requires a valid
`repmgr.conf` file for the standby, either specified explicitly with
`-f/--config-file` or located in the current working directory; no
additional arguments are required.
This command will force a restart of the standby server. It can only be used
to attach a standby to a new master node.
* `cluster show`
Displays information about each node in the replication cluster. This
command polls each registered server and shows its role (master / standby /
witness) or "FAILED" if the node doesn't respond. It polls each server
directly and can be run on any node in the cluster; this is also useful
when analyzing connectivity from a particular node.
This command requires a valid `repmgr.conf` file for the node on which it is
executed, either specified explicitly with `-f/--config-file` or located in
the current working directory; no additional arguments are required.
Example:
repmgr -f /path/to/repmgr.conf cluster show
Role | Connection String
* master | host=node1 dbname=repmgr user=repmgr
standby | host=node2 dbname=repmgr user=repmgr
standby | host=node3 dbname=repmgr user=repmgr
* `cluster cleanup`
Purges monitoring history from the `repl_monitor` table to prevent excessive
table growth. Use the `-k/--keep-history` to specify the number of days of
monitoring history to retain. This command can be used manually or as a
cronjob.
This command requires a valid `repmgr.conf` file for the node on which it is
executed, either specified explicitly with `-f/--config-file` or located in
the current working directory; no additional arguments are required.
### repmgr configuration file
See `repmgr.conf.sample` for an example configuration file with available
configuration settings annotated.
### repmgr database schema
`repmgr` creates a small schema for its own use in the database specified in
each node's `conninfo` configuration parameter. This database can in principle
be any database. The schema name is the global `cluster` name prefixed
with `repmgr_`, so for the example setup above the schema name is
`repmgr_test`.
The schema contains two tables:
* `repl_nodes`
stores information about all registered servers in the cluster
* `repl_monitor`
stores monitoring information about each node (generated by `repmgrd` with
`-m/--monitoring-history` option enabled)
and one view:
* `repl_status`
summarizes the latest monitoring information for each node (generated by `repmgrd` with
`-m/--monitoring-history` option enabled)
### Error codes
`repmgr` or `repmgrd` will return one of the following error codes on program
exit:
* SUCCESS (0) Program ran successfully.
* ERR_BAD_CONFIG (1) Configuration file could not be parsed or was invalid
* ERR_BAD_RSYNC (2) An rsync call made by the program returned an error
* ERR_NO_RESTART (4) An attempt to restart a PostgreSQL instance failed
* ERR_DB_CON (6) Error when trying to connect to a database
* ERR_DB_QUERY (7) Error while executing a database query
* ERR_PROMOTED (8) Exiting program because the node has been promoted to master
* ERR_BAD_PASSWORD (9) Password used to connect to a database was rejected
* ERR_STR_OVERFLOW (10) String overflow error
* ERR_FAILOVER_FAIL (11) Error encountered during failover (repmgrd only)
* ERR_BAD_SSH (12) Error when connecting to remote host via SSH
* ERR_SYS_FAILURE (13) Error when forking (repmgrd only)
* ERR_BAD_BASEBACKUP (14) Error when executing pg_basebackup
Support and Assistance
----------------------
2ndQuadrant provides 24x7 production support for repmgr, including
configuration assistance, installation verification and training for
running a robust replication cluster. For further details see:
* http://2ndquadrant.com/en/support/
There is a mailing list/forum to discuss contributions or issues
http://groups.google.com/group/repmgr
The IRC channel #repmgr is registered with freenode.
Further information is available at http://www.repmgr.org/
We'd love to hear from you about how you use repmgr. Case studies and
news are always welcome. Send us an email at info@2ndQuadrant.com, or
send a postcard to
repmgr
c/o 2ndQuadrant
7200 The Quorum
Oxford Business Park North
Oxford
OX4 2JZ
United Kingdom
Thanks from the repmgr core team.
* Ian Barwick
* Jaime Casanova
* Abhijit Menon-Sen
* Simon Riggs
* Cedric Villemain
Further reading
---------------
* http://blog.2ndquadrant.com/announcing-repmgr-2-0/
* http://blog.2ndquadrant.com/managing-useful-clusters-repmgr/
* http://blog.2ndquadrant.com/easier_postgresql_90_clusters/

View File

@@ -1,628 +0,0 @@
===================================================
repmgr: Replication Manager for PostgreSQL clusters
===================================================
Introduction
============
PostgreSQL 9.0 allow us to have replicated Hot Standby servers
which we can query and/or use for high availability.
While the main components of the feature are included with
PostgreSQL, the user is expected to manage the high availability
part of it.
repmgr allows you to monitor and manage your replicated PostgreSQL
databases as a single cluster.
repmgr includes two components:
* repmgr: command program that performs tasks and then exits
* repmgrd: management and monitoring daemon that watches the cluster
Requirements
------------
repmgr is currently aimed for installation on UNIX-like systems that include
development tools such as gcc and gmake. It also requires that the
``rsync`` utility is available in the PATH of the user running the repmgr
programs.
Installation Outline
====================
To install and use repmgr and repmgrd follow these steps:
1. Build repmgr programs
2. Set up trusted copy between postgres accounts, needed for the
``STANDBY CLONE`` step
3. Check your primary server is correctly configured
4. Write a suitable ``repmgr.conf`` for the node
5. Setup repmgrd to aid in failover transitions
Build repmgr programs
---------------------
Both methods of installation will place the binaries at the same location as your
postgres binaries, such as ``psql``. There are two ways to build it. The second
requires a full PostgreSQL source code tree to install the program directly into.
The first instead uses the PostgreSQL Extension System (PGXS) to install. For
this method to work, you will need the pg_config program available in your PATH.
In some distributions of PostgreSQL, this requires installing a separate
development package in addition to the basic server software.
Build repmgr programs - PGXS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you are using a packaged PostgreSQL build and have ``pg_config``
available, the package can be built and installed using PGXS instead::
tar xvzf repmgr-1.0.tar.gz
cd repmgr
make USE_PGXS=1
make USE_PGXS=1 install
This is preferred to building from the ``contrib`` subdirectory of the main
source code tree.
If you need to remove the source code temporary files from this directory,
that can be done like this::
make USE_PGXS=1 clean
See below for building notes specific to RedHat Linux variants.
Using a full source code tree
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In this method, the repmgr distribution is copied into the PostgreSQL source
code tree, assumed to be at the ${postgresql_sources} for this example.
The resulting subdirectory must be named ``contrib/repmgr``, without any
version number::
cp repmgr.tar.gz ${postgresql_sources}/contrib
cd ${postgresql_sources}/contrib
tar xvzf repmgr-1.0.tar.gz
cd repmgr
make
make install
If you need to remove the source code temporary files from this directory,
that can be done like this::
make clean
Notes on RedHat Linux, Fedora, and CentOS Builds
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The RPM packages of PostgreSQL put ``pg_config`` into the ``postgresql-devel``
package, not the main server one. And if you have a RPM install of PostgreSQL
9.0, the entire PostgreSQL binary directory will not be in your PATH by default
either. Individual utilities are made available via the ``alternatives``
mechanism, but not all commands will be wrapped that way. The files installed
by repmgr will certainly not be in the default PATH for the postgres user
on such a system. They will instead be in /usr/pgsql-9.0/bin/ on this
type of system.
When building repmgr against a RPM packaged build, you may discover that some
development packages are needed as well. The following build errors can
occur::
/usr/bin/ld: cannot find -lxslt
/usr/bin/ld: cannot find -lpam
Install the following packages to correct those::
yum install libxslt-devel
yum install pam-devel
If building repmgr as a regular user, then doing the install into the system
directories using sudo, the syntax is hard. ``pg_config`` won't be in root's
path either. The following recipe should work::
sudo PATH="/usr/pgsql-9.0/bin:$PATH" make USE_PGXS=1 install
Confirm software was built correctly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You should now find the repmgr programs available in the subdirectory where
the rest of your PostgreSQL installation is at. You can confirm the software
is available by checking its version::
repmgr --version
repmgrd --version
You may need to include
the full path of the binary instead, such as this RHEL example::
/usr/pgsql-9.0/bin/repmgr --version
/usr/pgsql-9.0/bin/repmgrd --version
Below this binary installation base directory is referred to as PGDIR.
Set up trusted copy between postgres accounts
---------------------------------------------
Initial copy between nodes uses the rsync program running over ssh. For this
to work, the postgres accounts on each system need to be able to access files
on their partner node without a password.
First generate a ssh key, using an empty passphrase, and copy the resulting
keys and a maching authorization file to a privledged user on the other system::
[postgres@db1]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/var/lib/pgsql/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/lib/pgsql/.ssh/id_rsa.
Your public key has been saved in /var/lib/pgsql/.ssh/id_rsa.pub.
The key fingerprint is:
aa:bb:cc:dd:ee:ff:aa:11:22:33:44:55:66:77:88:99 postgres@db1.domain.com
[postgres@db1]$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
[postgres@db1]$ chmod go-rwx ~/.ssh/*
[postgres@db1]$ cd ~/.ssh
[postgres@db1]$ scp id_rsa.pub id_rsa authorized_keys user@db2:
Login as a user on the other system, and install the files into the postgres
user's account::
[user@db2 ~]$ sudo chown postgres.postgres authorized_keys id_rsa.pub id_rsa
[user@db2 ~]$ sudo mkdir -p ~postgres/.ssh
[user@db2 ~]$ sudo chown postgres.postgres ~postgres/.ssh
[user@db2 ~]$ sudo mv authorized_keys id_rsa.pub id_rsa ~postgres/.ssh
[user@db2 ~]$ sudo chmod -R go-rwx ~postgres/.ssh
Now test that ssh in both directions works. You may have to accept some new
known hosts in the process.
Primary server configuration
============================
PostgreSQL should have been previously built and installed on the system. Here
is a sample of changes to the ``postgresql.conf`` file::
listen_addresses='*'
wal_level = 'hot_standby'
archive_mode = on
archive_command = 'cd .' # we can also use exit 0, anything that
# just does nothing
max_wal_senders = 10
wal_keep_segments = 5000 # 80 GB required on pg_xlog
hot_standby = on
Also you need to add the machines that will participate in the cluster in
``pg_hba.conf`` file. One possibility is to trust all connections from the
replication users from all internal addresses, such as::
host all all 192.168.1.0/24 trust
host replication all 192.168.1.0/24 trust
A more secure setup adds a repmgr user and database, just giving
access to that user::
host repmgr repmgr 192.168.1.0/24 trust
host replication all 192.168.1.0/24 trust
If you give a password to the user, you need to create a ``.pgpass`` file for
them as well to allow automatic login. In this case you might use the
``md5`` authentication method instead of ``trust`` for the repmgr user.
Configuration File
==================
``repmgr.conf`` is looked for in the directory repmgrd or repmgr exists.
The configuration file should have 3 lines:
It should have these three parameters:
1. cluster: A string (single quoted) that identify the cluster we are on
2. node: An integer that identify our node in the cluster
3. conninfo: A string (single quoted) specifying how we can connect to this node's PostgreSQL service
Command line syntax
===================
The current supported syntax for the program can be seen using::
repmgr --help
The output from this program looks like this::
repmgr: Replicator manager
Usage:
repmgr [OPTIONS] master {register}
repmgr [OPTIONS] standby {register|clone|promote|follow}
General options:
--help show this help, then exit
--version output version information, then exit
--verbose output verbose activity information
Connection options:
-d, --dbname=DBNAME database to connect to
-h, --host=HOSTNAME database server host or socket directory
-p, --port=PORT database server port
-U, --username=USERNAME database user name to connect as
Configuration options:
-D, --data-dir=DIR local directory where the files will be copied to
-f, --config_file=PATH path to the configuration file
-R, --remote-user=USERNAME database server username for rsync
-w, --wal-keep-segments=VALUE minimum value for the GUC wal_keep_segments (default: 5000)
repmgr performs some tasks like clone a node, promote it or making follow another node and then exits.
COMMANDS:
master register - registers the master in a cluster
standby register - registers a standby in a cluster
standby clone [node] - allows creation of a new standby
standby promote - allows manual promotion of a specific standby into a new master in the event of a failover
standby follow - allows the standby to re-point itself to a new master
The ``--verbose`` option can be useful in troubleshooting issues with
the program.
Commands
========
Not all of these commands need the ``repmgr.conf`` file, but they need to be able to
connect to the remote and local databases.
You can teach it which is the remote database by using the -h parameter or
as a last parameter in standby clone and standby follow. If you need to specify
a port different then the default 5432 you can specify a -p parameter.
Standby is always considered as localhost and a second -p parameter will indicate
its port if is different from the default one.
* master register
* Registers a master in a cluster, it needs to be executed before any node is
registered
* standby register
* Registers a standby in a cluster, it needs to be executed before any repmgrd
is executed
* standby clone [node to be cloned]
* Does a backup via ``rsync`` of the data directory of the primary. And it
creates the recovery file we need to start a new hot standby server.
It doesn't need the ``repmgr.conf`` so it can be executed anywhere on the
new node. You can change to the directory you want the new database
cluster at and execute::
./repmgr standby clone 10.68.1.161
or run from wherever you are with a full path::
./repmgr -D /path/to/new/data/directory standby clone 10.68.1.161
That will make a backup of the primary then you only need to start the server
using a command like::
pg_ctl -D /your_data_directory_path start
Note that some installations will also redirect the output log file when
executing ``pg_ctl``.
* standby promote
* Allows manual promotion of a specific standby into a new primary in the
event of a failover. This needs to be executed on the same directory
where the ``repmgr.conf`` is in the standby, or you can use the ``-f`` option
to indicate where the ``repmgr.conf`` is at. It doesn't need any
additional arguments::
./repmgr standby promote
That will restart your standby postgresql service.
* standby follow
* Allows the standby to base itself to the new primary passed as a
parameter. This needs to be executed on the same directory where the
``repmgr.conf`` is in the standby, or you can use the ``-f`` option
to indicate where the ``repmgr.conf`` is at. Example::
./repmgr standby follow
Examples
========
Suppose we have 3 nodes: node1 (the initial master), node2 and node3
To make node2 and node3 be standbys of node1, execute this on both nodes
(node2 and node3)::
repmgr -D /var/lib/postgresql/9.0 standby clone node1
If we lose node1 we can run on node2::
repmgr -f /home/postgres/repmgr.conf standby promote
Which makes node2 the new master. We then run on node3::
repmgr standby follow
To make node3 follow node2 (rather than node1)
If now we want to add a new node we can a prepare a new server (node4)
and run::
repmgr -D /var/lib/postgresql/9.0 standby clone node2
NOTE: you need to have $PGDIR/bin (where the PostgreSQL binaries are installed)
in your path for the above to work. If you don't want that as a permanent
setting, you can temporarily set it before running individual commands like
this::
PATH=$PGDIR/bin:$PATH repmgr standby promote
repmgr Daemon
=============
Command line syntax
-------------------
The current supported syntax for the program can be seen using::
repmgrd --help
The output from this program looks like this::
repmgrd: Replicator manager daemon
Usage:
repmgrd [OPTIONS]
Options:
--help show this help, then exit
--version output version information, then exit
--verbose output verbose activity information
-f, --config_file=PATH database to connect to
repmgrd monitors a cluster of servers.
The ``--verbose`` option can be useful in troubleshooting issues with
the program.
Setup
-----
To use the repmgrd (repmgr daemon) to monitor standby so we know how is going
the replication and how far they are from primary, you need to execute the
``repmgr.sql`` script in the postgres database.
You also need to add a row for every node in the ``repl_node`` table. This work
may be done for you by the daemon itself, as described below.
Lag monitoring
--------------
To look at the current lag between primary and each node listed
in ``repl_node``, consult the ``repl_status`` view::
psql -d postgres -c "SELECT * FROM repl_status"
This view shows the latest monitor info from every node.
* replication_lag: in bytes. This is how far the latest xlog record
we have received is from master.
* apply_lag: in bytes. This is how far the latest xlog record
we have applied is from the latest record we have received.
* time_lag: in seconds. How many seconds behind the master is this node.
Usage
-----
repmgrd reads the ``repmgr.conf`` file in current directory, or as indicated with -f
parameter. It checks if the standby is in repl_nodes and adds it if not.
Before you can run the repmgr daemon (repmgrd) you need to register a master
and at least a standby in a cluster using the ``MASTER REGISTER`` and
``STANDBY REGISTER`` commands.
For example, following last example and assuming that ``repmgr.conf`` is in postgres
home directory you will run this on the master::
repmgr -f /home/postgres/repmgr.conf master register
and the same in the standby.
The repmgr daemon creates 2 connections: one to the master and another to the
standby.
Detailed walkthrough
====================
This assumes you've already followed the steps in "Installation Outline" to
install repmgr and repmgr on the system.
The following scenario involves two PostgreSQL installations on the same server
hardware, so that additional systems aren't needed for testing. A normal
production installation of ``repmgr`` will normally involve two different
systems running on the same port, typically the default of 5432,
with both using files owned by the ``postgres`` user account. In places where
``127.0.0.1`` is used as a host name below, you would instead use the name of
the relevant host for that parameter. You can usually leave out changes
to the port number in this case too.
The test setup assumes you might be using the default installation of
PostgreSQL on port 5432 for some other purpose, and instead relocates these
instances onto different ports running as different users:
* A primary (master) server called “prime," with a user as “prime," who is
also the owner of the files. This server is operating on port 5433. This
server will be known as “node1" in the cluster “test"
* A standby server called “standby", with a user of “standby", who is the
owner of the files. This server is operating on port 5434. This server
will be known and “node2" on the cluster “test."
* A database exists on “prime" called “testdb."
* The Postgress installation in each of the above is defined as $PGDATA,
which is represented here with ``/data/prime`` as the "prime" server and
``/data/standby`` as the "standby" server.
You might setup such an installation by adjusting the login script for the
"prime" and "standby" users as in these two examples::
# prime
PGDATA=/data/prime
PGENGINE=/usr/pgsql-9.0/bin
PGPORT=5433
export PGDATA PGENGINE PGPORT
PATH="$PATH:$PGENGINE"
# standby
PGDATA=/data/standby
PGENGINE=/usr/pgsql-9.0/bin
PGPORT=5434
export PGDATA PGENGINE PGPORT
PATH="$PATH:$PGENGINE"
And then starting/stopping each installation as needed using the ``pg_ctl``
utility.
Note: naming your nodes based on their starting role is not a recommended
best practice! As you'll see in this example, once there is a failover, names
strongly associated with one particular role (primary or standby) can become
confusing, once that node no longer has that role. Future versions of this
walkthrough are expected to use more generic terminology for these names.
Clearing the PostgreSQL installation on the Standby
---------------------------------------------------
Setup a streaming replica, strip away any PostgreSQL installation on the existing replica:
* Stop both servers.
* Go to “standby" database directory and remove the PostgreSQL installation::
cd $PGDATA
rm -rf *
This will delete the entire database installation in ``/data/standby``.
Building the standby
--------------------
Create a directory to store each repmgr configuration in for each node.
In that, there needs to be a ``repmgr.conf`` file for each node in the cluster.
For “prime" we'll assume this is stored in ``/home/prime/repmgr``
and it should contain::
cluster=test
node=1
conninfo='host=127.0.0.1 dbname=dbtest'
On “standby" create the file ``/home/standby/repmgr/repmgr.conf`` with::
cluster=test
node=2
conninfo='host=127.0.0.1 dbname=dbtest'
Next, with “prime" server running, we want to use the ``clone standby`` command
in repmgr to copy over the entire PostgreSQL database cluster onto the
“standby" server. On the “standby" server, type::
repmgr -D $PGDATA -p 5433 -U prime -R prime --verbose standby clone localhost
Next, we need a recovery.conf file on “standby" in the $PGDATA directory
that reads as follows::
standby_mode = 'on'
primary_conninfo = 'host=127.0.0.1 port=5433'
Make sure that standby has a qualifying role in the database, “testdb" in this
case, and can login. Start ``psql`` on the testdb database on “prime" and at
the testdb# prompt type::
CREATE ROLE standby SUPERUSER LOGIN
Registering the master and standby
----------------------------------
First, register the master by typing on “prime"::
repmgr -f /home/prime/repmgr/repmgr.conf --verbose master register
On “standby," edit the ``postgresql.conf`` file and change the port to 5434.
Start the “standby" server.
Register the standby by typing on “standby"::
repmgr -f /home/standby/repmgr/repmgr.conf --verbose standby register
At this point, you have a functioning primary on “prime" and a functioning
standby server running on “standby." It's recommended that you insert some
records into the primary server here, then confirm they appear very quickly
(within milliseconds) on the standby. Also verify that one can make queries
against the standby server and cannot make insertions into the standby database.
Simulating the failure of the primary server
--------------------------------------------
To simulate the loss of the primary server, simply stop the “prime" server.
At this point, the standby contains the database as it existed at the time of
the “failure" of the primary server.
Promoting the Standby to be the Primary
---------------------------------------
Now you can promote the standby server to be the primary, to allow
applications to read and write to the database again, by typing::
repmgr -f /home/standby/repmgr/repmgr.conf --verbose standby promote
The server restarts and now has read/write ability.
Bringing the former Primary up as a Standby
-------------------------------------------
To make the former primary act as a standby, which is necessary before
restoring the original roles, type::
repmgr -U standby -R prime -h 127.0.0.1 -p 5433 -d dbtest --force --verbose standby clone
Stop and restart the “prime" server, which is now acting as a standby server.
Make sure the record(s) inserted the earlier step are still available on the
now standby (prime). Confirm the database on “prime" is read-only.
Restoring the original roles of prime to primary and standby to standby
-----------------------------------------------------------------------
Now restore to the original configuration by stopping the
“standby" (now acting as a primary), promoting “prime" again to be the
primary server, then bringing up “standby" as a standby with a valid
``recovery.conf`` file on “standby".
Stop the “standby" server::
repmgr -f /home/prime/repmgr/repmgr.conf standby promote
Now the original primary, “prime" is acting again as primary.
Start the “standby" server and type this on “prime"::
repmgr standby clone --force -h 127.0.0.1 -p 5434 -U prime -R standby --verbose
Stop the “standby" and change the port to be 5434 in the ``postgresql.conf``
file.
Verify the roles have reversed by attempting to insert a record on “standby"
and on “prime."
The servers are now again acting as primary on “prime" and standby on “standby".

61
RHEL/repmgr3-93.spec Normal file
View File

@@ -0,0 +1,61 @@
Summary: repmgr
Name: repmgr
Version: 3.0
Release: 1
License: GPLv3
Group: System Environment/Daemons
URL: http://repmgr.org
Packager: Ian Barwick <ian@2ndquadrant.com>
Vendor: 2ndQuadrant Limited
Distribution: centos
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
%description
repmgr is a utility suite which greatly simplifies
the process of setting up and managing replication
using streaming replication within a cluster of
PostgreSQL servers.
%prep
%setup
%build
export PATH=$PATH:/usr/pgsql-9.3/bin/
%{__make} USE_PGXS=1
%install
[ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot}
export PATH=$PATH:/usr/pgsql-9.3/bin/
%{__make} USE_PGXS=1 install DESTDIR=%{buildroot} INSTALL="install -p"
%{__make} USE_PGXS=1 install_prog DESTDIR=%{buildroot} INSTALL="install -p"
%{__make} USE_PGXS=1 install_rhel DESTDIR=%{buildroot} INSTALL="install -p"
%clean
[ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot}
%files
%defattr(-,root,root)
/usr/bin/repmgr
/usr/bin/repmgrd
/usr/pgsql-9.3/bin/repmgr
/usr/pgsql-9.3/bin/repmgrd
/usr/pgsql-9.3/lib/repmgr_funcs.so
/usr/pgsql-9.3/share/contrib/repmgr.sql
/usr/pgsql-9.3/share/contrib/repmgr_funcs.sql
/usr/pgsql-9.3/share/contrib/uninstall_repmgr.sql
/usr/pgsql-9.3/share/contrib/uninstall_repmgr_funcs.sql
%attr(0755,root,root)/etc/init.d/repmgrd
%attr(0644,root,root)/etc/sysconfig/repmgrd
%attr(0644,root,root)/etc/repmgr/repmgr.conf.sample
%changelog
* Tue Mar 10 2015 Ian Barwick ian@2ndquadrant.com>
- build for repmgr 3.0
* Thu Jun 05 2014 Nathan Van Overloop <nathan.van.overloop@nexperteam.be> 2.0.2
- fix witness creation to create db and user if needed
* Fri Apr 04 2014 Nathan Van Overloop <nathan.van.overloop@nexperteam.be> 2.0.1
- initial build for RHEL6

114
RHEL/repmgrd.init Executable file
View File

@@ -0,0 +1,114 @@
#!/bin/bash
#
# repmgrd Start up the repmgrd daemon
# repmrgd (replication manager daemon)
#
# chkconfig: - 75 16
# description: repmgrd is the repliation manager daemon \
# The repmgrd replication management and monitoring daemon for PostgreSQL.
### BEGIN INIT INFO
# Provides: repmgrd
# Required-Start: $local_fs $remote_fs $network $syslog postgresql
# Required-Stop: $local_fs $remote_fs $network $syslog postgresql
# Should-Start: $syslog postgresql-9.3
# Should-Stop: $syslog postgresql-9.3
# Short-Description: start and stop repmrgd
# Description: Enable repmgrd replication management and monitoring daemon for PostgreSQL
# this is used to monitor a postgresql cluster.
### END INIT INFO
# Source function library.
. /etc/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
prog=repmgrd
REPMGRD_ENABLED=yes
REPMGRD_OPTS=
REPMGRD_USER=postgres
DAEMONIZE="-d"
# pull in sysconfig settings
[ -f /etc/sysconfig/repmgrd ] && . /etc/sysconfig/repmgrd
LOCKFILE=/var/lock/subsys/$prog
RETVAL=0
case "$REPMGRD_ENABLED" in
[Yy]*)
#nothing to do here
;;
*)
exit 2
;;
esac
if [ -z "$REPMGRD_OPTS" ]
then
echo "Not starting $prog, REPMGRD_OPTS not set in /etc/sysconfig/$prog"
exit 2
fi
start() {
[ "$EUID" != "0" ] && exit 4
[ "$NETWORKING" = "no" ] && exit 1
# Start daemons.
echo -n $"Starting $prog: "
daemon --user $REPMGRD_USER $prog $DAEMONIZE $REPMGRD_OPTS
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch $LOCKFILE
return $RETVAL
}
stop() {
[ "$EUID" != "0" ] && exit 4
echo -n $"Shutting down $prog: "
killproc $prog
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f $LOCKFILE
return $RETVAL
}
status() {
if [ -f "$LOCKFILE" ]; then
echo "$prog is running"
else
RETVAL=3
echo "$prog is stopped"
fi
return $RETVAL
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status $prog
;;
restart|force-reload)
stop
start
;;
try-restart|condrestart)
if status $prog > /dev/null; then
stop
start
fi
;;
reload)
exit 3
;;
*)
echo $"Usage: $0 {start|stop|status|restart|try-restart|force-reload}"
exit 2
esac

4
RHEL/repmgrd.sysconfig Normal file
View File

@@ -0,0 +1,4 @@
#default sysconfig file for repmrgd
#custom overrides can be placed here
REPMGRD_OPTS="-f /etc/repmgr/repmgr.conf"

35
SSH-RSYNC.md Normal file
View File

@@ -0,0 +1,35 @@
Set up trusted copy between postgres accounts
---------------------------------------------
If you need to use rsync to clone standby servers, the postgres account
on your master and standby servers must be each able to access the other
using SSH without a password.
First generate a ssh key, using an empty passphrase, and copy the resulting
keys and a maching authorization file to a privledged user on the other system::
[postgres@node1]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/var/lib/pgsql/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/lib/pgsql/.ssh/id_rsa.
Your public key has been saved in /var/lib/pgsql/.ssh/id_rsa.pub.
The key fingerprint is:
aa:bb:cc:dd:ee:ff:aa:11:22:33:44:55:66:77:88:99 postgres@db1.domain.com
[postgres@node1]$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
[postgres@node1]$ chmod go-rwx ~/.ssh/*
[postgres@node1]$ cd ~/.ssh
[postgres@node1]$ scp id_rsa.pub id_rsa authorized_keys user@node2:
Login as a user on the other system, and install the files into the postgres
user's account::
[user@node2 ~]$ sudo chown postgres.postgres authorized_keys id_rsa.pub id_rsa
[user@node2 ~]$ sudo mkdir -p ~postgres/.ssh
[user@node2 ~]$ sudo chown postgres.postgres ~postgres/.ssh
[user@node2 ~]$ sudo mv authorized_keys id_rsa.pub id_rsa ~postgres/.ssh
[user@node2 ~]$ sudo chmod -R go-rwx ~postgres/.ssh
Now test that ssh in both directions works. You may have to accept some new
known hosts in the process.

25
TODO Normal file
View File

@@ -0,0 +1,25 @@
Known issues in repmgr
======================
* When running repmgr against a remote machine, operations that start
the database server using the ``pg_ctl`` command may accidentally
terminate after their associated ssh session ends.
Planned feature improvements
============================
* A better check which standby did receive most of the data
* Make the fact that a standby may be delayed a factor in the voting
algorithm
* include support for delayed standbys
* Create the repmgr user/database on "master register".
* Use pg_basebackup for the data directory, and ALSO rsync for the
configuration files.
* Use pg_basebackup -X s
NOTE: this can be used by including `-X s` in the configuration parameter
`pg_basebackup_options`

View File

@@ -1,8 +1,20 @@
/*
* check_dir.c
* Copyright (c) 2ndQuadrant, 2010
* check_dir.c - Directories management functions
* Copyright (C) 2ndQuadrant, 2010-2015
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Directories management functions
*/
#include <sys/stat.h>
@@ -12,11 +24,12 @@
#include <stdio.h>
#include <string.h>
/* NB: postgres_fe must be included BEFORE check_dir */
#include "postgres_fe.h"
#include "check_dir.h"
static int mkdir_p(char *path, mode_t omode);
#include "strutil.h"
#include "log.h"
/*
* make sure the directory either doesn't exist or is empty
@@ -31,67 +44,68 @@ static int mkdir_p(char *path, mode_t omode);
int
check_dir(char *dir)
{
DIR *chkdir;
struct dirent *file;
int result = 1;
DIR *chkdir;
struct dirent *file;
int result = 1;
errno = 0;
errno = 0;
chkdir = opendir(dir);
chkdir = opendir(dir);
if (!chkdir)
return (errno == ENOENT) ? 0 : -1;
if (!chkdir)
return (errno == ENOENT) ? 0 : -1;
while ((file = readdir(chkdir)) != NULL)
{
if (strcmp(".", file->d_name) == 0 ||
strcmp("..", file->d_name) == 0)
{
/* skip this and parent directory */
continue;
}
else
{
result = 2; /* not empty */
break;
}
}
while ((file = readdir(chkdir)) != NULL)
{
if (strcmp(".", file->d_name) == 0 ||
strcmp("..", file->d_name) == 0)
{
/* skip this and parent directory */
continue;
}
else
{
result = 2; /* not empty */
break;
}
}
#ifdef WIN32
/*
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
* released version
*/
if (GetLastError() == ERROR_NO_MORE_FILES)
errno = 0;
/*
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
* released version
*/
if (GetLastError() == ERROR_NO_MORE_FILES)
errno = 0;
#endif
closedir(chkdir);
closedir(chkdir);
if (errno != 0)
return -1; /* some kind of I/O error? */
if (errno != 0)
return -1; /* some kind of I/O error? */
return result;
}
/*
* Create directory
* Create directory with error log message when failing
*/
bool
create_directory(char *dir)
create_dir(char *dir)
{
if (mkdir_p(dir, 0700) == 0)
return true;
if (mkdir_p(dir, 0700) == 0)
return true;
fprintf(stderr, _("Could not create directory \"%s\": %s\n"),
dir, strerror(errno));
log_err(_("unable to create directory \"%s\": %s\n"),
dir, strerror(errno));
return false;
return false;
}
bool
set_directory_permissions(char *dir)
set_dir_permissions(char *dir)
{
return (chmod(dir, 0700) != 0) ? false : true;
}
@@ -99,7 +113,7 @@ set_directory_permissions(char *dir)
/* function from initdb.c */
/* source stolen from FreeBSD /src/bin/mkdir/mkdir.c and adapted */
/* source adapted from FreeBSD /src/bin/mkdir/mkdir.c */
/*
* this tries to build all the elements of a path to a directory a la mkdir -p
@@ -109,7 +123,7 @@ set_directory_permissions(char *dir)
* note that on failure, the path arg has been modified to show the particular
* directory level we had problems with.
*/
static int
int
mkdir_p(char *path, mode_t omode)
{
struct stat sb;
@@ -207,10 +221,88 @@ mkdir_p(char *path, mode_t omode)
bool
is_pg_dir(char *dir)
{
char path[8192];
const size_t buf_sz = 8192;
char path[buf_sz];
struct stat sb;
int r;
sprintf(path, "%s/PG_VERSION", dir);
/* test pgdata */
xsnprintf(path, buf_sz, "%s/PG_VERSION", dir);
if (stat(path, &sb) == 0)
return true;
return (stat(path, &sb) == 0) ? true : false;
/* test tablespace dir */
sprintf(path, "ls %s/PG_*/ -I*", dir);
r = system(path);
if (r == 0)
return true;
return false;
}
bool
create_pg_dir(char *dir, bool force)
{
bool pg_dir = false;
/* Check this directory could be used as a PGDATA dir */
switch (check_dir(dir))
{
case 0:
/* dir not there, must create it */
log_info(_("creating directory \"%s\"...\n"), dir);
if (!create_dir(dir))
{
log_err(_("unable to create directory \"%s\"...\n"),
dir);
return false;
}
break;
case 1:
/* Present but empty, fix permissions and use it */
log_info(_("checking and correcting permissions on existing directory %s ...\n"),
dir);
if (!set_dir_permissions(dir))
{
log_err(_("unable to change permissions of directory \"%s\": %s\n"),
dir, strerror(errno));
return false;
}
break;
case 2:
/* Present and not empty */
log_warning(_("directory \"%s\" exists but is not empty\n"),
dir);
pg_dir = is_pg_dir(dir);
/*
* we use force to reduce the time needed to restore a node which
* turn async after a failover or anything else
*/
if (pg_dir && force)
{
/* Let it continue */
break;
}
else if (pg_dir && !force)
{
log_warning(_("\nThis looks like a PostgreSQL directory.\n"
"If you are sure you want to clone here, "
"please check there is no PostgreSQL server "
"running and use the --force option\n"));
return false;
}
return false;
default:
/* Trouble accessing directory */
log_err(_("could not access directory \"%s\": %s\n"),
dir, strerror(errno));
return false;
}
return true;
}

View File

@@ -1,10 +1,30 @@
/*
* check_dir.h
* Copyright (c) 2ndQuadrant, 2010
* Copyright (c) 2ndQuadrant, 2010-2015
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
int check_dir(char *dir);
bool create_directory(char *dir);
bool set_directory_permissions(char *dir);
bool is_pg_dir(char *dir);
#ifndef _REPMGR_CHECK_DIR_H_
#define _REPMGR_CHECK_DIR_H_
int mkdir_p(char *path, mode_t omode);
int check_dir(char *dir);
bool create_dir(char *dir);
bool set_dir_permissions(char *dir);
bool is_pg_dir(char *dir);
bool create_pg_dir(char *dir, bool force);
#endif

718
config.c
View File

@@ -1,80 +1,339 @@
/*
* config.c
* Copyright (c) 2ndQuadrant, 2010
* config.c - Functions to parse the config file
* Copyright (C) 2ndQuadrant, 2010-2015
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Functions to parse the config file
*/
#include <sys/stat.h> /* for stat() */
#include "config.h"
#include "log.h"
#include "strutil.h"
#include "repmgr.h"
void
parse_config(const char *config_file, char *cluster_name, int *node, char *conninfo)
{
char *s, buff[256];
FILE *fp = fopen (config_file, "r");
static void parse_event_notifications_list(t_configuration_options *options, const char *arg);
static void tablespace_list_append(t_configuration_options *options, const char *arg);
/*
* parse_config()
*
* Set default options and overwrite with values from provided configuration
* file.
*
* Returns true if a configuration file could be parsed, otherwise false.
*
* Any configuration options changed in this function must also be changed in
* reload_config()
*/
bool
parse_config(const char *config_file, t_configuration_options *options)
{
char *s,
buff[MAXLINELENGTH];
char config_file_buf[MAXLEN];
char name[MAXLEN];
char value[MAXLEN];
bool config_file_provided = false;
FILE *fp;
/* Sanity checks */
/*
* If a configuration file was provided, check it exists, otherwise
* emit an error
*/
if (config_file[0])
{
struct stat config;
strncpy(config_file_buf, config_file, MAXLEN);
canonicalize_path(config_file_buf);
if(stat(config_file_buf, &config) != 0)
{
log_err(_("provided configuration file '%s' not found: %s\n"),
config_file,
strerror(errno)
);
exit(ERR_BAD_CONFIG);
}
config_file_provided = true;
}
/*
* If no configuration file was provided, set to a default file
* which `parse_config()` will attempt to read if it exists
*/
else
{
strncpy(config_file_buf, DEFAULT_CONFIG_FILE, MAXLEN);
}
fp = fopen(config_file_buf, "r");
/*
* Since some commands don't require a config file at all, not having one
* isn't necessarily a problem.
*
* If the user explictly provided a configuration file and we can't
* read it we'll raise an error.
*
* If no configuration file was provided, we'll try and read the default\
* file if it exists and is readable, but won't worry if it's not.
*/
if (fp == NULL)
return;
{
if(config_file_provided)
{
log_err(_("unable to open provided configuration file '%s'; terminating\n"), config_file_buf);
exit(ERR_BAD_CONFIG);
}
log_notice(_("no configuration file provided and default file '%s' not found - "
"continuing with default values\n"),
DEFAULT_CONFIG_FILE);
return false;
}
/* Initialize configuration options with sensible defaults */
memset(options->cluster_name, 0, sizeof(options->cluster_name));
options->node = -1;
options->upstream_node = NO_UPSTREAM_NODE;
memset(options->conninfo, 0, sizeof(options->conninfo));
options->failover = MANUAL_FAILOVER;
options->priority = DEFAULT_PRIORITY;
memset(options->node_name, 0, sizeof(options->node_name));
memset(options->promote_command, 0, sizeof(options->promote_command));
memset(options->follow_command, 0, sizeof(options->follow_command));
memset(options->rsync_options, 0, sizeof(options->rsync_options));
memset(options->ssh_options, 0, sizeof(options->ssh_options));
memset(options->pg_bindir, 0, sizeof(options->pg_bindir));
memset(options->pg_ctl_options, 0, sizeof(options->pg_ctl_options));
memset(options->pg_basebackup_options, 0, sizeof(options->pg_basebackup_options));
/* default master_response_timeout is 60 seconds */
options->master_response_timeout = 60;
/* default to 6 reconnection attempts at intervals of 10 seconds */
options->reconnect_attempts = 6;
options->reconnect_intvl = 10;
options->monitor_interval_secs = 2;
options->retry_promote_interval_secs = 300;
memset(options->event_notification_command, 0, sizeof(options->event_notification_command));
options->tablespace_mapping.head = NULL;
options->tablespace_mapping.tail = NULL;
/* Read next line */
while ((s = fgets (buff, sizeof buff, fp)) != NULL)
while ((s = fgets(buff, sizeof buff, fp)) != NULL)
{
char name[MAXLEN];
char value[MAXLEN];
bool known_parameter = true;
/* Skip blank lines and comments */
if (buff[0] == '\n' || buff[0] == '#')
continue;
/* Skip blank lines and comments */
if (buff[0] == '\n' || buff[0] == '#')
continue;
/* Parse name/value pair from line */
/* Parse name/value pair from line */
parse_line(buff, name, value);
/* Copy into correct entry in parameters struct */
if (strcmp(name, "cluster") == 0)
strncpy (cluster_name, value, MAXLEN);
else if (strcmp(name, "node") == 0)
*node = atoi(value);
else if (strcmp(name, "conninfo") == 0)
strncpy (conninfo, value, MAXLEN);
else
printf ("WARNING: %s/%s: Unknown name/value pair!\n", name, value);
}
/* Copy into correct entry in parameters struct */
if (strcmp(name, "cluster") == 0)
strncpy(options->cluster_name, value, MAXLEN);
else if (strcmp(name, "node") == 0)
options->node = atoi(value);
else if (strcmp(name, "upstream_node") == 0)
options->upstream_node = atoi(value);
else if (strcmp(name, "conninfo") == 0)
strncpy(options->conninfo, value, MAXLEN);
else if (strcmp(name, "rsync_options") == 0)
strncpy(options->rsync_options, value, QUERY_STR_LEN);
else if (strcmp(name, "ssh_options") == 0)
strncpy(options->ssh_options, value, QUERY_STR_LEN);
else if (strcmp(name, "loglevel") == 0)
strncpy(options->loglevel, value, MAXLEN);
else if (strcmp(name, "logfacility") == 0)
strncpy(options->logfacility, value, MAXLEN);
else if (strcmp(name, "failover") == 0)
{
char failoverstr[MAXLEN];
/* Close file */
fclose (fp);
strncpy(failoverstr, value, MAXLEN);
if (strcmp(failoverstr, "manual") == 0)
{
options->failover = MANUAL_FAILOVER;
}
else if (strcmp(failoverstr, "automatic") == 0)
{
options->failover = AUTOMATIC_FAILOVER;
}
else
{
log_err(_("value for 'failover' must be 'automatic' or 'manual'\n"));
exit(ERR_BAD_CONFIG);
}
}
else if (strcmp(name, "priority") == 0)
options->priority = atoi(value);
else if (strcmp(name, "node_name") == 0)
strncpy(options->node_name, value, MAXLEN);
else if (strcmp(name, "promote_command") == 0)
strncpy(options->promote_command, value, MAXLEN);
else if (strcmp(name, "follow_command") == 0)
strncpy(options->follow_command, value, MAXLEN);
else if (strcmp(name, "master_response_timeout") == 0)
options->master_response_timeout = atoi(value);
else if (strcmp(name, "reconnect_attempts") == 0)
options->reconnect_attempts = atoi(value);
else if (strcmp(name, "reconnect_interval") == 0)
options->reconnect_intvl = atoi(value);
else if (strcmp(name, "pg_bindir") == 0)
strncpy(options->pg_bindir, value, MAXLEN);
else if (strcmp(name, "pg_ctl_options") == 0)
strncpy(options->pg_ctl_options, value, MAXLEN);
else if (strcmp(name, "pg_basebackup_options") == 0)
strncpy(options->pg_basebackup_options, value, MAXLEN);
else if (strcmp(name, "logfile") == 0)
strncpy(options->logfile, value, MAXLEN);
else if (strcmp(name, "monitor_interval_secs") == 0)
options->monitor_interval_secs = atoi(value);
else if (strcmp(name, "retry_promote_interval_secs") == 0)
options->retry_promote_interval_secs = atoi(value);
else if (strcmp(name, "use_replication_slots") == 0)
options->use_replication_slots = atoi(value);
else if (strcmp(name, "event_notification_command") == 0)
strncpy(options->event_notification_command, value, MAXLEN);
else if (strcmp(name, "event_notifications") == 0)
parse_event_notifications_list(options, value);
else if (strcmp(name, "tablespace_mapping") == 0)
tablespace_list_append(options, value);
else
{
known_parameter = false;
log_warning(_("%s/%s: unknown name/value pair provided; ignoring\n"), name, value);
}
/*
* Raise an error if a known parameter is provided with an empty value.
* Currently there's no reason why empty parameters are needed; if
* we want to accept those, we'd need to add stricter default checking,
* as currently e.g. an empty `node` value will be converted to '0'.
*/
if(known_parameter == true && !strlen(value)) {
log_err(_("no value provided for parameter '%s'\n"), name);
exit(ERR_BAD_CONFIG);
}
}
fclose(fp);
/* Check config settings */
/* The following checks are for the presence of the parameter */
if (*options->cluster_name == '\0')
{
log_err(_("required parameter 'cluster' was not found\n"));
exit(ERR_BAD_CONFIG);
}
if (options->node == -1)
{
log_err(_("required parameter 'node' was not found\n"));
exit(ERR_BAD_CONFIG);
}
if (*options->node_name == '\0')
{
log_err(_("required parameter 'node_name' was not found\n"));
exit(ERR_BAD_CONFIG);
}
if (*options->conninfo == '\0')
{
log_err(_("required parameter 'conninfo' was not found\n"));
exit(ERR_BAD_CONFIG);
}
/* The following checks are for valid parameter values */
if (options->master_response_timeout <= 0)
{
log_err(_("'master_response_timeout' must be greater than zero\n"));
exit(ERR_BAD_CONFIG);
}
if (options->reconnect_attempts < 0)
{
log_err(_("'reconnect_attempts' must be zero or greater\n"));
exit(ERR_BAD_CONFIG);
}
if (options->reconnect_intvl < 0)
{
log_err(_("'reconnect_interval' must be zero or greater\n"));
exit(ERR_BAD_CONFIG);
}
return true;
}
char *
trim (char *s)
trim(char *s)
{
/* Initialize start, end pointers */
char *s1 = s, *s2 = &s[strlen (s) - 1];
/* Initialize start, end pointers */
char *s1 = s,
*s2 = &s[strlen(s) - 1];
/* Trim and delimit right side */
while ( (isspace (*s2)) && (s2 >= s1) )
s2--;
*(s2+1) = '\0';
/* If string is empty, no action needed */
if(s2 < s1)
return s;
/* Trim left side */
while ( (isspace (*s1)) && (s1 < s2) )
s1++;
/* Trim and delimit right side */
while ((isspace(*s2)) && (s2 >= s1))
--s2;
*(s2 + 1) = '\0';
/* Copy finished string */
strcpy (s, s1);
return s;
/* Trim left side */
while ((isspace(*s1)) && (s1 < s2))
++s1;
/* Copy finished string */
memmove(s, s1, s2 - s1);
s[s2 - s1 + 1] = '\0';
return s;
}
void
parse_line(char *buff, char *name, char *value)
{
int i;
int j;
int i = 0;
int j = 0;
/*
* first we find the name of the parameter
*/
j = 0;
for (i = 0; i < MAXLEN; i++)
for (; i < MAXLEN; ++i)
{
if (buff[i] != '=')
name[j++] = buff[i];
@@ -83,12 +342,11 @@ parse_line(char *buff, char *name, char *value)
}
name[j] = '\0';
i++;
/*
* Now the value
*/
*/
j = 0;
for ( ; i < MAXLEN; i++)
for (++i; i < MAXLEN; ++i)
if (buff[i] == '\'')
continue;
else if (buff[i] != '\n')
@@ -96,5 +354,367 @@ parse_line(char *buff, char *name, char *value)
else
break;
value[j] = '\0';
trim(value);
trim(value);
}
bool
reload_config(char *config_file, t_configuration_options * orig_options)
{
PGconn *conn;
t_configuration_options new_options;
bool config_changed = false;
/*
* Re-read the configuration file: repmgr.conf
*/
log_info(_("reloading configuration file and updating repmgr tables\n"));
parse_config(config_file, &new_options);
if (new_options.node == -1)
{
log_warning(_("unable to parse new configuration, retaining current configuration\n"));
return false;
}
if (strcmp(new_options.cluster_name, orig_options->cluster_name) != 0)
{
log_warning(_("unable to change cluster name, retaining current configuration\n"));
return false;
}
if (new_options.node != orig_options->node)
{
log_warning(_("unable to change node ID, retaining current configuration\n"));
return false;
}
if (strcmp(new_options.node_name, orig_options->node_name) != 0)
{
log_warning(_("unable to change standby name, keeping current configuration\n"));
return false;
}
if (new_options.failover != MANUAL_FAILOVER && new_options.failover != AUTOMATIC_FAILOVER)
{
log_warning(_("new value for 'failover' must be 'automatic' or 'manual'\n"));
return false;
}
if (new_options.master_response_timeout <= 0)
{
log_warning(_("new value for 'master_response_timeout' must be greater than zero\n"));
return false;
}
if (new_options.reconnect_attempts < 0)
{
log_warning(_("new value for 'reconnect_attempts' must be zero or greater\n"));
return false;
}
if (new_options.reconnect_intvl < 0)
{
log_warning(_("new value for 'reconnect_interval' must be zero or greater\n"));
return false;
}
if(strcmp(orig_options->conninfo, new_options.conninfo) != 0)
{
/* Test conninfo string */
conn = establish_db_connection(new_options.conninfo, false);
if (!conn || (PQstatus(conn) != CONNECTION_OK))
{
log_warning(_("'conninfo' string is not valid, retaining current configuration\n"));
return false;
}
PQfinish(conn);
}
/*
* No configuration problems detected - copy any changed values
*
* NB: keep these in the same order as in config.h to make it easier
* to manage them
*/
/* cluster_name */
if(strcmp(orig_options->cluster_name, new_options.cluster_name) != 0)
{
strcpy(orig_options->cluster_name, new_options.cluster_name);
config_changed = true;
}
/* conninfo */
if(strcmp(orig_options->conninfo, new_options.conninfo) != 0)
{
strcpy(orig_options->conninfo, new_options.conninfo);
config_changed = true;
}
/* node */
if(orig_options->node != new_options.node)
{
orig_options->node = new_options.node;
config_changed = true;
}
/* failover */
if(orig_options->failover != new_options.failover)
{
orig_options->failover = new_options.failover;
config_changed = true;
}
/* priority */
if(orig_options->priority != new_options.priority)
{
orig_options->priority = new_options.priority;
config_changed = true;
}
/* node_name */
if(strcmp(orig_options->node_name, new_options.node_name) != 0)
{
strcpy(orig_options->node_name, new_options.node_name);
config_changed = true;
}
/* promote_command */
if(strcmp(orig_options->promote_command, new_options.promote_command) != 0)
{
strcpy(orig_options->promote_command, new_options.promote_command);
config_changed = true;
}
/* follow_command */
if(strcmp(orig_options->follow_command, new_options.follow_command) != 0)
{
strcpy(orig_options->follow_command, new_options.follow_command);
config_changed = true;
}
/*
* XXX These ones can change with a simple SIGHUP?
*
* strcpy (orig_options->loglevel, new_options.loglevel); strcpy
* (orig_options->logfacility, new_options.logfacility);
*
* logger_shutdown(); XXX do we have progname here ? logger_init(progname,
* orig_options.loglevel, orig_options.logfacility);
*/
/* rsync_options */
if(strcmp(orig_options->rsync_options, new_options.rsync_options) != 0)
{
strcpy(orig_options->rsync_options, new_options.rsync_options);
config_changed = true;
}
/* ssh_options */
if(strcmp(orig_options->ssh_options, new_options.ssh_options) != 0)
{
strcpy(orig_options->ssh_options, new_options.ssh_options);
config_changed = true;
}
/* master_response_timeout */
if(orig_options->master_response_timeout != new_options.master_response_timeout)
{
orig_options->master_response_timeout = new_options.master_response_timeout;
config_changed = true;
}
/* reconnect_attempts */
if(orig_options->reconnect_attempts != new_options.reconnect_attempts)
{
orig_options->reconnect_attempts = new_options.reconnect_attempts;
config_changed = true;
}
/* reconnect_intvl */
if(orig_options->reconnect_intvl != new_options.reconnect_intvl)
{
orig_options->reconnect_intvl = new_options.reconnect_intvl;
config_changed = true;
}
/* pg_ctl_options */
if(strcmp(orig_options->pg_ctl_options, new_options.pg_ctl_options) != 0)
{
strcpy(orig_options->pg_ctl_options, new_options.pg_ctl_options);
config_changed = true;
}
/* pg_basebackup_options */
if(strcmp(orig_options->pg_basebackup_options, new_options.pg_basebackup_options) != 0)
{
strcpy(orig_options->pg_basebackup_options, new_options.pg_basebackup_options);
config_changed = true;
}
/* monitor_interval_secs */
if(orig_options->monitor_interval_secs != new_options.monitor_interval_secs)
{
orig_options->monitor_interval_secs = new_options.monitor_interval_secs;
config_changed = true;
}
/* retry_promote_interval_secs */
if(orig_options->retry_promote_interval_secs != new_options.retry_promote_interval_secs)
{
orig_options->retry_promote_interval_secs = new_options.retry_promote_interval_secs;
config_changed = true;
}
/* use_replication_slots */
if(orig_options->use_replication_slots != new_options.use_replication_slots)
{
orig_options->use_replication_slots = new_options.use_replication_slots;
config_changed = true;
}
if(config_changed == true)
{
log_debug(_("reload_config(): configuration has changed\n"));
}
else
{
log_debug(_("reload_config(): configuration has not changed\n"));
}
return config_changed;
}
/*
* Split argument into old_dir and new_dir and append to tablespace mapping
* list.
*
* Adapted from pg_basebackup.c
*/
static void
tablespace_list_append(t_configuration_options *options, const char *arg)
{
TablespaceListCell *cell;
char *dst;
char *dst_ptr;
const char *arg_ptr;
cell = (TablespaceListCell *) pg_malloc0(sizeof(TablespaceListCell));
if(cell == NULL)
{
log_err(_("unable to allocate memory; terminating\n"));
exit(ERR_BAD_CONFIG);
}
dst_ptr = dst = cell->old_dir;
for (arg_ptr = arg; *arg_ptr; arg_ptr++)
{
if (dst_ptr - dst >= MAXPGPATH)
{
log_err(_("directory name too long\n"));
exit(ERR_BAD_CONFIG);
}
if (*arg_ptr == '\\' && *(arg_ptr + 1) == '=')
; /* skip backslash escaping = */
else if (*arg_ptr == '=' && (arg_ptr == arg || *(arg_ptr - 1) != '\\'))
{
if (*cell->new_dir)
{
log_err(_("multiple \"=\" signs in tablespace mapping\n"));
exit(ERR_BAD_CONFIG);
}
else
{
dst = dst_ptr = cell->new_dir;
}
}
else
*dst_ptr++ = *arg_ptr;
}
if (!*cell->old_dir || !*cell->new_dir)
{
log_err(_("invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"\n"),
arg);
exit(ERR_BAD_CONFIG);
}
canonicalize_path(cell->old_dir);
canonicalize_path(cell->new_dir);
if (options->tablespace_mapping.tail)
options->tablespace_mapping.tail->next = cell;
else
options->tablespace_mapping.head = cell;
options->tablespace_mapping.tail = cell;
}
/*
* parse_event_notifications_list()
*
*
*/
static void
parse_event_notifications_list(t_configuration_options *options, const char *arg)
{
const char *arg_ptr;
char event_type_buf[MAXLEN] = "";
char *dst_ptr = event_type_buf;
for (arg_ptr = arg; arg_ptr <= (arg + strlen(arg)); arg_ptr++)
{
/* ignore whitespace */
if(*arg_ptr == ' ' || *arg_ptr == '\t')
{
continue;
}
/*
* comma (or end-of-string) should mark the end of an event type -
* just as long as there was something preceding it
*/
if((*arg_ptr == ',' || *arg_ptr == '\0') && event_type_buf[0] != '\0')
{
EventNotificationListCell *cell;
cell = (EventNotificationListCell *) pg_malloc0(sizeof(EventNotificationListCell));
if(cell == NULL)
{
log_err(_("unable to allocate memory; terminating\n"));
exit(ERR_BAD_CONFIG);
}
strncpy(cell->event_type, event_type_buf, MAXLEN);
if (options->event_notifications.tail)
{
options->event_notifications.tail->next = cell;
}
else
{
options->event_notifications.head = cell;
}
options->event_notifications.tail = cell;
memset(event_type_buf, 0, MAXLEN);
dst_ptr = event_type_buf;
}
/* ignore duplicated commas */
else if(*arg_ptr == ',')
{
continue;
}
else
{
*dst_ptr++ = *arg_ptr;
}
}
}

View File

@@ -1,9 +1,91 @@
/*
* config.h
* Copyright (c) 2ndQuadrant, 2010
* Copyright (c) 2ndQuadrant, 2010-2015
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
void parse_config(const char *config_file, char *cluster_name, int *node, char *service);
void parse_line(char *buff, char *name, char *value);
char *trim(char *s);
#ifndef _REPMGR_CONFIG_H_
#define _REPMGR_CONFIG_H_
#include "postgres_fe.h"
#include "strutil.h"
typedef struct EventNotificationListCell
{
struct EventNotificationListCell *next;
char event_type[MAXLEN];
} EventNotificationListCell;
typedef struct EventNotificationList
{
EventNotificationListCell *head;
EventNotificationListCell *tail;
} EventNotificationList;
typedef struct TablespaceListCell
{
struct TablespaceListCell *next;
char old_dir[MAXPGPATH];
char new_dir[MAXPGPATH];
} TablespaceListCell;
typedef struct TablespaceList
{
TablespaceListCell *head;
TablespaceListCell *tail;
} TablespaceList;
typedef struct
{
char cluster_name[MAXLEN];
int node;
int upstream_node;
char conninfo[MAXLEN];
int failover;
int priority;
char node_name[MAXLEN];
char promote_command[MAXLEN];
char follow_command[MAXLEN];
char loglevel[MAXLEN];
char logfacility[MAXLEN];
char rsync_options[QUERY_STR_LEN];
char ssh_options[QUERY_STR_LEN];
int master_response_timeout;
int reconnect_attempts;
int reconnect_intvl;
char pg_bindir[MAXLEN];
char pg_ctl_options[MAXLEN];
char pg_basebackup_options[MAXLEN];
char logfile[MAXLEN];
int monitor_interval_secs;
int retry_promote_interval_secs;
int use_replication_slots;
char event_notification_command[MAXLEN];
EventNotificationList event_notifications;
TablespaceList tablespace_mapping;
} t_configuration_options;
#define T_CONFIGURATION_OPTIONS_INITIALIZER { "", -1, NO_UPSTREAM_NODE, "", MANUAL_FAILOVER, -1, "", "", "", "", "", "", "", -1, -1, -1, "", "", "", "", 0, 0, 0, "", { NULL, NULL }, {NULL, NULL} }
bool parse_config(const char *config_file, t_configuration_options *options);
void parse_line(char *buff, char *name, char *value);
char *trim(char *s);
bool reload_config(char *config_file, t_configuration_options *orig_options);
#endif

1337
dbutils.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,68 @@
/*
* dbutils.h
* Copyright (c) 2ndQuadrant, 2010
* Copyright (c) 2ndQuadrant, 2010-2015
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
PGconn *establishDBConnection(const char *conninfo, const bool exit_on_error);
bool is_standby(PGconn *conn);
char *pg_version(PGconn *conn);
bool guc_setted(PGconn *conn, const char *parameter, const char *op, const char *value);
const char *get_cluster_size(PGconn *conn);
PGconn * getMasterConnection(PGconn *standby_conn, int id, char *cluster, int *master_id);
#ifndef _REPMGR_DBUTILS_H_
#define _REPMGR_DBUTILS_H_
#include "config.h"
#include "strutil.h"
PGconn *establish_db_connection(const char *conninfo,
const bool exit_on_error);
PGconn *establish_db_connection_by_params(const char *keywords[],
const char *values[],
const bool exit_on_error);
bool check_cluster_schema(PGconn *conn);
int is_standby(PGconn *conn);
bool is_pgup(PGconn *conn, int timeout);
int get_master_node_id(PGconn *conn, char *cluster);
int get_server_version(PGconn *conn, char *server_version);
bool get_cluster_size(PGconn *conn, char *size);
bool get_pg_setting(PGconn *conn, const char *setting, char *output);
int guc_set(PGconn *conn, const char *parameter, const char *op,
const char *value);
int guc_set_typed(PGconn *conn, const char *parameter, const char *op,
const char *value, const char *datatype);
PGconn *get_upstream_connection(PGconn *standby_conn, char *cluster,
int node_id,
int *upstream_node_id_ptr,
char *upstream_conninfo_out);
PGconn *get_master_connection(PGconn *standby_conn, char *cluster,
int *master_id, char *master_conninfo_out);
int wait_connection_availability(PGconn *conn, long long timeout);
bool cancel_query(PGconn *conn, int timeout);
char *get_repmgr_schema(void);
char *get_repmgr_schema_quoted(PGconn *conn);
bool create_replication_slot(PGconn *conn, char *slot_name);
bool start_backup(PGconn *conn, char *first_wal_segment, bool fast_checkpoint);
bool stop_backup(PGconn *conn, char *last_wal_segment);
bool set_config_bool(PGconn *conn, const char *config_param, bool state);
bool copy_configuration(PGconn *masterconn, PGconn *witnessconn, char *cluster_name);
bool create_node_record(PGconn *conn, char *action, int node, char *type, int upstream_node, char *cluster_name, char *node_name, char *conninfo, int priority, char *slot_name);
bool delete_node_record(PGconn *conn, int node, char *action);
bool create_event_record(PGconn *conn, t_configuration_options *options, int node_id, char *event, bool successful, char *details);
#endif

9
debian/DEBIAN/control vendored Normal file
View File

@@ -0,0 +1,9 @@
Package: repmgr-auto
Version: 2.0beta2
Section: database
Priority: optional
Architecture: all
Depends: rsync, postgresql-9.0 | postgresql-9.1 | postgresql-9.2 | postgresql-9.3 | postgresql-9.4
Maintainer: Jaime Casanova <jaime@2ndQuadrant.com>
Description: PostgreSQL replication setup, magament and monitoring
has two main executables

18
debian/repmgr.repmgrd.default vendored Normal file
View File

@@ -0,0 +1,18 @@
# default settings for repmgrd. This file is source by /bin/sh from
# /etc/init.d/repmgrd
# disable repmgrd by default so it won't get started upon installation
# valid values: yes/no
REPMGRD_ENABLED=no
# Options for repmgrd (required)
#REPMGRD_OPTS="--config-file /path/to/repmgr.conf"
# User to run repmgrd as
#REPMGRD_USER=postgres
# repmgrd binary
#REPMGR_BIN=/usr/bin/repmgr
# pid file
#REPMGR_PIDFILE=/var/run/repmgrd.pid

101
debian/repmgr.repmgrd.init vendored Normal file
View File

@@ -0,0 +1,101 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: repmgrd
# Required-Start: $local_fs $remote_fs $network $syslog postgresql
# Required-Stop: $local_fs $remote_fs $network $syslog postgresql
# Should-Start: $syslog postgresql
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start/stop repmgrd
# Description: Enable repmgrd replication management and monitoring daemon for PostgreSQL
### END INIT INFO
set -e
DESC="PostgreSQL replication management and monitoring daemon"
NAME=repmgrd
REPMGRD_ENABLED=no
REPMGRD_OPTS=
REPMGRD_USER=postgres
REPMGRD_BIN=/usr/bin/repmgrd
REPMGRD_PIDFILE=/var/run/repmgrd.pid
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
test -x $REPMGRD_BIN || exit 0
case "$REPMGRD_ENABLED" in
[Yy]*)
break
;;
*)
exit 0
;;
esac
# Define LSB log_* functions.
. /lib/lsb/init-functions
if [ -z "$REPMGRD_OPTS" ]
then
log_warning_msg "Not starting $NAME, REPMGRD_OPTS not set in /etc/default/$NAME"
exit 0
fi
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# other if daemon could not be started or a failure occured
start-stop-daemon --start --quiet --background --chuid $REPMGRD_USER --make-pidfile --pidfile $REPMGRD_PIDFILE --exec $REPMGRD_BIN -- $REPMGRD_OPTS
}
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# other if daemon could not be stopped or a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $REPMGRD_PIDFILE --exec $REPMGRD_BIN
}
case "$1" in
start)
log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_progress_msg "already started"
log_end_msg 0 ;;
*) log_end_msg 1 ;;
esac
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0) log_end_msg 0 ;;
1) log_progress_msg "already stopped"
log_end_msg 0 ;;
*) log_end_msg 1 ;;
esac
;;
restart|force-reload)
$0 stop
$0 start
;;
status)
status_of_proc -p $REPMGRD_PIDFILE $REPMGRD_BIN $NAME && exit 0 || exit $?
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}" >&2
exit 3
;;
esac
exit 0

39
errcode.h Normal file
View File

@@ -0,0 +1,39 @@
/*
* errcode.h
* Copyright (C) 2ndQuadrant, 2010-2015
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _ERRCODE_H_
#define _ERRCODE_H_
/* Exit return code */
#define SUCCESS 0
#define ERR_BAD_CONFIG 1
#define ERR_BAD_RSYNC 2
#define ERR_NO_RESTART 4
#define ERR_DB_CON 6
#define ERR_DB_QUERY 7
#define ERR_PROMOTED 8
#define ERR_BAD_PASSWORD 9
#define ERR_STR_OVERFLOW 10
#define ERR_FAILOVER_FAIL 11
#define ERR_BAD_SSH 12
#define ERR_SYS_FAILURE 13
#define ERR_BAD_BASEBACKUP 14
#endif /* _ERRCODE_H_ */

255
log.c Normal file
View File

@@ -0,0 +1,255 @@
/*
* log.c - Logging methods
* Copyright (C) 2ndQuadrant, 2010-2015
*
* This module is a set of methods for logging (currently only syslog)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "repmgr.h"
#include <stdlib.h>
#ifdef HAVE_SYSLOG
#include <syslog.h>
#endif
#include <stdarg.h>
#include <time.h>
#include "log.h"
#define DEFAULT_IDENT "repmgr"
#ifdef HAVE_SYSLOG
#define DEFAULT_SYSLOG_FACILITY LOG_LOCAL0
#endif
/* #define REPMGR_DEBUG */
void
stderr_log_with_level(const char *level_name, int level, const char *fmt, ...)
{
time_t t;
struct tm *tm;
char buff[100];
va_list ap;
if (log_level >= level)
{
time(&t);
tm = localtime(&t);
strftime(buff, 100, "[%Y-%m-%d %H:%M:%S]", tm);
fprintf(stderr, "%s [%s] ", buff, level_name);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fflush(stderr);
}
}
static int detect_log_level(const char *level);
static int detect_log_facility(const char *facility);
int log_type = REPMGR_STDERR;
int log_level = LOG_NOTICE;
bool
logger_init(t_configuration_options * opts, const char *ident, const char *level, const char *facility)
{
int l;
int f;
#ifdef HAVE_SYSLOG
int syslog_facility = DEFAULT_SYSLOG_FACILITY;
#endif
#ifdef REPMGR_DEBUG
printf("Logger initialisation (Level: %s, Facility: %s)\n", level, facility);
#endif
if (!ident)
{
ident = DEFAULT_IDENT;
}
if (level && *level)
{
l = detect_log_level(level);
#ifdef REPMGR_DEBUG
printf("Assigned level for logger: %d\n", l);
#endif
if (l > 0)
log_level = l;
else
stderr_log_warning(_("Cannot detect log level %s (use any of DEBUG, INFO, NOTICE, WARNING, ERR, ALERT, CRIT or EMERG)\n"), level);
}
if (facility && *facility)
{
f = detect_log_facility(facility);
#ifdef REPMGR_DEBUG
printf("Assigned facility for logger: %d\n", f);
#endif
if (f == 0)
{
/* No syslog requested, just stderr */
#ifdef REPMGR_DEBUG
printf(_("Use stderr for logging\n"));
#endif
}
else if (f == -1)
{
stderr_log_warning(_("Cannot detect log facility %s (use any of LOCAL0, LOCAL1, ..., LOCAL7, USER or STDERR)\n"), facility);
}
#ifdef HAVE_SYSLOG
else
{
syslog_facility = f;
log_type = REPMGR_SYSLOG;
}
#endif
}
#ifdef HAVE_SYSLOG
if (log_type == REPMGR_SYSLOG)
{
setlogmask(LOG_UPTO(log_level));
openlog(ident, LOG_CONS | LOG_PID | LOG_NDELAY, syslog_facility);
stderr_log_notice(_("Setup syslog (level: %s, facility: %s)\n"), level, facility);
}
#endif
if (*opts->logfile)
{
FILE *fd;
fd = freopen(opts->logfile, "a", stderr);
if (fd == NULL)
{
fprintf(stderr, "error reopening stderr to '%s': %s",
opts->logfile, strerror(errno));
}
}
return true;
}
bool
logger_shutdown(void)
{
#ifdef HAVE_SYSLOG
if (log_type == REPMGR_SYSLOG)
closelog();
#endif
return true;
}
/*
* Set a minimum logging level. Intended for command line verbosity
* options, which might increase requested logging over what's specified
* in the regular configuration file.
*/
void
logger_min_verbose(int minimum)
{
if (log_level < minimum)
log_level = minimum;
}
int
detect_log_level(const char *level)
{
if (!strcmp(level, "DEBUG"))
return LOG_DEBUG;
if (!strcmp(level, "INFO"))
return LOG_INFO;
if (!strcmp(level, "NOTICE"))
return LOG_NOTICE;
if (!strcmp(level, "WARNING"))
return LOG_WARNING;
if (!strcmp(level, "ERR"))
return LOG_ERR;
if (!strcmp(level, "ALERT"))
return LOG_ALERT;
if (!strcmp(level, "CRIT"))
return LOG_CRIT;
if (!strcmp(level, "EMERG"))
return LOG_EMERG;
return 0;
}
int
detect_log_facility(const char *facility)
{
int local = 0;
if (!strncmp(facility, "LOCAL", 5) && strlen(facility) == 6)
{
local = atoi(&facility[5]);
switch (local)
{
case 0:
return LOG_LOCAL0;
break;
case 1:
return LOG_LOCAL1;
break;
case 2:
return LOG_LOCAL2;
break;
case 3:
return LOG_LOCAL3;
break;
case 4:
return LOG_LOCAL4;
break;
case 5:
return LOG_LOCAL5;
break;
case 6:
return LOG_LOCAL6;
break;
case 7:
return LOG_LOCAL7;
break;
}
}
else if (!strcmp(facility, "USER"))
{
return LOG_USER;
}
else if (!strcmp(facility, "STDERR"))
{
return 0;
}
return -1;
}

126
log.h Normal file
View File

@@ -0,0 +1,126 @@
/*
* log.h
* Copyright (c) 2ndQuadrant, 2010-2015
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _REPMGR_LOG_H_
#define _REPMGR_LOG_H_
#include "repmgr.h"
#define REPMGR_SYSLOG 1
#define REPMGR_STDERR 2
void
stderr_log_with_level(const char *level_name, int level, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
/* Standard error logging */
#define stderr_log_debug(...) stderr_log_with_level("DEBUG", LOG_DEBUG, __VA_ARGS__)
#define stderr_log_info(...) stderr_log_with_level("INFO", LOG_INFO, __VA_ARGS__)
#define stderr_log_notice(...) stderr_log_with_level("NOTICE", LOG_NOTICE, __VA_ARGS__)
#define stderr_log_warning(...) stderr_log_with_level("WARNING", LOG_WARNING, __VA_ARGS__)
#define stderr_log_err(...) stderr_log_with_level("ERROR", LOG_ERR, __VA_ARGS__)
#define stderr_log_crit(...) stderr_log_with_level("CRITICAL", LOG_CRIT, __VA_ARGS__)
#define stderr_log_alert(...) stderr_log_with_level("ALERT", LOG_ALERT, __VA_ARGS__)
#define stderr_log_emerg(...) stderr_log_with_level("EMERGENCY", LOG_EMERG, __VA_ARGS__)
#ifdef HAVE_SYSLOG
#include <syslog.h>
#define log_debug(...) \
if (log_type == REPMGR_SYSLOG) \
syslog(LOG_DEBUG, __VA_ARGS__); \
else \
stderr_log_debug(__VA_ARGS__);
#define log_info(...) \
{ \
if (log_type == REPMGR_SYSLOG) syslog(LOG_INFO, __VA_ARGS__); \
else stderr_log_info(__VA_ARGS__); \
}
#define log_notice(...) \
{ \
if (log_type == REPMGR_SYSLOG) syslog(LOG_NOTICE, __VA_ARGS__); \
else stderr_log_notice(__VA_ARGS__); \
}
#define log_warning(...) \
{ \
if (log_type == REPMGR_SYSLOG) syslog(LOG_WARNING, __VA_ARGS__); \
else stderr_log_warning(__VA_ARGS__); \
}
#define log_err(...) \
{ \
if (log_type == REPMGR_SYSLOG) syslog(LOG_ERR, __VA_ARGS__); \
else stderr_log_err(__VA_ARGS__); \
}
#define log_crit(...) \
{ \
if (log_type == REPMGR_SYSLOG) syslog(LOG_CRIT, __VA_ARGS__); \
else stderr_log_crit(__VA_ARGS__); \
}
#define log_alert(...) \
{ \
if (log_type == REPMGR_SYSLOG) syslog(LOG_ALERT, __VA_ARGS__); \
else stderr_log_alert(__VA_ARGS__); \
}
#define log_emerg(...) \
{ \
if (log_type == REPMGR_SYSLOG) syslog(LOG_ALERT, __VA_ARGS__); \
else stderr_log_alert(__VA_ARGS__); \
}
#else
#define LOG_EMERG 0 /* system is unusable */
#define LOG_ALERT 1 /* action must be taken immediately */
#define LOG_CRIT 2 /* critical conditions */
#define LOG_ERR 3 /* error conditions */
#define LOG_WARNING 4 /* warning conditions */
#define LOG_NOTICE 5 /* normal but significant condition */
#define LOG_INFO 6 /* informational */
#define LOG_DEBUG 7 /* debug-level messages */
#define log_debug(...) stderr_log_debug(__VA_ARGS__)
#define log_info(...) stderr_log_info(__VA_ARGS__)
#define log_notice(...) stderr_log_notice(__VA_ARGS__)
#define log_warning(...) stderr_log_warning(__VA_ARGS__)
#define log_err(...) stderr_log_err(__VA_ARGS__)
#define log_crit(...) stderr_log_crit(__VA_ARGS__)
#define log_alert(...) stderr_log_alert(__VA_ARGS__)
#define log_emerg(...) stderr_log_emerg(__VA_ARGS__)
#endif
/* Logger initialisation and shutdown */
bool logger_shutdown(void);
bool logger_init(t_configuration_options * opts, const char *ident,
const char *level, const char *facility);
void logger_min_verbose(int minimum);
extern int log_type;
extern int log_level;
#endif

3963
repmgr.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +0,0 @@
cluster=test
node=2
conninfo='host=192.168.204.104'

134
repmgr.conf.sample Normal file
View File

@@ -0,0 +1,134 @@
###################################################
# Replication Manager sample configuration file
###################################################
# Required configuration items
# ============================
#
# repmgr and repmgrd require these items to be configured:
# Cluster name
cluster=test
# Node ID and name
# (Note: we recommend to avoid naming nodes after their initial
# replication funcion, as this will cause confusion when e.g.
# "standby2" is promoted to master)
node=2
node_name=node2
# Database connection information
conninfo='host=192.168.204.104 dbname=repmgr_db user=repmgr_usr'
# Optional configuration items
# ============================
# Replication settings
# ---------------------
# when using cascading replication and a standby is to be connected to an
# upstream standby, specify that node's ID with 'upstream_node'. The node
# must exist before the new standby can be registered. If a standby is
# to connect directly to a master node, this parameter is not required.
#
# upstream_node=1
# physical replication slots - PostgreSQL 9.4 and later only
# (default: 0)
#
# use_replication_slots=0
# Logging and monitoring settings
# -------------------------------
# Log level: possible values are DEBUG, INFO, NOTICE, WARNING, ERR, ALERT, CRIT or EMERG
# (default: NOTICE)
loglevel=NOTICE
# Logging facility: possible values are STDERR or - for Syslog integration - one of LOCAL0, LOCAL1, ..., LOCAL7, USER
# (default: STDERR)
logfacility=STDERR
# stderr can be redirected to an arbitrary file:
#
# logfile='/var/log/repmgr.log'
# event notifications can be passed to an arbitrary external program
# together with the following parameters:
#
# %n - node ID
# %e - event type
# %s - success (1 or 0)
# %t - timestamp
# %d - details
#
# the values provided for "%t" and "%d" will probably contain spaces,
# so should be quoted in the provided command configuration, e.g.:
#
# event_notification_command='/path/to/some/script %n %e %s "%t" "%d"'
# By default, all notifications will be passed; the notification types
# can be filtered to explicitly named ones:
#
# event_notifications=master_register,standby_register,witness_create
# Environment/command settings
# ----------------------------
# path to PostgreSQL binary directory (location of pg_ctl, pg_basebackup etc.)
# (if not provided, defaults to system $PATH)
# pg_bindir=/usr/bin/
# external command options
# rsync_options=--archive --checksum --compress --progress --rsh="ssh -o \"StrictHostKeyChecking no\""
# ssh_options=-o "StrictHostKeyChecking no"
# external command arguments
# pg_ctl_options='-s'
# pg_basebackup_options='--xlog-method=s'
# Standby clone settings
# ----------------------
#
# These settings apply when cloning a standby (`repmgr standby clone`).
# Tablespaces can be remapped from one file system location to another:
#
# tablespace_mapping=/path/to/original/tablespace=/path/to/new/tablespace
# Failover settings (repmgrd)
# ---------------------------
#
# These settings are only applied when repmgrd is running.
# How many seconds we wait for master response before declaring master failure
master_response_timeout=60
# How many time we try to reconnect to master before starting failover procedure
reconnect_attempts=6
reconnect_interval=10
# Autofailover options
failover=automatic # one of 'automatic', 'manual'
priority=100 # a value of zero or less prevents the node being promoted to master
promote_command='repmgr standby promote -f /path/to/repmgr.conf'
follow_command='repmgr standby follow -f /path/to/repmgr.conf -W'
# monitoring interval; default is 2s
#
# monitor_interval_secs=2
# change wait time for master; before we bail out and exit when the master
# disappears, we wait 'reconnect_attempts' * 'retry_promote_interval_secs'
# seconds; by default this would be half an hour, as 'retry_promote_interval_secs'
# default value is 300)
#
# retry_promote_interval_secs=300

101
repmgr.h
View File

@@ -1,6 +1,19 @@
/*
* dbutils.h
* Copyright (c) 2ndQuadrant, 2010
* repmgr.h
* Copyright (c) 2ndQuadrant, 2010-2015
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
@@ -8,17 +21,91 @@
#define _REPMGR_H_
#include "postgres_fe.h"
#include "getopt_long.h"
#include "libpq-fe.h"
#include "getopt_long.h"
#include "strutil.h"
#include "dbutils.h"
#include "errcode.h"
#include "config.h"
#define MIN_SUPPORTED_VERSION "9.3"
#define MIN_SUPPORTED_VERSION_NUM 90300
#define PRIMARY_MODE 0
#define STANDBY_MODE 1
#include "config.h"
#define MAXFILENAME 1024
#define ERRBUFF_SIZE 512
#define MAXLEN 80
#define CONFIG_FILE "repmgr.conf"
#define DEFAULT_CONFIG_FILE "./repmgr.conf"
#define DEFAULT_WAL_KEEP_SEGMENTS "5000"
#define DEFAULT_DEST_DIR "."
#define DEFAULT_MASTER_PORT "5432"
#define DEFAULT_DBNAME "postgres"
#define DEFAULT_REPMGR_SCHEMA_PREFIX "repmgr_"
#define DEFAULT_PRIORITY 100
#define FAILOVER_NODES_MAX_CHECK 50
#define MANUAL_FAILOVER 0
#define AUTOMATIC_FAILOVER 1
#define NO_UPSTREAM_NODE -1
typedef enum {
UNKNOWN = 0,
MASTER,
STANDBY,
WITNESS
} t_server_type;
/* Run time options type */
typedef struct
{
char dbname[MAXLEN];
char host[MAXLEN];
char username[MAXLEN];
char dest_dir[MAXFILENAME];
char config_file[MAXFILENAME];
char remote_user[MAXLEN];
char superuser[MAXLEN];
char wal_keep_segments[MAXLEN];
bool verbose;
bool force;
bool wait_for_master;
bool ignore_rsync_warn;
bool initdb_no_pwprompt;
bool rsync_only;
bool fast_checkpoint;
bool ignore_external_config_files;
char masterport[MAXLEN];
char localport[MAXLEN];
/* parameter used by CLUSTER CLEANUP */
int keep_history;
char pg_bindir[MAXLEN];
char recovery_min_apply_delay[MAXLEN];
} t_runtime_options;
#define T_RUNTIME_OPTIONS_INITIALIZER { "", "", "", "", "", "", "", DEFAULT_WAL_KEEP_SEGMENTS, false, false, false, false, false, false, false, false, "", "", 0, "", "" }
extern char repmgr_schema[MAXLEN];
typedef struct ErrorListCell
{
struct ErrorListCell *next;
char *error_message;
} ErrorListCell;
typedef struct ErrorList
{
ErrorListCell *head;
ErrorListCell *tail;
} ErrorList;
#endif

View File

@@ -1,3 +1,10 @@
/*
* repmgr.sql
*
* Copyright (C) 2ndQuadrant, 2010-2015
*
*/
CREATE USER repmgr;
CREATE SCHEMA repmgr;
@@ -5,51 +12,50 @@ CREATE SCHEMA repmgr;
* The table repl_nodes keeps information about all machines in
* a cluster
*/
drop table if exists repl_nodes cascade;
CREATE TABLE repl_nodes (
id integer primary key,
cluster text not null, -- Name to identify the cluster
conninfo text not null
id integer primary key,
cluster text not null, -- Name to identify the cluster
name text not null,
conninfo text not null,
priority integer not null,
witness boolean not null default false
);
ALTER TABLE repl_nodes OWNER TO repmgr;
/*
* Keeps monitor info about every node and their relative "position"
* Keeps monitor info about every node and their relative "position"
* to primary
*/
drop table if exists repl_monitor cascade;
CREATE TABLE repl_monitor (
primary_node INTEGER NOT NULL,
standby_node INTEGER NOT NULL,
last_monitor_time TIMESTAMP WITH TIME ZONE NOT NULL,
last_wal_primary_location TEXT NOT NULL,
last_wal_standby_location TEXT NOT NULL,
replication_lag BIGINT NOT NULL,
apply_lag BIGINT NOT NULL
last_monitor_time TIMESTAMP WITH TIME ZONE NOT NULL,
last_wal_primary_location TEXT NOT NULL,
last_wal_standby_location TEXT, -- In case of a witness server this will be NULL
replication_lag BIGINT NOT NULL,
apply_lag BIGINT NOT NULL
);
ALTER TABLE repl_monitor OWNER TO repmgr;
/*
* This view shows the latest monitor info about every node.
* Interesting thing to see:
* replication_lag: in bytes (this is how far the latest xlog record
* replication_lag: in bytes (this is how far the latest xlog record
* we have received is from master)
* apply_lag: in bytes (this is how far the latest xlog record
* we have applied is from the latest record we
* we have applied is from the latest record we
* have received)
* time_lag: how many seconds are we from being up-to-date with master
*/
drop view if exists repl_status;
CREATE VIEW repl_status AS
WITH monitor_info AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY primary_node, standby_node
ORDER BY last_monitor_time desc)
FROM repl_monitor)
SELECT primary_node, standby_node, last_monitor_time, last_wal_primary_location,
last_wal_standby_location, pg_size_pretty(replication_lag) replication_lag,
pg_size_pretty(apply_lag) apply_lag,
SELECT primary_node, standby_node, name AS standby_name, last_monitor_time, last_wal_primary_location,
last_wal_standby_location, pg_size_pretty(replication_lag) replication_lag,
pg_size_pretty(apply_lag) apply_lag,
age(now(), last_monitor_time) AS time_lag
FROM monitor_info a
WHERE row_number = 1;
FROM repl_monitor JOIN repl_nodes ON standby_node = id
WHERE (standby_node, last_monitor_time) IN (SELECT standby_node, MAX(last_monitor_time)
FROM repl_monitor GROUP BY 1);
ALTER VIEW repl_status OWNER TO repmgr;
CREATE INDEX idx_repl_status_sort ON repl_monitor(last_monitor_time, standby_node);

2628
repmgrd.c

File diff suppressed because it is too large Load Diff

21
sql/Makefile Normal file
View File

@@ -0,0 +1,21 @@
#
# Makefile
#
# Copyright (c) 2ndQuadrant, 2010-2015
#
MODULE_big = repmgr_funcs
DATA_built=repmgr_funcs.sql
DATA=uninstall_repmgr_funcs.sql
OBJS=repmgr_funcs.o
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/repmgr/sql
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif

76
sql/repmgr2_repmgr3.sql Normal file
View File

@@ -0,0 +1,76 @@
/*
* Update a repmgr 2.x installation to repmgr 3.0
* ----------------------------------------------
*
* 1. Stop any running repmgrd instances
* 2. On the master node, execute the SQL statements listed below,
* taking care to identify the master node and any inactive
* nodes
* 3. Restart repmgrd (being sure to use repmgr 3.0)
*/
/*
* Set the search path to the name of the schema used by
* your repmgr installation
* (this should be "repmgr_" + the cluster name defined in
* 'repmgr.conf')
*/
-- SET search_path TO 'name_of_repmgr_schema';
BEGIN;
ALTER TABLE repl_nodes RENAME TO repl_nodes2_0;
CREATE TABLE repl_nodes (
id INTEGER PRIMARY KEY,
type TEXT NOT NULL CHECK (type IN('master','standby','witness')),
upstream_node_id INTEGER NULL REFERENCES repl_nodes (id),
cluster TEXT NOT NULL,
name TEXT NOT NULL,
conninfo TEXT NOT NULL,
slot_name TEXT NULL,
priority INTEGER NOT NULL,
active BOOLEAN NOT NULL DEFAULT TRUE
);
INSERT INTO repl_nodes
(id, type, cluster, name, conninfo, priority)
SELECT id,
CASE
WHEN witness IS TRUE THEN 'witness'
ELSE 'standby'
END AS type,
cluster,
name,
conninfo,
priority + 100
FROM repl_nodes2_0;
/*
* You'll need to set the master explicitly; the following query
* should identify the master node ID but will only work if all
* standby servers are connected:
*
* SELECT id FROM repmgr_test.repl_nodes WHERE name NOT IN (SELECT application_name FROM pg_stat_replication)
*
* If in doubt, execute 'repmgr cluster show' will definitively identify
* the master.
*/
UPDATE repl_nodes SET type = 'master' WHERE id = $master_id;
/* If any nodes are known to be inactive, update them here */
-- UPDATE repl_nodes SET active = FALSE WHERE id IN (...);
/* When you're sure of your changes, commit them */
-- COMMIT;
/*
* execute the following command when you are sure you no longer
* require the old table:
*/
-- DROP TABLE repl_nodes2_0;

236
sql/repmgr_funcs.c Normal file
View File

@@ -0,0 +1,236 @@
/*
* repmgr_funcs.c
* Copyright (c) 2ndQuadrant, 2010
*
* Shared memory state management and some backend functions in SQL
*/
#include "postgres.h"
#include "fmgr.h"
#include "access/xlog.h"
#include "miscadmin.h"
#include "replication/walreceiver.h"
#include "storage/ipc.h"
#include "storage/lwlock.h"
#include "storage/procarray.h"
#include "storage/shmem.h"
#include "storage/spin.h"
#include "utils/builtins.h"
#include "utils/timestamp.h"
/* same definition as the one in xlog_internal.h */
#define MAXFNAMELEN 64
PG_MODULE_MAGIC;
/*
* Global shared state
*/
typedef struct repmgrSharedState
{
LWLockId lock; /* protects search/modification */
char location[MAXFNAMELEN]; /* last known xlog location */
TimestampTz last_updated;
} repmgrSharedState;
/* Links to shared memory state */
static repmgrSharedState *shared_state = NULL;
static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
void _PG_init(void);
void _PG_fini(void);
static void repmgr_shmem_startup(void);
static Size repmgr_memsize(void);
static bool repmgr_set_standby_location(char *locationstr);
Datum repmgr_update_standby_location(PG_FUNCTION_ARGS);
Datum repmgr_get_last_standby_location(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(repmgr_update_standby_location);
PG_FUNCTION_INFO_V1(repmgr_get_last_standby_location);
Datum repmgr_update_last_updated(PG_FUNCTION_ARGS);
Datum repmgr_get_last_updated(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(repmgr_update_last_updated);
PG_FUNCTION_INFO_V1(repmgr_get_last_updated);
/*
* Module load callback
*/
void
_PG_init(void)
{
/*
* In order to create our shared memory area, we have to be loaded via
* shared_preload_libraries. If not, fall out without hooking into any of
* the main system. (We don't throw error here because it seems useful to
* allow the repmgr functions to be created even when the module isn't
* active. The functions must protect themselves against being called
* then, however.)
*/
if (!process_shared_preload_libraries_in_progress)
return;
/*
* Request additional shared resources. (These are no-ops if we're not in
* the postmaster process.) We'll allocate or attach to the shared
* resources in repmgr_shmem_startup().
*/
RequestAddinShmemSpace(repmgr_memsize());
RequestAddinLWLocks(1);
/*
* Install hooks.
*/
prev_shmem_startup_hook = shmem_startup_hook;
shmem_startup_hook = repmgr_shmem_startup;
}
/*
* Module unload callback
*/
void
_PG_fini(void)
{
/* Uninstall hooks. */
shmem_startup_hook = prev_shmem_startup_hook;
}
/*
* shmem_startup hook: allocate or attach to shared memory,
*/
static void
repmgr_shmem_startup(void)
{
bool found;
if (prev_shmem_startup_hook)
prev_shmem_startup_hook();
/* reset in case this is a restart within the postmaster */
shared_state = NULL;
/*
* Create or attach to the shared memory state, including hash table
*/
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
shared_state = ShmemInitStruct("repmgr shared state",
sizeof(repmgrSharedState),
&found);
if (!found)
{
/* First time through ... */
shared_state->lock = LWLockAssign();
snprintf(shared_state->location,
sizeof(shared_state->location), "%X/%X", 0, 0);
}
LWLockRelease(AddinShmemInitLock);
}
/*
* Estimate shared memory space needed.
*/
static Size
repmgr_memsize(void)
{
return MAXALIGN(sizeof(repmgrSharedState));
}
static bool
repmgr_set_standby_location(char *locationstr)
{
/* Safety check... */
if (!shared_state)
return false;
LWLockAcquire(shared_state->lock, LW_EXCLUSIVE);
strncpy(shared_state->location, locationstr, MAXFNAMELEN);
LWLockRelease(shared_state->lock);
return true;
}
/* SQL Functions */
/* Read last xlog location reported by this standby from shared memory */
Datum
repmgr_get_last_standby_location(PG_FUNCTION_ARGS)
{
char location[MAXFNAMELEN];
/* Safety check... */
if (!shared_state)
PG_RETURN_NULL();
LWLockAcquire(shared_state->lock, LW_SHARED);
strncpy(location, shared_state->location, MAXFNAMELEN);
LWLockRelease(shared_state->lock);
PG_RETURN_TEXT_P(cstring_to_text(location));
}
/* Set update last xlog location reported by this standby to shared memory */
Datum
repmgr_update_standby_location(PG_FUNCTION_ARGS)
{
text *location = PG_GETARG_TEXT_P(0);
char *locationstr;
/* Safety check... */
if (!shared_state)
PG_RETURN_BOOL(false);
locationstr = text_to_cstring(location);
PG_RETURN_BOOL(repmgr_set_standby_location(locationstr));
}
/* update and return last updated with current timestamp */
Datum
repmgr_update_last_updated(PG_FUNCTION_ARGS)
{
TimestampTz last_updated = GetCurrentTimestamp();
/* Safety check... */
if (!shared_state)
PG_RETURN_NULL();
LWLockAcquire(shared_state->lock, LW_SHARED);
shared_state->last_updated = last_updated;
LWLockRelease(shared_state->lock);
PG_RETURN_TIMESTAMPTZ(last_updated);
}
/* get last updated timestamp */
Datum
repmgr_get_last_updated(PG_FUNCTION_ARGS)
{
TimestampTz last_updated;
/* Safety check... */
if (!shared_state)
PG_RETURN_NULL();
LWLockAcquire(shared_state->lock, LW_EXCLUSIVE);
last_updated = shared_state->last_updated;
LWLockRelease(shared_state->lock);
PG_RETURN_TIMESTAMPTZ(last_updated);
}

23
sql/repmgr_funcs.sql.in Normal file
View File

@@ -0,0 +1,23 @@
/*
* repmgr_function.sql
* Copyright (c) 2ndQuadrant, 2010-2015
*
*/
-- SET SEARCH_PATH TO 'repmgr';
CREATE FUNCTION repmgr_update_standby_location(text) RETURNS boolean
AS 'MODULE_PATHNAME', 'repmgr_update_standby_location'
LANGUAGE C STRICT;
CREATE FUNCTION repmgr_get_last_standby_location() RETURNS text
AS 'MODULE_PATHNAME', 'repmgr_get_last_standby_location'
LANGUAGE C STRICT;
CREATE FUNCTION repmgr_update_last_updated() RETURNS TIMESTAMP WITH TIME ZONE
AS 'MODULE_PATHNAME', 'repmgr_update_last_updated'
LANGUAGE C STRICT;
CREATE FUNCTION repmgr_get_last_updated() RETURNS TIMESTAMP WITH TIME ZONE
AS 'MODULE_PATHNAME', 'repmgr_get_last_updated'
LANGUAGE C STRICT;

View File

@@ -0,0 +1,11 @@
/*
* uninstall_repmgr_funcs.sql
* Copyright (c) 2ndQuadrant, 2010-2015
*
*/
DROP FUNCTION repmgr_update_standby_location(text);
DROP FUNCTION repmgr_get_last_standby_location();
DROP FUNCTION repmgr_update_last_updated();
DROP FUNCTION repmgr_get_last_updated();

89
strutil.c Normal file
View File

@@ -0,0 +1,89 @@
/*
* strutil.c
*
* Copyright (C) 2ndQuadrant, 2010-2015
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "log.h"
#include "strutil.h"
static int
xvsnprintf(char *str, size_t size, const char *format, va_list ap)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
static int
xvsnprintf(char *str, size_t size, const char *format, va_list ap)
{
int retval;
retval = vsnprintf(str, size, format, ap);
if (retval >= (int) size)
{
log_err(_("Buffer of size not large enough to format entire string '%s'\n"),
str);
exit(ERR_STR_OVERFLOW);
}
return retval;
}
int
xsnprintf(char *str, size_t size, const char *format,...)
{
va_list arglist;
int retval;
va_start(arglist, format);
retval = xvsnprintf(str, size, format, arglist);
va_end(arglist);
return retval;
}
int
sqlquery_snprintf(char *str, const char *format,...)
{
va_list arglist;
int retval;
va_start(arglist, format);
retval = xvsnprintf(str, QUERY_STR_LEN, format, arglist);
va_end(arglist);
return retval;
}
int
maxlen_snprintf(char *str, const char *format,...)
{
va_list arglist;
int retval;
va_start(arglist, format);
retval = xvsnprintf(str, MAXLEN, format, arglist);
va_end(arglist);
return retval;
}

46
strutil.h Normal file
View File

@@ -0,0 +1,46 @@
/*
* strutil.h
* Copyright (C) 2ndQuadrant, 2010-2015
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _STRUTIL_H_
#define _STRUTIL_H_
#include <stdlib.h>
#include "errcode.h"
#define QUERY_STR_LEN 8192
#define MAXLEN 1024
#define MAXLINELENGTH 4096
#define MAXVERSIONSTR 16
#define MAXCONNINFO 1024
extern int
xsnprintf(char *str, size_t size, const char *format,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
extern int
sqlquery_snprintf(char *str, const char *format,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
extern int
maxlen_snprintf(char *str, const char *format,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
#endif /* _STRUTIL_H_ */

13
uninstall_repmgr.sql Normal file
View File

@@ -0,0 +1,13 @@
/*
* uninstall_repmgr.sql
*
* Copyright (C) 2ndQuadrant, 2010-2015
*
*/
DROP TABLE IF EXISTS repl_nodes;
DROP TABLE IF EXISTS repl_monitor;
DROP VIEW IF EXISTS repl_status;
DROP SCHEMA repmgr;
DROP USER repmgr;

6
version.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef _VERSION_H_
#define _VERSION_H_
#define REPMGR_VERSION "3.0dev"
#endif