【CarbonData】CarbonData误删恢复(防误删功能)
1.1 CarbonData
如果执行了CarbonData误删除操作,并且core-site.xml中提前配置有fs.trash.interval值(hdfs回收站文件过期时间),并且未超出回收站文件过期时间,则可以分以下场景进行数据恢复。
恢复HDFS回收站的数据,需要先知道hdfs回收站目录,一般情况下为“/user/${用户名}/.Trash”。
1.1.1 使用drop table误删除表
如果使用了drop table语句误删除了表,可以通过以下步骤恢复:
步骤1:使用hdfs命令,从HDFS回收站将表文件夹挪回原位;命令如:
hdfs dfs –mv ${hdfs回收站表目录路径} ${表原所在数据库路径}
步骤2:进入spark-beeline或spark-sql命令行,执行REFRESH语句将表进行重新注册,如:
REFRESH TABLE $db_NAME.$table_NAME;
步骤3:如果原数据表有关联二级索引表,则需要通过步骤1和步骤2再将该数据表的二级索引表进行恢复,然后参考《2.7.6 恢复索引表与主表的索引关系》,恢复索引表与主表间的关系。
1.1.2 使用drop database误删除数据库
如果使用了drop database语句误删除了数据库,可以通过以下步骤恢复:
步骤1:进入spark-beeline或spark-sql命令行,使用建库语句创建同名数据库,如:
create database $database_name;
步骤2:参考《2.7.1 使用drop table删除了表》,恢复每一张库内的表。
1.1.3 使用delete语句误删除指定segment
1.1.3.1 场景一:删除segment,尚未执行clean语句
执行了删除segment语句但尚未执行clean file语句,则被删除的segment数据实际未被删除,只是指定的segment被标记为了Marked For Deleted (通过show segments for table $table_name语句可以查看)。这种情况下需要使用CarbonData数据恢复工具进行数据恢复。
步骤1:下载安装Spark2x客户端,source环境变量和kinit登入用户后,进入目录 /${客户端目录}/Spark2x/spark/tool/carbonRecover;
步骤2:执行脚本recover_segments_before_clean.sh,需要三个参数(数据库名+表名,表路径,需要恢复的segment ID),如:
sh recover_segments_before_clean.sh dbName.TableName /user/hive/warehouse/carbon.store/dbName/TableName/ 16,17
步骤3:在spark-sql或spark-beeline命令行中,使用show indexes语句查看被恢复的表有没有索引表,如:
SHOW INDEXES ON db_name.table_name;
步骤4:如果存在索引表,则需要参考步骤2将索引表恢复,即执行脚本recover_segments_before_clean.sh,需要三个参数(数据库名+索引表名,索引表路径,需要恢复的segment ID)。
1.1.3.2 场景二:删除segment,已经执行了clean语句
执行了删除segment语句而且已经执行了clean file语句,则被删除的segment数据实际已被删除,通过show segments for table $table_name语句无法看到被删除segment的状态。这种情况下需要使用CarbonData数据恢复工具进行数据恢复。
此场景分为两个细分场景:普通表和分区表
1.1.3.2.1 场景二-一:普通表
步骤1:下载安装Spark2x客户端,source环境变量和kinit登入用户后,进入目录 /${客户端目录}/Spark2x/spark/tool/carbonRecover;
步骤2:执行脚本recover_segments_after_clean.sh,需要五个参数(数据库名+表名,表路径,用户回收站路径,需要恢复的segment ID,是否分区表(此处为false)),如:
sh recover_segments_after_clean.sh dbName.TableName /user/hive/warehouse/carbon.store/dbName/TableName/ /user/userName/.Trash/ 16,17 false
步骤3:在spark-sql或spark-beeline命令行中,使用show indexes语句查看被恢复的表有没有索引表,如:
SHOW INDEXES ON db_name.table_name;
步骤4:如果存在索引表,则需要参考步骤2将索引表恢复,即执行脚本recover_segments_after_clean.sh,需要五个参数(数据库名+索引表名,索引表路径,用户回收站路径,需要恢复的segment ID,是否分区表(此处为false))。
1.1.3.2.2 场景二-二:分区表
步骤1:下载安装Spark2x客户端,source环境变量和kinit登入用户后,进入目录 /${客户端目录}/Spark2x/spark/tool/carbonRecover;
步骤2:执行脚本recover_segments_after_clean.sh,需要五个参数(数据库名+表名,表路径,用户回收站路径,需要恢复的segment ID,是否分区表(此处为true)),如:
sh recover_segments_after_clean.sh dbName.TableName /user/hive/warehouse/carbon.store/dbName/TableName/ /user/userName/.Trash/ 16,17 true
注意:此处表路径最后的斜杠不可省略,防止表名因前缀重复而匹配错误。
步骤3:在spark-sql或spark-beeline命令行中,使用show indexes语句查看被恢复的表有没有索引表,如:
SHOW INDEXES ON db_name.table_name;
步骤4:如果存在索引表,则需要将索引表恢复。分区表的索引表是普通表,所以即执行脚本recover_segments_after_clean.sh,需要五个参数(数据库名+索引表名,索引表路径,用户回收站路径,需要恢复的segment ID,是否分区表(此处为false))。
1.1.4 使用insert/load overwrite覆盖了表数据
使用insert/load overwrite语句覆盖了表数据,则数据实际未被删除,只是以前的segment被标记为了Marked ForDeleted (通过show segments for table $table_name语句可以查看)。
这种情况则参考《2.7.3.1 场景一:删除segment,尚未执行clean语句》,使用CarbonData数据恢复工具进行数据恢复。
1.1.4.3 补丁6.5.1.9版本对普通表insert/load overwrite的恢复操作
6.5.1版本打了6.5.1.9补丁后,CarbonData也支持防误删。
1.1.4.3.3 场景一:执行insert/overwrite后未执行clean
在6.5.1.9补丁版本中,对普通表执行insert/load overwrite,未执行clean操作,则数据文件会被删除至回收站(spark-sql场景下,回收站路径是/user/${kinit 用户}/.Trash;spark-beeline场景下,回收站路径是/user/spark2x/.Trash),此时需要使用recover_segment_after_clean.sh来进行恢复。
步骤1:下载安装Spark2x客户端,source环境变量和kinit登入用户后,进入目录 /${客户端目录}/Spark2x/spark/tool/carbonRecover;
步骤2:执行脚本recover_segments_after_clean.sh,需要五个参数(数据库名+表名,表路径,用户回收站路径,需要恢复的segment ID,是否分区表(此处为false)),如:
sh recover_segments_after_clean.sh dbName.TableName /user/hive/warehouse/carbon.store/dbName/TableName/ /user/userName/.Trash/ 16,17 false
1.1.4.3.4 场景二:执行insert/overwrite后已执行clean
如果对普通表执行insert/load overwrite,已执行clean操作,则
1. 数据文件会被删除至回收站(spark-sql场景下,回收站路径是/user/${kinit 用户}/.Trash;spark-beeline场景下,回收站路径是/user/spark2x/.Trash或者/user/${kinit 用户}/.Trash,回收站路径和HiveServer的“hive.server2.enable.doAs”配置有关,如果该配置为true,则回收站路径为/user/spark2x/.Trash,如果该配置为false,则回收站路径为/user/${kinit 用户}/.Trash);
2. 元数据文件会被删除至/user/${kinit 用户}/.Trash回收站。
所以恢复需要步骤如下:
步骤1:下载安装Spark2x客户端,source环境变量和kinit登入用户后,进入目录 /${客户端目录}/Spark2x/spark/tool/carbonRecover;
步骤2:使用hdfs命令将.segment文件从回收站mv回表目录(恢复元数据,只有spark-beeline场景需要执行),如:
hdfs dfs –mv /user/userName/.Trash/user/hive/warehouse/carbon.store/dbName/TableName/Metadata/segments/"${sId}"_*.segment /user/hive/warehouse/carbon.store/dbName/TableName/Metadata/segments/
步骤3:执行脚本recover_segments_after_clean.sh,需要五个参数(数据库名+表名,表路径,用户回收站路径,需要恢复的segment ID,是否分区表(此处为false)),如:
sh recover_segments_after_clean.sh dbName.TableName /user/hive/warehouse/carbon.store/dbName/TableName/ /user/userName/.Trash/ 16,17 false
1.1.5 使用alter drop partition语句删除了分区
1.1.5.4 场景一:alter drop partition语句不带“WITH DATA”,未执行clean
在操作carbondata分区表时,使用alter drop partition语句删除了分区,但语句中不带“ WITH DATA”,且未执行clean files语句,则数据实际未被删除,通过show segments for table $table_name语句可以查看到,指定的segment被标记为了Marked ForDeleted,这种情况下可以使用CarbonData数据恢复工具进行数据恢复。
步骤1:下载安装Spark2x客户端,source环境变量和kinit登入用户后,进入目录 /${客户端目录}/Spark2x/spark/tool/carbonRecover;
步骤2:执行脚本recover_partition_before_clean.sh,需要三个参数(数据库名+表名,表路径,分区ID),如:
sh recover_partition_before_clean.sh dbName.TableName /user/hive/warehouse/carbon.store/dbName/TableName/ p_int=002
步骤3:进入spark-sql或spark-beeline命令行,执行语句将被删除的partition加回去,如:
ALTER TABLE dbName.TableName ADD PARTITION(p_int=002);
1.1.5.5 场景二:alter drop partition语句不带“WITH DATA”,已执行clean
在操作carbondata分区表时,使用alter drop partition语句删除了分区,并且已经执行了clean语句,则数据实际已被删除,这种情况下可以使用CarbonData数据恢复工具进行数据恢复。
步骤1:下载安装Spark2x客户端,source环境变量和kinit登入用户后,进入目录 /${客户端目录}/Spark2x/spark/tool/carbonRecover;
步骤2:执行脚本recover_partition_after_clean.sh,需要三个参数(数据库名+表名,表路径,分区ID),如:
sh recover_partition_after_clean.sh dbName.TableName /user/hive/warehouse/carbon.store/dbName/TableName/ /user/userName/.Trash/ p_int=002
步骤3:进入spark-sql或spark-beeline命令行,执行语句将被删除的partition加回去,如:
ALTER TABLE dbName.TableName ADD PARTITION(p_int=002);
1.1.6 恢复索引表与主表的索引关系
在恢复了数据主表和它的索引表后,数据主表和索引表之间的索引关系并未恢复,需要执行REGISTER语句来恢复它们之间的索引关系。
即登入spark-beeline或spark-sql命令行,执行REGISTER语句如:
REGISTER INDEX TABLE indextable_name ON db_name.maintable_name;
- 点赞
- 收藏
- 关注作者
评论(0)