@cloudant/couchbackup 2.7.1-SNAPSHOT.56 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.md +4 -1
- package/README.md +1 -1
- package/includes/spoolchanges.js +44 -25
- package/package.json +1 -1
package/CHANGES.md
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 2.8.0 (2021-11-25)
|
|
2
2
|
- [FIXED] Corrected `user-agent` header on requests.
|
|
3
3
|
- [FIXED] Restore of shallow backups created with versions <=2.4.2.
|
|
4
4
|
- [IMPROVED] Added quiet option to backup and restore to suppress batch messages.
|
|
5
5
|
- [IMPROVED] Added a preflight check for restore function to make sure that a target database is new and empty.
|
|
6
6
|
- [IMPROVED] Added handling for errors reading log file.
|
|
7
|
+
- [IMPROVED] Split changes spooling to improve reliability on databases with
|
|
8
|
+
millions of documents.
|
|
9
|
+
- [UPGRADED] `@ibm-cloud/cloudant`, `commander` and `debug` dependencies.
|
|
7
10
|
|
|
8
11
|
# 2.7.0 (2021-09-14)
|
|
9
12
|
- [UPGRADED] Cloudant client dependency from `@cloudant/cloudant` to `@ibm-cloud/cloudant`.
|
package/README.md
CHANGED
package/includes/spoolchanges.js
CHANGED
|
@@ -34,6 +34,9 @@ module.exports = function(db, log, bufferSize, ee, callback) {
|
|
|
34
34
|
let batch = 0;
|
|
35
35
|
let lastSeq = null;
|
|
36
36
|
const logStream = fs.createWriteStream(log);
|
|
37
|
+
let pending = 0;
|
|
38
|
+
// The number of changes to fetch per request
|
|
39
|
+
const limit = 100000;
|
|
37
40
|
|
|
38
41
|
// send documents ids to the queue in batches of bufferSize + the last batch
|
|
39
42
|
const processBuffer = function(lastOne) {
|
|
@@ -57,36 +60,52 @@ module.exports = function(db, log, bufferSize, ee, callback) {
|
|
|
57
60
|
processBuffer(false);
|
|
58
61
|
} else if (c.last_seq) {
|
|
59
62
|
lastSeq = c.last_seq;
|
|
63
|
+
pending = c.pending;
|
|
60
64
|
}
|
|
61
65
|
}
|
|
62
66
|
};
|
|
63
67
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
.
|
|
68
|
-
|
|
68
|
+
function getChanges(since = 0) {
|
|
69
|
+
debug('making changes request since ' + since);
|
|
70
|
+
return db.service.postChangesAsStream({ db: db.db, since: since, limit: limit, seq_interval: limit })
|
|
71
|
+
.then(response => {
|
|
72
|
+
response.result.pipe(liner())
|
|
73
|
+
.on('error', function(err) {
|
|
74
|
+
logStream.end();
|
|
75
|
+
callback(err);
|
|
76
|
+
})
|
|
77
|
+
.pipe(change(onChange))
|
|
78
|
+
.on('error', function(err) {
|
|
79
|
+
logStream.end();
|
|
80
|
+
callback(err);
|
|
81
|
+
})
|
|
82
|
+
.on('finish', function() {
|
|
83
|
+
processBuffer(true);
|
|
84
|
+
if (!lastSeq) {
|
|
85
|
+
logStream.end();
|
|
86
|
+
debug('changes request terminated before last_seq was sent');
|
|
87
|
+
callback(new error.BackupError('SpoolChangesError', 'Changes request terminated before last_seq was sent'));
|
|
88
|
+
} else {
|
|
89
|
+
debug(`changes request completed with last_seq: ${lastSeq} and ${pending} changes pending.`);
|
|
90
|
+
if (pending > 0) {
|
|
91
|
+
// Return the next promise
|
|
92
|
+
return getChanges(lastSeq);
|
|
93
|
+
} else {
|
|
94
|
+
debug('finished streaming database changes');
|
|
95
|
+
logStream.end(':changes_complete ' + lastSeq + '\n', 'utf8', callback);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
});
|
|
69
99
|
})
|
|
70
|
-
.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (!lastSeq) {
|
|
77
|
-
logStream.end();
|
|
78
|
-
debug('changes request terminated before last_seq was sent');
|
|
79
|
-
callback(new error.BackupError('SpoolChangesError', 'Changes request terminated before last_seq was sent'));
|
|
80
|
-
} else {
|
|
81
|
-
debug('finished streaming database changes');
|
|
82
|
-
logStream.end(':changes_complete ' + lastSeq + '\n', 'utf8', callback);
|
|
100
|
+
.catch(err => {
|
|
101
|
+
logStream.end();
|
|
102
|
+
if (err.status && err.status >= 400) {
|
|
103
|
+
callback(error.convertResponseError(err));
|
|
104
|
+
} else if (err.name !== 'SpoolChangesError') {
|
|
105
|
+
callback(new error.BackupError('SpoolChangesError', `Failed changes request - ${err.message}`));
|
|
83
106
|
}
|
|
84
107
|
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
} else {
|
|
89
|
-
callback(new error.BackupError('SpoolChangesError', `Failed changes request - ${err.message}`));
|
|
90
|
-
}
|
|
91
|
-
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
getChanges();
|
|
92
111
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudant/couchbackup",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "CouchBackup - command-line backup utility for Cloudant/CouchDB",
|
|
5
5
|
"homepage": "https://github.com/cloudant/couchbackup",
|
|
6
6
|
"repository": "https://github.com/cloudant/couchbackup.git",
|