5be9c31001
Accounts have been migrated to NoteDb, hence also the account sequence should be moved to NoteDb. In NoteDb the current account sequence number is stored as UTF-8 text in a blob pointed to by the 'refs/sequences/accounts' ref in the 'All-Users' repository. Multiple processes share the same sequence by incrementing the counter using normal git ref updates. To amortize the cost of these ref updates, processes can increment the counter by a larger number and hand out numbers from that range in memory until they run out. The size of the account ID batch that each process retrieves at once is controlled by the 'notedb.accounts.sequenceBatchSize' configuration parameter in 'gerrit.config'. By default the value is 1 since it's unlikely that a process ever creates more than one account. This follows the example of storing the change sequence in NoteDb. A difference is that the account sequence is stored in the 'All-Users' repository while the change sequence is stored in the 'All-Projects' repository. Storing the account sequence in the 'All-Users' repository makes more sense since this repository already contains all of the other account data. Injecting the Sequences class that provides new sequences numbers requires request scope. There are 2 places outsite of request scope where new account sequence numbers are required, AccountManager and AccountCreator (only used for tests). These classes need to create a request context to get an account sequence number. For AccountManager the request scope is only created when a new account is created and not when an existing account is authenticated. Since there is an init step that creates an initial admin user we must make the account sequence available during the init phase. For this the class SequencesOnInit is added which can only generate account IDs, but only depends on classes that are available during the init phase. For this class the account ID batch size is hard-coded to 1, since init only creates a single account and we don't want to waste account IDs when a new Gerrit server is initialized. This change also contains a schema migration that ensures that the account sequence is created in NoteDb. To support a live migration on a multi-master Gerrit installation, there is a configuration parameter ('notedb.accounts.readSequenceFromNoteDb') that controls whether account sequence numbers are read from NoteDb or ReviewDb. By default the value for this parameter is `false` so account sequence numbers are read from ReviewDb. If account sequence numbers are read from ReviewDb the sequence numbers in NoteDb will be kept in sync. This is achieved by writing the next available sequence number to NoteDb whenever a sequence number from ReviewDb is retrieved. If writing to NoteDb fails, an exception is raised to the caller and the sequence number that was retrieved from ReviewDb is not used. Writing to NoteDb is retried several times so that the caller only gets an exception if writing to NoteDb fails permanently. For the case where two threads try to update the sequence number in NoteDb concurrently we must make sure that the value in NoteDb is never decreased. E.g.: 1. Thread 1 retrieves account ID 14 from ReviewDb 2. Thread 2 retrieves account ID 15 from ReviewDb 3. Thread 2 writes the next available account ID 16 to NoteDb 4. Thread 1 tries to write the next available account ID 15 to NoteDb but fails since Thread 2 updated the value concurrently. 5. Thread 1 finds that it doesn't need to update the account ID in NoteDb anymore since Thread 2 already updated the account ID to a higher value This means at any point in time it is safe to switch to reading account IDs from NoteDb. However once this switch is done it is not possible to switch back to reading account IDs from ReviewDb, since ReviewDb will be out of sync as soon as the first account ID was retrieved from NoteDb. The migration on a multi-master Gerrit installation will be done with the following steps: 1. rollout this change to all nodes: - account sequence numbers are read from ReviewDb - the sequence numbers in NoteDb are kept in sync 2. wait some time until we are sure that we don't need to roll back to a release that doesn't contain this change 3. run an offline migration to ensure that the account sequence number in NoteDb is initialized on all nodes 4. set 'notedb.accounts.readSequenceFromNoteDb' to true so that account sequence numbers are now read from NoteDb (this setting cannot be reverted since the account sequence in ReviewDb will be outdated once account IDs are retrieved from NoteDb) After this is done a follow-up change can remove the handling for 'notedb.accounts.readSequenceFromNoteDb' so that account IDs are now always retrieved from NoteDb. Change-Id: I023d2de643ed0c15197c09fa19105cc2acb5091e Signed-off-by: Edwin Kempin <ekempin@google.com> |
||
---|---|---|
.. | ||
src | ||
BUILD |