리눅스를 이용한 SD 카드 스트레스 테스트


19

어제 누군가 내 대답 의 논리 및 / 또는 진실성에 관해 약간의 토론에 들어갔습니다 . 합리적인 시간 (년과 년)으로 반론의 핵심은 SD 카드를 착용하는 사람들에 대한 많은 이야기가 온라인에 있기 때문에 내가 틀렸다는 것 같았습니다.

24/7에 남아있는 rw 루트 파일 시스템을 포함하는 SD 카드가있는 장치가 있기 때문에 전제 조건을 만족스럽게 테스트했습니다. 이 테스트를 약간 조정하고 (실제로 동일한 카드를 사용하여) 반복하여 여기에 제시했습니다. 내가 가지고있는 두 가지 주요 질문은 다음과 같습니다.

  1. 나는 쓰기를 다시 계속의 효과를 재현하는 의도 염두에두고, 카드가 가능한 난파 시도에 사용하는 방법입니다 작은 양의 데이터는?
  2. 카드를 확인하는 데 사용한 방법이 여전히 유효합니까?

첫 번째 부분에 대한 이의 제기는 아마도 내 테스트가 실제로 내가하는 방식대로 카드에 쓰지 않았다고 주장해야하기 때문에 아마도 여기에 SO 또는 SuperUser 대신 질문을하고 있습니다. 리눅스에 대한 특별한 지식.

[SD 카드는 같은 종류의 스마트 버퍼링 또는 캐시를 사용하여 같은 장소에 반복해서 쓰는 것이 마모가 덜 발생하는 곳에서 버퍼링 / 캐시 될 수 있습니다. 어디에서나 이것에 대한 징후를 찾지 못했지만 SU 에 대해 묻고 있습니다. ]

테스트의 기본 개념은 카드의 동일한 작은 블록에 수백만 번 쓰는 것입니다. 이는 이러한 디바이스가 유지할 수있는 쓰기주기 수에 대한 주장을 훨씬 넘어서는 것이지만 , 카드의 크기가 적당한 경우 마모 레벨링 이 효과적이라고 가정 하면 "같은 블록"과 같이 수백만 개의 쓰기는 여전히 중요하지 않습니다. 말 그대로 동일한 물리적 블록이 아닙니다. 이를 위해 모든 쓰기 작업이 하드웨어 및 동일한 겉보기 영역 으로 완전히 비워 졌는지 확인해야했습니다 .

하드웨어로 플러시하기 위해 POSIX 라이브러리 호출에 의존했습니다 fdatasync().

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>

// Compile std=gnu99

#define BLOCK 1 << 16

int main (void) {
    int in = open ("/dev/urandom", O_RDONLY);
    if (in < 0) {
        fprintf(stderr,"open in %s", strerror(errno));
        exit(0);
    }

    int out = open("/dev/sdb1", O_WRONLY);
    if (out < 0) {
        fprintf(stderr,"open out %s", strerror(errno));
        exit(0);
    }

    fprintf(stderr,"BEGIN\n");

    char buffer[BLOCK];
    unsigned int count = 0;
    int thousands = 0;
    for (unsigned int i = 1; i !=0; i++) {
        ssize_t r = read(in, buffer, BLOCK);
        ssize_t w = write(out, buffer, BLOCK);
        if (r != w) {
            fprintf(stderr, "r %d w %d\n", r, w);
            if (errno) {
                fprintf(stderr,"%s\n", strerror(errno));
                break;
            }
        }
        if (fdatasync(out) != 0) {
            fprintf(stderr,"Sync failed: %s\n", strerror(errno));
            break;
        }
        count++;
        if (!(count % 1000)) {
            thousands++;
            fprintf(stderr,"%d000...\n", thousands);
        }
        lseek(out, 0, SEEK_SET);
    }
    fprintf(stderr,"TOTAL %lu\n", count);
    close(in);
    close(out);

    return 0;
}                                 

나는 파티션 의 시작 부분에 2 백만 회 이상의 쓰기 를 축적 할 때까지 ~ 8 시간 동안 이것을 실행했습니다 /dev/sdb1. 1/dev/sdb (파티션이 아닌 원시 장치)를 쉽게 사용할 수 있었지만 이것이 어떻게 다른지 알 수 없습니다.

그런 다음 파일 시스템을 만들고 마운트하여 카드를 확인했습니다 /dev/sdb1. 이것은 밤새도록 쓰던 특정 블록이 실현 가능하다는 것을 나타냅니다. 그러나 이는 카드의 일부 영역이 마모 레벨링으로 마모 및 교체되지 않았지만 접근 가능한 상태로 남아 있음을 의미하지는 않습니다.

이를 테스트하기 badblocks -v -w위해 파티션에서 사용 했습니다. 이 테스트 는 파괴적인 읽기 / 쓰기 테스트이지만 마모 레벨링 여부는 각 롤링 쓰기를위한 공간을 제공해야하므로 카드의 실행 가능성을 강력하게 나타냅니다. 다시 말해, 카드를 완전히 채우고 문자가 모두 맞는지 확인하는 것은 문자 그대로입니다. 불량 블록이 몇 가지 패턴을 통해 작동하게했기 때문에 여러 번.

[아래 Jason C의 의견에 따르면, 이런 방식으로 불량 블록을 사용하는 것에 대해 잘못된 점은 없습니다. SD 카드의 특성으로 인해 실제로 불량 블록을 식별하는 데 유용하지는 않지만 개정 된 테스트가 진행된 -band -c스위치를 사용하여 임의 크기의 파괴적인 읽기-쓰기 테스트를 수행 하는 것이 좋습니다 (나의 답변 참조). ). 카드 컨트롤러에 의한 마법이나 캐싱의 양은 몇 메가 바이트의 데이터를 하드웨어에 쓰고 올바르게 다시 읽을 수있는 테스트를 속일 수 없습니다. Jason의 다른 의견은 오해- 의도적 인 IMO에 근거한 것 같습니다. 그래서 내가 논쟁하지 않아도됩니다. 머리가 위로 올라가면 독자에게 맡겨서 무엇이 합리적이고 무엇이 아닌지 를 결정하게 됩니다.]

1 이 카드는 내가 거의 사용하지 않은 오래된 4GB Sandisk 카드 ( "클래스"번호가 없음)였습니다. 다시 한 번, 이것은 문자 그대로 동일한 물리적 장소에 2 백만 쓰기가 아니라는 점을 명심하십시오. 마모 레벨링으로 인해 "첫 번째 블록"은 테스트 중에 컨트롤러에 의해 지속적으로 움직였으며 상태 는 마모 상태를 레벨 아웃했습니다.


아래에 설명 된 이유로 신뢰할 수없는 테스트입니다. 또한 badblocks플래시 드라이브에서 페이지 오류를 표시 하는 데 사용할 수 없으며 오해의 소지가 있다고 주장 할 수 없습니다 . 이들은 컨트롤러에 의해 처리되고 감지 될 때 공간을 확보하도록 매핑됩니다. 드라이브에서 데이터의 물리적 레이아웃은 I / O를 수행 할 때 표시되는 물리적 레이아웃과 동일하지 않으므로웨어 레벨링이 투명성을 유지하는 방식입니다. I / O 중에이 중 어느 것도 보이지 않습니다. 드라이브가 SMART를 지원하는 경우, 컨트롤러에서 장애 및 예약 된 공간에 대한 정보를 얻을 수 있습니다.
Jason C

에 관해서는 /dev/sdb1/dev/sdb그것은 당신의 프로그램에 대한 차이가 없습니다,하지만 않습니다 (아래 설명 참조) 차이를 만드는 장치에 사용되지 않은 블록의 상태가 테스트에 대한 미지의 행방 불명, 그리고 것입니다 당신이 전체 장치를 기입하지 않는 한 (예를 들어, /dev/sdb) 먼저 데이터를 사용하면 공간 마모 레벨링이 작동해야하는 양이 주요 변수입니다. 따라서 장치 대 파티션은 테스트와 관련이 없지만 장치에 데이터를 올바르게 채운 후에는 파티션별로 사용 ​​가능한 옵션이 아니므로 결함이있는 테스트의 결과입니다.
Jason C

테스트를 비현실적으로 만드는 또 다른 요점은 페이지가 실패 할 수 있고 (그리고 일반적으로 발생하지만) SD 카드를 나중에 100 % 사용할 수 있다는 것입니다. 컨트롤러가 장애를 감지하고 마스킹했지만 데이터를 읽을 수없는 경우, 컨트롤러가 블록을 복사하려고 시도 할 때 파일 시스템 데이터가 손상 될 수 있습니다.
Jason C

SD 카드를 닳게하는 재현 가능한 테스트특정 용어 로 설명 하면 진지하게 알려 드리겠습니다. 돌이킬 수없는 "권리 주장"과 개인적인 일화는 바로 그 것입니다. Argumentum ab auctoritate
goldilocks

1
나는 그 특정 카드에 대해 모른다. 그러나 그들 대부분은 어쨌든 이미 조금 죽었다. 이 사람들은 하나 이상의 SD 카드 브랜드에서 마이크로 컨트롤러를 해킹했습니다. bunniestudios.com/blog/?p=3554 그들이 주제에 대해 한 시간 대화는 꽤 좋았습니다.
mikeserv

답변:


11

SD 카드 스트레스 테스트는 일반적으로 두 가지 문제가 있다고 생각합니다.

  1. 마모 평준화 다음에 한 번의 기록이 실제로 SD에서 동일한 물리적 위치를 사용한다고 보장 할 수는 없습니다. 제자리에있는 대부분의 SD 시스템은 우리가 알고있는대로 적극적으로 차단하고 있으며 각 위치에 적용되는 인식 된 "마모"를 기준으로 물리적 위치를 이동시킵니다.

  2. 다른 기술 (MLC vs. SLC) 이것과 함께 볼 수있는 다른 문제는 기술의 차이입니다. SLC 유형의 SSD MLC 제품보다 수명이 훨씬 길 것으로 예상됩니다. 또한 MLC에는 SLC에 대해 다루지 않아도되는 훨씬 더 엄격한 허용 오차가 있거나 적어도 이러한 방식으로 실패하는 것에 훨씬 더 관대합니다.

    • MLC-멀티 레벨 셀
    • SLC-단일 레벨 셀

MLC의 문제점은 주어진 셀이 여러 값을 저장할 수 있고 비트는 물리적 + 5V 또는 0V가 아니라 전압을 사용하여 본질적으로 스택되므로 SLC보다 훨씬 높은 고장률이 발생할 수 있다는 것입니다. 동등한.

기대 수명

하드웨어가 얼마나 오래 지속될 수 있는지에 대해 설명하는이 링크를 찾았습니다. 제목 은 SSD를 알고 있습니다-SLC vs. MLC .

SLC

SLC ssds는 대부분 49 년에서 149 년 사이에 평균적으로 최상의 추정치에 따라 산다고 계산할 수 있습니다. Memoright 테스트는 하루 평균 쓰기 속도가 100Gb 인 쓰기 내구성 수명이 200 년 이상인 128Gb SSD를 검증 할 수 있습니다.

MLC

여기서 mlc 디자인이 부족합니다. 아직까지 릴리스 된 것이 없습니다. mlc로 어떤 종류의 기대 수명이 보장되는지 실제로 조사한 사람은 없습니다. 나는 slc 디자인에 찬성하여 평균 10 대 1의 수명을 갖는 여러 가지 다른 신념을 받았다. 보수적 인 추측은 대부분의 수명 추정치가 각 제조업체의 컨트롤러 내에서 '마모 레벨링 알고리즘'의 발전에 따라 7 년에서 10 년 사이에 올 것이라는 것입니다.

비교

쓰기주기를 통해 비교를하기 위해 slc의 수명은 10,000 쓰기주기의 mlc와 비교하여 100,000의 완전한 쓰기주기를 갖습니다. 사용되는 '마모 레벨링'의 디자인에 따라 크게 증가 할 수 있습니다.


1
WRT웨어 레벨링 "다음에 한 번의 쓰기 작업이 실제로 SD에서 동일한 물리적 위치를 사용한다고 보장 할 수는 없습니다." -질문 slm! 매우 명확하게 생각합니다. 마모 레벨링이 없으면 명시된 쓰기주기 수명을 초과하여이 테스트가 통과 될 것으로 예상하지 않습니다. 이 테스트 는 마모 레벨링의 효과를 입증하기위한 것이며 무시하지 않아야합니다. 같은 겉보기 장소에 2 백만 번 쓸 수 있다는 사실 은 마모 레벨링이 유효 하다는 것을 나타냅니다.
goldilocks

WRT # 2, 품질 및 기술은 물론 한 카드를 다른 카드와 차별화 할 것입니다. 내 요점은 그 샌디 스크 카드 사기꾼 실행 평범한 것입니다 여전히 사람이 정말 너무 그것을 필요로보다 더 오래 마지막 방법 경우 하루에 기록 된 데이터의 양이 상대적으로 작다.
goldilocks

@goldilocks-알았어. 알았어. 8-), 당신이 말하는 것은 방정식에서 마모 레벨링을 효과적으로 제거하고 나쁜 블록을 실행하기에 충분한 양의 데이터를 쓰면 마모 레벨링의 효과를 보여주기에 충분합니까?
slm

1
@ goldilocks-방금 판도라의 상자를 열었습니까?
slm

1
(예 : SD 카드에 이미지를 써서 복제 한 fstrim후 나중에 할 수 없거나 나중에 할 수없는 경우 , 동적 마모 레벨링을 완전히 비활성화했습니다 (정적 마모 레벨링 기능이있는 소비자 등급 SD 카드를 찾기 어려울 것임).
Jason C

6

테스트에는 몇 가지 문제가 있습니다. 그것은 또한 당신의 목표에 달려 있습니다. 두 가지 미묘한 종류의 퍼지 문제는 다음과 같습니다.

  • 읽고있는 것과 동일한 영역에서 읽고 있지 않으며, 읽기 테스트를 효과적으로 수행 한 다음 아무 것도 수행하지 않습니다 (컨트롤러가 읽기 방해 수정을하지 않은 경우 때때로 페이지를 다른 곳으로 이동할 수 있지만 여전히 그렇지 않습니다. 테스트에 영향을 미치지 않습니다).
  • 불량 블록에 대한 읽기 / 쓰기가 컨트롤러에 의해 감지 및보고된다고 가정합니다 (그리고 보장되지는 않습니다). 데이터를 쓰고, 다시 읽고, 보장 된 검사를 위해 비교하려고합니다.

그러나 그것들은 논란의 여지가 있습니다. 더 심각한 것은 :

  • badblocks플래시 메모리에서 실패한 페이지를 표시하는 데 사용할 수 없습니다 . 모든 오류 감지 및 후속 페이지 맵핑은 컨트롤러에 의해 수행되며 OS에 투명합니다. 드라이브가 지원하는 경우 SMART에서 일부 정보를 얻을 수 있습니다 (지원하는 SD 카드가 없다는 것을 알고 있습니다.
  • 사전 TRIM 명령, 테스트 중 드라이브의 사용 가능 / 사용 상태 및 예약 된 공간을 고려하지 않은 테스트로 인해 복잡한 마모 수준.

마모 레벨링 : 주요 문제는 마모 레벨링이 테스트의 주요 변수라는 것입니다. 컨트롤러 (보통)에서 발생하며, 어떤 경우에도 직접 장치 검색 + 읽기 / 쓰기에 투명합니다. 귀하의 예에서 실제로 마모 레벨링 상태를 알지 못합니다 (특히 최근 블록을 해제하기 위해 TRIM 명령이 발행 되었습니까?) ...

장치의 동적웨어 레벨링 (거의 모든 소비자 등급 저장 장치에 있음)의 경우 어느 상태에있을 수 있습니다. 극단적 인 페이지가 하나도없는 것으로 표시되지 않으므로 컨트롤러가 작동해야하는 유일한 페이지 예약 된 공간에있는 것이 있습니다 (있는 경우). 이 경우주의 입니다 장치의 예약 된 공간, 그것은 것입니다 당신이 보장하기 시작하기 전에 완전히 실패 할 필요는 (무료 남은 것으로 표시 다른 페이지가 없습니다 추정) 페이지 쓰기에 실패합니다. 다른 모든 극단적 인 경우, 모든 페이지는 사용 가능으로 표시됩니다.이 경우 이론적으로 쓰기 실패를보기 전에 장치의 모든 페이지가 실패해야합니다.

정적웨어 레벨링 (SSD가있는 경향이 있고 SD 카드가없는 경향이 있으며 썸 드라이브가 다름)의 경우 : 장치의 모든 페이지에 반복해서 쓰는 것 외에는 실제로 그 방법이 없습니다.

다른 말로하면, 특히 동적 마모 레벨링의 사용 여부, 정적 마모 레벨링의 사용 여부 및 웨어 레벨링을 위해 장치에 예약 된 공간의 양 (컨트롤러 (또는 경우에 따라 M-Systems Old DiskOnChip과 같은 드라이버에서는 볼 수 없음)).

SLC / MLC : SLC와 MLC의 경우 이는 예상 한 한계에 매우 직접적인 영향을 주지만 일반적인 마모 레벨링 절차와 테스트 절차는 모두 동일합니다. 페이지 당 100k + 사이클 제한을 요구하는 플래시 드라이브가 SLC 일 가능성이 높지만 많은 공급 업체는 장치가 더 저렴한 소비자 제품을 위해 SLC 또는 MLC인지 여부를 게시하지 않습니다.

캐싱 : 캐싱의 경우 약간 문제가 있습니다. 일반적인 경우 OS 수준에서 fsync / fdatasync는 실제로 데이터가 기록되는 것을 보증하지 않습니다. 그러나 이동식 드라이브는 일반적으로 다음과 같은 일반적인 사용 패턴을 위해 설계 되었으므로이 경우 컨트롤러가 최소한 (또는 적어도 컨트롤러가 그렇게하기 위해 최선을 다하고 있습니다. "꺼내기"(마운트 해제> 동기화) 한 다음 제거하십시오 (전원 차단). 우리가 확실하지는 않지만 교육받은 추측에 따르면 동기화는 쓰기, 특히 쓰기-> 동기화-> 읽기에서 쓰기가 절대적으로 이루어질 것이라고 가정하는 것이 안전하다고 말합니다 (그렇지 않은 경우 드라이브를 신뢰할 수 없음) 꺼내기 후). 꺼내기시 발행 될 수있는 'sync'이외의 다른 명령은 없습니다.

컨트롤러에서는 무엇이든 가능하지만, 위의 가정에는 컨트롤러가 동기화 후 데이터 손실을 위험에 빠뜨리기 위해 최소한 "복잡한"작업을 수행하지 않는다는 가정도 포함됩니다. 동일한 데이터가 재기록되는 경우 (제한된 정도로), 제어기는 버퍼 및 그룹 기록을 말하거나 데이터를 기록하지 않을 수있다. 아래 프로그램에서, 우리는 합리적인 컨트롤러 캐싱 메커니즘을 물리 치기 위해 두 개의 서로 다른 데이터 블록을 번갈아 가며 읽기 전에 동기화를 수행합니다. 물론, 보장 및 알 방법은 없지만 이러한 장치의 정상적인 사용과 정상적인 캐싱 메커니즘을 기반으로 합리적인 가정을 할 수 있습니다.

테스트 :

당신이하지 않으면 불행하게도, 진리이며, 알고 장치에는 예약 된 공간이없고 정적 수평을하고 있지 않은지 확실히 특정 페이지의 사이클 한계를 테스트 할 수있는 방법은 없습니다. 그러나 가장 가까운 거리는 다음과 같습니다 (정적 마모 레벨링이 없다고 가정).

가장 먼저 해야 할 일은 전체 카드를 데이터로 채우는 것입니다. 이것은 중요하며 원래 테스트에서 남은 주요 변수입니다. 이것은 예약 된 공간을 제외하고 사용 가능한 많은 블록을 표시합니다 (액세스 할 수있는 방법이 없음). 단일 파티션으로 작업하면 장치의 특정 영역에만 영향을 미치므로 전체 장치를 사용하여 작업하면 모든 데이터가 손상됩니다.

dd if=/dev/urandom bs=512k of=/dev/sdb conv=fsync oflag=sync

진행률 표시 줄인 경우 :

pv -pterb -s <device_size> /dev/urandom | dd bs=512k of=/dev/sdb conv=fsync oflag=sync

편집 : 4MB 지우기 블록이있는 카드의 경우 더 빠른 쓰기를 위해 다음을 시도하십시오.

dd if=/dev/urandom bs=4M of=/dev/sdb conv=fsync oflag=direct,sync iflag=fullblock

그런 다음 다음과 같이 사이클 테스트 프로그램을 작성하여 가능한 한 많은 OS 버퍼링 및 캐싱을 잘라 내고 이론적으로 컨트롤러에 직접 작성하여 및를 사용 O_DIRECT하여 O_SYNC(및 편집증, 중복 사용 fsync()) 할 수 있습니다 작업이 완료되었다고보고 될 때까지 기다립니다.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>

using namespace std;

static const int BLOCK_SIZE = 512;
static const int ALIGNMENT = 512;
static const int OFFSET = 1024 * ALIGNMENT; // 1024 is arbitrary


int main (int argc, char **argv) {

    if (argc != 2) {
        fprintf(stderr, "usage: %s device\n", argv[0]);
        return 1;
    }

    int d = open(argv[1], O_RDWR | O_DIRECT | O_SYNC);
    if (d == -1) {
        perror(argv[1]);
        return 1;
    }

    char *block[2], *buffer;
    int index = 0, count = -1;

    // buffers must be aligned for O_DIRECT.
    posix_memalign((void **)&(block[0]), ALIGNMENT, BLOCK_SIZE);
    posix_memalign((void **)&(block[1]), ALIGNMENT, BLOCK_SIZE);
    posix_memalign((void **)&buffer, ALIGNMENT, BLOCK_SIZE);

    // different contents in each buffer
    memset(block[0], 0x55, BLOCK_SIZE);
    memset(block[1], 0xAA, BLOCK_SIZE);

    while (true) {

        // alternate buffers
        index = 1 - index;

        if (!((++ count) % 100)) {
            printf("%i\n", count);
            fflush(stdout);
        }

        // write -> sync -> read back -> compare
        if (lseek(d, OFFSET, SEEK_SET) == (off_t)-1)
            perror("lseek(w)");
        else if (write(d, block[index], BLOCK_SIZE) != BLOCK_SIZE)
            perror("write");
        else if (fsync(d))
            perror("fsync");
        else if (lseek(d, OFFSET, SEEK_SET) == (off_t)-1)
            perror("lseek(r)");
        else if (read(d, buffer, BLOCK_SIZE) != BLOCK_SIZE)
            perror("read");
        else if (memcmp(block[index], buffer, BLOCK_SIZE))
            fprintf(stderr, "memcmp: test failed\n");
        else
            continue;

        printf("failed after %i successful cycles.\n", count);
        break;

    }

}

O_DIRECT경우 버퍼를 적절히 정렬해야합니다. 512 바이트 경계면 충분합니다. 다음과 같이 컴파일 할 수 있습니다.

g++ -O0 test.cpp -o test

-D_POSIX_C_SOURCE=200112L필요한 경우 추가 하십시오.

그런 다음 위와 같이 장치를 완전히 채운 후 밤새 실행하십시오.

./test /dev/sdb

512 바이트, 정렬 된 쓰기는 양호하므로 전체 페이지를 지우고 다시 쓸 수 있습니다. 더 큰 블록 크기를 사용하여 테스트 속도를 크게 높일 수는 있지만 구체적인 결과를 얻는 것이 복잡해집니다.

나는 현재 어제 보도에서 찾은 다소 두들겨 보이는 4GB PNY 썸 드라이브를 테스트하고 있습니다 ( http://www3.pny.com/4GB-Micro-Sleek-Attach의 남은 것으로 보입니다 . -Purple-P2990C418.aspx ).

위의 프로그램은 기본적으로 제한된 버전이므로 badblocks예약 된 공간이 모두 소진 될 때까지 오류가 표시되지 않습니다. 따라서 (반복 당 1 페이지를 기록한) 기대 값은 상기 절차가 평균적으로 reserved_page_count * write_cycle_limit 반복 에서 실패해야한다는 것입니다 (마모 레벨링이 주요 변수 임). 썸 드라이브가 너무 나쁘고 SD 카드는 일반적으로 SMART를 지원하지 않으므로 예약 된 공간 크기를보고 할 수 있습니다.

그건 그렇고, fsyncvs fdatasync는이 테스트의 목적을 위해 수행중인 블록 장치 쓰기에 아무런 차이가 없습니다. 당신의 open()모드는 중요합니다.

기술적 세부 사항이 궁금한 경우 다음은 SD 카드의 내부 작동에 대해 알아야 할 모든 것입니다 ( https://www.sdcard.org/downloads/pls/simplified_specs/part1_410.pdf).

편집 : 바이트 대 페이지 : 이러한 유형의 테스트와 관련하여 바이트가 아닌 페이지로 생각하는 것이 중요합니다. 반대의 행동을하는 것은 매우 잘못된 일일 수 있습니다. 예를 들어, SanDisk 8GB SD의 경우 컨트롤러를 통한 페이지 크기 (를 통해 액세스 가능 /sys/classes/mmc_host/mmc?/mmc?:????/preferred_erase_size)는 전체 4MB입니다. 16MB (4MB 경계에 정렬)를 쓴 다음 4 페이지를 지우거나 씁니다. 그러나 서로 4MB 오프셋으로 4 개의 단일 바이트를 쓰면 4 페이지를 지우거나 씁니다.

"16MB 쓰기로 테스트했습니다"라고 말하는 것은 정확하지 않습니다. "4 바이트 쓰기로 테스트 한 것"과 같은 마모량입니다. 보다 정확하게는 "4 페이지 쓰기로 테스트했습니다".


바이트 대 페이지에 대한 의견을 추가했습니다.
Jason C

PNY는 파괴 불가능한 것으로 보입니다. 그러나 새로운 SanDisk 8GB MicroSD에서 ~ 8.1mil 반복 (약 8 시간 이상) 후 전원주기 dd가 지나면 최대 쓰기 속도 (원래 4MB / 초)가 ~ 410kB / 초로 영구적으로 떨어지고 250MB를 쓴 후 실패합니다. . 전원을 껐다 켤 때까지 손상이 나타나지 않았습니다. PNY 썸 드라이브는 ~ 30mil 반복 후에도 영향을받지 않습니다. 위의 프로그램을 수정했지만 (위의 코드에는 반영되지 않음) 매번 동일한 대신 16kB 정렬 된 임의의 위치에 쓰지 만 SD에서 ~ 4mil 반복 후에 그 작업을 수행했습니다. 새 카드로 다시 테스트합니다.
Jason C

dd그 카드에 대한 세 번째 시도 는 250MB를 넘어서고 그 시점 이후의 영역에 대한 쓰기 성능은 다시 전체 4MB / 초로 증가했습니다. 블록이 계속 섞여서 성능을 예측할 수 없을 것으로 기대합니다. 나는 카드가 파괴되었다고 말하지는 않지만 확실히 100 %가 아닙니다.
Jason C

5

slm의 답변에 몇 가지 요점을 추가하기 만하면됩니다. SSD는 데이터와 함께 훨씬 더 복잡한 트릭을 수행하므로 (예 : 중복 제거) "dumb"SD 카드보다 SSD에 더 적합 합니다.

  • 장치의 시작 부분에 64KB를 쓰고 있습니다.이 자체에는 두 가지 문제가 있습니다.

    1. 플래시 셀은 일반적으로 16KB 이상 크기의 소거 블록을 갖습니다 (128-512KB 범위 일 가능성이 높음). 즉이 크기 이상의 캐시가 필요합니다. 따라서 64KB를 작성하는 것만으로는 충분하지 않은 것 같습니다.

    2. 로우 엔드 ( "엔터프라이즈가 아닌"읽기) 솔루션의 경우 (SSD보다 SD / CF 카드에 더 많은 기능을 기대할 것입니다) 중요한 구조-장치의 단일 파티션에있는 파티션 테이블과 FAT (대부분의 메모리 카드는이 설정을 사용하고 있음)가 있습니다. 따라서 카드의 시작 테스트는 편향 될 수 있습니다.

  • fdatasync() 실제로 데이터가 물리적 매체에 기록되는 것을 보장하지는 않습니다 (아마도 OS의 통제하에 최선을 다하더라도)-맨 페이지를 참조하십시오 :

    장치 에서 전송이 완료되었다고 보고때까지 통화가 차단 됩니다.

    작은 커패시터가 있다는 것이 밝혀지면 놀라지 않을 것입니다.이 커패시터는 외부 전원이 끊길 경우 캐시 된 데이터를 플래시 메모리에 쓸 수있는 에너지를 제공 할 수 있습니다.

    어쨌든, 카드에 캐시가 있다고 가정 할 때 ( SU에 대한 귀하의 질문에 대한 답변 참조 ) 64KB를 작성하고 (with fdatasync())을 동기화하는 것이이 목적을 위해 충분히 설득력이있는 것으로 보이지 않습니다. "전원 백업"이 없어도 펌웨어는 여전히 안전하지 않은 상태로 재생되고 예상보다 조금 더 오래 데이터를 기록되지 않은 상태로 유지할 수 있습니다 (일반적인 사용 사례에서는 문제가 발생하지 않기 때문에).

  • 새 블록을 작성하고 비교하기 전에 데이터를 읽고 실제로 작동하는지 확인하기 위해 (그리고 편집증이 충분하면 판독을 위해 클리어 버퍼를 사용하십시오).


+1 캐싱 가능성과 소거 블록의 중요성을 강조합니다. 그러나 ...
goldilocks

"카드의 시작을 테스트하는 것은 바이어스 될 수있다" 때문에 마모 레벨링의 기억 (재생에 있어야합니다 -이 시점에서 쓰기 사이클의 적절한 수를 초과했습니다) -이 아니라 분명히 첫 번째 블록. 즉, 첫 번째 물리적 블록이 아니라 첫 번째 가상 블록입니다.
금발 미녀

"fdatasync ()는 실제로 데이터가 물리적 매체에 기록되는 것을 보장하지 않습니다" IMO, 전송이 완료되었다고보고하는 장치는 장치가 읽기-쓰기 테스트를 통과 한 경우 쓰기가 발생했음을 나타냅니다 ( 아직 실패했습니다). 캐싱이이를 복잡하게 만들 수 있지만,이를 해결하기 위해 상당히 큰 청크를 사용하는 경우 장치에서 성공을보고했을 때 "가짜 쓰기"가 불가능할 수 있습니다. 그렇게하면 쓸모가 없을 것입니다.
goldilocks

1
@goldilocks 아니오, 장치에서 데이터를 다시 읽는 것이 아무것도 보장하지 않습니다. 이다 합리적인것으로 예상 데이터가 물리적 매체에 있어야하고, 아마 대부분의 경우에있을 것입니다,하지만 보장 아니에요 - 적어도 당신은 캐시 크기를 넘어하지 않는 한.
peterph

1
@goldilocks peterph는 내가 지적하고 싶은 또 다른 것을 불러옵니다. read테스트에서 그것은 어떤 정보를 추가하지 않고 쓰기 사이클 시험 관련이없는, 불필요합니다. 실제 테스트의 경우 컨트롤러가 모든 장애 모드를 감지하고 다시보고 할 수 있는지 확실하지 않은 경우 방금 작성한 블록을 읽고 검증해야합니다.
Jason C

2

Peterph의 대답은 가능한 캐싱 문제를 더 고려하게 만들었습니다. 주변을 파고 난 후에도 여전히 SD 카드 중 일부 또는 전부가이 작업을 수행하는지 확실하게 알 수 없지만 가능하다고 생각합니다.

그러나 캐싱에 지우기 블록보다 큰 데이터가 포함되어 있다고는 생각하지 않습니다. 확실히하기 위해 64kB 대신 16MB 청크를 사용하여 테스트를 반복했습니다. 이것은 4GB 카드 총 용량의 1/250입니다. 이 10,000 번을 수행하는 데 ~ 8 시간이 걸렸습니다. 마모 레벨링이 하중을 분산시키는 데 최선이라면, 모든 물리적 블록이 40 번 사용 된 것입니다.

그다지 많지는 않지만 테스트의 원래 요점 은 적당한 양의 데이터를 동일한 (명백한) 위치에 반복적으로 기록하여 카드를 쉽게 손상시킬 수 없음을 보여줌으로써 마모 레벨링의 효과입증하는 것이 었습니다 . 이전 64 kB 테스트의 IMO는 실제 테스트 일 것입니다. 그러나 16MB는 필수입니다. 시스템이 데이터를 하드웨어로 플러시했으며 하드웨어가 오류없이 쓰기를보고했습니다. 이것이기만이라면, 그 카드는 아무 것도 좋지 않을 것이며, 16MB를 주 저장소에서 캐싱 할 수 없으며, 이는 테스트를 강조하기위한 것입니다.

바라건대, 각 16MB의 10,000 쓰기는 하단 엔드 브랜드 카드 (값 : $ 5 CDN)에서도 매일 적당한 양의 데이터를 쓰는 rw 루트 파일 시스템을 24/7로 실행 해도 카드가 마모되지 않음 을 증명하기에 충분합니다. 합리적인 시간. 10,000 일은 27 년이며 카드는 여전히 괜찮습니다 ...

그보다 더 많은 작업을 수행 한 시스템을 개발하기 위해 돈을 받고 있다면, 카드 얼마나 오래 지속될 있는지 결정하기 위해 최소한 몇 가지 테스트를하고 싶습니다 . 필자의 직감은 쓰기 속도가 느린 이와 같은 것으로 최대 속도로 몇 주, 몇 달 또는 몇 년 동안 연속 쓰기가 필요할 수 있습니다 (온라인에서 이러한 종류의 비교 테스트가 없다는 사실은 사실 그것은 매우 긴 일이 될 것입니다).

카드가 여전히 올바른지 확인하는 것과 관련하여 더 이상 badblocks기본 구성을 사용하는 것이 적절 하지 않다고 생각 합니다. 대신, 나는 이렇게했다 :

badblocks -v -w -b 524288 -c 8

이는 8 번 반복 된 512 kB 블록을 사용하여 테스트한다는 의미입니다 (= 4MB). 이것은 파괴적인 rw 테스트이기 때문에 연속 루프에서 사용되는 경우 장치에 스트레스를주는 것과 관련하여 내 가정의 것으로 테스트하는 것이 좋습니다.

또한 파일 시스템을 2GB 파일로 복사 diff하여 파일을 원본과 비교 한 다음 파일로 .iso 파일로 이미지로 마운트하고 파일 시스템을 찾아 보았습니다.

카드는 여전히 괜찮습니다. 어쨌든 어느 정도 예상되는 것은 ...

;);)


나는 당신의 수학이 옳다고 생각하지 않습니다. 클래스 2 카드의 처리량은 2MB / s로 유지되므로 약 4 개월 내에 20TB를 사용할 수 있습니다. 물론, 당신은 당신이 비 분류 한 카드를 가지고 있지만, (terdon는 지적으로 당신이 정말로 오프 크기 순서 것으로 보인다 언급 unix.stackexchange.com/questions/84902/... ). 그렇지 않으면 나는 slm에 전적으로 동의한다.
peterph 2016 년

나는 우리가 할 수 있다고 합리적으로 영향을 자주 제거 할 수 있도록 설계되었습니다 미디어 동기화 후 확인 캐싱이있는 경우, 최소한 가지고 있으며 전원 버스입니다. 이러한 장치는 안정적으로 "배출"되고 제거되도록 설계되었으며 동기화는 가능한 경우 전원을 끄는 것 이외의 다른 장치에 대해 OS가 수행 할 수있는 마지막 방법입니다. 예를 들어 USB 드라이브 나 SD 카드가 동기화 후에 물리적으로 쓰여지거나 최소한 전원을 끈 후에도 아주 짧은 시간 안에 쓰기를한다고 가정하는 것이 합리적입니다.
Jason C

또한 btw badblocks는 플래시 메모리의 실패한 페이지를 표시하지 않습니다. 이 작업에 적합한 도구는 아니며 플래시에서 실패한 페이지를 찾는 데 사용할 수 없습니다. 컨트롤러가 오류를 감지하면 내부적으로 페이지를 불량으로 표시하고 예약 된 공간의 페이지에 다시 매핑합니다. 이 모든 것은 컨트롤러 뒤에서 발생 하며 원시 장치 덤프에서도 전혀 볼 수 없습니다 . SMART가 지원되는 경우 컨트롤러에서 정보를 얻을 수 있습니다. 장치의 물리적 데이터 순서가 장치에서 IO를 수행 할 때 표시되는 바이트 순서와 일치하지 않습니다.
Jason C

FYI에 대한 또 다른 의견 : 소비자 등급 인 SanDisk 8GB MicroSD에서 할당 단위 (예 : 페이지 크기)는 컨트롤러가보고 한대로 4MB입니다. 즉, 해당 카드의 16MB는 4 페이지입니다 (정렬되지 않은 경우 5 페이지). 16MB를 카드에 공급하는 대신 512MB를 서로 4MB 오프셋으로 쓰면 테스트 속도를 높일 수 있습니다. 바이트와 ​​페이지 수를 구분하지는 않지만 예를 들어 SanDisk 8GB 카드 인 경우 "16MB"는 "2KB"와 동일한 마모를 일으 킵니다. 페이지 대신 바이트를 참조하는 것은 매우 잘못된 것입니다.
Jason C

위에서 작성한 테스트 프로그램에서 ~ 8.1mil 반복 (8 시간 이상) 후 새 SanDisk 8GB MicroSD에서 전원을 껐다 켜면 쓰기 속도가 약 450kB / 초로 영구적으로 제한되어 약 dd250MB를 지나서 쓰기에 실패했습니다. 표. 세 번째 dd시도에서 250MB를 초과 한 후에는 해당 영역에서 쓰기 성능이 다시 향상되었습니다. 나는 카드가 파괴되었다고 말하지는 않지만 확실히 100 %가 아닙니다.
Jason C
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.