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   46846 use 5.010;
  3         10  
4 3     3   15 use strict;
  3         8  
  3         56  
5 3     3   16 use warnings;
  3         15  
  3         81  
6 3     3   1328 use Moo;
  3         36927  
  3         18  
7 3     3   4190 use Carp;
  3         9  
  3         1602  
8              
9             =head1 NAME
10              
11             PGObject::Util::Replication::Slot - Manage and Monitor Replication Slots
12              
13             =head1 VERSION
14              
15             Version v0.10.2
16              
17             =cut
18              
19             our $VERSION = 0.010002;
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, pg_current_xlog_location(),
124             pg_current_xlog_location() - restart_lsn AS current_lag_bytes
125             FROM pg_replication_slots s
126             WHERE slot_name LIKE ?
127             ORDER BY slot_name
128             ";
129              
130             sub _query {
131 0     0     my ($dbh, $filter) = @_;
132 0           my $sth = $dbh->prepare($query);
133 0 0         $sth->execute($filter) or return;
134 0 0         return $sth->fetchrow_hashref('NAME_lc') unless wantarray;
135 0           my @return = ();
136 0           my $hashref;
137 0           push @return, $hashref while $hashref = $sth->fetchrow_hashref('NAME_lc');
138 0           return @return;
139             }
140              
141             sub all {
142 0     0 1   my ($self, $dbh, $prefix) = @_;
143 0   0       $prefix //= '';
144 0           my @items = _query($dbh, $prefix . '%');
145 0           return map { __PACKAGE__->new($_) } @items;
  0            
146             }
147              
148             sub get {
149 0     0 1   my ($self, $dbh, $name) = @_;
150 0 0         croak 'Must specify which slot to get' unless defined $name;
151 0 0         my $ref = _query($dbh, $name) or return;
152 0           return __PACKAGE__->new($ref);
153             }
154              
155             sub create {
156 0     0 1   my ($self, $dbh, $name, $type) = @_;
157 0   0       $type //= 'physical';
158 0           $type = lc($type);
159             croak 'Slot type must be logical or physical'
160 0 0         unless scalar grep { $type eq $_ } qw(logical physical);
  0            
161 0           my $sth = $dbh->prepare("SELECT pg_create_${type}_replication_slot(?)");
162 0           $sth->execute($name);
163 0           return __PACKAGE__->get($dbh, $name);
164             }
165              
166             sub delete {
167 0     0 1   my ($self, $dbh, $name) = @_;
168 0           my $sth = $dbh->prepare("select pg_drop_replication_slot(?)");
169 0           return $sth->execute($name);
170             }
171              
172              
173              
174             =head1 AUTHOR
175              
176             Chris Travers, C<< >>
177              
178             =head1 BUGS
179              
180             Please report any bugs or feature requests to C, or through
181             the web interface at L. I will be notified, and then you'll
182             automatically be notified of progress on your bug as I make changes.
183              
184              
185              
186              
187             =head1 SUPPORT
188              
189             You can find documentation for this module with the perldoc command.
190              
191             perldoc PGObject::Util::Replication::Slot
192              
193              
194             You can also look for information at:
195              
196             =over 4
197              
198             =item * RT: CPAN's request tracker (report bugs here)
199              
200             L
201              
202             =item * AnnoCPAN: Annotated CPAN documentation
203              
204             L
205              
206             =item * CPAN Ratings
207              
208             L
209              
210             =item * Search CPAN
211              
212             L
213              
214             =back
215              
216              
217             =head1 ACKNOWLEDGEMENTS
218              
219              
220             =head1 LICENSE AND COPYRIGHT
221              
222             Copyright 2017 Adjust.com
223              
224             This program is distributed under the (Revised) BSD License:
225             L
226              
227             Redistribution and use in source and binary forms, with or without
228             modification, are permitted provided that the following conditions
229             are met:
230              
231             * Redistributions of source code must retain the above copyright
232             notice, this list of conditions and the following disclaimer.
233              
234             * Redistributions in binary form must reproduce the above copyright
235             notice, this list of conditions and the following disclaimer in the
236             documentation and/or other materials provided with the distribution.
237              
238             * Neither the name of Adjust.com
239             nor the names of its contributors may be used to endorse or promote
240             products derived from this software without specific prior written
241             permission.
242              
243             THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
244             "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
245             LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
246             A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
247             OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
248             SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
249             LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
250             DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
251             THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252             (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
253             OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
254              
255              
256             =cut
257              
258             1; # End of PGObject::Util::Replication::Slot