MongoDB 7.0 기준.

 

사이즈가 너무 작거나 심지어는 0 인 chunk는 metadata만 차지하고 무의미하므로 그냥 merge 해버리는게 좋음.

config.chunks 에서 사이즈 체크를 하고자하는 chunk 리스트를 가져온 후,

dataSize 로 사이즈를 재서 특정 사이즈 미만의 chunk의 경우 해당 chunk의 min을 max로 가지는 (혹은 max를 min으로 가지는) chunk와 merge 하면 됨. (필요시 moveChunk)

 

아래는 namespace, 지정 사이즈, shard 이름을 넘겨받아 위에서 설명한 각 단계를 수행하는 mongosh용 js 함수 예제.

function mergeChunksSizeLte(ns, sizeLte = 10 * 1024 * 1024, shard = null) 
{
    const config = db.getSiblingDB('config');
    const col = config.collections.findOne({
        _id: ns
    });
    const uuid = col.uuid;
    const shardKey = col.key;
    
    const q = {
        uuid: uuid
    };
    if (shard) q.shard = shard;
 
    // 지정 사이즈 미만의 chunk 리스트 가져오기
    const chunkListSizeLte = [];
    config.chunks.find(q).forEach((chunk) => {
        const dataSize = db.runCommand({
            dataSize: ns,
            keyPattern: shardKey,
            min: chunk.min,
            max: chunk.max
        });

        if (dataSize.numObjects < 1 || dataSize.size < sizeLte) {
            chunk.size = dataSize.size;
            chunk.numObjects = dataSize.numObjects;
            chunkListSizeLte.push(chunk);
        }
    });

    if (chunkListSizeLte.length < 1) {
        print('지정한 sizeLte 미만의 chunk가 없습니다.');
        return;
    }
 
    const adminDb = db.getSiblingDB('admin');
 
    for (let i = 0; i < chunkListSizeLte.length; i++) {
        let chunk = chunkListSizeLte[i];
 
        while (true) {
            let preChunk = config.chunks.findOne({
                uuid: uuid,
                max: chunk.min
            });
 
            // move chunk
            if (chunk.shard !== preChunk.shard) {
                db.adminCommand({
                    moveChunk: ns,
                    find: chunk.min,
                    to: preChunk.shard
                });
            }
 
            // merge chunk
            const bounds = [];
            bounds.push(preChunk.min);
            bounds.push(chunk.max);
            adminDb.adminCommand({
                mergeChunks: ns,
                bounds: bounds
            });
 
            // merge된 chunk도 지정 사이즈 미만이라면 재차 시도
            chunk = preChunk;
            const dataSize = db.runCommand({
                dataSize: ns,
                keyPattern: shardKey,
                min: chunk.min,
                max: chunk.max
            });
 
            if (dataSize.size < sizeLte) {
                chunk.size = dataSize.size;
                chunk.numObjects = dataSize.numObjects;
            } else {
                break;
            }
        }
    }
}

 

 

 

 

 

 

 

 

Posted by bloodguy
,