cluster 0.5.38 → 0.5.40

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,7 +12,7 @@ class Cluster
12
12
  class Version < Net::SSH::Version
13
13
  MAJOR = 0
14
14
  MINOR = 5
15
- TINY = 38
15
+ TINY = 40
16
16
 
17
17
  # The current version, as a Version instance
18
18
  CURRENT = new(MAJOR, MINOR, TINY)
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 5
8
- - 38
9
- version: 0.5.38
8
+ - 40
9
+ version: 0.5.40
10
10
  platform: ruby
11
11
  authors:
12
12
  - Simon de Boer
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-02-28 00:00:00 -05:00
17
+ date: 2011-04-28 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -143,7 +143,6 @@ email:
143
143
  executables:
144
144
  - cluster
145
145
  - periodic.sh
146
- - ec2-consistent-snapshot
147
146
  extensions: []
148
147
 
149
148
  extra_rdoc_files: []
@@ -162,7 +161,6 @@ files:
162
161
  - lib/ext/array.rb
163
162
  - lib/ext/cluster_extensions.rb
164
163
  - bin/cluster
165
- - bin/ec2-consistent-snapshot
166
164
  - bin/periodic.sh
167
165
  - Rakefile
168
166
  - VERSION
@@ -1,676 +0,0 @@
1
- #!/usr/bin/perl
2
- #
3
- # Copyright (C) 2008-2009 Eric Hammond
4
- #
5
- use strict;
6
- use warnings;
7
- (our $Prog) = ($0 =~ m%([^/]+)$%);
8
- use Getopt::Long;
9
- use Pod::Usage;
10
- use File::Slurp;
11
- use Time::HiRes qw(ualarm usleep);
12
- use Net::Amazon::EC2 0.11;
13
- use POSIX ':signal_h';
14
- my $SIGALRM = 14;
15
-
16
- #---- OPTIONS ----
17
-
18
- my $Help = 0;
19
- my $Debug = 0;
20
- my $Quiet = 0;
21
- my $Noaction = 0;
22
-
23
- my $aws_access_key_id = $ENV{AWS_ACCESS_KEY_ID};
24
- my $aws_secret_access_key = $ENV{AWS_SECRET_ACCESS_KEY};
25
- my $aws_access_key_id_file = $ENV{AWS_ACCESS_KEY_ID};
26
- my $aws_secret_access_key_file = $ENV{AWS_SECRET_ACCESS_KEY};
27
- my $region = undef;
28
- my $description = $Prog;
29
- my $xfs_filesystem = undef;
30
- my $mysql = 0;
31
- my $mysql_defaults_file = undef;
32
- my $mysql_master_status_file = undef;
33
- my $mysql_username = undef;
34
- my $mysql_password = undef;
35
- my $mysql_host = undef;
36
- my $mysql_stop = 0;
37
- my $snapshot_timeout = 10.0; # seconds
38
- my $lock_timeout = 0.5; # seconds
39
- my $lock_tries = 60;
40
- my $lock_sleep = 5.0; # seconds
41
-
42
- Getopt::Long::config('no_ignore_case');
43
- GetOptions(
44
- 'help|?' => \$Help,
45
- 'debug' => \$Debug,
46
- 'quiet' => \$Quiet,
47
- 'noaction' => \$Noaction,
48
-
49
- 'aws-access-key-id=s' => \$aws_access_key_id,
50
- 'aws-secret-access-key=s' => \$aws_secret_access_key,
51
- 'aws-access-key-id-file=s' => \$aws_access_key_id_file,
52
- 'aws-secret-access-key-file=s' => \$aws_secret_access_key_file,
53
- 'region=s' => \$region,
54
- 'description=s' => \$description,
55
- 'xfs-filesystem=s' => \$xfs_filesystem,
56
- 'mysql' => \$mysql,
57
- 'mysql-defaults-file=s' => \$mysql_defaults_file,
58
- 'mysql-master-status-file=s' => \$mysql_master_status_file,
59
- 'mysql-username=s' => \$mysql_username,
60
- 'mysql-password=s' => \$mysql_password,
61
- 'mysql-host=s' => \$mysql_host,
62
- 'mysql-stop' => \$mysql_stop,
63
- 'snapshot-timeout=s' => \$snapshot_timeout,
64
- 'lock-timeout=s' => \$lock_timeout,
65
- 'lock-tries=s' => \$lock_tries,
66
- 'lock-sleep=s' => \$lock_sleep,
67
- ) or pod2usage(2);
68
-
69
- pod2usage(1) if $Help;
70
-
71
- my @volume_ids = @ARGV;
72
- pod2usage(2) unless scalar @volume_ids;
73
-
74
- #---- MAIN ----
75
-
76
- ($aws_access_key_id, $aws_secret_access_key) = determine_access_keys(
77
- $aws_access_key_id, $aws_secret_access_key,
78
- $aws_access_key_id_file, $aws_secret_access_key_file,
79
- );
80
- die "$Prog: ERROR: Can't find AWS access key or secret access key"
81
- unless $aws_access_key_id and $aws_secret_access_key;
82
-
83
- my $mysql_stopped = undef;
84
- my $mysql_dbh = undef;
85
- if ( $mysql_stop ) {
86
- $mysql_stopped = mysql_stop();
87
- } elsif ( $mysql ) {
88
- $mysql_dbh = mysql_connect($mysql_host, $mysql_username, $mysql_password);
89
- mysql_lock($mysql_dbh);
90
- }
91
-
92
- # sync may help flush changed blocks, increasing the consistency on
93
- # non-XFS file systems, and reducing the time the freeze locks changes
94
- # out on XFS file systems.
95
- run_command(['sync']);
96
-
97
- xfs_freeze($xfs_filesystem) if $xfs_filesystem;
98
-
99
- ebs_snapshot(\@volume_ids, $region, $description);
100
-
101
- exit 0;
102
-
103
- END {
104
- xfs_thaw($xfs_filesystem) if $xfs_filesystem;
105
-
106
- if ( defined($mysql_master_status_file) ) {
107
- $Debug and warn "$Prog: ", scalar localtime,
108
- ": removing master info file: $mysql_master_status_file\n";
109
- if ( not $Noaction ) {
110
- unlink $mysql_master_status_file
111
- or die "$Prog: Couldn't remove file: $mysql_master_status_file: $!\n";
112
- }
113
- }
114
-
115
- if ( $mysql_stopped ) {
116
- mysql_start();
117
- } elsif ( $mysql_dbh ) {
118
- mysql_unlock($mysql_dbh);
119
- $Debug and warn "$Prog: ", scalar localtime, ": MySQL disconnect\n";
120
- $mysql_dbh->disconnect;
121
- }
122
-
123
- $Debug and warn "$Prog: ", scalar localtime, ": done\n";
124
- }
125
-
126
- #---- METHODS ----
127
-
128
- sub ebs_snapshot {
129
- my ($volume_ids, $region, $description) = @_;
130
-
131
- $Debug and warn "$Prog: ", scalar localtime, ": create EC2 object\n";
132
-
133
- # EC2 API object
134
- my $ec2 = Net::Amazon::EC2->new(
135
- AWSAccessKeyId => $aws_access_key_id,
136
- SecretAccessKey => $aws_secret_access_key,
137
- ($region ? (base_url => "http://$region.ec2.amazonaws.com") : ()),
138
- # ($Debug ? (debug => 1) : ()),
139
- );
140
-
141
- VOLUME:
142
- for my $volume_id ( @$volume_ids ) {
143
- # Snapshot
144
- $Debug and
145
- warn "$Prog: ", scalar localtime, ": ec2-create-snapshot $volume_id\n";
146
- if ( $Noaction ) {
147
- warn "snapshot SKIPPED (--noaction)\n";
148
- next VOLUME;
149
- }
150
-
151
- my $snapshot;
152
- eval {
153
- ualarm($snapshot_timeout * 1_000_000);
154
- $snapshot = $ec2->create_snapshot(
155
- VolumeId => $volume_id,
156
- Description => $description,
157
- );
158
- ualarm(0);
159
- };
160
- ualarm(0);
161
- if ( $@ ){
162
- warn "$Prog: ERROR: create_snapshot: $@";
163
- return undef;
164
- }
165
-
166
- my $snapshot_id;
167
- if ( not defined $snapshot ) {
168
- warn "$Prog: ERROR: create_snapshot returned undef\n";
169
- } elsif ( not ref $snapshot ) {
170
- warn "$Prog: ERROR: create_snapshot returned '$snapshot'\n";
171
- } elsif ( $snapshot->can('snapshot_id') ) {
172
- $snapshot_id = $snapshot->snapshot_id;
173
- $Quiet or print "$snapshot_id\n";
174
- } else {
175
- for my $error ( @{$snapshot->errors} ) {
176
- warn "$Prog: ERROR: ".$error->message."\n";
177
- }
178
- }
179
- }
180
- }
181
-
182
- sub mysql_connect {
183
- my ($mysql_host, $mysql_username, $mysql_password) = @_;
184
-
185
- require DBI;
186
- DBI->import;
187
-
188
- if ( defined($mysql_defaults_file) )
189
- {
190
- ($mysql_host, $mysql_username, $mysql_password) = read_mydefaultsfile(
191
- $mysql_defaults_file,
192
- );
193
- } else {
194
- ($mysql_host, $mysql_username, $mysql_password) = read_mycnf(
195
- $mysql_host, $mysql_username, $mysql_password,
196
- );
197
- }
198
-
199
- $mysql_host ||= 'localhost';
200
-
201
- $Debug and warn "$Prog: ", scalar localtime,
202
- ": MySQL connect as $mysql_username\n";
203
-
204
- my $mysql_dbh = DBI->connect("DBI:mysql:;host=$mysql_host",
205
- $mysql_username, $mysql_password)
206
- or die "$Prog: ERROR: Unable to connect to MySQL"
207
- . " on $mysql_host as $mysql_username";
208
-
209
- return $mysql_dbh;
210
- }
211
-
212
- sub mysql_lock {
213
- my ($mysql_dbh) = @_;
214
-
215
- # Don't pass FLUSH TABLES statements on to replication slaves
216
- # as this can interfere with long-running queries on the slaves.
217
- $mysql_dbh->do(q{ SET SQL_LOG_BIN=0 }) unless $Noaction;
218
-
219
- # Try a flush first without locking so the later flush with lock
220
- # goes faster. This may not be needed as it seems to interfere with
221
- # some statements anyway.
222
- sql_timeout_retry(
223
- q{ FLUSH LOCAL TABLES },
224
- "MySQL flush",
225
- $lock_timeout,
226
- $lock_tries,
227
- $lock_sleep,
228
- );
229
-
230
- # Get a lock on the entire database
231
- sql_timeout_retry(
232
- q{ FLUSH LOCAL TABLES WITH READ LOCK },
233
- "MySQL flush & lock",
234
- $lock_timeout,
235
- $lock_tries,
236
- $lock_sleep,
237
- );
238
-
239
- my ($mysql_logfile, $mysql_position,
240
- $mysql_binlog_do_db, $mysql_binlog_ignore_db);
241
- if ( not $Noaction ) {
242
- # This might be a slave database already
243
- my $slave_status = $mysql_dbh->selectrow_hashref(q{ SHOW SLAVE STATUS });
244
- $mysql_logfile = $slave_status->{Master_Log_File};
245
- $mysql_position = $slave_status->{Read_Master_Log_Pos};
246
- $mysql_binlog_do_db = $slave_status->{Replicate_Do_DB};
247
- $mysql_binlog_ignore_db = $slave_status->{Replicate_Ignore_DB};
248
-
249
- # or this might be the master
250
- ($mysql_logfile, $mysql_position,
251
- $mysql_binlog_do_db, $mysql_binlog_ignore_db) =
252
- $mysql_dbh->selectrow_array(q{ SHOW MASTER STATUS })
253
- unless $mysql_logfile;
254
- }
255
-
256
- $mysql_dbh->do(q{ SET SQL_LOG_BIN=1 }) unless $Noaction;
257
-
258
- print "$Prog: master_log_file=\"$mysql_logfile\",",
259
- " master_log_pos=$mysql_position\n"
260
- if $mysql_logfile and not $Quiet;
261
-
262
- if ( defined($mysql_master_status_file) && $mysql_logfile ) {
263
- $Debug and warn "$Prog: ", scalar localtime,
264
- ": writing MASTER STATUS to $mysql_master_status_file\n";
265
- if ( not $Noaction ) {
266
- open(MYSQLMASTERSTATUS,"> $mysql_master_status_file") or
267
- die "$Prog: Unable to open for write: $mysql_master_status_file: $!\n";
268
- print MYSQLMASTERSTATUS <<"EOM";
269
- master_log_file="$mysql_logfile"
270
- master_log_pos="$mysql_position"
271
- master_binlog_do_db="$mysql_binlog_do_db"
272
- master_binlog_ignore_db="$mysql_binlog_ignore_db"
273
- EOM
274
- close(MYSQLMASTERSTATUS);
275
- }
276
- }
277
-
278
- return ($mysql_logfile, $mysql_position);
279
- }
280
-
281
- sub mysql_unlock {
282
- my ($mysql_dbh) = @_;
283
-
284
- $Debug and warn "$Prog: ", scalar localtime, ": MySQL unlock\n";
285
- $mysql_dbh->do(q{ UNLOCK TABLES }) unless $Noaction;
286
-
287
- }
288
-
289
- sub mysql_stop {
290
- $Debug and warn "$Prog: ", scalar localtime, ": MySQL stop\n";
291
-
292
- my $result = system('/usr/bin/mysqladmin', 'shutdown');
293
-
294
- if ( $result != 0 ) {
295
- die "$Prog: Unable to stop mysqld: $? $!";
296
- }
297
-
298
- return 1;
299
- }
300
-
301
- sub mysql_start {
302
- $Debug and warn "$Prog: ", scalar localtime, ": MySQL start\n";
303
-
304
- my $result = system('/etc/init.d/mysql', 'start');
305
-
306
- if ( $result != 0 ) {
307
- warn "$Prog: Unable to start mysqld: $? $!";
308
- }
309
- }
310
-
311
- # See also:
312
- #http://search.cpan.org/dist/DBI/DBI.pm#Signal_Handling_and_Canceling_Operations
313
- sub sql_timeout_retry {
314
- my ($sql, $description, $lock_timeout, $lock_tries, $lock_sleep) = @_;
315
-
316
- my $action = POSIX::SigAction->new(
317
- sub { die "timeout" },
318
- POSIX::SigSet->new( SIGALRM ),
319
- );
320
- my $oldaction = POSIX::SigAction->new();
321
- sigaction($SIGALRM, $action, $oldaction);
322
- LOCK:
323
- while ( $lock_tries -- ) {
324
- $Debug and warn "$Prog: ", scalar localtime, ": $description\n";
325
- eval {
326
- ualarm($lock_timeout * 1_000_000);
327
- $mysql_dbh->do($sql) unless $Noaction;
328
- ualarm(0);
329
- };
330
- ualarm(0);
331
- last LOCK unless $@ =~ /timeout/;
332
-
333
- } continue {
334
- $Quiet or warn "$Prog: MySQL timeout at $lock_timeout sec\n";
335
- $Debug and warn "$Prog: Trying again in $lock_sleep seconds\n";
336
- usleep($lock_sleep * 1_000_000);
337
- #TBD: May need to reopen $mysql_dbh here as the handle may not be clean.
338
- }
339
- sigaction($SIGALRM, $oldaction);
340
- die "$Prog: ERROR: MySQL failure: $@" if $@;
341
- }
342
-
343
- sub xfs_freeze {
344
- my ($xfs_filesystem) = @_;
345
-
346
- run_command(['xfs_freeze', '-f', $xfs_filesystem]);
347
- }
348
-
349
- sub xfs_thaw {
350
- my ($xfs_filesystem) = @_;
351
-
352
- run_command(['xfs_freeze', '-u', $xfs_filesystem]);
353
- }
354
-
355
- # mysql defaults-file
356
- sub read_mydefaultsfile {
357
- my ($mysql_defaults_file) = @_;
358
-
359
- open(MYCNF, $mysql_defaults_file)
360
- or die "$Prog: ERROR: Couldn't open defaults-file $mysql_defaults_file\n";
361
- while ( defined (my $line = <MYCNF>) ) {
362
- $mysql_host = $1 if $line =~ m%^\s*host\s*=\s*"?(\S+?)"?$%
363
- and not defined $mysql_host;
364
- $mysql_username = $1 if $line =~ m%^\s*user\s*=\s*"?(\S+?)"?$%
365
- and not defined $mysql_username;
366
- $mysql_password = $1 if $line =~ m%^\s*password\s*=\s*"?(\S+?)"?$%
367
- and not defined $mysql_password;
368
- }
369
- close(MYCNF);
370
-
371
- return ($mysql_host, $mysql_username, $mysql_password);
372
- }
373
-
374
- # Look for the MySQL username/password in $HOME/.my.cnf
375
- sub read_mycnf {
376
- my ($mysql_host, $mysql_username, $mysql_password) = @_;
377
-
378
- open(MYCNF, "$ENV{HOME}/.my.cnf")
379
- or return($mysql_host, $mysql_username, $mysql_password);
380
- while ( defined (my $line = <MYCNF>) ) {
381
- $mysql_host = $1 if $line =~ m%^\s*host\s*=\s*"?(\S+?)"?$%
382
- and not defined $mysql_host;
383
- $mysql_username = $1 if $line =~ m%^\s*user\s*=\s*"?(\S+?)"?$%
384
- and not defined $mysql_username;
385
- $mysql_password = $1 if $line =~ m%^\s*password\s*=\s*"?(\S+?)"?$%
386
- and not defined $mysql_password;
387
- }
388
- close(MYCNF);
389
-
390
- return ($mysql_host, $mysql_username, $mysql_password);
391
- }
392
-
393
-
394
- # Figure out which AWS access keys to use
395
- sub determine_access_keys {
396
- my ($aws_access_key_id, $aws_secret_access_key,
397
- $aws_access_key_id_file, $aws_secret_access_key_file,
398
- ) = @_;
399
-
400
- # 1. --aws-access-key-id and --aws-secret-access-key
401
- return ($aws_access_key_id, $aws_secret_access_key)
402
- if $aws_access_key_id;
403
-
404
- # 2. --aws-access-key-id-file and --aws-secret-access-key-file
405
- if ( $aws_access_key_id_file ) {
406
- die "$Prog: Please provide both --aws-access-key-id-file and --aws-secret-access-key-file"
407
- unless $aws_secret_access_key_file;
408
- $aws_access_key_id = File::Slurp::read_file($aws_access_key_id_file);
409
- $aws_secret_access_key= File::Slurp::read_file($aws_secret_access_key_file);
410
- chomp($aws_access_key_id);
411
- chomp($aws_secret_access_key);
412
- return ($aws_access_key_id, $aws_secret_access_key);
413
- }
414
-
415
- # 3. $HOME/.awssecret
416
- return read_awssecret();
417
- }
418
-
419
-
420
- # Look for the access keys in ~/.awssecret
421
- sub read_awssecret {
422
- my $filename = "$ENV{HOME}/.awssecret";
423
- my ($aws_access_key_id, $aws_secret_access_key);
424
- eval {
425
- ($aws_access_key_id, $aws_secret_access_key) =
426
- File::Slurp::read_file($filename);
427
- chomp $aws_access_key_id;
428
- chomp $aws_secret_access_key;
429
- };
430
- return ($aws_access_key_id, $aws_secret_access_key);
431
- }
432
-
433
- # Run a system command, warning if there are problems.
434
- # Pass in reference to an array of command args.
435
- sub run_command {
436
- my ($command) = @_;
437
-
438
- $Debug and warn "$Prog: ", scalar localtime, ": @$command\n";
439
- return if $Noaction;
440
- eval {
441
- system(@$command) and die "failed($?)\n";
442
- };
443
- warn "$Prog: ERROR: @$command: $@" if $@;
444
- }
445
-
446
-
447
- =head1 NAME
448
-
449
- ec2-consistent-snapshot - Create snapshot, locking db and freezing file system
450
-
451
- =head1 SYNOPSIS
452
-
453
- ec2-consistent-snapshot [opts] VOLUMEID...
454
-
455
- =head1 OPTIONS
456
-
457
- -h --help Print help and exit.
458
- -d --debug Debug mode.
459
- -q --quiet Quiet mode.
460
- -n --noaction Don't do it. Just say what you would have done.
461
-
462
- --aws-access-key-id KEY
463
- --aws-secret-access-key SECRET
464
-
465
- Amazon AWS access key and secret access key. Defaults to
466
- environment variables or .awssecret file contents described below.
467
-
468
- --aws-access-key-id-file KEYFILE
469
- --aws-secret-access-key-file SECRETFILE
470
-
471
- Files containing Amazon AWS access key and secret access key.
472
- Defaults to environment variables or .awssecret file contents
473
- described below.
474
-
475
- --region REGION
476
-
477
- Specify a different region like "eu-west-1". Defaults to
478
- "us-east-1".
479
-
480
- --description DESCRIPTION
481
-
482
- Specify a description string for the EBS snapshot. Defaults to the
483
- name of the program.
484
-
485
- --xfs-filesystem MOUNTPOINT
486
-
487
- Indicates that the volume contains an XFS file system at the specified
488
- mount point, which will be flushed and frozen during the snapshot.
489
-
490
- --mysql
491
-
492
- Indicates that the volume contains data files for a running MySQL
493
- database, which will be flushed and locked during the snapshot.
494
-
495
- --mysql-defaults-file FILE
496
-
497
- MySQL defaults file, containing host, username and password, this
498
- option will ignore the --mysql-host, --mysql-username,
499
- --mysql-password parameters
500
-
501
- --mysql-host HOST
502
- --mysql-username USER
503
- --mysql-password PASS
504
-
505
- MySQL host, username, and password used to flush logs and lock
506
- tables. User must have appropriate permissions. Defaults to
507
- $HOME/.my.cnf file contents.
508
-
509
- --mysql-master-status-file FILE
510
-
511
- Store the MASTER STATUS output in a file on the snapshot. It will
512
- be removed after the EBS snapshot is taken. This option will be
513
- ignored with --mysql-stop
514
-
515
- --mysql-stop
516
-
517
- Indicates that the volume contains data files for a running MySQL
518
- database. The database is shutdown before the snapshot is initiated
519
- and restarted afterwards. [EXPERIMENTAL]
520
-
521
- --snapshot-timeout SECONDS
522
-
523
- How many seconds to wait for the snapshot-create to return.
524
- Defaults to 10.0
525
-
526
- --lock-timeout SECONDS
527
-
528
- How many seconds to wait for a database lock. Defaults to 0.5.
529
- Making this too large can force other processes to wait while this
530
- process waits for a lock. Better to make it small and try lots of
531
- times.
532
-
533
- --lock-tries COUNT
534
-
535
- How many times to try to get a database lock before failing.
536
- Defaults to 60.
537
-
538
- --lock-sleep SECONDS
539
-
540
- How many seconds to sleep between database lock tries. Defaults
541
- to 5.0.
542
-
543
- =head1 ARGUMENTS
544
-
545
- VOLUMEID EBS volume id(s) for which to create a snapshot.
546
-
547
- =head1 DESCRIPTION
548
-
549
- This program creates an EBS snapshot for an Amazon EC2 EBS volume. To
550
- help ensure consistent data in the snapshot, it tries to flush and
551
- freeze the file system first as well as flushing and locking the
552
- database, if applicable.
553
-
554
- There are a number of timeouts to reduce the risk of interfering with
555
- the normal database operation while improving the chances of getting a
556
- consistent snapshot.
557
-
558
- If you have multiple EBS volumes in a RAID configuration, you can
559
- specify all of the volume ids on the command line and it will create
560
- snapshots for each while the filesystem and database are locked. Note
561
- that it is your responsibility to keep track of the resulting snapshot
562
- ids and to figure out how to put these back together when you need to
563
- restore the RAID setup.
564
-
565
- If you have multiple EBS volumes which are hosting different file
566
- systems, it might be better to simply run the command once for each
567
- volume id.
568
-
569
- =head1 EXAMPLES
570
-
571
- Snapshot a volume which has a MySQL database on XFS under /vol:
572
-
573
- ec2-consistent-snapshot --mysql --xfs-filesystem /vol vol-VOLUMEID
574
-
575
- Snapshot a volume with XFS on /var/local but no MySQL database:
576
-
577
- ec2-consistent-snapshot --xfs-filesystem /var/local vol-VOLUMEID
578
-
579
- Snapshot four European volumes in a RAID configuration with MySQL on
580
- XFS, saving the snapshots with a description marking the current time:
581
-
582
- ec2-consistent-snapshot \
583
- --mysql \
584
- --xfs-filesystem /vol \
585
- --region eu-west-1 \
586
- --description "RAID snapshot $(date +'%Y-%m-%d %H:%M:%S')" \
587
- vol-VOL1 vol-VOL2 vol-VOL3 vol-VOL4
588
-
589
- =head1 ENVIRONMENT
590
-
591
- $AWS_ACCESS_KEY_ID
592
-
593
- Default value for access key
594
- Can be overridden by command line options.
595
-
596
- $AWS_SECRET_ACCESS_KEY
597
-
598
- Default value for secret access key
599
- Can be overridden by command line options.
600
-
601
- =head1 FILES
602
-
603
- $HOME/.my.cnf
604
-
605
- Default values for MySQL user and password are sought here in the
606
- standard format.
607
-
608
- $HOME/.awssecret
609
-
610
- Default values for access key and secret access keys are sought
611
- here. Can be overridden by environment variables and command line
612
- options.
613
-
614
- =head1 INSTALLATION
615
-
616
- On most Ubuntu releases, the B<ec2-consistent-snapshot> package can be
617
- installed directly from the Alestic.com PPA using the following
618
- commands:
619
-
620
- code=$(lsb_release -cs)
621
- echo "deb http://ppa.launchpad.net/alestic/ppa/ubuntu $code main"|
622
- sudo tee /etc/apt/sources.list.d/alestic-ppa.list
623
- sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BE09C571
624
- sudo apt-get update
625
- sudo apt-get install -y ec2-consistent-snapshot
626
-
627
- This program also requires the installation of the Net::Amazon::EC2
628
- Perl package from CPAN. On an Ubuntu system this can be accomplished
629
- with the following commands.:
630
-
631
- sudo PERL_MM_USE_DEFAULT=1 cpan Net::Amazon::EC2
632
-
633
- On Ubuntu 8.04 Hardy, use the following commands instead:
634
-
635
- sudo apt-get install -y build-essential
636
- sudo cpan Net::Amazon::EC2
637
-
638
- The default values can be accepted for most of the prompts, though it
639
- is necessary to select a CPAN mirror on Hardy.
640
-
641
- =head1 SEE ALSO
642
-
643
- Amazon EC2
644
- Amazon EC2 EBS (Elastic Block Store)
645
- ec2-create-snapshot
646
-
647
- =head1 CAVEATS
648
-
649
- This program currently supports the MySQL database and the XFS file
650
- system. Patches are welcomed for other databases and file systems.
651
-
652
- =head1 BUGS
653
-
654
- Please report bugs at https://bugs.launchpad.net/ec2-consistent-snapshot
655
-
656
- =head1 CREDITS
657
-
658
- Thanks to the following for performing tests on early versions,
659
- providing feedback, and patches:
660
-
661
- David Erickson
662
- Steve Caldwell
663
- Gryp
664
-
665
- =head1 AUTHOR
666
-
667
- Eric Hammond <ehammond@thinksome.com>
668
-
669
- =head1 LICENSE
670
-
671
- Copyright (C) 2009 Eric Hammond <ehammond@thinksome.com>
672
-
673
- Licensed under the Apache License, Version 2.0, see
674
- http://www.apache.org/licenses/LICENSE-2.0
675
-
676
- =cut