日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql binlog oplog_mongodb 学习之oplog

發布時間:2023/12/4 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql binlog oplog_mongodb 学习之oplog 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景:

原來一個同事問我主從mongodb數據庫為什么數據差距很大,我讓他察看一下兩邊有啥不一樣,發現

主的local庫有13G從卻很小,進入local之后du發現有一個collection前綴的文件有13g,說明是local數據庫中一個集合太大了,推測是oplog太大了,oplog是類似于mysql的binlog oracle的archivelog

當Primary進行寫操作的時候,會將這些寫操作記錄寫入Primary的Oplog中,而后Secondary會將Oplog復制到本機并應用這些操作,從而實現Replication的功能。同時由于其記錄了Primary上的寫操作,故還能將其用作數據恢復。可以簡單的將其視作Mysql中的binlog。

為了進一步確認,進入mongodb之后通過

show dbs

use local

show collections

看到現有的集合

然后

db.getReplicationInfo()

rs.printReplicationInfo()

了解一下復制信息以及oplog大小與使用情況

為進一步確認相應的文件是否為oplog

db.printCollectionStats()

根據展示出來的結果只需要知道兩條信息:

"ns" : "local.oplog.$main",

"uri" : "statistics:table:local/collection-2-1716662444632575459"

就可以確認oplog集合的相應文件,oplog如果太大可以清理和修改大小。

MongoDB oplog是一個capped collection,創建capped collection時,createCollection可以設置size(最大字節數)和max(最大文檔數)的參數,當這個集合的『總大小超過size』或者『總文檔數超過max』時,在新插入文檔時就會自動刪除一些集合內最先插入的文檔,相當于一片環形的存儲空間。

oplog(local.oplog.rs集合)默認情況下配置為可用磁盤空間的5%,當oplog寫滿時,就會開始刪除最先寫入的oplog,一次正常的insert操作包含如下步驟:將文檔寫入指定的集合

將寫入操作記錄到oplog

如果oplog滿了,刪除最先寫入的oplog

優化策略

MongoDB 3.2為了提升寫入性能,使用wiredtiger引擎時,針對local.oplog.rs這個集合的刪除策略進行了優化,主要改進:將刪除動作從用戶的寫入路徑移除,放到后臺線程執行

批量刪除,并不是oplog一滿就立馬觸發刪除,而是一次刪除一批

實施方案

monogd啟動時,會根據oplog的最大字節數將整個集合分為10-100個Stone(可以理解為oplog的一段數據,包含多個文檔,Stone的具體個數oplogSizeMB的配置相關)。WiredTigerRecordStore::OplogStones::OplogStones(OperationContext*?txn,?WiredTigerRecordStore*?rs)

:?_rs(rs)?{

//...

unsigned?long?long?maxSize?=?rs->cappedMaxSize();

const?unsigned?long?long?kMinStonesToKeep?=?10ULL;

const?unsigned?long?long?kMaxStonesToKeep?=?100ULL;

unsigned?long?long?numStones?=?maxSize?/?BSONObjMaxInternalSize;

_numStonesToKeep?=?std::min(kMaxStonesToKeep,?std::max(kMinStonesToKeep,?numStones));

_minBytesPerStone?=?maxSize?/?_numStonesToKeep;

//?...

}

其中_numStonesToKeep為oplog應該保持的Stone個數,而_minBytesPerStone代表每個Stone的最小字節數。

接下來,會根據oplog當前的大小以及_minBytesPerStone來估算下,當前的oplog大致包含的Stone數量,并通過采樣的方式來獲取每個Stone的起始位置(不能保證每個Stone的大小跟預期完全一樣),然后將所有的Stone按順序存儲到一個隊列中。

mongod在服務寫請求的過程中,每次都會記錄下新產生oplog的大小,當新產生的oplog的總量超過_minBytesPerStones時,就會產生一個新的Stone加入到隊列中。void?WiredTigerRecordStore::OplogStones::createNewStoneIfNeeded(RecordId?lastRecord)?{

if?(_currentBytes.load()?<?_minBytesPerStone)?{

//?Must?have?raced?to?create?a?new?stone,?someone?else?already?triggered?it.

return;

}

//?...

OplogStones::Stone?stone?=?{_currentRecords.swap(0),?_currentBytes.swap(0),?lastRecord};

_stones.push_back(stone);

_pokeReclaimThreadIfNeeded();?//?喚醒后臺回收oplog空間的線程

}

當隊列中的Stone數量超過_numStonesToKeep,后臺線程就會刪除最老的Stone里的數據,來回收oplog的存儲空間。

修改mongodb oplog size

oplog簡介:

oplog:operations log的簡寫,存儲在一個特殊的數據庫中(local),oplog就存儲在其中的oplog.$main集合里面,這個集合是一個固定集合,新操作會自動替換舊的操作,以保證oplog不會超過預設的大小,其中的每個文檔都代表主節點上執行的一個操作,oplog會包含所有對數據有修改的的操作(查詢操作不會記錄),默認下,oplog大小會占用64位的實例5%的可用磁盤空間。

mongo復制的過程:主節點應用業務操作修改到數據庫中,然后記錄這些操作到oplog中,從節點復制這些oplog,然后應用這些修改。ps:這些操作是異步的。如果從節點的操作已經被主節點落下很遠,oplog日志在從節點還沒執行完,oplog可能已經輪滾一圈了,從節點跟不上同步,復制就會停下,從節點需要重新做完整的同步,為了避免此種情況,盡量保證主節點的oplog足夠大,能夠存放相當長時間的操作記錄。

查詢oplog的大小及保存的操作記錄持續的時長

repltest:PRIMARY> db.printReplicationInfo()

configured oplog size: ? 1024MB

log length start to end: 3705secs (1.03hrs)

oplog first event time: ?Thu Oct 10 2013 11:13:29 GMT+0800 (CST)

oplog last event time: ? Thu Oct 10 2013 12:15:14 GMT+0800 (CST)

now: ? ? ? ? ? ? ? ? ? ? Fri Oct 11 2013 16:33:42 GMT+0800 (CST)

查詢從節點的數據源列表,其中有數據滯后的時間

repltest:PRIMARY> db.printSlaveReplicationInfo()

source: ? 192.168.1.101:37017

syncedTo: Fri Oct 11 2013 16:38:16 GMT+0800 (CST)

= 1 secs ago (0hrs)

source: ? 192.168.1.100:37017

no replication info, yet. ?State: ARBITER

so,修改oplog的大小:(下面介紹兩種方式)

方式一:

The oplog exists internally as a capped collection, so you cannot modify its size in the course of normal operations.另:改變oplog大小,需要在每個節點上執行維護模式。(官方推薦)

步驟:

1:重啟一個實例以單機模式,

通常再關閉server之前,使用rs.stepDown() 強制primary成為secondary

2:重新創建一個新大小,

其中包含舊的oplgo的入口條目的oplog

3:重啟mongod作為replica set的成員

操作步驟:

1>: Restart a Secondary in Standalone Mode on a Different Port

關閉mongod實例:

repset:PRIMARY> use admin

repset:PRIMARY> db.shutdownServer()

重啟mongod實例以單機模式,修改端口,并不要加--replSet參數

#vim /etc/mongo.conf

dbpath=/var/lib/mongodb

logpath=/var/log/mongodb/mongo.log

pidfilepath=/var/run/mongo.pid

directoryperdb=true

logappend=true

#replSet=repset

bind_ip=192.168.1.100,127.0.0.1

port=37017

oplogSize=2000

fork=true# mongod -f /etc/mongo.conf

備份oplog# mongodump --db local --collection 'oplog.rs' --port 37017

2>: Recreate the Oplog with a New Size and a Seed Entry

保存oplog的最新的時間點

> use local

> db.temp.save( db.oplog.rs.find( { }, { ts: 1, h: 1 } ).sort( {$natural : -1} ).limit(1).next() )

> db.temp.find()

刪除舊的oplog

> db.oplog.rs.drop()

3> :Create a New Oplog

創建一個新的Oplog,大小為2G

> db.runCommand( { create: "oplog.rs", capped: true, size: (2 * 1024 * 1024 * 1024) } )

插入前面保存的舊的oplog的時間點的記錄

> db.oplog.rs.save( db.temp.findOne() )

> db.oplog.rs.find()

4>:Restart the Member:

關閉單機實例:

> use admin

> db.shutdownServer()

修改回配置# vim /etc/mongo.conf

dbpath=/var/lib/mongodb

logpath=/var/log/mongodb/mongo.log

pidfilepath=/var/run/mongo.pid

directoryperdb=true

logappend=true

replSet=repset

bind_ip=192.168.1.100,127.0.0.1

port=37017

oplogSize=2000

fork=true

啟動mongod

# mongod -f /etc/mongo.conf

重復上述步驟到所有需要更改的節點。

方式二:

步驟:

1:停掉所有replca set節點.

2:主節點刪除local庫下的文件,從節點刪除數據目錄下所有文件.

3:修改所有節點配置文件.

4:重啟所有節點.

5:重新配置replca set,從節點會重新同步所有數據(initial sync).

ps:此法好處是簡單,但需要停掉服務,且如果數據量很大,初始同步的成本較高

1>:關閉mongod實例(所有節點)

> use admin

> db.shutdownServer()

2>:刪除local數據庫下的所有文件(PRIMARY節點)

# rm -rf /var/lib/mongodb/local/*

刪除mongo數據目錄(其他節點上操作,可不要刪錯哦,建議所有rm操作先mv,待無問題時候再刪除)# rm -rf /var/lib/mongodb/*

3> 修改所有節點配置文件(oplogsize)

# vim /etc/mongo.conf

dbpath=/var/lib/mongodb

logpath=/var/log/mongodb/mongo.log

pidfilepath=/var/run/mongo.pid

directoryperdb=true

logappend=true

replSet=repset

bind_ip=192.168.1.100,127.0.0.1

port=37017

oplogSize=2000

fork=true

4> 重啟所有節點mongod

> mongod -f /etc/mongo.conf

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的mysql binlog oplog_mongodb 学习之oplog的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。