Открыть сервис

Копирование при записи

Копирование при записи (англ. Copy-on-write, COW) — это механизм управления памятью или данными, при котором несколько процессов или объектов совместно используют один и тот же ресурс (например, страницу физической памяти или блок данных), и копия этого ресурса создаётся только в тот момент, когда один из процессов выполняет операцию записи в этот ресурс. До момента записи все процессы, ссылающиеся на ресурс, имеют доступ к его исходной, неизменённой версии, что позволяет экономить память и увеличивать производительность, особенно в ситуациях, когда данные активно считываются, но редко модифицируются. Механизм используется в операционных системах, файловых системах, системах виртуализации, базах данных и других областях.

История

Концепция копирования при записи впервые была предложена и реализована в операционной системе MULTICS (разрабатывалась с 1965 года). В MULTICS механизм применялся для совместного использования сегментов данных между процессами. Позднее, в 1970-х годах, идея была адаптирована для виртуальной памяти в системе TENEX, где страницы памяти, принадлежащие разным процессам, могли быть общими до первой попытки записи. Значительное развитие механизм получил в операционной системе Unix, начиная с версии 4.2BSD (1983 год), где COW был реализован для системного вызова fork(). В 1990-х и 2000-х годах механизм начал широко применяться в файловых системах (ZFS, Btrfs) и системах виртуализации (VMware, KVM). В настоящее время COW является стандартной техникой во многих современных ядрах операционных систем (Linux, FreeBSD, Windows NT).

Принцип работы

Основная идея COW заключается в отложенном копировании. Когда несколько процессов запрашивают доступ к одному и тому же блоку данных (например, после клонирования процесса через fork в Unix), ядро операционной системы отображает их виртуальные адреса на одну и ту же страницу физической памяти. При этом флаги доступа к этой странице устанавливаются как «только для чтения», хотя фактически она может быть изменяемой. Если процесс пытается выполнить запись, возникает страничное нарушение (page fault). Обработчик этого нарушения определяет, что страница является COW-страницей, создаёт её копию в новом физическом фрейме, меняет отображение виртуального адреса пишущего процесса на новую копию и устанавливает для неё права на чтение и запись. Исходная страница остаётся доступной для других процессов (или для родительского процесса) с тем же содержимым.

Применение

В операционных системах

Наиболее известное применение COW — системный вызов fork() в Unix-подобных ОС. При вызове fork() родительский процесс порождает дочерний процесс. Без механизма COW системе пришлось бы немедленно копировать всё адресное пространство родителя, что затратно по времени и памяти. COW позволяет дочернему и родительскому процессу совместно использовать все страницы памяти. Копирование происходит только для тех страниц, которые один из процессов модифицирует. Аналогичные подходы применяются при клонировании потоков (например, в операционной системе Solaris) и в некоторых реализациях разделяемой памяти.

В файловых системах

Механизм COW широко используется в файловых системах нового поколения, таких как ZFS (разработана Sun Microsystems, 2005), Btrfs (Oracles, 2007), APFS (Apple, 2017), LizardFS и некоторых других. В таких файловых системах при изменении данных не происходит перезапись старых блоков на диске. Вместо этого изменения записываются в новые блоки, а метаданные обновляются так, чтобы указывать на новую версию данных. Благодаря этому достигается высокая устойчивость к сбоям, моментальное создание снимков (snapshot) и клонов, а также эффективное использование дискового пространства.

В виртуализации

В системах виртуализации (VMware ESXi, KVM/QEMU, VirtualBox) механизм COW применяется для управления виртуальными машинами. При создании снимка состояния (snapshot) или клона виртуальной машины её диск изначально реализуется как неизменяемый базовый образ. При записи данных виртуальной машиной COW сохраняет изменённые блоки в отдельный файл, не затрагивая базовый образ. Это позволяет уменьшить занимаемое дисковое пространство и ускорить создание клонов.

В базах данных

Некоторые системы управления базами данных (СУБД) реализуют механизм COW для повышения производительности транзакций и обеспечения изоляции (например, в реализации многоверсионного управления параллельным доступом, MVCC). В таких СУБД при изменении записи данные не перезаписываются, а создаётся новая версия строки, а старая остаётся доступной для других транзакций до завершения текущей.

В программировании и структурах данных

В библиотеках структур данных часто применяется COW для создания иммутабельных (неизменяемых) копий коллекций. Например, в C++ механизм COW использовался в ранних реализациях класса std::string, однако позже от него отказались из-за проблем с многопоточностью и несовместимости с стандартной библиотекой. В функцию getline встроен метод copy_on_write. В языках Rust и Swift COW применяется в некоторых стандартных структурах данных (например, в Arc и Data), позволяя эффективно работать с потенциально большими объёмами данных без явного копирования.

Преимущества и недостатки

Преимущества

Недостатки

Критика

Несмотря на широкое распространение, механизм COW критикуется за неоптимальную производительность в некоторых высоконагруженных сценариях. Например, в случае интенсивных операций записи (базы данных с большим числом параллельных транзакций) постоянное создание копий может приводить к значительному росту накладных расходов на управление памятью и к фрагментации. В файловых системах COW может вызывать задержки операций ввода-вывода при массовом копировании изменений. Кроме того, в многопроцессорных системах с общей памятью механизм требует дополнительной синхронизации, что может снижать общую производительность.

Альтернативы

В качестве альтернативы копированию при записи применяются следующие техники:

Источники

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →