[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 ...
随机推荐
- 探索C++多态和实现机理
前一段时间被问到过一个问题,当时模模糊糊,就是说不清楚,问题问到说:什么情况下会将基类的析构函数定义成虚函数? 当时想到 如果子类B继承了父类A,那么定义出一个子类对象b,析构时,调用完子类析构函数, ...
- prop与attr的区别
与prop一样attr也可以用来获取与设置元素的属性. 区别在于,对于自定义属性和选中属性的处理. 选中属性指的是 checked,selected 这2种属性 1. 对于自定义属性 attr能够获取 ...
- python2.7入门---操作mysql数据库增删改查
Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口.Python 数据库接口支持非常多的数据库,你可以选择适合你项目的数据库: G ...
- 利用css3+js实现简单带立体过渡效果的图片切换(chrome浏览器)
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- 4月18开始看《C++Primer Plus》
好久没有写博客了,之前也说过水平有限,也写不出什么技术博客,只能写些感悟. 过年之后,陆续做了2.3个项目,刚开始可能不太熟悉流程,怎么和页面传数据?最近一个项目1/2天就写完代码了,真的很简单,主要 ...
- FreeMarker学习教程
copy自http://demojava.iteye.com/blog/800204 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...
- Centos 7安装MYSQL
1.下载RPM源 直接使用yum命令下载mysql来进行安装是不能成功的,安装过程会有问题,这里需要使用rpm命令来先进下载.下载路径为: http://dev.mysql.com/get/mysql ...
- ACM 数塔
在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的: 有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少? 已经告诉你了,这是个DP的题 ...
- MongoDB 关系
MongoDB 的关系表示多个文档之间在逻辑上的相互联系. 文档间可以通过嵌入和引用来建立联系. MongoDB 中的关系可以是: 1:1 (1对1) 1: N (1对多) N: 1 (多对1) N: ...
- 算法之路(三)----查找斐波纳契数列中第 N 个数
算法题目 查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: * 前2个数是 0 和 1 . * 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列的前10个数字是: 0, 1 ...