Skip to content

Instantly share code, notes, and snippets.

@sebastianwebber
Last active March 20, 2018 13:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sebastianwebber/6f9177aceb03564d1f30339a1bac0a0f to your computer and use it in GitHub Desktop.
Save sebastianwebber/6f9177aceb03564d1f30339a1bac0a0f to your computer and use it in GitHub Desktop.
Compare PostgreSQL LSN in ruby
# select pg_xlog_location_diff('951A/EA0F8000', '9518/1ECB6000');
# super_db=# select pg_xlog_location_diff('951A/EA0F8000', '9518/1ECB6000');
# pg_xlog_location_diff
# -----------------------
# 12000174080
# (1 row)
# super_db=# select pg_xlogfile_name('951A/EA0F8000'), pg_xlogfile_name('9518/1ECB6000');
# -[ RECORD 1 ]----+-------------------------
# pg_xlogfile_name | 000000030000951A000000EA
# pg_xlogfile_name | 00000003000095180000001E
class String
def trim_lead(n)
self.gsub!(/^#{n}+/,'')
end
end
def to_lsn lsn
timeline, logfile, offset = lsn.scan(/.{8}/)
"#{logfile.trim_lead("0")}/#{offset.trim_lead("0").ljust(8, "0")}"
end
def to_bytes lsn
file, pos = lsn.split('/')
('FFFFFFFF'.hex * file.hex + pos.hex)
end
def compare_lsn master_lsn, slave_lsn
( to_bytes(master_lsn) + 2) - to_bytes(slave_lsn)
end
# puts compare_lsn '951A/EA0F8000', '9518/1ECB6000'
# first = to_lsn '000000030000951A000000EA'
# second = to_lsn '00000003000095180000001E'
# puts "select pg_xlogfile_name('#{first}'), pg_xlogfile_name('#{second}');"
# puts "select pg_xlog_location_diff('#{first}','#{second}');"
### computed: 12012486656
### correct : 12000174080
require 'optparse'
options = {
:compare_wal => false,
:origin_input => "",
:destiny_input => "",
}
OptionParser.new do |opts|
opts.banner = "Usage: replication_diff.rb [options]"
opts.separator ""
opts.separator "General options:"
opts.on "-w", "--wal", "compare walfiles and compute the LSN" do |v|
options[:compare_wal] = true
end
opts.on "-o", "--origin VALUE", "origin wal file (or LSN)" do |v|
options[:origin_input] = v
end
opts.on "-d", "--destiny VALUE", "destiny wal file (or LSN)" do |v|
options[:destiny_input] = v
end
end.parse!
if options[:compare_wal]
first = to_lsn options[:origin_input]
second = to_lsn options[:destiny_input]
else
first = options[:origin_input]
second = options[:destiny_input]
end
puts compare_lsn first, second
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment