Advertisement
Guest User

Untitled

a guest
Aug 3rd, 2016
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.72 KB | None | 0 0
  1. #!/usr/bin/perl
  2. #
  3. # A simple rotational wrapper for innobackupex
  4. #
  5. # Version 1.0
  6. #
  7. # By Dean M Rantala - drantala@ena.com / deanrantala@gmail.com
  8. #
  9. # Special credit: a huge thanks goes to Education Networks of America
  10. # for allowing me to develop free software on company dime!
  11. #
  12. # http://www.ena.com
  13. #
  14. #
  15. # <Released under the GPL license>
  16. #
  17. # This program is free software: you can redistribute it and/or modify
  18. # it under the terms of the GNU General Public License as published by
  19. # the Free Software Foundation, either version 3 of the License, or
  20. # (at your option) any later version.
  21. #
  22. # This program is distributed in the hope that it will be useful,
  23. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. # GNU General Public License for more details.
  26. #
  27. # You should have received a copy of the GNU General Public License
  28. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  29. #
  30. use strict;
  31. use File::Path qw(make_path remove_tree);
  32. #
  33. #
  34.  
  35. # -------------
  36. # CONFIGURATION
  37. # -------------
  38.  
  39. # How many full backups should always be kept?
  40. my $full_backup_retention = 7;
  41.  
  42. # How many incremental backups should we perform
  43. # between each full backup? (0=disable incremental)
  44. my $incremental_backups = 23;
  45.  
  46. # Full path to your backup directory
  47. # WITHOUT LEADING SLASH!
  48. my $backup_dir = '/mnt/archive/mysql';
  49.  
  50. # Database user/pass credentials
  51. my $dbuser = 'perconaXB';
  52. my $dbpass = 'perconaXB';
  53.  
  54. # This stuff should never change, but in case it does...
  55. my $timestamp_regexp = '^\d{4}\-\d{2}\-\d{2}_\d{2}\-\d{2}\-\d{2}$';
  56. my $checkpoint_file = 'xtrabackup_checkpoints';
  57.  
  58. # Full path to the innobackupex script
  59. my $innobackupex = '/usr/bin/innobackupex';
  60.  
  61. # --------------------------------------------------------------
  62. # NO NEED TO EDIT BELOW HERE UNLESS YOU KNOW WHAT YOU ARE DOING!
  63. # --------------------------------------------------------------
  64.  
  65.  
  66. # ---------------------------------------------
  67. # Inspect a backup directory and determine
  68. # if it is a full backup or an incremental
  69. # backup. Return the status. Returns
  70. # 'unknown' if a checkpoint file is not found.
  71. #
  72. sub determine_backup_type
  73. {
  74. my $checkpoint_file = shift;
  75. my $type = 'unknown';
  76. if(-f $checkpoint_file)
  77. {
  78. open(my $fh, "<$checkpoint_file") or die("Could not open file $checkpoint_file: $!");
  79. while(my $line = <$fh>)
  80. {
  81. chomp $line;
  82. if($line =~ m/^backup_type/)
  83. {
  84. $line =~ s/^backup_type = //g;
  85. if($line eq 'full-backuped')
  86. {
  87. $type = 'full';
  88. last;
  89. }
  90. if($line eq 'incremental')
  91. {
  92. $type = 'incremental';
  93. last;
  94. }
  95. }
  96. }
  97. close($fh);
  98. }
  99. print "Backup type determined to be: $type\n\n";
  100. return $type;
  101. }
  102. #
  103. # --------------------------------------------
  104.  
  105.  
  106. # ---------------------------------------------
  107. # List the contents of a directory
  108. # This is meant to simplify and centralize
  109. # some re-usable logic.
  110. # @param $directory (directory to generate listing for)
  111. # @param $order (asc|desc, optional, listing order)
  112. # @param $filter (REGEXP, optional, regex filter folders must match to be listed)
  113. # @returns @array
  114. #
  115. sub list_directory
  116. {
  117.  
  118. my $directory = shift;
  119. my $order = shift || 'asc';
  120. my $filter = shift || '.*';
  121. my @entries = ();
  122. opendir(my $dh,$directory) || die("Unable to open directory: $directory");
  123. while(readdir($dh))
  124. {
  125. chomp $_;
  126. $_ =~ s/^\s+|\s+$//g;
  127. if( $_ =~ /$filter/g )
  128. {
  129. push @entries, $_;
  130. }
  131. }
  132. closedir($dh);
  133. if($order eq 'desc')
  134. {
  135. @entries = sort {$b cmp $a} @entries;
  136. }
  137. else
  138. {
  139. @entries = sort @entries;
  140. }
  141. return @entries;
  142. }
  143. #
  144. # --------------------------------------------
  145.  
  146.  
  147. # Let's centralize the username/password and any general options
  148. # that should be passed to innobackupex
  149. $innobackupex = "nice -n 10 $innobackupex --user=$dbuser --password=$dbpass --throttle=20";
  150.  
  151. print "Starting...\n\n";
  152.  
  153. my $cmd_to_execute = '';
  154.  
  155. if($incremental_backups == 0)
  156. {
  157. # Incrementals are disabled, just create a fresh full-backup
  158. print "Incrementals disabled.\n";
  159. $cmd_to_execute = "$innobackupex $backup_dir";
  160. }
  161. else
  162. {
  163. print "Incrementals have been defined.\n";
  164. # Incremental backups have been defined, so lets determine what we
  165. # need to perform for this backup.
  166. my @entries = list_directory($backup_dir,'desc',$timestamp_regexp);
  167. my $incrementals_found = 0;
  168. my $most_recent_backup = '';
  169. my $pass = 0;
  170. foreach(@entries)
  171. {
  172. my $backup_type = determine_backup_type("$backup_dir/$_/$checkpoint_file");
  173. # We ignore folders that cannot be determined
  174. if($backup_type eq 'unknown')
  175. {
  176. next;
  177. }
  178. # Capture the first iteration as this is the most recent backup
  179. # that has been made.
  180. if($pass==0)
  181. {
  182. $most_recent_backup = $_;
  183. }
  184. $pass++;
  185. if($backup_type eq 'full')
  186. {
  187. # Perform an incremental
  188. $cmd_to_execute = "$innobackupex --incremental $backup_dir --incremental-basedir=$backup_dir/$most_recent_backup";
  189. last;
  190. }
  191. if($backup_type eq 'incremental')
  192. {
  193. $incrementals_found++;
  194. }
  195. if($incrementals_found==$incremental_backups)
  196. {
  197. # Perform a full backup
  198. $cmd_to_execute = "$innobackupex $backup_dir";
  199. last;
  200. }
  201. }
  202. if($pass>0 && $cmd_to_execute eq '')
  203. {
  204. # We obviously have no existing backups, so this
  205. # must be a full backup we need to run.
  206. print "No existing backups, full one must be run.\n";
  207. $cmd_to_execute = "$innobackupex $backup_dir";
  208. }
  209.  
  210. }
  211.  
  212. if($cmd_to_execute ne '')
  213. {
  214. print "EXECUTING: $cmd_to_execute\n";
  215. system $cmd_to_execute;
  216. }
  217. else
  218. {
  219. print "No command to execute, sorry.\n";
  220. print "You might want to run a full backup; have at it:\n";
  221. $cmd_to_execute = "$innobackupex $backup_dir";
  222. print $cmd_to_execute . "\n";
  223. }
  224.  
  225.  
  226.  
  227.  
  228. # Time to cycle out the oldest folders based on our retention policy.
  229. #
  230. # This logic is simple: start counting the number of full backups found
  231. # (from newest to oldest) until we count as many as are defined in the
  232. # $full_backup_retention variable and start deleting everything else
  233. # we find moving backwards.
  234. #
  235. my @entries = list_directory($backup_dir,'desc',$timestamp_regexp);
  236. my $full_backups_found = 0;
  237. my $start_deleting = 0;
  238. foreach(@entries)
  239. {
  240. my $backup_type = determine_backup_type("$backup_dir/$_/$checkpoint_file");
  241. # We ignore folders that cannot be determined
  242. if($backup_type eq 'unknown')
  243. {
  244. next;
  245. }
  246. if($backup_type eq 'full')
  247. {
  248. $full_backups_found++;
  249. if($full_backups_found==$full_backup_retention)
  250. {
  251. $start_deleting = 1;
  252. next;
  253. }
  254. }
  255. if($start_deleting==1)
  256. {
  257. # Delete this backup!
  258. print "REMOVING: $backup_dir/$_\n\n";
  259. remove_tree("$backup_dir/$_");
  260. }
  261. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement