Advertisement
Guest User

Untitled

a guest
May 2nd, 2018
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.46 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. import os
  4. import subprocess
  5. import sys
  6. import datetime
  7. from datetime import datetime, timedelta
  8.  
  9. import glob
  10. import string
  11. import shlex
  12.  
  13. import smtplib
  14. import email
  15.  
  16. #must be set manually to avoid additional python modules
  17. DATADIR = '/home/mysql/data'
  18. ISSLAVE = False #can be True or False
  19. #
  20.  
  21. #basic config - please do not change
  22. HOSTNAME = os.uname()[1]
  23. LOCKDIR = "/tmp/rn-innobackup.lock" #LOCKDIR
  24. LOGFILE = "/var/log/rn-mysqlbackup.log" #LOGFILE
  25. INNOBACKUPEX = "/usr/bin/innobackupex"
  26. ALERTMAIL = "mmaros@reflected.net" #to use multiple recepients, this needs to be turned into a list ["email1@bla.com", "email2@bla.com", "email3@bla.com", ...]
  27. #ALERTMAIL = "support@reflected.net" #to use multiple recepients, this needs to be turned into a list ["email1@bla.com", "email2@bla.com", "email3@bla.com", ...]
  28.  
  29.  
  30. #backup configuration
  31. #to use one binary over other, please put it at the start of the list, if it doesnt exist it will get skipped
  32. COMPRESS = ["/usr/bin/pbzip2","/usr/local/sbin/pbzip2","/usr/bin/pigz","/usr/local/sbin/pigz"]
  33. BACKUPDIR = '/home/backups/mysql/'
  34. RETENTION =int(7)
  35. STREAMING = False
  36. PARALEL = "4"
  37. USEMEMORY = "1G"
  38. CUSTOMOPT = "" #separate them with a space between, use syntax same as on the cli "--option=value --option2=value"
  39.  
  40.  
  41.  
  42. ########Bunch of checks that need to be ran before we proceed
  43. ########
  44. #check which compression to use
  45. compression = ""
  46. for i in range(0, len(COMPRESS)):
  47. if os.path.isfile(COMPRESS[i]):
  48. compression = COMPRESS[i]
  49. break
  50. #exit if compression is not set up
  51. if compression == "":
  52. print ("none of compressions are available, please check which ones are available and which ones are provided")
  53. sys.exit()
  54. #exit if datadir doesnt exist
  55. if os.path.isdir(DATADIR) is False:
  56. print (DATADIR + "does not exit")
  57. sys.exit()
  58.  
  59. #compression being used:
  60. if ("pbzip2" in compression):
  61. backupSuffix = ".tar.bz2"
  62. elif ("pigz" in compression):
  63. backupSuffix = ".tar.gz"
  64. else:
  65. print ("wrong compression")
  66. sys.exit()
  67.  
  68.  
  69. #set backupname
  70. createDate = datetime.today().strftime("%Y%m%d-%H%M%S")
  71. if STREAMING:
  72. createName = "mysql_backups_" + HOSTNAME + "_" + createDate + "-streaming"
  73. createNameCompressed = "mysql_backups_" + HOSTNAME + "_" + createDate + "-streaming" + backupSuffix
  74. else:
  75. createName = "mysql_backups_" + HOSTNAME + "_" + createDate
  76. createNameCompressed = "mysql_backups_" + HOSTNAME + "_" + createDate + backupSuffix
  77.  
  78. #if the machine is a slave add --slave-info to options
  79. if ISSLAVE:
  80. CUSTOMOPT += " --no-timestamp --slave-info "
  81. else:
  82. CUSTOMOPT += " --no-timestamp "
  83.  
  84.  
  85.  
  86. #skip disk check if .skipcheck is present in backupdir, remove after the run
  87. def skipCheck():
  88. if os.path.isfile(BACKUPDIR + ".skipcheck"):
  89. now = datetime.today().strftime("%Y-%m-%d %H:%M:%S")
  90. print(now + ": Skipping prerun disk space checks and running backups. skipcheck file will be removed")
  91. #function that runs backups
  92. os.remove(BACKUPDIR + ".skipcheck")
  93. else:
  94. isRunnable()
  95.  
  96. #check total freeDisk disk space on partition containting BACKUPDIR, in bytes
  97. def freeSpace(BACKUPDIR):
  98. st = os.statvfs(BACKUPDIR)
  99. freeDisk = int(st.f_bavail * st.f_frsize)
  100. return freeDisk
  101.  
  102. #get the size of the backup specified
  103. def listBackups(BACKUPDIR, backupSuffix):
  104. backupNameRegex = os.path.join(BACKUPDIR + 'mysql_backups_' + HOSTNAME + '_' + '*' + backupSuffix)
  105. listBackups = glob.glob(backupNameRegex)
  106. return listBackups
  107.  
  108. def lastBackupSize():
  109. backupNames = listBackups(BACKUPDIR, backupSuffix)
  110. print (backupNames)
  111. if not backupNames:
  112. lastSize = 0
  113. else:
  114. lastSize = os.path.getsize(max(backupNames , key = os.path.getctime))
  115. return lastSize
  116.  
  117. #get size of the mysql datadir
  118. def dirSize(path):
  119. total_size = 0
  120. for dirpath, dirnames, filenames in os.walk(path):
  121. for f in filenames:
  122. fp = os.path.join(dirpath, f)
  123. total_size += os.path.getsize(fp)
  124. return total_size
  125.  
  126. #prerun checks
  127. def isRunnable():
  128. oldAge = 1
  129. lastSize = lastBackupSize()
  130. freeDisk = freeSpace(BACKUPDIR)
  131. #if streaming backup, we dont care about size of the datadir
  132. if STREAMING:
  133. datadirSize = 0
  134. else:
  135. datadirSize = dirSize(DATADIR)
  136. print("Size of last backup")
  137. print(lastSize)
  138. print("Free disk size")
  139. print(freeDisk)
  140. print("Datadir size")
  141. print(datadirSize)
  142. if ((freeDisk - lastSize - datadirSize) * 1.1) < (lastSize + datadirSize):
  143. msgBody = "Cant run backups as there is not enough free disk space"
  144. sendMail(msgBody)
  145. print("All gucci")
  146. runBackup()
  147.  
  148. def runBackup():
  149. #how to split it
  150. #https://docs.python.org/2/library/subprocess.html
  151. #
  152. print("runBackup")
  153. if not STREAMING:
  154. commandToRun = INNOBACKUPEX + " " + CUSTOMOPT + "--parallel=" + PARALEL + " " + BACKUPDIR + createName
  155. #parse it into a list for the popen to work properly
  156. args = shlex.split(commandToRun)
  157. with open("/tmp/innobackupex.stdout.log", "a+") as f_stdout, open("/tmp/innobackupex.stderr.log", "a+") as f_stderr:
  158. p = subprocess.Popen(args, stdout=f_stdout, stderr=f_stderr)
  159. else:
  160. print("stuff")
  161. #$innobackupex $innobackupex_backup_options --stream=tar $WORKDIR 2> $lockdir/innobackupex-run.log | $COMPRESS $COMPRESS_ARGS -c > $BACKUPDIR/$FILEPREFIX.$FILESUFFIX
  162. #bashCommand = ['ls', '-lah', '/home/backups']
  163. #subprocess.run(bashCommand)
  164. #when the innobackupex compresses the data to workdir add apply log.
  165. #if streaming, no apply log!
  166. #when this is done, compress the directory using COMPRESSION
  167. #add checks if the backup finished fine
  168.  
  169. #sendmail and exit function
  170. def sendMail(msgBody):
  171. sender = 'root@' + HOSTNAME + '.ded.reflected.net'
  172. receivers = ALERTMAIL
  173. msgBody = msgBody
  174.  
  175. #print ("this works")
  176. #message = """From: """ + sender + """\nTo: """ + receivers + """\nSubject: backup failed on """ + HOSTNAME + """\n\n""" + msgBody + """\n"""
  177.  
  178. #its still ugly, but ugly in mutliple lines
  179. message = ("From: " + sender + "\n"
  180. "To:" + receivers + "\n"
  181. "Subject: Backup failed on " + HOSTNAME + "\n\n"
  182. + msgBody + "\n")
  183.  
  184. #smtpObj = smtplib.SMTP('smtp-out.reflected.net')
  185. #smtpObj.sendmail(sender, receivers, message)
  186. print ("Successfully sent email")
  187. sys.exit()
  188.  
  189.  
  190. skipCheck()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement