Replica set 의 모든 Secondary 멤버는 Primary 멤버로 부터 변경이 기록된 로그(oplog.rs)를 가져와서 적용 하면서, Primary 와 Secondary 간의 데이터를 동기화를 하게 됩니다.
아래 테스트를 보면 확인 할 수 있듯이, 수행된 MQL이 저장되지 않고 실제 저장될 document 내용이 oplog.rs에 저장 됩니다
그래서 현재 시간을 사용할 경우 쿼리를 이용한다면 Primary, secondary의 내용이 다를 수 있지만, mongodb는 실 데이터를 가져가서 반영 시키므로 데이터가 달라지지는 않습니다.
##################
# 테스트 시나리오
##################
insert , update, delete , drop 명령 수행 후 oplog.rs 내용 확인
use test
db.t2.insertOne({col1 : Date() , name : 'hong gil dong' , city : 'seoul' , meta : { gu : 'jongno-gu' , other : 'jong-ro 33-gil'}})
db.t2.insertOne({col1 : Date() , name : 'Yi Sun-sin' , city : 'Gyeongsangnam-do'})
db.t2.update(
{},
{$set:{col1:Date()}},
{multi: true}
)
db.t2.remove(
{name : 'hong gil dong'}
)
##########################
# oplog.rs field 값 설명
##########################
ts (timestamp)
: Unix Epoch 시간 값
이 값을 기준으로 Secondary에서 데이터를 요청 (기존에 반영한 이후의 데이터를 찾는 용도)
op (operation type)
: i : insert
d : delete
u : update
c : command
n : no operation
c : 데이터베이스 생성, 컬렉션 생성, 컬렉션 삭제, 컬렉션 속성 변경 등이 발생 할 경우
n : 단순한 정보 메세지를 저장하는 경우
ns (namespace)
: 대상 컬렉션의 네임스페이스
네임스페이스 = "데이터베이스.컬렉션명"
o (operation)
: 실제 Document에 반영 된 값이 저장
insert : insert된 Document값
update : update된 filed 값
delete : delete된 document의 PK값 (_id filed값)
create, drop : 명령어 + 컬렉션 명
o2 (operation 2)
: insert, update, delete : 영향을 받은 Document PK값 (_id field값)
##################
# PSS 정보
##################
PRIMARY : 'rhel:26001'
SECONDARY : 'rhel:26002'
SECONDARY : 'rhel:26003'
#####################
# Primary 에서 Insert
#####################
insert MQL을 수행하면, MQL로 인해서 실제 저장되는 Document 내용이 저장 됨
최초 insert 발생 시 자동으로 collection이 생성되는 것도 확인 할 수 있다
test | comu [primary] test> use test comu [direct: primary] test> db.t2.insertOne({col1 : Date() , name : 'hong gil dong' , city : 'seoul' , meta : { gu : 'jongno-gu' , other : 'jong-ro 33-gil'}}) { acknowledged: true, insertedId: ObjectId('6646f4d1986dc1b24cc934df') } comu [direct: primary] test> db.t2.insertOne({col1 : Date() , name : 'Yi Sun-sin' , city : 'Gyeongsangnam-do'}) { acknowledged: true, insertedId: ObjectId('6646f4e0986dc1b24cc934e0') } comu [direct: primary] test> db.t2.find() [ { _id: ObjectId('6646f4d1986dc1b24cc934df'), col1: 'Fri May 17 2024 15:10:25 GMT+0900 (Korean Standard Time)', name: 'hong gil dong', city: 'seoul', meta: { gu: 'jongno-gu', other: 'jong-ro 33-gil' } }, { _id: ObjectId('6646f4e0986dc1b24cc934e0'), col1: 'Fri May 17 2024 15:10:40 GMT+0900 (Korean Standard Time)', name: 'Yi Sun-sin', city: 'Gyeongsangnam-do' } ] |
local | comu [direct: primary] test> use local comu [direct: primary] local> db.oplog.rs.find({op : 'i'}).sort({$natural: -1}).limit(2).pretty() [ { lsid: { id: UUID('5756aba4-9615-4139-922a-9b7a25d45e6e'), uid: Binary.createFromBase64('Y5mrDaxi8gv8RmdTsQ+1j7fmkr7JUsabhNmXAheU0fg=', 0) }, txnNumber: Long('3'), op: 'i', ns: 'test.t2', ui: UUID('2a11f34d-ec5b-4bde-baef-db13f903fe18'), o: { _id: ObjectId('6646f4e0986dc1b24cc934e0'), col1: 'Fri May 17 2024 15:10:40 GMT+0900 (Korean Standard Time)', name: 'Yi Sun-sin', city: 'Gyeongsangnam-do' }, o2: { _id: ObjectId('6646f4e0986dc1b24cc934e0') }, stmtId: 0, ts: Timestamp({ t: 1715926240, i: 1 }), t: Long('10'), v: Long('2'), wall: ISODate('2024-05-17T06:10:40.409Z'), prevOpTime: { ts: Timestamp({ t: 0, i: 0 }), t: Long('-1') } }, { lsid: { id: UUID('5756aba4-9615-4139-922a-9b7a25d45e6e'), uid: Binary.createFromBase64('Y5mrDaxi8gv8RmdTsQ+1j7fmkr7JUsabhNmXAheU0fg=', 0) }, txnNumber: Long('2'), op: 'i', ns: 'test.t2', ui: UUID('2a11f34d-ec5b-4bde-baef-db13f903fe18'), o: { _id: ObjectId('6646f4d1986dc1b24cc934df'), col1: 'Fri May 17 2024 15:10:25 GMT+0900 (Korean Standard Time)', name: 'hong gil dong', city: 'seoul', meta: { gu: 'jongno-gu', other: 'jong-ro 33-gil' } }, o2: { _id: ObjectId('6646f4d1986dc1b24cc934df') }, stmtId: 0, ts: Timestamp({ t: 1715926225, i: 2 }), t: Long('10'), v: Long('2'), wall: ISODate('2024-05-17T06:10:25.827Z'), prevOpTime: { ts: Timestamp({ t: 0, i: 0 }), t: Long('-1') } } ] comu [direct: primary] local> db.oplog.rs.find({op : 'c' , "o.create" : 't2'}).sort({$natural: -1}).limit(1).pretty() [ { op: 'c', ns: 'test.$cmd', ui: UUID('2a11f34d-ec5b-4bde-baef-db13f903fe18'), o: { create: 't2', idIndex: { v: 2, key: { _id: 1 }, name: '_id_' } }, ts: Timestamp({ t: 1715926225, i: 1 }), t: Long('10'), v: Long('2'), wall: ISODate('2024-05-17T06:10:25.827Z') } ] |
#####################
# Secondary에서 조회
#####################
Secondary 1 | secondary 2 |
comu [direct: primary] local> db = connect('rhel:26002/admin','root','root') comu [direct: secondary] admin> use test comu [direct: secondary] test> db.t2.find() [ { _id: ObjectId('6646f4d1986dc1b24cc934df'), col1: 'Fri May 17 2024 15:10:25 GMT+0900 (Korean Standard Time)', name: 'hong gil dong', city: 'seoul', meta: { gu: 'jongno-gu', other: 'jong-ro 33-gil' } }, { _id: ObjectId('6646f4e0986dc1b24cc934e0'), col1: 'Fri May 17 2024 15:10:40 GMT+0900 (Korean Standard Time)', name: 'Yi Sun-sin', city: 'Gyeongsangnam-do' } ] |
comu [direct: secondary] test> db = connect('rhel:26003/admin','root','root') comu [direct: secondary] admin> use test comu [direct: secondary] test> db.t2.find() [ { _id: ObjectId('6646f4d1986dc1b24cc934df'), col1: 'Fri May 17 2024 15:10:25 GMT+0900 (Korean Standard Time)', name: 'hong gil dong', city: 'seoul', meta: { gu: 'jongno-gu', other: 'jong-ro 33-gil' } }, { _id: ObjectId('6646f4e0986dc1b24cc934e0'), col1: 'Fri May 17 2024 15:10:40 GMT+0900 (Korean Standard Time)', name: 'Yi Sun-sin', city: 'Gyeongsangnam-do' } ] |
########################
# Primary에서 update 수행
########################
update에 의해서 변경되는 부분만 저장. 해당 데이터는 PK인 _id 값이 같이 저장되므로 해당 값을 이용해서 변경
test | comu [direct: secondary] test> db = connect('rhel:26001/admin','root','root') comu [direct: primary] admin> use test comu [direct: primary] test> db.t2.update( ... {}, ... {$set:{col1:Date()}}, ... {multi: true} ... ) { acknowledged: true, insertedId: null, matchedCount: 2, modifiedCount: 2, upsertedCount: 0 } comu [direct: primary] test> db.t2.find() [ { _id: ObjectId('6646f4d1986dc1b24cc934df'), col1: 'Fri May 17 2024 15:21:45 GMT+0900 (Korean Standard Time)', name: 'hong gil dong', city: 'seoul', meta: { gu: 'jongno-gu', other: 'jong-ro 33-gil' } }, { _id: ObjectId('6646f4e0986dc1b24cc934e0'), col1: 'Fri May 17 2024 15:21:45 GMT+0900 (Korean Standard Time)', name: 'Yi Sun-sin', city: 'Gyeongsangnam-do' } ] |
local | comu [direct: primary] test> use local comu [direct: primary] local> db.oplog.rs.find({op : 'u'}).sort({$natural: -1}).limit(2).pretty() [ { op: 'u', ns: 'test.t2', ui: UUID('2a11f34d-ec5b-4bde-baef-db13f903fe18'), o: { '$v': 2, diff: { u: { col1: 'Fri May 17 2024 15:21:45 GMT+0900 (Korean Standard Time)' } } }, o2: { _id: ObjectId('6646f4e0986dc1b24cc934e0') }, ts: Timestamp({ t: 1715926905, i: 2 }), t: Long('10'), v: Long('2'), wall: ISODate('2024-05-17T06:21:45.353Z') }, { op: 'u', ns: 'test.t2', ui: UUID('2a11f34d-ec5b-4bde-baef-db13f903fe18'), o: { '$v': 2, diff: { u: { col1: 'Fri May 17 2024 15:21:45 GMT+0900 (Korean Standard Time)' } } }, o2: { _id: ObjectId('6646f4d1986dc1b24cc934df') }, ts: Timestamp({ t: 1715926905, i: 1 }), t: Long('10'), v: Long('2'), wall: ISODate('2024-05-17T06:21:45.353Z') } ] |
#####################
# Secondary 에서 조회
#####################
Secondary 1 | secondary 2 |
comu [direct: primary] local> db = connect('rhel:26002/admin','root','root') comu [direct: secondary] admin> use test comu [direct: secondary] test> db.t2.find() [ { _id: ObjectId('6646f4d1986dc1b24cc934df'), col1: 'Fri May 17 2024 15:21:45 GMT+0900 (Korean Standard Time)', name: 'hong gil dong', city: 'seoul', meta: { gu: 'jongno-gu', other: 'jong-ro 33-gil' } }, { _id: ObjectId('6646f4e0986dc1b24cc934e0'), col1: 'Fri May 17 2024 15:21:45 GMT+0900 (Korean Standard Time)', name: 'Yi Sun-sin', city: 'Gyeongsangnam-do' } ] |
comu [direct: secondary] test> db = connect('rhel:26003/admin','root','root') comu [direct: secondary] admin> use test comu [direct: secondary] test> db.t2.find() [ { _id: ObjectId('6646f4d1986dc1b24cc934df'), col1: 'Fri May 17 2024 15:21:45 GMT+0900 (Korean Standard Time)', name: 'hong gil dong', city: 'seoul', meta: { gu: 'jongno-gu', other: 'jong-ro 33-gil' } }, { _id: ObjectId('6646f4e0986dc1b24cc934e0'), col1: 'Fri May 17 2024 15:21:45 GMT+0900 (Korean Standard Time)', name: 'Yi Sun-sin', city: 'Gyeongsangnam-do' } ] |
#####################
# Primary에서 삭제 진행
#####################
delete 진행 시 지워 진 Document의 pk값인 _id만 저장
drop 진행 시 명령어와 collection명 확인 가능
test | comu [direct: secondary] test> db = connect('rhel:26001/admin','root','root') comu [direct: primary] admin> use test comu [direct: primary] test> db.t2.remove( ... {name : 'hong gil dong'} ... ) DeprecationWarning: Collection.remove() is deprecated. Use deleteOne, deleteMany, findOneAndDelete, or bulkWrite. { acknowledged: true, deletedCount: 1 } comu [direct: primary] test> db.t2.find() [ { _id: ObjectId('6646f4e0986dc1b24cc934e0'), col1: 'Fri May 17 2024 15:21:45 GMT+0900 (Korean Standard Time)', name: 'Yi Sun-sin', city: 'Gyeongsangnam-do' } ] |
local | comu [direct: primary] local> db.oplog.rs.find({op : 'd'}).sort({$natural: -1}).limit(1).pretty() [ { op: 'd', ns: 'test.t2', ui: UUID('2a11f34d-ec5b-4bde-baef-db13f903fe18'), o: { _id: ObjectId('6646f4d1986dc1b24cc934df') }, ts: Timestamp({ t: 1715927604, i: 1 }), t: Long('10'), v: Long('2'), wall: ISODate('2024-05-17T06:33:24.014Z') } ] |
test | comu [direct: primary] local> use test comu [direct: primary] test> db.t2.drop() comu [direct: primary] test> db.t2.find() |
local | comu [direct: primary] test> use local comu [direct: primary] local> db.oplog.rs.find({op : 'c' , "o.drop" : 't2'}).sort({$natural: -1}).limit(1).pretty() [ { op: 'c', ns: 'test.$cmd', ui: UUID('2a11f34d-ec5b-4bde-baef-db13f903fe18'), o: { drop: 't2' }, o2: { numRecords: 1 }, ts: Timestamp({ t: 1715927871, i: 1 }), t: Long('10'), v: Long('2'), wall: ISODate('2024-05-17T06:37:51.638Z') } ] |