Системный вызов sync
sync (от англ. synchronize — синхронизировать) — это системный вызов в операционных системах семейства Unix (включая Linux), предназначенный для принудительной записи всех изменённых, но ещё не сохранённых на постоянном носителе (например, жёстком диске или твердотельном накопителе) данных из буферов файловой системы (кэша) на устройство хранения. Вызов обеспечивает синхронизацию состояния файловой системы в оперативной памяти с её состоянием на диске, что критически важно для предотвращения потери данных при внезапном отключении питания, сбое ядра или аппаратном сбое.
Принцип работы
Современные операционные системы, включая ядро Linux, используют механизм кэширования для повышения производительности ввода-вывода. При записи данных в файл они сначала помещаются в оперативную память (в так называемый «страничный кэш» или «буферный кэш»), а затем асинхронно сбрасываются на диск фоновыми процессами (например, pdflush в Linux). Это позволяет приложению быстро завершить операцию записи, не дожидаясь медленного обращения к физическому устройству. Однако при сбое питания или аварийном завершении работы данные, находящиеся только в кэше, могут быть потеряны.
Системный вызов sync заставляет ядро немедленно начать сброс всех изменённых буферов на диск и дождаться завершения всех операций записи. После возврата из вызова гарантируется, что все данные, которые были записаны в файловую систему до этого момента, физически находятся на носителе. Вызов sync не принимает аргументов и не возвращает значения, указывающего на успех или неудачу (хотя в некоторых реализациях может возвращать 0 в случае успеха). Он действует на всю файловую систему целиком, а не на отдельный файл или каталог.
История
Системный вызов sync появился в самых ранних версиях операционной системы Unix, разработанной в Bell Labs (AT&T) в конце 1960-х — начале 1970-х годов. В то время компьютеры были менее надёжны, а сбои питания — обычным делом, поэтому необходимость в принудительной синхронизации данных была очевидна. В первой редакции Unix (1971 год) sync уже присутствовал как одна из основных системных функций. Впоследствии он был стандартизирован в рамках POSIX (Portable Operating System Interface) и стал обязательным элементом для всех Unix-подобных систем, включая Linux, FreeBSD, macOS и другие.
В Linux вызов sync реализован в ядре и документирован в разделе 2 руководства (man 2 sync). В более поздних версиях ядра (начиная с 2.6.33) появилась также системная функция syncfs(), которая синхронизирует данные только для одной указанной файловой системы, а не для всех смонтированных.
Связанные системные вызовы и утилиты
Помимо sync, существуют другие системные вызовы и утилиты, обеспечивающие синхронизацию данных на различных уровнях:
fsync()— синхронизирует только данные и метаданные одного конкретного файла, заданного файловым дескриптором. Более эффективен, чемsync, если требуется гарантировать сохранность только одного файла (например, базы данных или журнала транзакций).fdatasync()— аналогиченfsync(), но синхронизирует только данные файла, не затрагивая метаданные (например, время последнего изменения), если это не влияет на целостность данных. Может быть быстрее.syncfs()— синхронизирует все данные, относящиеся к одной файловой системе, смонтированной по указанному файловому дескриптору.- Утилита
sync— командная программа, доступная в терминале, которая вызывает системный вызовsync(илиsyncfs()в некоторых реализациях). Используется администраторами для принудительной записи данных перед отключением устройства или выключением системы. - Утилита
mountс опциейsync— при монтировании файловой системы с опциейsync(например,mount -o sync /dev/sda1 /mnt) все операции записи выполняются синхронно, без кэширования. Это снижает производительность, но гарантирует, что данные сразу записываются на диск. Используется для сменных носителей (флешек, внешних дисков), чтобы избежать потери данных при внезапном извлечении.
Применение
Системный вызов sync и связанные с ним утилиты применяются в следующих сценариях:
- Перед отключением питания или извлечением накопителя. При использовании съёмных устройств (USB-флешек, внешних дисков) рекомендуется выполнить команду
syncперед физическим отключением, чтобы гарантировать, что все данные записаны. Однако современные операционные системы автоматически выполняют синхронизацию при размонтировании (umount), поэтому прямой вызовsyncчасто избыточен. - В сценариях резервного копирования. Перед копированием данных на внешний носитель или в облачное хранилище может быть выполнен
sync, чтобы убедиться, что исходные данные полностью сохранены на диске. - В системах с повышенными требованиями к надёжности. Серверы баз данных, файловые серверы и критически важные приложения могут вызывать
fsync()илиfdatasync()после каждой транзакции, чтобы гарантировать целостность данных. Полныйsyncиспользуется реже из-за его высокой стоимости по производительности (он блокирует всю систему ввода-вывода). - В процедурах выключения и перезагрузки. Команды
shutdown,rebootиhaltв Unix-системах перед завершением работы вызываютsyncдля сохранения всех изменений. В Linux это делается автоматически. - В тестировании и отладке. Разработчики файловых систем и драйверов устройств могут использовать
syncдля принудительного сброса кэша и проверки корректности работы после сбоев.
Производительность и ограничения
Вызов sync является дорогостоящей операцией, так как он блокирует выполнение всех процессов, пытающихся выполнить запись на диск, до завершения синхронизации. Время выполнения зависит от объёма данных в кэше, скорости диска и текущей нагрузки на подсистему ввода-вывода. В системах с большим количеством изменённых данных (например, при интенсивной записи) sync может занимать от нескольких секунд до нескольких минут.
Кроме того, sync не гарантирует, что данные будут записаны на физический носитель немедленно, если между диском и контроллером используется кэш записи самого устройства (например, на жёстких дисках с включённым кэшем). В таких случаях данные могут оставаться в кэше диска даже после возврата из sync. Для обхода этой проблемы в Linux существуют команды hdparm -W0 (отключение кэша записи на диске) или использование флага O_SYNC / O_DSYNC при открытии файла.
Безопасность и целостность данных
Системный вызов sync является важным инструментом для обеспечения целостности данных, но не является панацеей. В случае сбоя питания во время выполнения sync часть данных может быть потеряна, так как ядро не может гарантировать атомарность всей операции. Для критически важных приложений (например, баз данных) используются более сложные механизмы, такие как журналирование (журналируемые файловые системы, например, ext4, XFS, Btrfs) или транзакционные системы.
Реализация в различных операционных системах
- Linux: вызов
syncреализован в ядре и документирован вman 2 sync. В дополнение к нему существуетsyncfs(), а также утилитаsyncиз пакета coreutils. В большинстве дистрибутивов Linux командаsyncдоступна по умолчанию. - FreeBSD: аналогичная реализация, также поддерживается
syncfs(). Утилитаsyncвходит в базовую систему. - macOS: системный вызов
syncприсутствует, но его поведение может отличаться из-за особенностей файловой системы HFS+ или APFS. Утилитаsyncдоступна в терминале. - Windows: в операционных системах семейства Windows нет прямого аналога
sync, но существуют функции Win32 API, такие какFlushFileBuffers()(для одного файла) иFlushViewOfFile()(для отображённых в память файлов). Командаsyncотсутствует; для принудительной записи данных используетсяfsutilили вызовы API.
Интересные факты
- В ранних версиях Unix команда
syncвыполнялась дважды подряд, так как первый вызов мог инициировать запись, а второй гарантировал её завершение. В современных системах это не требуется. - В некоторых реализациях (например, в Linux) вызов
syncможет быть прерван сигналом, что может привести к частичной записи данных. - В ядре Linux существует системный вызов
sync_file_range(), который позволяет синхронизировать только определённый диапазон байт внутри файла, что даёт более тонкий контроль над производительностью.
Источники
- man-страницы:
sync(2),fsync(2),fdatasync(2),syncfs(2),sync(8)(Linux). - Спецификация POSIX.1-2017, раздел «sync».
- «The Design of the UNIX Operating System» by Maurice J. Bach (1986).
- «Linux Kernel Development» by Robert Love (3rd edition, 2010).
- Документация ядра Linux:
Documentation/filesystems/.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →