[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 ...
随机推荐
- mysql的连接处理过程
在mysqld_main函数中经过一系列的初始化后,mysql开始监听客户端的连接 mysqld_socket_acceptor->connection_event_loop(); 查看my ...
- DELL、HP、IBM X86服务器命名规则
DELL.HP.IBM X86服务器命名规则 各大服务器厂家对于自己的服务器命名都有一定的规则,通常会根据服务器的外观(如塔式.机架式.刀片等).处理器(如Intel或者AMD等).架构等信息来命名. ...
- 关于 "java中常量定义在interface中好还是定义在class中好" 的一些思考
原文链接 http://blog.csdn.net/voo00oov/article/details/50433672 java中interface中定义变量都是"public static ...
- js 当前时间刷新
<p>每隔1秒钟,打印当前时间</p> <div id="time"></div> <script> function ...
- 索引法则--LIKE以%开头会导致索引失效进而转向全表扫描(使用覆盖索引解决)
Mysql 系列文章主页 =============== 1 准备数据 1.1 建表 DROP TABLE IF EXISTS staff; CREATE TABLE IF NOT EXISTS st ...
- html下载excel模板
只需要href等于模板存放的路径即可 <a href="../../TempLate/Attitude.xlsx" class="easyui-linkbutton ...
- js遍历 for-of
for-of遍历 entries() 返回一个遍历器对象,用来遍历[键名, 键值]组成的数组.对于数组,键名就是索引值:对于 Set,键名与键值相同.Map 结构的 Iterator 接口,默认就是调 ...
- 解决Popup StayOpen=true时,永远置顶的问题
Popup设置了StayOpen=true时,会置顶显示. 如弹出了Popup后,打开QQ窗口,Popup显示在QQ聊天界面之上. 怎么解决问题? 获取绑定UserControl所在的窗口,窗口层级变 ...
- Create database 创建数据库
首先在ORACLE用户下进入.bash_profile文件 [oracle@linux02 ~]$ vi .bash_profile export ORACLE_SID=hldbexport ORAC ...
- 一个蒟蒻对FFT的理解(蒟蒻也能看懂的FFT)
建议同学们先自学一下"复数(虚数)"的性质.运算等知识,不然看这篇文章有很大概率看不懂. 前言 作为一个典型的蒟蒻,别人的博客都看不懂,只好自己写一篇了. 膜拜机房大佬 HY 一. ...