Hi, I have a question regarding RGW's Garbage Collection behavior. I'm looking GC code, because descriptions of GC related config options are far different from web document. e.g.,: rgw gc max objs http://docs.ceph.com/docs/master/radosgw/config-ref/ The maximum number of objects that may be handled by garbage collection in one garbage collection processing cycle. https://github.com/ceph/ceph/blob/9bc1d6037be091c7dbbff68fedcb142031a0625b/src/common/options.cc#L6036-L6042 The number of garbage collector data shards, is the number of RADOS objects that RGW will use to store the garbage collection information on. Actual code is as bellow. It seems latter description reflects actual behavior. But I have a question on this code. When large amount of objects are registered in GC data shards, a GC process may continue to delete objects up to 32 hours. rgw_gc_processor_max_time (default 1hr) * max_objs (= rgw_gc_max_objs: default 32) = 32 hrs Is it expected behavior? I expected maximum time for single GC process is limited by rgw_gc_processor_max_time regardless of rgw_gc_max_objs setting. And, I assumed rgw_gc_processor_period determines minimum interval between 2 GC processes. ----- https://github.com/ceph/ceph/blob/923a7ae885a0d6a73c24d538a8cea2da53b4a7e9/src/rgw/rgw_gc.cc#L239-L256 int RGWGC::process() { int max_secs = cct->_conf->rgw_gc_processor_max_time; unsigned start; int ret = get_random_bytes((char *)&start, sizeof(start)); if (ret < 0) return ret; for (int i = 0; i < max_objs; i++) { int index = (i + start) % max_objs; ret = process(index, max_secs); if (ret < 0) return ret; } return 0; } ----- https://github.com/ceph/ceph/blob/923a7ae885a0d6a73c24d538a8cea2da53b4a7e9/src/rgw/rgw_gc.cc#L280-L308 void *RGWGC::GCWorker::entry() { do { utime_t start = ceph_clock_now(); dout(2) << "garbage collection: start" << dendl; int r = gc->process(); if (r < 0) { dout(0) << "ERROR: garbage collection process() returned error r=" << r << dendl; } dout(2) << "garbage collection: stop" << dendl; if (gc->going_down()) break; utime_t end = ceph_clock_now(); end -= start; int secs = cct->_conf->rgw_gc_processor_period; if (secs <= end.sec()) continue; // next round secs -= end.sec(); lock.Lock(); cond.WaitInterval(lock, utime_t(secs, 0)); lock.Unlock(); } while (!gc->going_down()); return NULL; } -- KIMURA Osamu / 木村 修 SDS Business Planning Department, Data Center Division, Data Center Platform Business Unit, FUJITSU LIMITED