-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ft/mongo oplog #433
Ft/mongo oplog #433
Conversation
PR has been updated. Reviewers, please be cautious. |
2c3ca3d
to
730d16c
Compare
PR has been updated. Reviewers, please be cautious. |
730d16c
to
f266013
Compare
PR has been updated. Reviewers, please be cautious. |
f266013
to
acd7e19
Compare
PR has been updated. Reviewers, please be cautious. |
86027cc
to
82f06a5
Compare
PR has been updated. Reviewers, please be cautious. |
82f06a5
to
003af43
Compare
PR has been updated. Reviewers, please be cautious. |
1 similar comment
PR has been updated. Reviewers, please be cautious. |
056c97d
to
89b3620
Compare
PR has been updated. Reviewers, please be cautious. |
@ironman-machine try |
Hello @JianqinWang "try": Success: Try build successfully launched on 'http://ci.ironmann.io/gh/scality/Integration/20071' with the following env. args: {
"REPO_NAME": "Arsenal",
"SCALITY_ARSENAL_BRANCH": "ft/mongo-oplog",
"DEFAULT_BRANCH": "master",
"SCALITY_INTEGRATION_BRANCH": "ultron/master"
} |
@ironman-machine try |
Hello @JianqinWang "try": Success: Try build successfully launched on 'http://ci.ironmann.io/gh/scality/Integration/20072' with the following env. args: {
"REPO_NAME": "Arsenal",
"SCALITY_ARSENAL_BRANCH": "ft/mongo-oplog",
"DEFAULT_BRANCH": "master",
"SCALITY_INTEGRATION_BRANCH": "ultron/master"
} |
|
||
const ops = { | ||
i: 'put', | ||
u: 'put', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be get
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The i
and u
ops in mongo oplogs are insert
and update
, which I mapped both to put
I'm not sure if mongodb oplogs have any logs corresponding to get
actions - these logs are records of the replication that happens in the mongodb replication set itself, so the main actions are insert
, update
, and delete
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, Lauren and I never found super official documentation (that was clear enough) for an explanation on oplogs - we ended up using this relatively out-dated blog as our primary source: https://www.compose.com/articles/the-mongodb-oplog-and-node-js/
89b3620
to
ebf2c88
Compare
Do it again human slave!:point_right: :runner: (Oh and the pull request has been updated, by the way.)
PR has been updated. Reviewers, please be cautious. |
@ironman-machine try |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! 👍
MongoClient.connect(this.mongoUrl, { replicaSet: 'rs0' }, | ||
(err, client) => { | ||
if (err) { | ||
this.logger.error('Unable to connect to MongoDB', err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
err
=> { error: err }
recordStream.write(undefined); | ||
}); | ||
recordStream.once('info', info => { | ||
recordStream.removeAllListeners('error'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering if this is good to do as the error event not being listened for. Maybe we should add a listener in ListRecordStream
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was trying to follow the format here as closely as possible:
recordStream.removeAllListeners('error'); |
@rahulreddy @vrancurel any opinions? XD
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's important to understand why that was put in LogConsumer in the first place. I don't like the idea of removing all error listeners. I believe the reason it was used in RecordStream was because Metadata was returning InternalError when we request the next sequence id but there are no logs available. @jonathan-gramain was the author of that class, can you check with him?
readRecords(params, cb) { | ||
const recordStream = new ListRecordStream(this.logger); | ||
const limit = params.limit || 10000; | ||
const startIDandSeq = params.startSeq.toString().split('|'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the JSDoc, this function expects params.startSeq
to be a number. If it has a |
char, I'm guessing it is actually a string? In this case, no need to use toString
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's possible that the last logs use numbers though if the instances were started with a different backend - I think I had the toString() here just in case we got a number
this.database = 'local'; | ||
this.mongoUrl = format( | ||
'mongodb://%s/local', | ||
replicaSetHosts); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering about the need for format
, seems like just a template string would do (that way we don't have to import this utility). Maybe there is something about replicaSetHosts
which requires this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will make a separate commit, since MongoClientInterface also uses this format
Hello @vrancurel "try": Success: Try build successfully launched on 'http://ci.ironmann.io/gh/scality/Integration/20075' with the following env. args: {
"REPO_NAME": "Arsenal",
"SCALITY_ARSENAL_BRANCH": "ft/mongo-oplog",
"DEFAULT_BRANCH": "master",
"SCALITY_INTEGRATION_BRANCH": "ultron/master"
} |
💔 ☔ circleCI test failed. |
PR has been updated. Reviewers, please be cautious. |
|
@ironman-machine try |
Hello @JianqinWang "try": Success: Try build successfully launched on 'http://ci.ironmann.io/gh/scality/Integration/20080' with the following env. args: {
"REPO_NAME": "Arsenal",
"SCALITY_ARSENAL_BRANCH": "ft/mongo-oplog",
"DEFAULT_BRANCH": "master",
"SCALITY_INTEGRATION_BRANCH": "ultron/master"
} |
☀️ 👍 circleCI test succeeded! |
Hello @vrancurel "r+": Success |
⌛ PR is now pending. CI build url: http://ci.ironmann.io/gh/scality/Integration/20110 |
💔 ☔ circleCI test failed. |
cb69218
to
a9a6b24
Compare
PR has been updated. Reviewers, please be cautious. |
Hello @vrancurel "r-": Success |
@ironman-machine try |
Hello @vrancurel "try": Success: Try build successfully launched on 'http://ci.ironmann.io/gh/scality/Integration/20116' with the following env. args: {
"REPO_NAME": "Arsenal",
"SCALITY_ARSENAL_BRANCH": "ft/mongo-oplog",
"DEFAULT_BRANCH": "master",
"SCALITY_INTEGRATION_BRANCH": "ultron/master"
} |
Hello @vrancurel "r+": Success |
⌛ PR is now pending. CI build url: http://ci.ironmann.io/gh/scality/Integration/20130 |
|
||
this.coll = this.db.collection('oplog.rs'); | ||
return this.coll.find({ | ||
ns: /^(?!.*metadata.*(?:__)).*metadata\.\w+.*/, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this regular expression? Adding a comment of what the expression is trying to filter out would be helpful. Cleaner way would be writing it as a constant on the top of the file
/*
** This is a comment to explain this filter
*/
const METADATA_FILTER = /^(?!.*metadata.*(?:__)).*metadata\.\w+.*/
and then use it in the code as
return this.coll.find({
ns: METADATA_FILTER,
...
awaitData: false, | ||
noCursorTimeout: true, | ||
OplogReplay: true, | ||
numberOfRetries: Number.MAX_VALUE, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is retry configured to such a high number?
recordStream.write(data); | ||
}); | ||
stream.on('end', () => { | ||
recordStream.write(undefined); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be null
to indicate the end of stream?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we write 'null', it throws this error:
TypeError: May not write null values to stream
at validChunk (_stream_writable.js:211:10)
at ListRecordStream.Writable.write (_stream_writable.js:245:12)
at Cursor.stream.on (/home/jay/Scality/backbeat/node_modules/arsenal/lib/storage/metadata/mongoclient/LogConsumer.js:176:30)
at emitNone (events.js:91:20)
at Cursor.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9)
☀️ 👍 circleCI test succeeded! |
Merge after #425
Based off of https://github.com/scality/Arsenal/blob/master/lib/storage/metadata/bucketclient/LogConsumer.js