Mysql 自动创建分区表及自动删除分区表

有时我们需要保存大量数据,而这些数据是有时效性的,例如一些日志,在经过一段周期以后,这些数据存在的意义就不大了,除了占用大量的硬盘空间外还可能使数据查询变得缓慢。这些数据需要定时清除。我们可以采用表水平分割的方式(或分库分表)应对这种情况,但是水平分割表更适合具有大量查询或需要长期保存数据的情况。在某些情况下,我们数据的查询量并不大且表数据在单机情况下能满足系统需要,这时候Mysql分区表更适合。

 首先创建分区表创建存储过程,并将其命名为:create_log_partition

BEGIN
	select replace(partition_name,'device_log_','') into @PName	from INFORMATION_SCHEMA. PARTITIONS where	table_name = 'device_log' order by partition_ordinal_position desc limit 1;
	
	IF isnull(@PName) THEN
		select min(days) into @minDay from device_log;
		select max(days) into @maxDays from device_log;

		SET @partStr='';
		WHILE @minDay <= @maxDays DO 
			SET @partStr = CONCAT(
					@partStr,
					'PARTITION device_log_' ,@minDay,
					' VALUES in (' ,@minDay,
					') ,'
				);
			SET @minDay = @minDay + 1;
		END	WHILE;

		SET @sql = CONCAT('ALTER TABLE device_log PARTITION by list (days)(',@partStr,'PARTITION device_log_' ,@maxDays+1 ,' VALUES in (' ,@maxDays+1,') )'); 
		
		PREPARE stmt FROM @sql ; 
		EXECUTE stmt ; 
		DEALLOCATE PREPARE stmt ;
	ELSE
		
		SET @minDay = CAST(@PName AS UNSIGNED INTEGER) + 1;
		select (DATEDIFF(now(),'1970-1-1') + 1) into @days;
		
		WHILE @minDay <= @days DO 
			SET @sql = CONCAT('ALTER TABLE device_log add PARTITION (PARTITION device_log_' ,@minDay,' VALUES in (' ,@minDay,') )'); 
			
			PREPARE stmt FROM @sql ; 
			EXECUTE stmt ; 
			DEALLOCATE PREPARE stmt ;

			SET @minDay = @minDay + 1;
		END	WHILE;

	END IF;
END

创建分区表删除存储过程,并将其命名为:reduce_log_partition

BEGIN
	select DATEDIFF(now(),'1970-1-1') into @days;
	SET @find = 1;

	WHILE @find > 0 DO
		select replace(partition_name,'device_log_','') into @minDay	from INFORMATION_SCHEMA. PARTITIONS where	table_name = 'device_log' order by partition_ordinal_position asc limit 1;

		IF ISNULL(@minDay) THEN
			SET @find = 0;
		ELSE
			SET @minDay = CAST(@minDay AS UNSIGNED INTEGER);			
			IF @minDay + 15 <= @days THEN
				SET @sql = CONCAT('alter table device_log drop partition device_log_',@minDay);

				PREPARE stmt FROM @sql ; 
				EXECUTE stmt ; 
				DEALLOCATE PREPARE stmt ;
			ELSE
				SET @find = 0;
			END IF;
		END IF;
	END WHILE;
END

这里创建2个存储过程是为了将来在某些时刻可能需要单独调用。

创建一个Mysql事件来定时执行以上两个存储过程:device_log_event

BEGIN
	DECLARE r_code CHAR(5) DEFAULT '00000';
  DECLARE r_msg TEXT;
  DECLARE v_starttime DATETIME DEFAULT NOW();

	BEGIN
		BEGIN
			DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 
			GET DIAGNOSTICS CONDITION 1 r_code = RETURNED_SQLSTATE , r_msg = MESSAGE_TEXT;
		END;

		call create_log_partition();
		call reduce_log_partition();
	END;

	insert into event_log (event_name,start_time,end_time,state,msg)values ('device_log_event',v_starttime,now(),r_code,r_msg);

END

设置执行周期 

 Mysql 自动创建分区表及自动删除分区表_第1张图片

这里面有一个event_log表,用来记录事件执行情况,定义如下 

CREATE TABLE `event_log` (
  `event_log_id` int(11) NOT NULL AUTO_INCREMENT,
  `event_name` varchar(255) NOT NULL,
  `start_time` datetime NOT NULL,
  `end_time` datetime NOT NULL,
  `state` varchar(5) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '0',
  `msg` text CHARACTER SET utf8 COLLATE utf8_general_ci,
  PRIMARY KEY (`event_log_id`)
) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8;

device_log为分区表名称,可根据您的表名称进行更改。

你可能感兴趣的:(数据库,mysql)