|
25 | 25 | #include "../common/isc_proto.h" |
26 | 26 | #include "../common/isc_s_proto.h" |
27 | 27 | #include "../jrd/jrd.h" |
| 28 | +#include "../jrd/cch_proto.h" |
28 | 29 |
|
29 | 30 | #include "Manager.h" |
30 | 31 | #include "Protocol.h" |
@@ -132,13 +133,27 @@ Manager::Manager(const string& dbId, |
132 | 133 | // Startup the journalling |
133 | 134 |
|
134 | 135 | const auto tdbb = JRD_get_thread_data(); |
135 | | - const auto* dbb = tdbb->getDatabase(); |
| 136 | + const auto dbb = tdbb->getDatabase(); |
136 | 137 |
|
137 | 138 | const auto& guid = dbb->dbb_guid; |
138 | | - m_sequence = dbb->dbb_repl_sequence; |
139 | 139 |
|
140 | 140 | if (config->journalDirectory.hasData()) |
141 | 141 | { |
| 142 | + // At this point it is unknown if change log shared memory exists or not. |
| 143 | + // To avoid race condition with concurrent changing of current replication |
| 144 | + // sequence, take and hold shared lock on header page while creating |
| 145 | + // ChangeLog instance. |
| 146 | + |
| 147 | + WIN window(HEADER_PAGE_NUMBER); |
| 148 | + CCH_FETCH(tdbb, &window, LCK_read, pag_header); |
| 149 | + |
| 150 | + Cleanup releaseHeader([&] { |
| 151 | + CCH_RELEASE(tdbb, &window); |
| 152 | + }); |
| 153 | + |
| 154 | + // Call below will fetch header page with LCK_read lock, it is allowed and OK. |
| 155 | + m_sequence = dbb->getReplSequence(tdbb); |
| 156 | + |
142 | 157 | m_changeLog = FB_NEW_POOL(getPool()) |
143 | 158 | ChangeLog(getPool(), dbId, guid, m_sequence, config); |
144 | 159 | } |
|
0 commit comments