File Coverage

blib/lib/PGObject/Util/Replication/Slot.pm
Criterion Covered Total %
statement 14 42 33.3
branch 0 10 0.0
condition 0 4 0.0
subroutine 5 10 50.0
pod 4 4 100.0
total 23 70 32.8


line stmt bran cond sub pod time code
1             package PGObject::Util::Replication::Slot;
2              
3 3     3   194312 use 5.010;
  3         10  
4 3     3   16 use strict;
  3         6  
  3         66  
5 3     3   28 use warnings;
  3         9  
  3         142  
6 3     3   1587 use Moo;
  3         32782  
  3         17  
7 3     3   4401 use Carp;
  3         8  
  3         1478  
8              
9             =head1 NAME
10              
11             PGObject::Util::Replication::Slot - Manage and Monitor Replication Slots
12              
13             =head1 VERSION
14              
15             Version v0.20.0
16              
17             =cut
18              
19             our $VERSION = "0.020000";
20              
21              
22             =head1 SYNOPSIS
23              
24             This module provides a low-level interface for monitoring and managing
25             replication slots. It is intended to be used by other management modules
26             and therefore requires read and write operations to pass in a database handle.
27              
28             Slots here represent values and should be treated as read-only once
29             instantiated. This is to improve utility when it comes to monitoring and
30             logging.
31              
32              
33             use PGObject::Util::Replication::Slot;
34              
35             my @slots = PGObject::Util::Replication::Slot->all($dbh);
36             my $slot = PGObject::Util::Replication::Slot->get($dbh, 'slotname');
37              
38             # can also create and delete
39             my $slot = PGObject::Util::Replication::Slot->create($dbh, 'slotname');
40             my $success = PGObject::Util::Replication::Slot->delete($dbh, 'slotname');
41            
42              
43             =head1 SLOT PROPERTIES
44              
45             Properties are set from the database. Tthey are not intended to be set
46             by develoers.
47              
48             =head2 slot_name
49              
50             Name of slot.
51              
52             =head2 slot_type
53              
54             logical or physical
55              
56             =head2 active
57              
58             boolean
59              
60             =head2 restart_lsn
61              
62             Last log serial number sent
63              
64             =head2 full_data
65              
66             A json object of the whole pg_replication_slots entry. You can use this to
67             get data not supported by base versions, such as last confirmed wal flush
68             on Postgres 9.6. Note that the format here varies from version to version.
69              
70             =head2 query_time
71              
72             The return value of the now() command at the time the query was run.
73              
74             =head2 pg_current_xlog_location
75              
76             The current transaction log/wal lsn for the current system. We will not
77             change this field here even when running on PostgreSQL 10
78              
79             =head2 current_lag_bytes
80              
81             The byte offset between the current xlog logation and the last restart lsn
82             for the slot. This means basically the number of bytes that have not yet
83             been confirmed as read by the slot compared to our current WAL.
84              
85             =cut
86              
87              
88             has slot_name => (is => 'ro');
89             has slot_type => (is => 'ro');
90             has active => (is => 'ro');
91             has restart_lsn => (is => 'ro');
92             has full_data => (is => 'ro');
93             has query_time => (is => 'ro');
94             has pg_current_xlog_location => (is => 'ro');
95             has current_lag_bytes => (is => 'ro');
96              
97              
98             =head1 METHODS
99              
100             =head2 all($dbh, [$prefix])
101              
102             Returns a list of objects fo this type filtered on the prefix specified/
103              
104             =head2 get($dbh, $name)
105              
106             Gets the slot specified by name
107              
108             =head2 create($dbh, $name, [$type])
109              
110             Creates a new slot, by default a physical one, with the specified name.
111              
112             =head2 delete($dbh, $name)
113              
114             Deletes the slot with the given name. Note that this will allow wal segments
115             that are pending to be archived and thus may prevent the replica from being
116             able to gatch up through normal means.
117              
118             =cut
119              
120             my $query =
121             "
122             SELECT slot_name, slot_type, active, restart_lsn, to_jsonb(s) as full_data,
123             now() as querytime, CASE WHEN pg_is_in_recovery()
124             THEN null::pg_lsn
125             ELSE pg_current_xlog_location() END
126             AS pg_current_xlog_location,
127             CASE WHEN pg_is_in_recovery() THEN null::int
128             ELSE pg_current_xlog_location() - restart_lsn END
129             AS current_lag_bytes
130             FROM pg_replication_slots s
131             WHERE slot_name LIKE ?
132             ORDER BY slot_name
133             ";
134              
135             sub _query {
136 0     0     my ($dbh, $filter) = @_;
137 0           my $sth = $dbh->prepare($query);
138 0 0         $sth->execute($filter) or return;
139 0 0         return $sth->fetchrow_hashref('NAME_lc') unless wantarray;
140 0           my @return = ();
141 0           my $hashref;
142 0           push @return, $hashref while $hashref = $sth->fetchrow_hashref('NAME_lc');
143 0           return @return;
144             }
145              
146             sub all {
147 0     0 1   my ($self, $dbh, $prefix) = @_;
148 0   0       $prefix //= '';
149 0           my @items = _query($dbh, $prefix . '%');
150 0           return map { __PACKAGE__->new($_) } @items;
  0            
151             }
152              
153             sub get {
154 0     0 1   my ($self, $dbh, $name) = @_;
155 0 0         croak 'Must specify which slot to get' unless defined $name;
156 0 0         my $ref = _query($dbh, $name) or return;
157 0           return __PACKAGE__->new($ref);
158             }
159              
160             sub create {
161 0     0 1   my ($self, $dbh, $name, $type) = @_;
162 0   0       $type //= 'physical';
163 0           $type = lc($type);
164             croak 'Slot type must be logical or physical'
165 0 0         unless scalar grep { $type eq $_ } qw(logical physical);
  0            
166 0           my $sth = $dbh->prepare("SELECT pg_create_${type}_replication_slot(?)");
167 0           $sth->execute($name);
168 0           return __PACKAGE__->get($dbh, $name);
169             }
170              
171             sub delete {
172 0     0 1   my ($self, $dbh, $name) = @_;
173 0           my $sth = $dbh->prepare("select pg_drop_replication_slot(?)");
174 0           return $sth->execute($name);
175             }
176              
177              
178              
179             =head1 AUTHOR
180              
181             Chris Travers, C<< >>
182              
183             =head1 BUGS
184              
185             Please report any bugs or feature requests to C, or through
186             the web interface at L. I will be notified, and then you'll
187             automatically be notified of progress on your bug as I make changes.
188              
189              
190              
191              
192             =head1 SUPPORT
193              
194             You can find documentation for this module with the perldoc command.
195              
196             perldoc PGObject::Util::Replication::Slot
197              
198              
199             You can also look for information at:
200              
201             =over 4
202              
203             =item * RT: CPAN's request tracker (report bugs here)
204              
205             L
206              
207             =item * AnnoCPAN: Annotated CPAN documentation
208              
209             L
210              
211             =item * CPAN Ratings
212              
213             L
214              
215             =item * Search CPAN
216              
217             L
218              
219             =back
220              
221              
222             =head1 ACKNOWLEDGEMENTS
223              
224              
225             =head1 LICENSE AND COPYRIGHT
226              
227             Copyright 2017 Adjust.com
228              
229             This program is distributed under the (Revised) BSD License:
230             L
231              
232             Redistribution and use in source and binary forms, with or without
233             modification, are permitted provided that the following conditions
234             are met:
235              
236             * Redistributions of source code must retain the above copyright
237             notice, this list of conditions and the following disclaimer.
238              
239             * Redistributions in binary form must reproduce the above copyright
240             notice, this list of conditions and the following disclaimer in the
241             documentation and/or other materials provided with the distribution.
242              
243             * Neither the name of Adjust.com
244             nor the names of its contributors may be used to endorse or promote
245             products derived from this software without specific prior written
246             permission.
247              
248             THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
249             "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
250             LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
251             A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
252             OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
253             SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
254             LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255             DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256             THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257             (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
258             OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
259              
260              
261             =cut
262              
263             1; # End of PGObject::Util::Replication::Slot