55from fabric .api import hide , settings , local
66from math import floor
77from multiprocessing import cpu_count
8- from signal import signal , SIGINT , SIG_IGN
98from time import sleep
109
1110from mongodb_consistent_backup .Common import MongoUri
1211from mongodb_consistent_backup .Errors import Error , OperationError
1312from mongodb_consistent_backup .Oplog import OplogState
13+ from mongodb_consistent_backup .Pipeline import Task
1414
1515from MongodumpThread import MongodumpThread
1616
1717
18- class Mongodump :
19- def __init__ (self , manager , config , timer , base_dir , backup_dir , ** kwargs ):
20- self .manager = manager
21- self .config = config
22- self .timer = timer
23- self .base_dir = base_dir
24- self .backup_dir = backup_dir
25- self .binary = self .config .backup .mongodump .binary
26- self .user = self .config .user
27- self .password = self .config .password
28- self .authdb = self .config .authdb
29- self .verbose = self .config .verbose
18+ class Mongodump (Task ):
19+ def __init__ (self , manager , config , timer , base_dir , backup_dir , replsets , sharding = None ):
20+ super (Mongodump , self ).__init__ (self .__class__ .__name__ , manager , config , timer , base_dir , backup_dir )
21+ self .compression_method = self .config .backup .mongodump .compression
22+ self .binary = self .config .backup .mongodump .binary
23+ self .user = self .config .user
24+ self .password = self .config .password
25+ self .authdb = self .config .authdb
26+ self .replsets = replsets
27+ self .sharding = sharding
3028
31- try :
32- self .replsets = kwargs ['replsets' ]
33- except KeyError :
34- raise Error ("'replsets' kwargs required!" )
35-
36- self .sharding = None
37- if 'sharding' in kwargs :
38- self .sharding = kwargs ['sharding' ]
39-
40- signal (SIGINT , SIG_IGN )
41- signal (SIGINT , self .close )
42-
43- self .completed = False
44- self .timer_name = self .__class__ .__name__
45- self .threads_per_dump_max = 16
46- self .config_replset = False
47- self .cpu_count = cpu_count ()
48- self .threads = []
49- self .states = {}
50- self ._summary = {}
51- self ._threads_per_dump = None
29+ self .threads_max = 16
30+ self .config_replset = False
31+ self .dump_threads = []
32+ self .states = {}
33+ self ._summary = {}
5234
5335 with hide ('running' , 'warnings' ), settings (warn_only = True ):
5436 self .version = local ("%s --version|awk 'NR >1 {exit}; /version/{print $NF}'" % self .binary , capture = True )
55- self .do_gzip = self .can_gzip ()
5637
57- if not self .do_gzip and self .config .backup .mongodump .compression == 'gzip' :
38+ if self .can_gzip ():
39+ if self .compression () == 'none' :
40+ self .compression ('gzip' )
41+ elif self .compression () == 'gzip' :
5842 logging .warning ("mongodump gzip compression requested on binary that does not support gzip!" )
5943
60- if not isinstance (self .replsets , dict ):
61- raise Error ("Field 'replsets' must be a dictionary of mongodb_consistent_backup.Replication.Replset classes!" )
62-
6344 def can_gzip (self ):
6445 if os .path .isfile (self .binary ) and os .access (self .binary , os .X_OK ):
46+ logging .debug ("Mongodump binary supports gzip" )
6547 if tuple ("3.2.0" .split ("." )) <= tuple (self .version .split ("." )):
6648 return True
6749 return False
6850 else :
6951 logging .fatal ("Cannot find or execute the mongodump binary file %s!" % self .binary )
7052 sys .exit (1 )
7153
72- def is_compressed (self ):
73- return self .can_gzip ()
74-
7554 def summary (self ):
7655 return self ._summary
7756
@@ -85,14 +64,14 @@ def get_summaries(self):
8564
8665 def wait (self ):
8766 completed = 0
88- start_threads = len (self .threads )
67+ start_threads = len (self .dump_threads )
8968 # wait for all threads to finish
90- while len (self .threads ) > 0 :
91- for thread in self .threads :
69+ while len (self .dump_threads ) > 0 :
70+ for thread in self .dump_threads :
9271 if not thread .is_alive ():
9372 if thread .exitcode == 0 :
9473 completed += 1
95- self .threads .remove (thread )
74+ self .dump_threads .remove (thread )
9675 sleep (0.5 )
9776
9877 # sleep for 3 sec to fix logging order before gathering summaries
@@ -106,19 +85,19 @@ def wait(self):
10685 else :
10786 raise OperationError ("Not all mongodump threads completed successfully!" )
10887
109- def threads_per_dump (self , threads = None ):
88+ def threads (self , threads = None ):
11089 if threads :
111- self ._threads_per_dump = int (threads )
112- elif not self ._threads_per_dump :
90+ self .thread_count = int (threads )
91+ elif not self .thread_count :
11392 if tuple (self .version .split ("." )) >= tuple ("3.2.0" .split ("." )):
114- self ._threads_per_dump = 1
93+ self .thread_count = 1
11594 if self .cpu_count > len (self .replsets ):
116- self ._threads_per_dump = int (floor (self .cpu_count / len (self .replsets )))
117- if self ._threads_per_dump > self .threads_per_dump_max :
118- self ._threads_per_dump = self .threads_per_dump_max
95+ self .thread_count = int (floor (self .cpu_count / len (self .replsets )))
96+ if self .thread_count > self .threads_max :
97+ self .thread_count = self .threads_max
11998 else :
12099 logging .warn ("Threading unsupported by mongodump version %s. Use mongodump 3.2.0 or greater to enable per-dump threading." % self .version )
121- return self ._threads_per_dump
100+ return self .thread_count
122101
123102 def run (self ):
124103 self .timer .start (self .timer_name )
@@ -137,18 +116,18 @@ def run(self):
137116 self .authdb ,
138117 self .backup_dir ,
139118 self .binary ,
140- self .threads_per_dump (),
119+ self .threads (),
141120 self .do_gzip ,
142121 self .verbose
143122 )
144- self .threads .append (thread )
123+ self .dump_threads .append (thread )
145124
146- if not len (self .threads ) > 0 :
125+ if not len (self .dump_threads ) > 0 :
147126 raise OperationError ('No backup threads started!' )
148127
149128 logging .info (
150- "Starting backups using mongodump %s (options: gzip =%s, threads_per_dump=%i)" % (self .version , str ( self .do_gzip ), self .threads_per_dump ()))
151- for thread in self .threads :
129+ "Starting backups using mongodump %s (options: compression =%s, threads_per_dump=%i)" % (self .version , self .compression ( ), self .threads ()))
130+ for thread in self .dump_threads :
152131 thread .start ()
153132 self .wait ()
154133
@@ -159,7 +138,7 @@ def run(self):
159138 logging .info ("Using non-replset backup method for config server mongodump" )
160139 mongo_uri = MongoUri (config_server ['host' ], 27019 , 'configsvr' )
161140 self .states ['configsvr' ] = OplogState (self .manager , mongo_uri )
162- self .threads = [MongodumpThread (
141+ self .dump_threads = [MongodumpThread (
163142 self .states ['configsvr' ],
164143 mongo_uri ,
165144 self .timer ,
@@ -168,20 +147,20 @@ def run(self):
168147 self .authdb ,
169148 self .backup_dir ,
170149 self .binary ,
171- self .threads_per_dump (),
150+ self .threads (),
172151 self .do_gzip ,
173152 self .verbose
174153 )]
175- self .threads [0 ].start ()
154+ self .dump_threads [0 ].start ()
176155 self .wait ()
177156
178157 self .completed = True
179158 return self ._summary
180159
181160 def close (self ):
182161 logging .info ("Stopping all mongodump threads" )
183- if len (self .threads ) > 0 :
184- for thread in self .threads :
162+ if len (self .dump_threads ) > 0 :
163+ for thread in self .dump_threads :
185164 thread .terminate ()
186165 try :
187166 self .timer .stop (self .timer_name )
0 commit comments