~stub/charms/precise/postgresql/bug-1205286

« back to all changes in this revision

Viewing changes to hooks/hooks.py

WIP

Show diffs side-by-side

added added

removed removed

Lines of Context:
1621
1621
            return None
1622
1622
 
1623
1623
        log("Election in progress")
1624
 
        winner = hookenv.local_unit()
1625
 
        winning_offset = local_state['wal_received_offset']
 
1624
        winner = None
 
1625
        winning_offset = -1
1626
1626
        for relid in hookenv.relation_ids('replication'):
 
1627
            candidates = set(hookenv.related_units(relid))
 
1628
            candidates.add(hookenv.local_unit())
 
1629
            candidates.discard(former_master)
1627
1630
            # Sort the unit lists so we get consistent results in a tie
1628
1631
            # and lowest unit number wins.
1629
 
            for unit in unit_sorted(hookenv.related_units(relid)):
1630
 
                if unit == former_master:
1631
 
                    continue
 
1632
            for unit in unit_sorted(candidates):
1632
1633
                relation = hookenv.relation_get(unit=unit, rid=relid)
1633
1634
                if int(relation['wal_received_offset']) > winning_offset:
1634
1635
                    winner = unit
1676
1677
 
1677
1678
    elif master == hookenv.local_unit():
1678
1679
        if local_state['state'] != 'master':
1679
 
            log("I have been elected master")
 
1680
            log("I have elected myself master")
1680
1681
            promote_database()
1681
1682
            if 'following' in local_state:
1682
1683
                del local_state['following']
1706
1707
        master_ip = hookenv.relation_get('private-address', master)
1707
1708
        wait_for_db(db='postgres', user='juju_replication', host=master_ip)
1708
1709
 
1709
 
        clone(master, master_ip)
 
1710
        clone_database(master, master_ip)
1710
1711
 
1711
1712
        local_state['state'] = 'hot standby'
1712
1713
        local_state['following'] = master
 
1714
        if 'wal_received_offset' in local_state:
 
1715
            del local_state['wal_received_offset']
1713
1716
 
1714
1717
    elif local_state['following'] == master:
1715
1718
        log("I am a hot standby already following {}".format(master))
1720
1723
            'replication_password', master)
1721
1724
        generate_pgpass()
1722
1725
        follow_database(master)
1723
 
        run_sql_as_postgres("SELECT pg_xlog_replay_resume()")
 
1726
        if not local_state["paused_at_failover"]:
 
1727
            run_sql_as_postgres("SELECT pg_xlog_replay_resume()")
 
1728
        local_state['state'] = 'hot standby'
1724
1729
        local_state['following'] = master
1725
1730
        del local_state['wal_received_offset']
 
1731
        del local_state['paused_at_failover']
1726
1732
 
1727
1733
    if local_state['state'] == 'hot standby':
1728
1734
        publish_hot_standby_credentials()
1815
1821
        # election, and publish that replay point. By comparing these
1816
1822
        # replay points, the most up to date hot standby can be
1817
1823
        # identified and promoted to the new master.
1818
 
        run_sql_as_postgres("SELECT pg_xlog_replay_pause()")
 
1824
        cur = db_cursor(autocommit=True)
 
1825
        cur.execute(
 
1826
            "SELECT pg_is_xlog_replay_paused()")
 
1827
        already_paused = cur.fetchone()[0]
 
1828
        local_state["paused_at_failover"] = already_paused
 
1829
        if not already_paused:
 
1830
            cur.execute("SELECT pg_xlog_replay_pause()")
1819
1831
        local_state['state'] = 'failover'
1820
1832
        local_state['wal_received_offset'] = postgresql_wal_received_offset()
1821
1833
 
1838
1850
    config_changed(postgresql_config)
1839
1851
 
1840
1852
 
1841
 
def clone(master_unit, master_host):
 
1853
def clone_database(master_unit, master_host):
1842
1854
    postgresql_stop()
1843
1855
    juju_log(MSG_INFO, "Cloning master {}".format(master_unit))
1844
1856