Table 软删除

功能目标

软删除主要用于防范数据被错误的永久删除。具体而言,软删除应该具有如下几个功能:

  • 当用户删除某个指定的表后,该表变得不可访问。
  • 被删除的表其数据不会立即物理清除,而是会保留一段时间。
  • 被删除的表过期(超过保留时间)后,数据会从物理上做彻底的删除,但是数据真正删除的时间还取决于其他因素,参见垃圾文件夹管理
  • 未过期的表可以通过一定的方式恢复,恢复成功后又可以像正常的表一样进行读写访问。

操作命令

shell端提供了droprecall命令支持软删除。

使用drop命令删除表

使用方式:

drop                   <app_name> [-r|--reserve_seconds num]

drop命令用于删除一个表,通过-r选项指定数据的保留时间,从删除时间开始计算,单位为秒。如果不指定,则使用配置文件hold_seconds_for_dropped_app指定的值,默认为7天。

表删除成功后:

  • 再次访问该表,将会返回ERR_OBJECT_NOT_FOUND,提示表不存在。
  • 通过shell的ls命令看不到被删除的表。
  • 通过shell的ls -a命令可以看到被删除的表。
  • 被删除的表的ID不会被重用,以防止恢复时出现ID冲突。
  • 表删除后,可以新建同名表,当客户端访问这个表名时,访问的是新表。

过期表数据的物理删除

过期表的数据在各个replica server上也未必能立即被物理删除,因为:

  • 表的保留时间过期后,只有通过shell设置了set_meta_level lively,使meta server进入负载均衡模式,meta server才会通过config_syncRPC通知replica server删除相关的replica。而replica server在收到meta server的通知后,就会将需删除的replica文件夹通过添加.gar后缀进行重命名,表示这是可以被删除的垃圾数据。但此时数据仍未被真正物理删除。
  • replica server会定期(配置文件disk_stat_interval_seconds)扫描各个数据文件夹(配置文件data_dirs),统计文件夹的使用情况。对于标记为.gar后缀的replica文件夹,获取其最后修改时间,并和当前时间进行比较,只有当两者时间差超过了阈值(配置文件gc_disk_garbage_replica_interval_seconds)后,在会将文件夹删除掉。此时数据才算被真正物理删除。

所以综上所述,能够影响表被删除后进行物理删除的时间点的配置项包括:

  • [meta_server] hold_seconds_for_dropped_app:当drop表没有指定-r选项时,决定该表的保留时间。
  • [replication] disk_stat_interval_seconds:replica server定期扫描各个数据文件夹的时间间隔。
  • [replication] gc_disk_garbage_replica_interval_seconds:垃圾replica文件夹的最后修改时间距离当前时间超过这个阈值,文件夹才会被删除。

如果遇到需要紧急删除数据以释放磁盘空间,但是又不方便重启replica server更新配置的情况,可以根据表ID进行手工暴力删除,但是千万注意:

  • 不到万不得已,不要进行手工暴力删表,避免误操作。
  • 坚决只能删除过期表的数据。
  • 不要误删其他表的数据。

使用recall命令恢复表

使用方式

recall                 <app_id> [new_app_name]

只要表的保留时间还没有过期,就能执行恢复:

  • 恢复时需指定表ID。
  • 可以指定新表名,如果不指定新表名,则会使用原表名。
  • 如果原表名已存在(删表后新建了同名表),则必须指定另外一个不同的新表名,否则会失败。
  • 恢复过程可能需要花费一段时间。

示例

以下是使用示例:删除mytable表,然后恢复成新表名mytable2

>>> ls
app_id    status              app_name            app_type            partition_count     replica_count       is_stateful         drop_expire_time    envs_count          
1         AVAILABLE           temp                pegasus             8                   3                   true                -                   0                   
2         AVAILABLE           mytable             pegasus             8                   3                   true                -                   0                   

list apps succeed

>>> drop mytable
reserve_seconds = 0
drop app mytable succeed

>>> ls
app_id    status              app_name            app_type            partition_count     replica_count       is_stateful         drop_expire_time    envs_count          
1         AVAILABLE           temp                pegasus             8                   3                   true                -                   0                   

list apps succeed

>>> ls -a
app_id    status              app_name            app_type            partition_count     replica_count       is_stateful         drop_expire_time    envs_count          
1         AVAILABLE           temp                pegasus             8                   3                   true                -                   0                   
2         DROPPED             mytable             pegasus             8                   3                   true                2018-07-28 19:07:21 0                   

list apps succeed

>>> recall 2 mytable2
recall app ok, id(2), name(mytable2), partition_count(8), wait it ready
mytable2 not ready yet, still waiting... (0/8)
mytable2 not ready yet, still waiting... (0/8)
mytable2 not ready yet, still waiting... (0/8)
mytable2 not ready yet, still waiting... (0/8)
mytable2 not ready yet, still waiting... (0/8)
mytable2 not ready yet, still waiting... (0/8)
mytable2 not ready yet, still waiting... (0/8)
mytable2 not ready yet, still waiting... (0/8)
mytable2 not ready yet, still waiting... (7/8)
mytable2 is ready now: (8/8)
recall app 2 succeed

>>> ls
app_id    status              app_name            app_type            partition_count     replica_count       is_stateful         drop_expire_time    envs_count          
1         AVAILABLE           temp                pegasus             8                   3                   true                -                   0                   
2         AVAILABLE           mytable2            pegasus             8                   3                   true                -                   0                   

list apps succeed

设计与实现

关键点:

  • 表的生命周期定义要清晰:对于正在删除/召回的表,其他的create/recall/drop的操作要禁止。
  • 表的过期时间要在各个meta server之间达成一致,这需要各个meta server做时钟同步。
  • 如果表格被多次的删除和召回,当这些消息以乱序的方式送达到replica server时,一定要保证replica server能处理这些情况。最好能把drop操作映射成replica configuration元数据的变更。

实现要点简述:

  • meta server对删除动作的响应:当收到客户端响应时,meta server需要把信息更新到zookeeper: (1) app的状态改为dropped, 记录过期时间 (2) 升级configuration的状态,并记录到zookeeper。
  • replica server的replica生命周期变化:replica server通过定期和meta server交换心跳获取自己所服务的replica,如果发现本地的replica已经在远端不存在,则把本地的replica清除掉。
  • 过期数据的删除:replica server和meta交换心跳时,汇报自己所存储的replica。当meta判定一个replica已经无效时,命令replica将其删掉。
Copyright © 2023 The Apache Software Foundation. Licensed under the Apache License, Version 2.0.

Apache Pegasus is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.

Apache Pegasus, Pegasus, Apache, the Apache feather logo, and the Apache Pegasus project logo are either registered trademarks or trademarks of The Apache Software Foundation in the United States and other countries.