有没有办法在SSD上写入,如果在写入过程中断开连接,数据不会丢失?

Is there a way to write on a SSD, such that if it is disconnected during the writing process, no data is lost?

我有一个 Python 脚本,可以在外部 SSD 上记录摄像机的运动。计算机(Raspberry Pi)很有可能受到冲击并与驱动器断开连接(甚至与它的电源断开连接,但这是另一个话题,对吗?),但我不想丢失任何数据发生。可以实现吗?

我了解到,当驱动器未安全弹出时,只会丢失最后一个写入周期。写周期到底是什么?我如何使用它来完成我想要的?也许我可以写 5 秒的块(写周期为 5 秒),这样如果 SSD 断开连接,只会丢失 5 秒,你怎么看?

这在代码方面如何应用?

现在我正在使用 Picamera 库,它使用文件流。如果 SSD 断开连接,没有足够的时间 close() 流,这就是数据丢失的原因吗?在我的测试中,当我断开 SSD 连接时,无论我录制的序列是 1 分钟还是 15 秒长,我似乎只能看到视频的前 2-3 秒。

断开 SSD 后,我通常会在控制台中收到一些内核错误消息 (Linux):

Message from syslogd@raspberrypi at Nov 12 01:43:41 ...
 kernel:[  138.263099] Internal error: Oops: 5 [#1] PREEMPT SMP ARM

Message from syslogd@raspberrypi at Nov 12 01:43:41 ...
 kernel:[  138.366239] Process vc.ril.video_en (pid: 2403, stack limit = 0xb47c0210)

Message from syslogd@raspberrypi at Nov 12 01:43:41 ...
 kernel:[  138.374211] Stack: (0xb47c1c80 to 0xb47c2000)

Message from syslogd@raspberrypi at Nov 12 01:43:41 ...\
 kernel:[  138.379835] 1c80: 00000000 b5b84ce0 807fd650 b667536c a0000013 00000000 b47c1ccc b47c1ca8\

...

这会冻结此控制台会话中的所有内容。

有时,但很少见(大约 1/10 次),内核不会给出错误,但脚本会引发异常 (IOError: [Errno 5] Input/output error) 并在控制台中显示堆栈跟踪。

如有任何见解,我们将不胜感激!

干杯!

当您的应用程序调用 "write()" 时,Linux 实际上并未写入磁盘。 (如果这样做,一切都会很慢。)

原因是磁盘在 "seeking" 时非常慢(绕磁盘移动),但在 "streaming" 时非常快(顺序写入数据)。所以 Linux 将在内存中缓冲数据,然后以大的顺序块将其全部写出。

默认情况下,Linux 会将数据在写出之前在内存中保留最多 30 秒。如果这对你来说太大了,你可以调整它。尝试 echo 500 > /proc/sys/vm/dirty_expire_centiseconds 尝试每 5 秒写出一次数据。

参见: http://www.westnet.com/~gsmith/content/linux-pdflush.htm https://lonesysadmin.net/2013/12/22/better-linux-disk-caching-performance-vm-dirty_ratio/

所以这就是我所做的,以确保只丢失非常少量的数据。

  1. 通过将 0 传递给 open 方法的 buffering 参数来关闭文件对象的缓冲模式(仅在以二进制模式打开文件时有效。例如 open(fileName, 'wb+', 0)) .您还可以手动调用 flush 以在 write.
  2. 之后清空文件缓冲区
  3. 正如@Evan 所指出的,定期调用syncfsync 以强制将数据写入磁盘。 fsync() 或 sync() 之前的任何 write() 调用都将在同步调用 returns 之前发送到磁盘。性能会受到影响,可能会非常大。