Skip to content

Commit da44951

Browse files
authored
Merge pull request #231 from arangodb-helper/bug-fix/fix-upgrade-from-346
Special upgrade procedure for from 3.4.6.
2 parents 891ddd2 + 948c5c7 commit da44951

File tree

5 files changed

+78
-3
lines changed

5 files changed

+78
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Changes from 0.14.4 to 0.14.5
44

5+
- Implement special upgrade procedure for upgrading from 3.4.6
56
- Move to alpine 3.9 for Docker image
67

78
## Changes from 0.14.3 to 0.14.4

MAINTAINERS.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@
44

55
A subset of all tests are frequently run in Travis.
66

7-
To run the entire test set, run:
7+
To run the entire test set, set the following environment variables,
8+
9+
- `ARANGODB`: name of Docker image for ArangoDB to use
10+
- `VERBOSE` (optional): set to `1` for more output
11+
- `IP` (for Docker tests): set to a valid IP address on the local machine
12+
- `TESTOPTIONS`` (optional): set to `-test.run=REGEXPTOMATCHTESTS` to
13+
run only some tests
14+
15+
Then run:
816

917
```bash
1018
make run-tests

client/client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"io/ioutil"
3030
"net/http"
3131
"net/url"
32+
"time"
3233

3334
driver "github.com/arangodb/go-driver"
3435
"github.com/pkg/errors"
@@ -245,6 +246,7 @@ func (c *client) RemovePeer(ctx context.Context, id string, force bool) error {
245246
func (c *client) StartDatabaseUpgrade(ctx context.Context) error {
246247
url := c.createURL("/database-auto-upgrade", nil)
247248

249+
c.client.Timeout = time.Minute * 5
248250
req, err := http.NewRequest("POST", url, nil)
249251
if err != nil {
250252
return maskAny(err)

service/peer.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,21 @@ func (p Peer) CreateCoordinatorAPI(clientBuilder ClientBuilder) (driver.Client,
126126
return nil, maskAny(fmt.Errorf("Peer has no coordinator"))
127127
}
128128

129+
// CreateAgentAPI creates a client for the agent of the peer
130+
func (p Peer) CreateAgentAPI(clientBuilder ClientBuilder) (driver.Client, error) {
131+
if p.HasAgent() {
132+
port := p.Port + p.PortOffset + ServerType(ServerTypeAgent).PortOffset()
133+
scheme := NewURLSchemes(p.IsSecure).Browser
134+
ep := fmt.Sprintf("%s://%s", scheme, net.JoinHostPort(p.Address, strconv.Itoa(port)))
135+
c, err := clientBuilder([]string{ep}, ConnectionTypeDatabase)
136+
if err != nil {
137+
return nil, maskAny(err)
138+
}
139+
return c, nil
140+
}
141+
return nil, maskAny(fmt.Errorf("Peer has no agent"))
142+
}
143+
129144
// PortRangeOverlaps returns true if the port range of this peer overlaps with a port
130145
// range starting at given port.
131146
func (p Peer) PortRangeOverlaps(otherPort int, clusterConfig ClusterConfig) bool {

service/upgrade_manager.go

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import (
3232

3333
driver "github.com/arangodb/go-driver"
3434
"github.com/arangodb/go-driver/agency"
35-
"github.com/arangodb/go-upgrade-rules"
35+
upgraderules "github.com/arangodb/go-upgrade-rules"
3636
"github.com/pkg/errors"
3737
"github.com/rs/zerolog"
3838
"github.com/ryanuber/columnize"
@@ -93,7 +93,7 @@ type UpgradeManagerContext interface {
9393
// NewUpgradeManager creates a new upgrade manager.
9494
func NewUpgradeManager(log zerolog.Logger, upgradeManagerContext UpgradeManagerContext) UpgradeManager {
9595
return &upgradeManager{
96-
log: log,
96+
log: log,
9797
upgradeManagerContext: upgradeManagerContext,
9898
}
9999
}
@@ -252,10 +252,14 @@ func (m *upgradeManager) StartDatabaseUpgrade(ctx context.Context) error {
252252
}
253253

254254
// Check if we can upgrade from running to binary versions
255+
specialUpgradeFrom346 := false
255256
for _, from := range runningDBVersions {
256257
if err := upgraderules.CheckUpgradeRules(from, toVersion); err != nil {
257258
return maskAny(errors.Wrap(err, "Found incompatible upgrade versions"))
258259
}
260+
if from.CompareTo("3.4.6") == 0 {
261+
specialUpgradeFrom346 = true
262+
}
259263
}
260264

261265
// Fetch mode
@@ -300,18 +304,61 @@ func (m *upgradeManager) StartDatabaseUpgrade(ctx context.Context) error {
300304
lock.Unlock(context.Background())
301305
}()
302306

307+
m.log.Debug().Msg("Reading upgrade plan...")
303308
// Check existing plan
304309
plan, err := m.readUpgradePlan(ctx)
305310
if err != nil && !agency.IsKeyNotFound(err) {
306311
// Failed to read upgrade plan
312+
m.log.Error().Msg("Failed to read upgrade plan")
307313
return errors.Wrap(err, "Failed to read upgrade plan")
308314
}
309315

316+
m.log.Debug().Msg("Checking if plan is ready...")
310317
// Check plan status
311318
if !plan.IsReady() {
319+
m.log.Debug().Msg("Current upgrade plan has not finished yet.")
312320
return maskAny(client.NewBadRequestError("Current upgrade plan has not finished yet"))
313321
}
314322

323+
// Special measure for upgrades from 3.4.6:
324+
if specialUpgradeFrom346 {
325+
// Write 1000 dummy values into agency to advance the log:
326+
for i := 0; i < 1000; i++ {
327+
err := api.WriteKey(nil, []string{"/arangodb-helper/dummy"}, 17, 0)
328+
if err != nil {
329+
m.log.Error().Msg("Could not append log entries to agency.")
330+
return maskAny(err)
331+
}
332+
}
333+
m.log.Debug().Msg("Have written 1000 log entries into agency.")
334+
335+
// wait for the compaction to be created
336+
time.Sleep(3 * time.Second)
337+
338+
// Repair each agent's persistent snapshots:
339+
for _, p := range config.AllPeers {
340+
if p.HasAgent() {
341+
cli, err := p.CreateAgentAPI(m.upgradeManagerContext.CreateClient)
342+
if err != nil {
343+
m.log.Error().Msgf("Could not create client for agent of peer %s", p.ID)
344+
return maskAny(err)
345+
}
346+
db, err := cli.Database(nil, "_system")
347+
if err != nil {
348+
m.log.Error().Msgf("Could not find _system database for agent of peer %s", p.ID)
349+
return maskAny(err)
350+
}
351+
_, err = db.Query(nil, "FOR x IN compact LET old = x.readDB LET new = (FOR i IN 0..LENGTH(old)-1 RETURN i == 1 ? {} : old[i]) UPDATE x._key WITH {readDB: new} IN compact", nil)
352+
if err != nil {
353+
m.log.Error().Msgf("Could not repair agent log compaction for agent of peer %s", p.ID)
354+
}
355+
m.log.Debug().Msgf("Finished repair of log compaction for agent of peer %s", p.ID)
356+
}
357+
}
358+
359+
m.log.Info().Msg("Applied special update procedure for 3.4.6")
360+
}
361+
315362
// Create upgrade plan
316363
m.log.Debug().Msg("Creating upgrade plan")
317364
plan = UpgradePlan{
@@ -387,8 +434,10 @@ func (m *upgradeManager) StartDatabaseUpgrade(ctx context.Context) error {
387434
m.log.Debug().Msg("Writing upgrade plan")
388435
overwrite := true
389436
if _, err := m.writeUpgradePlan(ctx, plan, overwrite); driver.IsPreconditionFailed(err) {
437+
m.log.Error().Msg("Failed to write upgrade plan because it was outdated or removed.")
390438
return errors.Wrap(err, "Failed to write upgrade plan because is was outdated or removed")
391439
} else if err != nil {
440+
m.log.Error().Msgf("Failed to write upgrade plan %v.", err)
392441
return errors.Wrap(err, "Failed to write upgrade plan")
393442
}
394443

0 commit comments

Comments
 (0)