1336
1339
dout(10) << "load_pgs done" << dendl;
1341
build_past_intervals_parallel();
1346
* build past_intervals efficiently on old, degraded, and buried
1347
* clusters. this is important for efficiently catching up osds that
1348
* are way behind on maps to the current cluster state.
1350
* this is a parallel version of PG::generate_past_intervals().
1351
* follow the same logic, but do all pgs at the same time so that we
1352
* can make a single pass across the osdmap history.
1356
vector<int> old_acting, old_up;
1357
epoch_t same_interval_since;
1360
void OSD::build_past_intervals_parallel()
1362
map<PG*,pistate> pis;
1364
// calculate untion of map range
1365
epoch_t end_epoch = superblock.oldest_map;
1366
epoch_t cur_epoch = superblock.newest_map;
1367
for (hash_map<pg_t, PG*>::iterator i = pg_map.begin();
1373
if (!pg->_calc_past_interval_range(&start, &end))
1376
dout(10) << pg->info.pgid << " needs " << start << "-" << end << dendl;
1377
pistate& p = pis[pg];
1380
p.same_interval_since = 0;
1382
if (start < cur_epoch)
1384
if (end > end_epoch)
1388
dout(10) << __func__ << " nothing to build" << dendl;
1392
dout(1) << __func__ << " over " << cur_epoch << "-" << end_epoch << dendl;
1393
assert(cur_epoch <= end_epoch);
1395
OSDMapRef cur_map, last_map;
1396
for ( ; cur_epoch <= end_epoch; cur_epoch++) {
1397
dout(10) << __func__ << " epoch " << cur_epoch << dendl;
1399
cur_map = get_map(cur_epoch);
1401
for (map<PG*,pistate>::iterator i = pis.begin(); i != pis.end(); ++i) {
1403
pistate& p = i->second;
1405
if (cur_epoch < p.start || cur_epoch > p.end)
1408
vector<int> acting, up;
1409
cur_map->pg_to_up_acting_osds(pg->info.pgid, up, acting);
1411
if (p.same_interval_since == 0) {
1412
dout(10) << __func__ << " epoch " << cur_epoch << " pg " << pg->info.pgid
1413
<< " first map, acting " << acting
1414
<< " up " << up << ", same_interval_since = " << cur_epoch << dendl;
1415
p.same_interval_since = cur_epoch;
1417
p.old_acting = acting;
1422
std::stringstream debug;
1423
bool new_interval = pg_interval_t::check_new_interval(p.old_acting, acting,
1425
p.same_interval_since,
1426
pg->info.history.last_epoch_clean,
1428
&pg->past_intervals,
1431
dout(10) << __func__ << " epoch " << cur_epoch << " pg " << pg->info.pgid
1432
<< " " << debug.str() << dendl;
1434
p.old_acting = acting;
1435
p.same_interval_since = cur_epoch;
1440
// write info only at the end. this is necessary because we check
1441
// whether the past_intervals go far enough back or forward in time,
1442
// but we don't check for holes. we could avoid it by discarding
1443
// the previous past_intervals and rebuilding from scratch, or we
1444
// can just do this and commit all our work at the end.
1445
ObjectStore::Transaction t;
1447
for (map<PG*,pistate>::iterator i = pis.begin(); i != pis.end(); ++i) {
1451
// don't let the transaction get too big
1452
if (++num >= g_conf->osd_target_transaction_size) {
1453
store->apply_transaction(t);
1454
t = ObjectStore::Transaction();
1459
store->apply_transaction(t);
1341
1464
* look up a pg. if we have it, great. if not, consider creating it IF the pg mapping