replicator/lib/ruby/pg-wal-plugin.rb
# Install infrastructure and update PostgreSQL configuration files
# to support replication.  Note:  Installation is designed to be identical
# for primary and standby.  
Install infrastructure and update PostgreSQL configuration files
to support replication.  Note:  Installation is designed to be identical
for primary and standby.
Install infrastructure and update PostgreSQL configuration files to support replication . Note : Installation is designed to be identical for primary and standby .
def plugin_install
    master_host         = @config.getProperty("postgresql.master.host")
    master_port         = @config.getProperty("postgresql.master.port")
    pg_data             = @config.getProperty("postgresql.data")
    archive_timeout     = @config.getProperty("postgresql.archive_timeout")
    pg_standby          = @config.getProperty("postgresql.pg_standby")
    pg_archive          = @config.getProperty("postgresql.archive")
    trigger             = @config.getProperty("postgresql.pg_standby.trigger")
    postgresql_conf     = @config.getProperty("postgresql.conf")
    pg_archivecleanup   = @config.getProperty("postgresql.pg_archivecleanup")
    tungsten_user       = ENV['USER']
    log "Checking pg_standby availability"
    if not command_exists?(pg_standby, false)
      log "ERROR: pg_standby is not available in the given path:"
      log "       " + pg_standby
      log "       Replication won't work without pg_standby."
      log "Please consult Replicator Guide for installation details."
      log ""
      print_batch_mode_suggestion
      log ""
      raise SystemError, "pg_standby is not available in: " + pg_standby
    end
    if not command_exists?(pg_standby, true)
      log "ERROR: pg_standby is not available for root user:"
      log "       " + pg_standby
      log "       Replication won't work without pg_standby."
      log "Please consult Replicator Guide for installation details."
      log ""
      print_batch_mode_suggestion
      log ""
      raise SystemError, "pg_standby is not available for root: " + pg_standby
    end
    if File.exist?(@initialized)
      log("Already initialized; nothing to do")
      return
    end
    log("Starting installation for PostgreSQL WAL shipping")
    log("Creating conf dir: " + @pg_wal_conf)
    FileUtils.mkdir_p(@pg_wal_conf)
    log("Creating WAL generation times' dir: " + @pg_wal_when)
    FileUtils.mkdir_p(@pg_wal_when)
    log("Updating postgresql.tungsten.conf")
    transformer = Transformer.new(@pg_tungsten_conf_s, @pg_tungsten_conf,
      "#");
    transformer.transform { |line|
      if line =~ /archive_mode/ then
        "archive_mode = on"
      elsif line =~ /archive_command/ then
        "archive_command ='" + @pg_wal_archive + " %p %f'"
      elsif line =~ /archive_timeout/
        "archive_timeout = " + archive_timeout
      elsif line =~ /#max_wal_senders/ and is_streaming_replication
        line[1..-1]
      elsif line =~ /#wal_level/ and is_streaming_replication
        line[1..-1]
      elsif line =~ /#hot_standby/ and is_streaming_replication
        line[1..-1]
      else
        line
      end
    }
    no_include = true
    transformer = Transformer.new(postgresql_conf, postgresql_conf, nil);
    transformer.transform { |line|
      if line =~ /^include.*postgresql.tungsten.conf/ then
        no_include = false
        "include '" + @pg_tungsten_conf + "'"
      else
        line
      end
    }
    if no_include
      exec_cmd("echo \"\" >> #{postgresql_conf}")
      exec_cmd("echo \"# Include for properties required by Tungsten.\" >> #{postgresql_conf}")
      exec_cmd("echo \"include '#{@pg_tungsten_conf}'\" >> #{postgresql_conf}")
    end
    hostname = `hostname`.chomp
    arch_active_props = Properties.new
    arch_active_props.setProperty("postgresql.standby.host", hostname)
    arch_active_props.setProperty("postgresql.standby.archive", pg_archive)
    arch_active_props.store(@archiving_active_template) 
    ckeys = ["postgresql.role", 
             "postgresql.port",
             "postgresql.master.host",
             "postgresql.master.port",
             "postgresql.archive",
             "postgresql.pg_standby",
             "postgresql.pg_standby.trigger",
             "postgresql.pg_archivecleanup"]
    cprops = Properties.new  
    ckeys.each do | key |
      val = @config.getProperty(key)
      cprops.setProperty(key, val)
    end
    cprops.store(@pg_wal_properties)
    role = @config.getProperty("postgresql.role")
    if role == "slave"
      install_standby(pg_data, postgresql_conf, pg_archive)
    elsif role == "master"
      if @options.skip_restart
        log "Skipping PostgreSQL server restart as requested by user."
      else
        stop_pg_server(true)
        status_pg_server(false) 
        start_pg_server(false)
        sleep(10)
        status_pg_server(true) 
        exec_cmd("touch #{trigger}") 
        wait_until_login_works
      end
      create_tungsten_db(true)
      exec_cmd2("psql -p#{@config.getProperty("postgresql.port")} -t -c \"CREATE TABLE progress_timestamp (wal varchar(32), segment varchar(12), datetime timestamp)\" #{@tungsten_db};", false)
    else
      raise UserError, "Unknown role: #{role}"
    end
    generate_recovery_conf(master_host, master_port)
    tag_file_write(@initialized, role)
    log("Installation completed successfully")
  end
def plugin_install master_host = @config . getProperty ( "postgresql.master.host" ) master_port = @config . getProperty ( "postgresql.master.port" ) pg_data = @config . getProperty ( "postgresql.data" ) archive_timeout = @config . getProperty ( "postgresql.archive_timeout" ) pg_standby = @config . getProperty ( "postgresql.pg_standby" ) pg_archive = @config . getProperty ( "postgresql.archive" ) trigger = @config . getProperty ( "postgresql.pg_standby.trigger" ) postgresql_conf = @config . getProperty ( "postgresql.conf" ) pg_archivecleanup = @config . getProperty ( "postgresql.pg_archivecleanup" ) tungsten_user = ENV [ 'USER' ] log "Checking pg_standby availability" if not command_exists? ( pg_standby , false ) log "ERROR: pg_standby is not available in the given path:" log "       " + pg_standby log "       Replication won't work without pg_standby." log "Please consult Replicator Guide for installation details." log "" print_batch_mode_suggestion log "" raise SystemError , "pg_standby is not available in: " + pg_standby end if not command_exists? ( pg_standby , true ) log "ERROR: pg_standby is not available for root user:" log "       " + pg_standby log "       Replication won't work without pg_standby." log "Please consult Replicator Guide for installation details." log "" print_batch_mode_suggestion log "" raise SystemError , "pg_standby is not available for root: " + pg_standby end if File . exist? ( @initialized ) log ( "Already initialized; nothing to do" ) return end log ( "Starting installation for PostgreSQL WAL shipping" ) log ( "Creating conf dir: " + @pg_wal_conf ) FileUtils . mkdir_p ( @pg_wal_conf ) log ( "Creating WAL generation times' dir: " + @pg_wal_when ) FileUtils . mkdir_p ( @pg_wal_when ) log ( "Updating postgresql.tungsten.conf" ) transformer = Transformer . new ( @pg_tungsten_conf_s , @pg_tungsten_conf , "#" ) ; transformer . transform { | line | if line =~ / archive_mode / then "archive_mode = on" elsif line =~ / archive_command / then "archive_command ='" + @pg_wal_archive + " %p %f'" elsif line =~ / archive_timeout / "archive_timeout = " + archive_timeout elsif line =~ / #max_wal_senders / and is_streaming_replication line [ 1 .. - 1 ] elsif line =~ / #wal_level / and is_streaming_replication line [ 1 .. - 1 ] elsif line =~ / #hot_standby / and is_streaming_replication line [ 1 .. - 1 ] else line end } no_include = true transformer = Transformer . new ( postgresql_conf , postgresql_conf , nil ) ; transformer . transform { | line | if line =~ / ^include.*postgresql.tungsten.conf / then no_include = false "include '" + @pg_tungsten_conf + "'" else line end } if no_include exec_cmd ( "echo \"\" >> #{postgresql_conf}" ) exec_cmd ( "echo \"# Include for properties required by Tungsten.\" >> #{postgresql_conf}" ) exec_cmd ( "echo \"include '#{@pg_tungsten_conf}'\" >> #{postgresql_conf}" ) end hostname = ` hostname ` . chomp arch_active_props = Properties . new arch_active_props . setProperty ( "postgresql.standby.host" , hostname ) arch_active_props . setProperty ( "postgresql.standby.archive" , pg_archive ) arch_active_props . store ( @archiving_active_template ) ckeys = [ "postgresql.role" , "postgresql.port" , "postgresql.master.host" , "postgresql.master.port" , "postgresql.archive" , "postgresql.pg_standby" , "postgresql.pg_standby.trigger" , "postgresql.pg_archivecleanup" ] cprops = Properties . new ckeys . each do | key | val = @config . getProperty ( key ) cprops . setProperty ( key , val ) end cprops . store ( @pg_wal_properties ) role = @config . getProperty ( "postgresql.role" ) if role == "slave" install_standby ( pg_data , postgresql_conf , pg_archive ) elsif role == "master" if @options . skip_restart log "Skipping PostgreSQL server restart as requested by user." else stop_pg_server ( true ) status_pg_server ( false ) start_pg_server ( false ) sleep ( 10 ) status_pg_server ( true ) exec_cmd ( "touch #{trigger}" ) wait_until_login_works end create_tungsten_db ( true ) exec_cmd2 ( "psql -p#{@config.getProperty("postgresql.port")} -t -c \"CREATE TABLE progress_timestamp (wal varchar(32), segment varchar(12), datetime timestamp)\" #{@tungsten_db};" , false ) else raise UserError , "Unknown role: #{role}" end generate_recovery_conf ( master_host , master_port ) tag_file_write ( @initialized , role ) log ( "Installation completed successfully" ) end
Install infrastructure and update PostgreSQL configuration files
to support replication.
Install infrastructure and update PostgreSQL configuration files to support replication .
# Fetch properties and define variables used for initialization. # Check for usage description: # If we are already initialized, nothing to do.  # Create conf/postgresql-wal directory if not already present. # Generate postgressql.conf include file from template.  # Update include statement in postgresql.conf if there is one to  # point to postgresql.tungsten.conf.  # If we didn't find an include, add it now.  # Generate local archiving_active template in case we are a standby.  # Create initial copy of current properties.  # Determine role and prepare accordingly.  # Ensure the server is started.  # Check PostgreSQL is stopped. # Bide a few seconds; If this PG instance was a slave, it might not be # in continuous recovery mode yet, thus trigger file might get eaten. # TODO: wait for SQLSTATE=57P03 (eg. develop a `./monitorctl checkdb`).  # Check PostgreSQL is started. # End recovery (needed if installing on previously a standby). # Note the happy outcome.  