数据清理的遗留问题处理

简介: 最近处理一个遗留问题,感觉手动修复真是让人抓狂,所以花了点力气写了一个半自动的脚本,总算从这个繁琐的工作中解放出来了。 问题的背景如下图所示。 存在一个很大的统计库(有容灾备库),还有一个历史统计库,历史统计库中都是相对较老的数据。
最近处理一个遗留问题,感觉手动修复真是让人抓狂,所以花了点力气写了一个半自动的脚本,总算从这个繁琐的工作中解放出来了。
问题的背景如下图所示。
存在一个很大的统计库(有容灾备库),还有一个历史统计库,历史统计库中都是相对较老的数据。
统计库中的数据相对要新一些,但是数据持续增长,空间使用太多,业务中使用历史数据的频率不高,把历史数据清理了又怕影响业务,就需要把数据暂时挪到历史库中,所以历史库中的数据都是几年前的老数据,而统计库中的都是近几年相对较新的数据。
比如一个分区表test,有2011年的分区数据在历史库中,有2014年的数据在统计库中,统计库中的数据太多,空间不足就需要把数据从统计库清理掉,同事保证历史库中存在这份数据。

可能之前的同事把有些表空间和分区绑定了起来,所以涉及的表空间非常多,需要检查这些表空间中所对应的数据文件,表空间所在的段中的分区数据情况,然后再在历史库中检查一遍,确定两边查到的数据条数是一样的(历史数据不会有dml改动),如果数据在两边都存在,就删除现网统计库中的,然后删除对应的数据文件,对应的表空间。
之前是每隔一周或者两周左右就会做一次这样的检查和清理工作,所以得时常惦记着,想多删点,因为手动校验检查处理着实费神费力,所以也删不了太多。
所以下了决心改进这个情况,至少做成半自动化,人工审核还是需要的,为了保证不误删,检查出现偏差。

我写了一个简单的脚本,运行内容如下:
清理之前,查看有多少含有DATA字样的表空间可清理,清理年份为2012年
check genaral status of data from year 2012
   SIZE_MB
----------
    308410
检查可清理的段情况,都是分区表和分区索引段。
check segement size summary from year 2012
SEGMENT_TYPE          SIZE_MB
------------------ ----------
INDEX PARTITION    255325.188
TABLE PARTITION        288483
检查可清理的段情况,有多少可清理
check segment count summary from year 2012
SEGMENT_TYPE         COUNT(*)
------------------ ----------
INDEX PARTITION          4148
TABLE PARTITION          1505

然后就得到了计划清理的表空间,数据文件和文件大小
CONSUMEID_DATA_20121008        +DATA/sgstatdb3/datafile/consumeid_data_20121008.758.840501581                200
CONSUMEID_DATA_20120705        +DATA/sgstatdb3/datafile/consumeid_data_20120705.752.840501565                210
CONSUMEID_DATA_20120403        +DATA/sgstatdb3/datafile/consumeid_data_20120403.742.840501535                230
CONSUMEID_DATA_20120704        +DATA/sgstatdb3/datafile/consumeid_data_20120704.743.840501541                230
CONSUMEID_DATA_20121009        +DATA/sgstatdb3/datafile/consumeid_data_20121009.746.840501549                230
CONSUMEID_DATA_20121007        +DATA/sgstatdb3/datafile/consumeid_data_20121007.741.840501535                240

然后统计有多少表空间可清理。
CONSUMEID_DATA_20121008               200
CONSUMEID_DATA_20120705               210
CONSUMEID_DATA_20121009               230
CONSUMEID_DATA_20120403               230
。。。

然后根据条件生成查看表分区数据的sql语句。
select 'TEST:TEST_SERVER_LOG_SERVER_LOG_20120410', count(*) from TEST.TEST_SERVER_LOG partition (SERVER_LOG_20120410);
select 'TEST:TEST_SERVER_LOG_SERVER_LOG_20120411', count(*) from TEST.TEST_SERVER_LOG partition (SERVER_LOG_20120411);
select 'TEST:TEST_SERVER_LOG_SERVER_LOG_20120412', count(*) from TEST.TEST_SERVER_LOG partition (SERVER_LOG_20120412);
。。。。
在统计库和历史统计库中查看。
统计库中查看
TEST:TEST_SERVER_LOG_SERVER_LOG_20120410    2118970
TEST:TEST_SERVER_LOG_SERVER_LOG_20120411    2145005
TEST:TEST_SERVER_LOG_SERVER_LOG_20120412    2128818

历史统计库中查看
TEST:TEST_SERVER_LOG_SERVER_LOG_20120410    2118970
TEST:TEST_SERVER_LOG_SERVER_LOG_20120411    2145005
TEST:TEST_SERVER_LOG_SERVER_LOG_20120412    2128818

比对两边的数据情况,如果一致则删除
alter table  TEST.TEST_SERVER_LOG drop partition (SERVER_LOG_20120410);
alter table  TEST.TEST_SERVER_LOG drop partition (SERVER_LOG_20120411);
alter table  TEST.TEST_SERVER_LOG drop partition (SERVER_LOG_20120412);

清理完成之后开始确认表空间中是否存在其它的段,然后开始尝试删除数据文件。

初版脚本如下,后面需要不断完善,不过目前所列的这些基本步骤都做到了,很多繁琐的检查工作都给提炼出来了,不用重复执行,费时费力了。
tmp_year=2012
conn_dba=testdba/testdba
hist_conn_dba=tesetdba/testdba@statdb_hist
sqlplus -s $conn_dba <<EOF
prompt check genaral status of data from year $tmp_year
select sum(bytes/1024/1024) size_MB from dba_data_files where tablespace_name like '%DATA%${tmp_year}%' ;

prompt check segement size summary from year $tmp_year
select segment_type,sum(bytes/1024/1024) size_MB from dba_segments where tablespace_name in (select tablespace_name from dba_data_files where tablespace_name like '%${tmp_year}%' ) group by segment_type;

prompt check segment count summary from year $tmp_year
select segment_type,count(*) from dba_segments where tablespace_name in (select tablespace_name from dba_data_files where tablespace_name like '%${tmp_year}%' ) group by segment_type;

set linesize 200
col file_name format a70
set pages 0
select tablespace_name,file_name,sum(bytes/1024/1024) size_MB from dba_data_files where tablespace_name like '%DATA%${tmp_year}%' group by tablespace_name,file_name order by size_MB;

select tablespace_name,sum(bytes/1024/1024) size_MB from dba_data_files where tablespace_name like '%DATA%${tmp_year}%' group by tablespace_name order by size_MB;

set feedback off
set linesize 200
spool get_tab_part_cnt.sql
select 'select '||chr(39)||owner||':'||segment_name||'_'||partition_name ||chr(39)||', count(*) from '||owner||'.'||segment_name||' partition ('||partition_name||');'
from dba_segments where tablespace_name in (select tablespace_name from dba_tablespaces  where tablespace_name like '%DATA%${tmp_year}%') and segment_type in ('TABLE PARTITION') and rownum<10;
spool off
EOF

sqlplus -s $conn_dba <<EOF
set pages 0
set feedback off
spool get_tab_part_cnt.log_statdb2
@get_tab_part_cnt.sql
spool off
EOF

sqlplus -s $hist_conn_dba <<EOF
set pages 0
set feedback off
spool get_tab_part_cnt.log_statdb2_hist
@get_tab_part_cnt.sql
spool off
EOF


sdiff get_tab_part_cnt.log_statdb2 get_tab_part_cnt.log_statdb2_hist > tab_cnt_summary.lst

diff_cnt=`diff get_tab_part_cnt.log_statdb2 get_tab_part_cnt.log_statdb2_hist`

sqlplus -s $conn_dba <<EOF
set feedback off
set pages 0
spool drop_tab_part.sql
select 'alter table  '||owner||'.'||segment_name||' drop partition ('||partition_name||');'
from dba_segments where tablespace_name in (select tablespace_name from dba_tablespaces  where tablespace_name like '%DATA%${tmp_year}%') and segment_type in ('TABLE PARTITION') and rownum<10;
spool off;
EOF

有的朋友可能疑惑为什么不用db link直接比较,因为使用db link来指定具体的分区就不支持了。
select count(*) from TEST.TEST_SERVER_LOG@db_link partition (SERVER_LOG_20120410);
ORA-14100: partition extended table name cannot refer to a remote object
要想突破,搜到的解决方法有两种,但是都果断放弃了,因为确实也没有太好的效果。
解决方式有两种:
1、  不使用partition选项,而在where的条件里进行数据筛选
2、  在源库设立视图,指向分区数据,通过dblink访问该视图
 另外通过创建远程表分区的同义词可以达到避过该错误的目的,但效果和全表扫描一样,并不能实现分区扫描,所以并无意义


目录
相关文章
|
Cloud Native 应用服务中间件 网络安全
15.1k Star! 一个不用会 Nginx 的反向代理神器 - Nginx Proxy Manager
应用简览 Nginx Proxy Manager 是一个开源的反向代理工具,不需要了解太多 Nginx 或 Letsencrypt 的相关知识,即可快速将你的服务暴露到外部环境,并且支持 SSL 配置。
603 0
|
11月前
「Mac畅玩鸿蒙与硬件41」UI互动应用篇18 - 多滑块联动控制器
本篇将带你实现一个多滑块联动的控制器应用。用户可以通过拖动多个滑块,动态控制不同参数(如红绿蓝三色值),并实时显示最终结果。我们将以动态颜色调节为例,展示如何结合状态管理和交互逻辑,打造一个高级的滑块控制器应用。
345 78
「Mac畅玩鸿蒙与硬件41」UI互动应用篇18 - 多滑块联动控制器
|
12月前
|
机器学习/深度学习 传感器 自动驾驶
基于深度学习的图像识别技术在自动驾驶汽车中的应用####
【10月更文挑战第21天】 本文探讨了深度学习中的卷积神经网络(CNN)如何革新自动驾驶车辆的视觉感知能力,特别是在复杂多变的道路环境中实现高效准确的物体检测与分类。通过分析CNN架构设计、数据增强策略及实时处理优化等关键技术点,揭示了该技术在提升自动驾驶系统环境理解能力方面的潜力与挑战。 ####
406 0
|
机器学习/深度学习 并行计算 大数据
【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧2
【Python篇】NumPy完整指南(上篇):掌握数组、矩阵与高效计算的核心技巧
381 10
|
JSON JavaScript 中间件
深入浅出Node.js后端开发之Express框架应用
【8月更文挑战第29天】本文将带领读者快速了解并掌握使用Express框架进行Node.js后端开发的基础和进阶知识。我们将一起探索Express的安装、基本使用方法,并通过实际代码示例学习如何搭建一个简单的Web服务器。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供有价值的指导和灵感。
|
Ubuntu 关系型数据库 应用服务中间件
在Ubuntu 18.04上安装和配置pgAdmin 4服务器模式的方法
在Ubuntu 18.04上安装和配置pgAdmin 4服务器模式的方法
339 0
|
文字识别 安全 网络安全
印刷文字识别产品使用合集之一般包含什么信息, 会被认为敏感信息
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
编解码 数据安全/隐私保护 计算机视觉
音视频学习之ffmpeg常用基础命令整理
音视频学习之ffmpeg常用基础命令整理
370 0
|
弹性计算 固态存储 大数据
阿里云企业云服务器实例可选配置及适用场景汇总
本文介绍了阿里云企业级云服务器的主要实例规格及各自的适用场景、可选配置、最大基础带宽能力、最大网络收发包能力等信息,可供新手用户了解和选择适合自己的实例。
715 1