Project

General

Profile

Actions

Bug #6685

closed

osd/ReplicatedPG.cc: 8345: FAILED assert(0 == "erroneously present object")

Added by Sage Weil over 10 years ago. Updated about 10 years ago.

Status:
Resolved
Priority:
Urgent
Assignee:
David Zafman
Category:
OSD
Target version:
-
% Done:

0%

Source:
Q/A
Tags:
Backport:
Regression:
Severity:
3 - minor
Reviewed:
Affected Versions:
ceph-qa-suite:
Pull request ID:
Crash signature (v1):
Crash signature (v2):

Description

     0> 2013-10-30 01:25:16.471146 7eff572f7700 -1 osd/ReplicatedPG.cc: In function 'virtual void ReplicatedPG::check_local()' thread 7eff572f7700 time 2013-10-30 01:25:16.465970
osd/ReplicatedPG.cc: 8345: FAILED assert(0 == "erroneously present object")

 ceph version 0.71-328-g1e2e429 (1e2e4297f8ed56ad83fb2083ae7e0ff4b86bdee1)
 1: (ReplicatedPG::check_local()+0x4c6) [0x7eb3a6]
 2: (PG::activate(ObjectStore::Transaction&, unsigned int, std::list<Context*, std::allocator<Context*> >&, std::map<int, std::map<pg_t, pg_query_t, std::less<pg_t>, std::allocator<std::pair<pg_t const, pg_query_t> > >, std::less<int>, std::allocator<std::pair<int const, std:
:map<pg_t, pg_query_t, std::less<pg_t>, std::allocator<std::pair<pg_t const, pg_query_t> > > > > >&, std::map<int, std::vector<std::pair<pg_notify_t, std::map<unsigned int, pg_interval_t, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, pg_interval_t> > >
 >, std::allocator<std::pair<pg_notify_t, std::map<unsigned int, pg_interval_t, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, pg_interval_t> > > > > >, std::less<int>, std::allocator<std::pair<int const, std::vector<std::pair<pg_notify_t, std::map<unsi
gned int, pg_interval_t, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, pg_interval_t> > > >, std::allocator<std::pair<pg_notify_t, std::map<unsigned int, pg_interval_t, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, pg_interval_t
> > > > > > > > >*)+0x157) [0x796a87]
 3: (PG::RecoveryState::Active::Active(boost::statechart::state<PG::RecoveryState::Active, PG::RecoveryState::Primary, PG::RecoveryState::Activating, (boost::statechart::history_mode)0>::my_context)+0x34f) [0x799fff]
 4: (boost::statechart::state<PG::RecoveryState::Active, PG::RecoveryState::Primary, PG::RecoveryState::Activating, (boost::statechart::history_mode)0>::shallow_construct(boost::intrusive_ptr<PG::RecoveryState::Primary> const&, boost::statechart::state_machine<PG::RecoverySta
te::RecoveryMachine, PG::RecoveryState::Initial, std::allocator<void>, boost::statechart::null_exception_translator>&)+0x5c) [0x7ce64c]
 5: (boost::statechart::detail::safe_reaction_result boost::statechart::simple_state<PG::RecoveryState::Peering, PG::RecoveryState::Primary, PG::RecoveryState::GetInfo, (boost::statechart::history_mode)0>::transit_impl<PG::RecoveryState::Active, PG::RecoveryState::RecoveryMac
hine, boost::statechart::detail::no_transition_function>(boost::statechart::detail::no_transition_function const&)+0x94) [0x7cf104]
 6: (boost::statechart::simple_state<PG::RecoveryState::Peering, PG::RecoveryState::Primary, PG::RecoveryState::GetInfo, (boost::statechart::history_mode)0>::react_impl(boost::statechart::event_base const&, void const*)+0x192) [0x7cf3a2]
 7: (boost::statechart::simple_state<PG::RecoveryState::WaitFlushedPeering, PG::RecoveryState::Peering, boost::mpl::list<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_:
:na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, (boost::statechart::history_mode)0>::react_impl(boost::statechart::event_base const&, void const*)+0x90) [0x7c96f0]
 8: (boost::statechart::state_machine<PG::RecoveryState::RecoveryMachine, PG::RecoveryState::Initial, std::allocator<void>, boost::statechart::null_exception_translator>::process_queued_events()+0xfb) [0x7af58b]
 9: (boost::statechart::state_machine<PG::RecoveryState::RecoveryMachine, PG::RecoveryState::Initial, std::allocator<void>, boost::statechart::null_exception_translator>::process_event(boost::statechart::event_base const&)+0x1e) [0x7af70e]
 10: (PG::handle_activate_map(PG::RecoveryCtx*)+0x103) [0x76b293]
 11: (OSD::advance_pg(unsigned int, PG*, ThreadPool::TPHandle&, PG::RecoveryCtx*, std::set<boost::intrusive_ptr<PG>, std::less<boost::intrusive_ptr<PG> >, std::allocator<boost::intrusive_ptr<PG> > >*)+0x420) [0x621bd0]
 12: (OSD::process_peering_events(std::list<PG*, std::allocator<PG*> > const&, ThreadPool::TPHandle&)+0x1d3) [0x621ef3]
 13: (OSD::PeeringWQ::_process(std::list<PG*, std::allocator<PG*> > const&, ThreadPool::TPHandle&)+0x12) [0x669bb2]
 14: (ThreadPool::worker(ThreadPool::WorkThread*)+0x4e6) [0x943796]
 15: (ThreadPool::WorkThread::entry()+0x10) [0x9455a0]
 16: (()+0x7e9a) [0x7eff6bb96e9a]
 17: (clone()+0x6d) [0x7eff69f4fccd]
 NOTE: a copy of the executable, or `objdump -rdS <executable>` is needed to interpret this.


ubuntu@teuthology:/var/lib/teuthworker/archive/teuthology-2013-10-29_23:00:22-rados-next-testing-basic-plana/75536

Files

ceph-osd.1.log.gz (26.7 MB) ceph-osd.1.log.gz Sage Weil, 01/24/2014 01:46 PM

Related issues 1 (0 open1 closed)

Has duplicate Ceph - Bug #6905: nightlies: failed to become clean before timeout expiredDuplicateDavid Zafman11/26/2013

Actions
Actions #1

Updated by Samuel Just over 10 years ago

Urgh, this is because we can advance last_backfill past uncompleted removal ops during backfill. Working on it.

Actions #2

Updated by Samuel Just over 10 years ago

  • Status changed from New to In Progress
  • Assignee set to Samuel Just
Actions #3

Updated by Samuel Just over 10 years ago

Or not, we process the OP_BACKFILL_PROGRESS ordered vs the removal ops.

Actions #4

Updated by Samuel Just over 10 years ago

It did happen immediately after transitioning from being the backfill target

Actions #5

Updated by Samuel Just over 10 years ago

ubuntu@teuthology:/a/teuthology-2013-11-01_23:00:05-rados-next-testing-basic-plana/80229/remote

Actions #6

Updated by Samuel Just over 10 years ago

Got it with logging, working on branch.

Actions #7

Updated by Samuel Just over 10 years ago

wip-6685

Actions #8

Updated by Samuel Just over 10 years ago

  • Status changed from In Progress to 7
Actions #9

Updated by Greg Farnum over 10 years ago

commit:72e2874f402575846d1bd84f2af865d28947bc67 ("ReplicatedPG::recover_backfill: adjust last_backfill to HEAD if snapdir") looks good to me.

Actions #10

Updated by Samuel Just over 10 years ago

  • Status changed from 7 to Resolved
Actions #11

Updated by Tamilarasi muthamizhan over 10 years ago

  • Status changed from Resolved to In Progress
  • Assignee changed from Samuel Just to Sage Weil

log: ubuntu@teuthology:/a/teuthology-2013-12-04_23:00:01-rados-master-testing-basic-plana/130920

this seems to be happening in the nightlies on master branch

     0> 2013-12-05 00:20:01.433548 7fc6c4eea700 -1 osd/ReplicatedPG.cc: In function 'virtual void ReplicatedPG::check_local()' thread 7fc6c4eea700 time 2013-12-05 00:20:01.428199
osd/ReplicatedPG.cc: 8409: FAILED assert(0 == "erroneously present object")

 ceph version 0.72-390-g0dd7d29 (0dd7d2985af95716423ebebb417866f83c76b508)
 1: (ReplicatedPG::check_local()+0x4c6) [0x7780f6]
 2: (PG::activate(ObjectStore::Transaction&, unsigned int, std::list<Context*, std::allocator<Context*> >&, std::map<int, std::map<pg_t, pg_query_t, std::less<pg_t>, std::allocator<std::pair<pg_t const, pg
_query_t> > >, std::less<int>, std::allocator<std::pair<int const, std::map<pg_t, pg_query_t, std::less<pg_t>, std::allocator<std::pair<pg_t const, pg_query_t> > > > > >&, std::map<int, std::vector<std::pa
ir<pg_notify_t, std::map<unsigned int, pg_interval_t, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, pg_interval_t> > > >, std::allocator<std::pair<pg_notify_t, std::map<unsigned int
, pg_interval_t, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, pg_interval_t> > > > > >, std::less<int>, std::allocator<std::pair<int const, std::vector<std::pair<pg_notify_t, std::
map<unsigned int, pg_interval_t, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, pg_interval_t> > > >, std::allocator<std::pair<pg_notify_t, std::map<unsigned int, pg_interval_t, std:
:less<unsigned int>, std::allocator<std::pair<unsigned int const, pg_interval_t> > > > > > > > >*)+0x157) [0x7233c7]
 3: (PG::RecoveryState::Active::Active(boost::statechart::state<PG::RecoveryState::Active, PG::RecoveryState::Primary, PG::RecoveryState::Activating, (boost::statechart::history_mode)0>::my_context)+0x399)
 [0x726849]
 4: (boost::statechart::state<PG::RecoveryState::Active, PG::RecoveryState::Primary, PG::RecoveryState::Activating, (boost::statechart::history_mode)0>::shallow_construct(boost::intrusive_ptr<PG::RecoveryS
tate::Primary> const&, boost::statechart::state_machine<PG::RecoveryState::RecoveryMachine, PG::RecoveryState::Initial, std::allocator<void>, boost::statechart::null_exception_translator>&)+0x5c) [0x75b5ec
]
 5: (boost::statechart::detail::safe_reaction_result boost::statechart::simple_state<PG::RecoveryState::Peering, PG::RecoveryState::Primary, PG::RecoveryState::GetInfo, (boost::statechart::history_mode)0>:
:transit_impl<PG::RecoveryState::Active, PG::RecoveryState::RecoveryMachine, boost::statechart::detail::no_transition_function>(boost::statechart::detail::no_transition_function const&)+0x94) [0x75c0a4]
 6: (boost::statechart::simple_state<PG::RecoveryState::Peering, PG::RecoveryState::Primary, PG::RecoveryState::GetInfo, (boost::statechart::history_mode)0>::react_impl(boost::statechart::event_base const&
, void const*)+0x192) [0x75c342]
 7: (boost::statechart::simple_state<PG::RecoveryState::WaitFlushedPeering, PG::RecoveryState::Peering, boost::mpl::list<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_
::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, (boost::statechart::history_mode)0>::react_impl(boost::statechart::event_base const&, vo
id const*)+0x90) [0x756860]
 8: (boost::statechart::state_machine<PG::RecoveryState::RecoveryMachine, PG::RecoveryState::Initial, std::allocator<void>, boost::statechart::null_exception_translator>::process_queued_events()+0xfb) [0x7
3c23b]
 9: (boost::statechart::state_machine<PG::RecoveryState::RecoveryMachine, PG::RecoveryState::Initial, std::allocator<void>, boost::statechart::null_exception_translator>::process_event(boost::statechart::e
vent_base const&)+0x1e) [0x73c3be]
 10: (PG::handle_activate_map(PG::RecoveryCtx*)+0x103) [0x6f7b03]
 11: (OSD::advance_pg(unsigned int, PG*, ThreadPool::TPHandle&, PG::RecoveryCtx*, std::set<boost::intrusive_ptr<PG>, std::less<boost::intrusive_ptr<PG> >, std::allocator<boost::intrusive_ptr<PG> > >*)+0x42
0) [0x622c30]
 12: (OSD::process_peering_events(std::list<PG*, std::allocator<PG*> > const&, ThreadPool::TPHandle&)+0x1d3) [0x622f53]
 13: (OSD::PeeringWQ::_process(std::list<PG*, std::allocator<PG*> > const&, ThreadPool::TPHandle&)+0x12) [0x66a4b2]
 14: (ThreadPool::worker(ThreadPool::WorkThread*)+0x4e6) [0x945906]
 15: (ThreadPool::WorkThread::entry()+0x10) [0x947710]
 16: (()+0x7e9a) [0x7fc6d9582e9a]
 17: (clone()+0x6d) [0x7fc6d7b433fd]
 NOTE: a copy of the executable, or `objdump -rdS <executable>` is needed to interpret this.

Actions #12

Updated by Sage Weil over 10 years ago

/a/teuthology-2013-12-07_23:00:19-rados-next-testing-basic-plana/135872

also possibly

ubuntu@teuthology:/a/teuthology-2013-12-07_23:00:19-rados-next-testing-basic-plana/135917

which got an ENOTEMPTY from the FileStore.. probably the same bug

Actions #13

Updated by Sage Weil over 10 years ago

  • Assignee changed from Sage Weil to Samuel Just
Actions #14

Updated by Sage Weil over 10 years ago

ubuntu@teuthology:/a/teuthology-2013-12-19_23:00:07-rados-next-distro-basic-plana/9508

Actions #15

Updated by Sage Weil about 10 years ago

i got a complete log with osd=20 and filestore=20

Actions #16

Updated by Samuel Just about 10 years ago

  • Assignee changed from Samuel Just to David Zafman
Actions #17

Updated by David Zafman about 10 years ago

  • Status changed from In Progress to Fix Under Review
Actions #18

Updated by David Zafman about 10 years ago

  • Status changed from Fix Under Review to In Progress
Actions #19

Updated by David Zafman about 10 years ago

As unsigned values CEPH_SNAPDIR (snapdir) > CEPH_NOSNAP (head). The code wants to collapse both into a single last_backfill_started value because there can never be a snapdir and a head at the same time. Since we are currently mapping snapdir to head, the test in is_degraded_object() for last_backfill_started is broken when the object being compared is snapdir.

So if there is a snapdir in flight and we are checking soid = CEPH_NOSNAP, but last_backfill_started == head, then last_backfill_started < slid so we don't even check backfills_in_flight() and return false when it should have returned true.

if (is_backfill_targets(peer) &&
peer_info[peer].last_backfill <= soid &&
last_backfill_started >= soid &&
backfills_in_flight.count(soid))
return true;

The fix is to reverse the mapping and map head to snapdir.

Actions #20

Updated by David Zafman about 10 years ago

  • Status changed from In Progress to 7
Actions #21

Updated by David Zafman about 10 years ago

  • Status changed from 7 to In Progress
Actions #22

Updated by David Zafman about 10 years ago

The fix 545135f3e1c75318940caa2c82ac32a53fc4f957 went in because it was thought that a race was occurring between backfill and a snapdir/head change. A head change while last_backfill_started == head affects snapdir which violates the constraint of not sending operations to peers for objects past last_backfill_started (see should_send_op()).

The fix was itself causing problems because it was backing up last_back_started by setting to head for a snapdir object but head < snapdir. The in-flight snapdir push wasn't considered by a client op because of the is_degraded_object() check. It is supposed to be that any object past last_backfill_started can't be in the backfills_in_flight set.

It is assuming that the original crash seen Oct 29 has been fix because we have not been able to come up with a scenario that would cause it based on the current code. We will revert the previous fix because recover_backfill() can return with last_backfill_started == head for the following reasons. First, because update_range() will detect in the pg_log any client operation which might have affected snapdir. The snapdir is still part of the BackfillInterval remaining work because begin is set to the value of last_backfill_started. Second, a redundant snapdir removal or snapdir creation will silently succeed. A crash like that on snapdir has not been seen as far as I know. Finally, it is assumed that enough locking between client ops being sent to peers and recover_backfill() processing is present to prevent the previous 2 requirements from failing.

Actions #23

Updated by David Zafman about 10 years ago

  • Status changed from In Progress to Resolved

a9677e136ee4753b86ed1151ca6ff08e4b63473d

Actions

Also available in: Atom PDF