summaryrefslogtreecommitdiff
path: root/python/londiste.py
blob: 916b104f7e4138b132b0e3f03ab7481a7c194b6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#! /usr/bin/env python

"""Londiste launcher.
"""

import sys, os, optparse, skytools

# python 2.3 will try londiste.py first...
import sys, os.path
if os.path.exists(os.path.join(sys.path[0], 'londiste.py')) \
    and not os.path.exists(os.path.join(sys.path[0], 'londiste')):
    del sys.path[0]

from londiste import *

command_usage = """
%prog [options] INI CMD [subcmd args]

commands:
  provider install           installs modules, creates queue
  provider add TBL ...       add table to queue
  provider remove TBL ...    remove table from queue
  provider tables            show all tables linked to queue
  provider seqs              show all sequences on provider

  subscriber install         installs schema
  subscriber add TBL ...     add table to subscriber
  subscriber remove TBL ...  remove table from subscriber
  subscriber tables          list tables subscriber has attached to
  subscriber seqs            list sequences subscriber is interested
  subscriber missing         list tables subscriber has not yet attached to
  subscriber link QUE        create mirror queue
  subscriber unlink          dont mirror queue

  replay                     replay events to subscriber

  switchover                 switch the roles between provider & subscriber
  compare [TBL ...]          compare table contents on both sides
  repair [TBL ...]           repair data on subscriber
  copy                       full copy of table, internal cmd
  subscriber check           compare table structure on both sides
  subscriber fkeys           print out fkey drop/create commands
  subscriber resync TBL ...  do full copy again
  subscriber register        attaches subscriber to queue (also done by replay)
  subscriber unregister      detach subscriber from queue
"""

"""switchover:
goal is to launch a replay with reverse config

- should link be required? (link should guarantee all tables/seqs same?)
- should link auto-add tables for subscriber

1. lock all tables on provider, in order specified by 'nr'
2. wait until old replay is past the point
3. sync seq
4. replace queue triggers on provider with deny triggers
5. replace deny triggers on subscriber with queue triggers
6. sync pgq tick seqs?  change pgq config?

"""

class Londiste(skytools.DBScript):
    def __init__(self, args):
        skytools.DBScript.__init__(self, 'londiste', args)

        if self.options.rewind or self.options.reset:
            self.script = Replicator(args)
            return

        if len(self.args) < 2:
            print "need command"
            sys.exit(1)
        cmd = self.args[1]

        if cmd =="provider":
            script = ProviderSetup(args)
        elif cmd == "subscriber":
            script = SubscriberSetup(args)
        elif cmd == "replay":
            method = self.cf.get('method', 'direct')
            if method == 'direct':
                script = Replicator(args)
            elif method == 'file_write':
                script = FileWrite(args)
            elif method == 'file_write':
                script = FileWrite(args)
            else:
                print "unknown method, quitting"
                sys.exit(1)
        elif cmd == "copy":
            script = CopyTable(args)
        elif cmd == "compare":
            script = Comparator(args)
        elif cmd == "repair":
            script = Repairer(args)
        elif cmd == "upgrade":
            script = UpgradeV2(args)
        else:
            print "Unknown command '%s', use --help for help" % cmd
            sys.exit(1)

        self.script = script

    def start(self):
        self.script.start()

    def init_optparse(self, parser=None):
        p = skytools.DBScript.init_optparse(self, parser)
        p.set_usage(command_usage.strip())

        g = optparse.OptionGroup(p, "expert options")
        g.add_option("--force", action="store_true",
                help = "add: ignore table differences, repair: ignore lag")
        g.add_option("--expect-sync", action="store_true", dest="expect_sync",
                help = "add: no copy needed", default=False)
        g.add_option("--skip-truncate", action="store_true", dest="skip_truncate",
                help = "add: keep old data", default=False)
        g.add_option("--rewind", action="store_true",
                help = "replay: sync queue pos with subscriber")
        g.add_option("--reset", action="store_true",
                help = "replay: forget queue pos on subscriber")
        p.add_option_group(g)

        return p

if __name__ == '__main__':
    script = Londiste(sys.argv[1:])
    script.start()