最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

[Mysql]备份同库中一张表的历史记录insertinto..select_MySQL

来源:懂视网 责编:小采 时间:2020-11-09 19:52:11
文档

[Mysql]备份同库中一张表的历史记录insertinto..select_MySQL

[Mysql]备份同库中一张表的历史记录insertinto..select_MySQL:需求 现在有个这么一个需求,mysql中有个表,数据增长的很快,但是呢这个数据有效期也就是1个月,一个月以前的记录不太重要了,但是又不能删除。为了保证这个表的查询速度,需要一个简单的备份表,把数据倒进去。 代码 于是我写了一个小脚本,用来做定时任务
推荐度:
导读[Mysql]备份同库中一张表的历史记录insertinto..select_MySQL:需求 现在有个这么一个需求,mysql中有个表,数据增长的很快,但是呢这个数据有效期也就是1个月,一个月以前的记录不太重要了,但是又不能删除。为了保证这个表的查询速度,需要一个简单的备份表,把数据倒进去。 代码 于是我写了一个小脚本,用来做定时任务

需求

现在有个这么一个需求,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")

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

[Mysql]备份同库中一张表的历史记录insertinto..select_MySQL

[Mysql]备份同库中一张表的历史记录insertinto..select_MySQL:需求 现在有个这么一个需求,mysql中有个表,数据增长的很快,但是呢这个数据有效期也就是1个月,一个月以前的记录不太重要了,但是又不能删除。为了保证这个表的查询速度,需要一个简单的备份表,把数据倒进去。 代码 于是我写了一个小脚本,用来做定时任务
推荐度:
标签: 历史 备份 mysql
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top