[Mysql]备份同库中一张表的历史记录 insert into ..select
需求
现在有个这么一个需求,mysql中有个表,数据增长的很快,但是呢这个数据有效期也就是1个月,一个月以前的记录不太重要了,但是又不能删除。为了保证这个表的查询速度,需要一个简单的备份表,把数据倒进去。
代码
于是我写了一个小脚本,用来做定时任务,把这个表某段时间的数据备份到备份表中,核心就是个简单的sql。
原始表radius
备份的表为 radius2015
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
#python2.7x
#authror: orangleliu
#备份radius中的上网记录表,每个月备份一次,原始表中保留一份数据
#使用同一个数据库中的一个不同表名的表备份
import time
import datetime
import logging
from datetime import timedelta
import MySQLdb
import MySQLdb.cursors
logging.basicConfig(format='%(asctime)s %(levelname)s - \
%(message)s')
logger = logging.getLogger('backup')
logger.setLevel(logging.DEBUG)
#数据库配置
DBPARAMS = {
"host":"127.0.0.1",
"user":"root",
"password":"",
"database":"test",
"charset": ""
}
#这里使用select into 来备份,数据校验对比记录数,一个月大概100w条数据
#radacct2015
#检查表,检查重传,备份,校验
create_table_sql = '''
CREATE TABLE `{0}` (
`radacctid` bigint(21) NOT NULL AUTO_INCREMENT,
`acctsessionid` varchar(64) NOT NULL DEFAULT '',
`acctuniqueid` varchar(32) NOT NULL DEFAULT '',
`username` varchar(64) NOT NULL DEFAULT '',
`groupname` varchar(64) NOT NULL DEFAULT '',
`realm` varchar(64) DEFAULT '',
`nasipaddress` varchar(15) NOT NULL DEFAULT '',
`nasportid` varchar(15) DEFAULT NULL,
`nasporttype` varchar(32) DEFAULT NULL,
`acctstarttime` int(11) DEFAULT NULL,
`acctupdatetime` int(11) DEFAULT NULL,
`acctstoptime` int(11) DEFAULT NULL,
`acctinterval` int(12) DEFAULT NULL,
`acctsessiontime` int(12) unsigned DEFAULT NULL,
`acctauthentic` varchar(32) DEFAULT NULL,
`connectinfo_start` varchar(50) DEFAULT NULL,
`connectinfo_stop` varchar(50) DEFAULT NULL,
`acctinputoctets` bigint(20) DEFAULT NULL,
`acctoutputoctets` bigint(20) DEFAULT NULL,
`calledstationid` varchar(50) NOT NULL DEFAULT '',
`callingstationid` varchar(50) NOT NULL DEFAULT '',
`acctterminatecause` varchar(32) NOT NULL DEFAULT '',
`servicetype` varchar(32) DEFAULT NULL,
`framedprotocol` varchar(32) DEFAULT NULL,
`framedipaddress` varchar(15) NOT NULL DEFAULT '',
PRIMARY KEY (`radacctid`),
UNIQUE KEY `acctuniqueid` (`acctuniqueid`),
KEY `username` (`username`),
KEY `framedipaddress` (`framedipaddress`),
KEY `acctsessionid` (`acctsessionid`),
KEY `acctsessiontime` (`acctsessiontime`),
KEY `acctstarttime` (`acctstarttime`),
KEY `acctinterval` (`acctinterval`),
KEY `acctstoptime` (`acctstoptime`),
KEY `nasipaddress` (`nasipaddress`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
'''
back_sql = '''
INSERT INTO {0}
SELECT *
FROM {1}
WHERE acctstarttime < UNIX_TIMESTAMP(
STR_TO_DATE('{2}', '%Y-%m-%d')
) AND acctstarttime >= UNIX_TIMESTAMP(
STR_TO_DATE('{3}', '%Y-%m-%d')
)'''
count_sql = """
SELECT count(*) FROM {0} WHERE 1=1 AND
acctstarttime < UNIX_TIMESTAMP(
STR_TO_DATE('{1}', '%Y-%m-%d')
) AND acctstarttime >= UNIX_TIMESTAMP(
STR_TO_DATE('{2}', '%Y-%m-%d')
)
"""
#date tools
def get_year(month):
#month like 201505
return datetime.datetime.strptime(month, "%Y%m").year
def get_month_firstday_str(month):
return datetime.datetime.strptime(month,"%Y%m").\
strftime("%Y-%m-%d")
def get_next_month_firstday_str(month):
month_firstday = datetime.datetime.strptime(month,"%Y%m")
monthnum = month_firstday.month
return "{0}-{1}-{2}".format(
month_firstday.year if monthnum < 12 else \
month_firstday.year + 1,
monthnum + 1 if monthnum < 12 else 1, 1)
class DBConn(object):
__CONFIG = {
'default': {
'host': "",
'user': "",
'database': "",
'password': "",
'charset': "",
}
}
def __init__(self, connname='', connconfig={}):
if connconfig:
self.connconfig = connconfig
else:
connname = connname or 'default'
self.connconfig = self.__CONFIG.get(connname, 'default')
self.conn = None
def __enter__(self):
try:
self.conn = MySQLdb.connect(
user=self.connconfig['user'],
db=self.connconfig['database'],
passwd=self.connconfig['password'],
host=self.connconfig['host'],
use_unicode=True,
charset=self.connconfig['charset'] or "utf8",
#cursorclass=MySQLdb.cursors.DictCursor
)
return self.conn
except Exception, e:
print str(e)
return None
def __exit__(self, exe_type, exe_value, exe_traceback):
if exe_type and exe_value:
print '%s: %s' % (exe_type, exe_value)
if self.conn:
self.conn.close()
class RadiusBackup(object):
def __init__(self, month, conn):
self.conn = conn
self.cursor = conn.cursor()
self.month = month
self.year = get_year(month)
self.month_firstday = get_month_firstday_str(month)
self.next_month_firstday = get_next_month_firstday_str(month)
self.tablename = "radacct{0}".format(self.year)
self.stable = "radacct"
def check_table_exist(self):
check_table_sql = "SHOW TABLES LIKE '{0}'".format(
self.tablename)
self.cursor.execute(check_table_sql)
res = self.cursor.fetchall()
return True if len(res) > 0 else False
def create_backup_table(self):
sql = create_table_sql.format(self.tablename)
self.cursor.execute(sql)
logger.info(u"开始创建备份表 {0}".format(self.tablename))
def check_datas_count(self, tablename):
sql = count_sql.format(tablename, self.next_month_firstday,
self.month_firstday)
logger.debug(sql)
self.cursor.execute(sql)
res = self.cursor.fetchone()
return res[0]
def check_before(self):
flag = False
#check table
if not self.check_table_exist():
self.create_backup_table()
if self.check_table_exist() == False:
logger.error(u"无法找到备份表 exit")
return flag
#check datas
if self.check_datas_count(self.tablename) > 0:
return flag
else:
return True
def backup_datas(self):
sql = back_sql.format(self.tablename, self.stable,
self.next_month_firstday, self.month_firstday)
logger.debug(sql)
self.cursor.execute(sql)
self.conn.commit()
def check_after(self):
snum = self.check_datas_count(self.stable)
bnum = self.check_datas_count(self.tablename)
if snum > 0 and (snum == bnum):
logger.info(u"备份成功")
return snum, True
else:
return -1, False
def backup_handler(self):
if self.check_before():
logger.info(u"检查完毕,开始备份数据")
self.backup_datas()
logger.info(u"开始备份")
num, flag = self.check_after()
logger.info(u"本次备份{0} 数据 {1}条".format(self.month, num))
else:
logger.info(u"数据已经有备份,请检查")
if __name__ == "__main__":
month = "201504"
with DBConn(connconfig=DBPARAMS) as dbconn:
if dbconn:
backup = RadiusBackup(month, dbconn)
backup.backup_handler()
else:
logger.error("can not connect to db")
本文出自 “orangleliu笔记本” 博客,转载请务必保留此出处http://blog.csdn.net/orangleliu/article/details/46650875 作者orangleliu 采用署名-非商业性使用-相同方式共享协议
[Mysql]备份同库中一张表的历史记录 insert into ..select的更多相关文章
- mysql查询一个库中有多少张表
SELECT COUNT(*) TABLES, table_schema FROM information_schema.TABLES WHERE table_schema = 'palm_2_0_ ...
- 查看Sql Server库中某张表的结构
--快速查看表结构(比较全面的) SELECT CASE WHEN col.colorder = THEN obj.name ELSE '' END AS 表名, col.colorder AS 序号 ...
- 从MySQL全库备份中恢复某个库和某张表【转】
从MySQL全库备份中恢复某个库和某张表 一.全库备份-A [root@mha2 backup]#mysqldump -uroot -p123456 --default-character-set=u ...
- 获取一个表中的字段总数(mysql) Navicat如何导出Excel格式表结构 获取某个库中的一个表中的所有字段和数据类型
如何获取一个表中的字段总数 1.function show columns from 表明: 结果 : 2.functiuon select count(*) from INFORMATION_SCH ...
- sql 从一个库中取某个表的数据导入到另一个库中相同结构的表中
sql 2008 从一个库中把 某个表中的数据导入到另一个库中的具有相同结构的表中 use 库1 go insert into 库1.dbo.表1 select * from 库2.dbo.表1 ...
- SQL-49 针对库中的所有表生成select count(*)对应的SQL语句
题目描述 针对库中的所有表生成select count(*)对应的SQL语句CREATE TABLE `employees` (`emp_no` int(11) NOT NULL,`birth_dat ...
- #mysql查询特定数据库中的所有表名
#mysql查询特定数据库中的所有表名select table_namefrom information_schema.tableswhere table_schema='smbms' and tab ...
- 从MySQL全库备份中恢复某个库和某张表
在Mysqldump官方工具中,如何只恢复某个库呢? 全库备份 [root@HE1 ~]# mysqldump -uroot -p --single-transaction -A --master-d ...
- MySQL只恢复某个库或某张表
在Mysqldump官方工具中,如何只恢复某个库呢? 全库备份 [root@HE1 ~]#mysqldump -uroot -p --single-transaction -A --master-da ...
随机推荐
- [ Java学习基础 ] Java构造函数
构造方法是类中特殊方法,用来初始化类的实例变量,它在创建对象(new运算符)之后自动调用. Java构造方法的特点如下: 构造方法名必须与类名相同. 构造方法没有任何返回值,包括void. 构造方法只 ...
- Unix系统使用的地址索引结构有什么特点?
使用地址索引表.索引节点中地址索引表标识出含有文件数据的磁盘块的分布情况.
- Win7删除文件夹提示找不到该项目无法删除
在使用win7操作系统的过程中,有一些朋友会遇到这种情况,因为某种不明原因,硬盘里面某一个文件夹无法删除,表现为在删除的时候,系统提示找不到该项目,即找不到该文件夹,就像它变成了幽灵一样,看得到却摸不 ...
- python2.7练习小例子(二)
2):题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%:2 ...
- Mybatis中 collection 和 association 的区别
public class A{ private B b1; private List<B> b2;} 在映射b1属性时用association标签,(一对一的关系) 映射b2时用colle ...
- 程序包org.junit不存在
三种解决方法 第一种 maven的改法 <dependency> <groupId>junit</groupId> &l ...
- hash数组快速查找一个字符串中出现最多的字符,并统计出现的次数
如何快速查找一个字符串中出现最多的字符,并统计出现的次数? 可以使用hash数组,也就是关联数组实现快速查找功能. function seek(str) { var hash = []; var ma ...
- 设计模式:HelloWorld之策略模式
一.概述 策略模式 定义了算法族,分别封装起来,让他们可以互相替换,此模式让算法的变化独立于使用算法的客户. 策略模式的三要素: 抽象策略角色: 策略类,通常由一个接口或者抽象类实现. 具体策略角色: ...
- ES6(类)
类的概念 1.基本定义 2.继承 继承如何传递参数?(super) 定义自己属性的时候调用 this 一定要在 super 之后(在继承关系中,子类的构造函数如果用 super 传递参数的过程中,su ...
- SSA-一种适合中小型企业的新型服务架构
写在前面 好久好久没写了,最近刚换了工作,花了几天的时候熟悉了项目,接着就是功能的完善,随后就是对新项目的基础架构搭建. 看过Po主博客的都知道,Po主一直致力于推广.Net Core在微服务架构上的 ...