要回答这个问题,面试首先我们要明确这个表的官果数据是否全部有用?使用MySQL的过程,经常会遇到一个问题,单表大办比如说某张”log”表,数据用于保存某种记录,量过随着时间的面试不断的累积数据,但是官果只有最新的一段时间的数据是有用的;这个时候会遇到性能和容量的瓶颈,需要将表中的单表大办历史数据进行归档。
也就是数据说,大部分情况,量过我们做数据归档就足以解决这个问题。面试只有那些全部很重要的云服务器提供商官果业务数据,才需要做分库分表。单表大办

创建一个新表,表结构和索引与旧表一模一样:
复制create table table_new like table_old;1.新建存储过程,量过查询30天的数据并归档进新数据库,然后把30天前的旧数据从旧表里删除:
复制delimiter $ create procedure sp() begin insert into tb_new select * from table_old where rectime < NOW() - INTERVAL 30 DAY; delete from db_smc.table_old where rectime < NOW() - INTERVAL 30 DAY; end1.2.3.4.5.6.创建EVENT,每天晚上凌晨00:00定时执行上面的存储过程:
复制create event if not exists event_temp on schedule every 1 day on completion preserve do call sp();1.2.3.4.备注:第一次执行存储过程的时候因为历史数据过大, 可能发生意外让该次执行没有成功。重新执行时会遇到报错ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction,应急解决方案如下:
执行show full processlist;查看所有MySQL线程。执行SELECT * FROM information_schema.INNODB_TRX; 查看是否有错误线程,即线程id在show full processlist;的结果中,状态为sleep的线程。kill进程id。另外写存储过程的时候可以控制事务的大小,IT技术网比如说可以根据时间字段每次归档一天或者更小时间段的数据,这样就不会有大事务的问题,里面还可以加入日志表,每次归档操作的行为都写入日志表,以后查起来也一目了然。
实战
首先,查看一下哪些表数据量特别大:
复制SELECT TABLE_NAME AS 表名, TABLE_ROWS AS 记录数 FROM information_schema.TABLES WHERE TABLE_SCHEMA = tms and TABLE_ROWS > 1000; -- 这里替换为你的数据库名1.2.3.4.5.6.7.
如图,我要对原数据库中的single_packaging表进行归档,就先新建一个用于归档的数据库doc_history:

然后建一张一模一样的表在这个数据库,编写归档的存储过程:
复制delimiter $ create procedure sp() begin insert into doc_history.single_packaging select * from old_schema.single_packaging where create_time < NOW() - INTERVAL 7 DAY; delete from old_schema.single_packaging where create_time < NOW() - INTERVAL 7 DAY; end1.2.3.4.5.6.7.注意老库和新库的区别。
最后,设置事件,每天定时跑:
复制create event if not exists event_temp on schedule every 1 day on completion preserve do call sp();1.2.3.4.
这样就OK了。


