用Python备份MYSQL 数据库
工作需要,对公司的MYSQL数据库进行备份,赶上刚刚开始学python,看了一套简单的python教学视频,简单的写了个备份脚本,个人表示 对python 的class 、function、build-in function 、私有变量、全局变量 等等,该怎么用,啥时候用等 毫无概念 ,仅此记录一下吧,也欢迎路过的pythoner赐教。
个人已知的一些问题:
1、该脚本必须要求 mysql配置文件内的所有行为 key=value的格式,并且不能存在多余的注释,否则ConfigParser模块解析配置文件时会出错,由于没研究过ConfigParser是不是有容错的方法可以调用,也没时间写容错处理,而是通过整理my.ini 配置文件使其符合ConfigParser的要求解决的。后面会附上我用的mysql配置文件。
2、大量使用类私有成员变量,因为完全不知道python 变量、类方法、等等啥时候该私有化,以及有啥区别,只知道类私有成员变量在别的脚本中import 或者继承时,是不可见的。
3、比较多的进行文件操作,以及传值操作,目前只保证按正确格式传值没问题,没有做多余的容错处理。 4、大量的在进行字符串拼接,第一次写运维相关脚本,由于要调用系统命令,和传递很多参数,也不会subprocess模块,不知道别人写运维脚本都具体咋做,就直接拼接了。
5、其他未知的bug、未发现的逻辑错误等等。
环境:
- Server : Dell PowerEdge T110
- OS: CentOS 6.3_x86_64
- PythonVersion: 2.7.3
- MysqlVersion: 5.5.28 linux x86_64
MysqlBackupScript.py
#!/usr/bin/env python # coding: utf8 # script MysqlBackupScript # by Becareful # version v1.0 """ This scripts provides auto backup mysql(version == 5.5.x) database . """ import os import sys import datetime #用于生成备份文件的日期 import linecache #用于读取文件的指定行 import ConfigParser #解析mysql配置文件 class DatabaseArgs(object): """ """ __MYSQL_BASE_DIR = r'/usr/local/mysql' #mysql安装目录 __MYSQL_BIN_DIR = __MYSQL_BASE_DIR + '/bin' #mysql二进制目录 __MYSQL_CONFIG_FILE = r'/usr/local/mysql/my.cnf' #mysql配置文件 __ONEDAY = datetime.timedelta(days=1) #一天的时长,用于计算下面的前一天和后一天日期 __TODAY = datetime.date.today() #当天日期格式为 YYYY-MM-DD __YESTERDAY = __TODAY - __ONEDAY #计算昨天日期 __TOMORROW = __TODAY + __ONEDAY #计算明天日期 __WEEKDAY = __TODAY.strftime('%w') #计算当天是一星期的星期几 __MYSQL_DUMP_ARGS = { #用一个字典存储mysqldump 命令备份数据库的参数 'MYISAM': ' -v -E -e -R --triggers -F -n --opt --master-data=2 --hex-blob -B ', 'INNODB': ' -v -E -e -R --triggers -F --single-transaction -n --opt --master-data=2 --hex-blob -B ' } __DUMP_COMMAND = __MYSQL_BIN_DIR + '/mysqldump' #mysqldump 命令的 路径 用于dump mysql数据 __FLUSH_LOG_COMMAND = __MYSQL_BIN_DIR + '/mysqladmin' #mysqladmin 命令的路径 ,用于执行 flush-logs 生成每天增量binlog __BACKUP_DIR = r'/backup/' # 指定备份文件存放的目录 __PROJECTNAME = 'example' # 指定需要备份的数据库对应的项目名,将来会生成 projectname-YYYY-MM-DD.sql 等文件 __DATABASE_LIST = [] # 指定需要备份的数据库名,可以是多个,使用列表 __HOST = 'localhost' __PORT = 3306 __USERNAME = 'root' __PASSWORD = '' __LOGINARGS = '' # 如果在localhost登陆,需要密码,可以设定登陆的参数,具体在下面有说明 __LOGFILE = __BACKUP_DIR + '/backup.logs' def __init__(self, baseDir=__MYSQL_BASE_DIR, backDir=__BACKUP_DIR, engine='MYISAM', projectName=__PROJECTNAME, dbList=__DATABASE_LIST, host=__HOST, port=__PORT, user=__USERNAME, passwd=__PASSWORD): """ 实例化对象时传入的参数,如不传入默认使用类的私有成员变量作为默认值 :param baseDir: :param backDir: :param engine: :param projectName: :param dbList: :param host: :param port: :param user: :param passwd: """ self.__MYSQL_BASE_DIR = baseDir self.__BACKUP_DIR = backDir self.__PROJECTNAME = projectName self.__DATABASE_LIST = dbList self.__HOST = host self.__PORT = port self.__USERNAME = user self.__PASSWORD = passwd self.__ENGINE = self.__MYSQL_DUMP_ARGS[engine] #下面定义了如需登陆时,参数 其实就是生成 这样的格式 “-hlocalhost -uroot --password=‘xxxx’” self.__LOGINARGS = " -h" + self.__HOST + " -P" + str( self.__PORT) + " -u" + self.__USERNAME + " --password='" + self.__PASSWORD + "'" self.checkDatabaseArgs() #调用检查函数 def __getconfig(self, cnf=__MYSQL_CONFIG_FILE, item=None): # 解析mysql配置文件的小函数,简单封装了下,传入一个值作为my.cnf的key去查找对应的value __mycnf = ConfigParser.ConfigParser() __mycnf.read(cnf) try: return __mycnf.get("mysqld", item) except BaseException, e: sys.stderr.write(str(e)) sys.exit(1) def __getBinlogPath(self): # 取每天需要增量备份的binlog日志的绝对路径,从mysql的binlog.index文件取倒数第二行 __BINLOG_INDEX = self.__getconfig(item='log-bin') + '.index' if not os.path.isfile(__BINLOG_INDEX): sys.stderr.write('BINLOG INDEX FILE: [' + __BINLOG_INDEX + ' ] NOT FOUND! \n') sys.exit(1) else: try: __BINLOG_PATH = linecache.getline(__BINLOG_INDEX, len(open(__BINLOG_INDEX,'r').readlines()) - 1) linecache.clearcache() except BaseException, e: sys.stderr.write(str(e)) sys.exit(1) return __BINLOG_PATH.strip() def flushDatabaseBinlog(self): # 调用此函数,将会执行 mysqladmin flush-logs ,刷新binlog日志 return os.popen(self.__FLUSH_LOG_COMMAND + self.__LOGINARGS + ' flush-logs') def dumpDatabaseSQL(self): #|通过mysqladmin 对指定数据库进行全备 if not os.path.isfile(self.__BACKUP_DIR + '/' + self.__PROJECTNAME + '/' + str(self.__YESTERDAY) + '-' + self.__PROJECTNAME + '.sql'): return os.popen(self.__DUMP_COMMAND + self.__LOGINARGS + self.__ENGINE + ' '.join( self.__DATABASE_LIST) + ' >> ' + self.__BACKUP_DIR + '/' + self.__PROJECTNAME + '/' +str( self.__YESTERDAY) + '-' + self.__PROJECTNAME + '.sql') else: sys.stderr.write('Backup File [' + str(self.__YESTERDAY) + '-' + self.__PROJECTNAME +'.sql] already exists.\n') def dumpDatabaseBinlog(self):#通过copy2() 将需要备份的binlog日志复制到指定备份目录 if not os.path.isfile(self.__BACKUP_DIR + '/' + self.__PROJECTNAME + '/' +str(self.__YESTERDAY) + '-' + os.path.split(self.__getBinlogPath())[1]): from shutil import copy2 try: copy2(self.__getBinlogPath(), self.__BACKUP_DIR + '/' + self.__PROJECTNAME + '/' +str(self.__YESTERDAY) + '-' + os.path.split(self.__getBinlogPath())[1]) except BaseException, e: sys.stderr.write(str(e)) else: sys.stderr.write('Binlog File [' + str(self.__YESTERDAY) + '-' +os.path.split(self.__getBinlogPath())[1] + '] already exists\n' ) def checkDatabaseArgs(self): #对一些必要条件进行检查 __rv = 0 if not os.path.isdir(self.__MYSQL_BASE_DIR): #检查指定的mysql安装目录是否存在 sys.stderr.write('MYSQL BASE DIR: [ ' + self.__MYSQL_BASE_DIR + ' ] NOT FOUND\n') __rv += 1 if not os.path.isdir(self.__BACKUP_DIR): #检查指定的备份目录是否存在,如不存在自动创建 sys.stderr.write('BACKUP DIR: [ ' + self.__BACKUP_DIR + '/' + self.__PROJECTNAME + ' ] NOT FOUND ,AUTO CREATED\n') os.makedirs(self.__BACKUP_DIR + '/' + self.__PROJECTNAME) if not os.path.isfile(self.__MYSQL_CONFIG_FILE): #检查mysql配置文件是否存在 sys.stderr.write('MYSQL CONFIG FILE: [' + self.__MYSQL_CONFIG_FILE + ' ] NOT FOUND\n') __rv += 1 if not os.path.isfile(self.__DUMP_COMMAND): #检查备份数据库时使用的mysqldump命令是否存在 sys.stderr.write('MYSQL DUMP COMMAND: [' + self.__DUMP_COMMAND + ' ] NOT FOUND\n') __rv += 1 if not os.path.isfile(self.__FLUSH_LOG_COMMAND): #检查刷新mysql binlog日志使用的mysqladmin命令是否存在 sys.stderr.write('MYSQL FLUSH LOG COMMAND: [' + self.__DUMP_COMMAND + ' ] NOT FOUND\n') __rv += 1 if not self.__DATABASE_LIST: #检查需要备份的数据库列表是否存在 sys.stderr.write('Database List is None \n') __rv += 1 if __rv: # 判断返回值,由于上述任何一步检查失败,都会导致 __rv 值 +1 ,只要最后__rv != 0就直接退出了。 sys.exit(1) def crontab(): # 使用字典,来进行相关参数传递,并实例化对象,调用相关方法进行操作 zabbix = { 'baseDir': '/usr/local/mysql/', 'backDir': '/backup/', 'projectName': 'Monitor', 'dbList': ['zabbix'], 'host': 'localhost', 'port': 3306, 'user': 'root', 'passwd': 'xxxxxxx' } monitor = DatabaseArgs(**zabbix) monitor.dumpDatabaseSQL() monitor.dumpDatabaseBinlog() monitor.flushDatabaseBinlog() if __name__ == '__main__': crontab()
my.cnf
[client] port = 3306 socket = /mysql/var/db.socket [mysqld] socket = /mysql/var/db.socket datadir = /mysql/db/ skip-external-locking = 1 skip-innodb = 0 key_buffer_size = 256M max_allowed_packet = 10M table_open_cache = 2048 sort_buffer_size = 4M read_buffer_size = 4M read_rnd_buffer_size = 8M myisam_sort_buffer_size = 64M myisam_max_sort_file_size = 1G myisam_repair_threads = 1 myisam_recover = DEFAULT thread_cache_size = 32 query_cache_size = 32M query_cache_min_res_unit = 2k bulk_insert_buffer_size = 64M tmp_table_size = 128M thread_stack = 192K skip-name-resolve = 1 max_connections = 65500 default-storage-engine = myisam federated = 0 server-id = 1 slave-skip-errors = all #log = /var/log/sql_query.log slow-query-log = 1 slow-query-log-file = /mysql/log/sql_query_slow.log long-query-time = 5 log-queries-not-using-indexes = 1 log-slow-admin-statements = 1 log-bin = /mysql/var/log/binlog/bin-log log-error = /mysql/var/log/mysql.err master-info-file = /mysql/var/log/master.info relay-log = /mysql/var/log/relay-bin/relay-bin relay-log-index = /mysql/var/log/relay-bin/relay-bin.index relay-log-info-file = /mysql/var/log/relay-bin/relay-bin.info binlog_cache_size = 8M binlog_format = MIXED max_binlog_cache_size = 20M max_binlog_size = 1G binlog-ignore-db = mysql binlog-ignore-db = performance_schema binlog-ignore-db = information_schema replicate-ignore-db = mysql replicate-ignore-db = performance_schema replicate-ignore-db = information_schema innodb_data_home_dir = /mysql/ibdata/ innodb_data_file_path = ibdata:156M:autoextend innodb_log_group_home_dir = /mysql/ibdata/ log-slave-updates = 0 back_log = 512 transaction_isolation = READ-COMMITTED max_heap_table_size = 246M interactive_timeout = 120 wait_timeout = 120 innodb_additional_mem_pool_size = 16M innodb_buffer_pool_size = 512M innodb_file_io_threads = 4 innodb_thread_concurrency = 8 innodb_flush_log_at_trx_commit = 2 innodb_log_buffer_size = 16M innodb_log_file_size = 128M innodb_log_files_in_group = 3 innodb_max_dirty_pages_pct = 90 innodb_lock_wait_timeout = 120 innodb_file_per_table = 1 innodb_open_file = 327500 open_files_limit = 327500 [mysqldump] quick = 1 max_allowed_packet = 50M [mysql] auto-rehash = 1 socket = /mysql/var/db.socket safe-updates = 0 [myisamchk] key_buffer_size = 256M sort_buffer_size = 256M read_buffer = 2M write_buffer = 2M [mysqlhotcopy] interactive-timeout = 100
最终生成的备份目录结构是这样的
[root@zabbix backup]# find ./ ./ ./Monitor ./Monitor/2013-03-16-bin-log.000008 ./Monitor/2013-03-14-bin-log.000006 ./Monitor/2013-03-16-Monitor.sql ./Monitor/2013-03-15-Monitor.sql ./Monitor/2013-03-15-bin-log.000007 ./Monitor/2013-03-14-Monitor.sql ~END~

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Di bawah rangka kerja beegoorm, bagaimana untuk menentukan pangkalan data yang berkaitan dengan model? Banyak projek beego memerlukan pelbagai pangkalan data untuk dikendalikan secara serentak. Semasa menggunakan beego ...

Untuk fail XML kecil, anda boleh menggantikan kandungan anotasi secara langsung dengan editor teks; Untuk fail besar, adalah disyorkan untuk menggunakan parser XML untuk mengubahnya untuk memastikan kecekapan dan ketepatan. Berhati -hati apabila memadam komen XML, menyimpan komen biasanya membantu pemahaman dan penyelenggaraan kod. Petua Lanjutan menyediakan kod sampel Python untuk mengubahsuai komen menggunakan parser XML, tetapi pelaksanaan khusus perlu diselaraskan mengikut perpustakaan XML yang digunakan. Beri perhatian kepada isu pengekodan semasa mengubah suai fail XML. Adalah disyorkan untuk menggunakan pengekodan UTF-8 dan menentukan format pengekodan.

Kelajuan XML mudah alih ke PDF bergantung kepada faktor -faktor berikut: kerumitan struktur XML. Kaedah Penukaran Konfigurasi Perkakasan Mudah Alih (Perpustakaan, Algoritma) Kaedah Pengoptimuman Kualiti Kod (Pilih perpustakaan yang cekap, mengoptimumkan algoritma, data cache, dan menggunakan pelbagai threading). Secara keseluruhannya, tidak ada jawapan mutlak dan ia perlu dioptimumkan mengikut keadaan tertentu.

Mengubah kandungan XML memerlukan pengaturcaraan, kerana ia memerlukan penemuan tepat nod sasaran untuk menambah, memadam, mengubah suai dan menyemak. Bahasa pengaturcaraan mempunyai perpustakaan yang sepadan untuk memproses XML dan menyediakan API untuk melaksanakan operasi yang selamat, cekap dan terkawal seperti pangkalan data operasi.

Permohonan yang menukarkan XML terus ke PDF tidak dapat dijumpai kerana mereka adalah dua format yang berbeza. XML digunakan untuk menyimpan data, manakala PDF digunakan untuk memaparkan dokumen. Untuk melengkapkan transformasi, anda boleh menggunakan bahasa pengaturcaraan dan perpustakaan seperti Python dan ReportLab untuk menghuraikan data XML dan menghasilkan dokumen PDF.

Isu Menentukan Penghitungan Tetap String Dalam Protobuf Apabila menggunakan Protobuf, anda sering menghadapi situasi di mana anda perlu mengaitkan jenis enum dengan pemalar rentetan ...

Untuk menukar imej XML, anda perlu menentukan struktur data XML terlebih dahulu, kemudian pilih perpustakaan grafik yang sesuai (seperti matplotlib Python) dan kaedah, pilih strategi visualisasi berdasarkan struktur data, pertimbangkan volum data dan format imej, lakukan pemprosesan batch atau gunakan perpustakaan yang cekap, dan akhirnya simpan sebagai PNG, JPEG, atau SVG mengikut keperluan.

Gunakan kebanyakan editor teks untuk membuka fail XML; Jika anda memerlukan paparan pokok yang lebih intuitif, anda boleh menggunakan editor XML, seperti editor XML oksigen atau XMLSPY; Jika anda memproses data XML dalam program, anda perlu menggunakan bahasa pengaturcaraan (seperti Python) dan perpustakaan XML (seperti XML.Etree.ElementTree) untuk menghuraikan.
