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

Copy-on-Write

Copy-on-Write (COW, копирование при записи) — это механизм управления памятью и данными, при котором несколько процессов или потоков могут совместно использовать один и тот же ресурс (например, страницу памяти или блок данных) до тех пор, пока один из них не попытается изменить его. В момент первой попытки записи создаётся отдельная копия ресурса для выполняющего запись процесса, а остальные продолжают использовать исходный экземпляр. Этот подход позволяет экономить память и ресурсы, откладывая дорогостоящую операцию копирования до момента, когда она действительно необходима.

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

Основная идея Copy-on-Write заключается в том, чтобы разделять (sharing) данные между несколькими потребителями, а не копировать их заранее. Когда процесс или поток запрашивает доступ к ресурсу, ему предоставляется указатель на оригинальный экземпляр. При этом для всех потребителей ресурс выглядит как их собственная копия. Если ни один из них не пытается изменить данные, никакого копирования не происходит. Как только один из процессов инициирует операцию записи, операционная система или система управления памятью перехватывает это действие, создаёт новый экземпляр ресурса, копирует в него текущие данные и перенаправляет указатель процесса на новую копию. После этого процесс может безопасно модифицировать свою копию, не затрагивая данные других потребителей.

Техническая реализация

На уровне операционной системы COW обычно реализуется с помощью механизма страничной памяти и таблиц страниц. Каждой странице памяти присваивается флаг «только для чтения». Когда процесс пытается выполнить запись в такую страницу, возникает исключение (page fault). Обработчик исключения в ядре ОС выделяет новую физическую страницу, копирует содержимое исходной страницы в новую, обновляет таблицу страниц процесса, чтобы он указывал на новую страницу (теперь уже с правами на запись), и снимает флаг «только для чтения» с исходной страницы для других процессов, если они всё ещё её используют. В современных ОС, таких как Linux, Windows и macOS, этот механизм активно применяется при создании процессов (через системный вызов fork()), при отображении файлов в память (mmap) и в файловых системах.

История

Концепция Copy-on-Write была впервые предложена и реализована в операционной системе TENEX в конце 1960-х годов. TENEX использовала COW для реализации разделяемых сегментов памяти между процессами. Впоследствии механизм был усовершенствован и внедрён в более поздние системы, включая UNIX. Особую известность COW получила благодаря операционной системе 4.2BSD, где была реализована оптимизация системного вызова fork() — создание дочернего процесса без немедленного копирования всей памяти родителя. В 1980-х годах механизм стал стандартным для большинства Unix-подобных систем. В последующие десятилетия COW нашёл применение в файловых системах (ZFS, Btrfs), в системах виртуализации (QEMU, VMware), в базах данных и в языках программирования с неизменяемыми структурами данных.

Применение

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

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

Файловые системы

Copy-on-Write широко применяется в современных файловых системах для обеспечения целостности данных и эффективного создания снимков (snapshots). Файловые системы, такие как ZFS, Btrfs, APFS (Apple File System) и WAFL (NetApp), используют COW для хранения данных. При записи новых данных они не перезаписывают существующие блоки, а записывают новые блоки в свободное место, после чего обновляют метаданные, указывающие на новые блоки. Старые блоки остаются неизменными, что позволяет создавать мгновенные снимки состояния файловой системы без затрат на копирование всего объёма данных. Это также повышает устойчивость к сбоям: в случае краха системы во время записи старые данные остаются неповреждёнными.

Системы виртуализации

В гипервизорах, таких как QEMU/KVM и VMware, COW используется для создания образов виртуальных машин. Например, формат QCOW2 (QEMU Copy-On-Write) позволяет создавать образы дисков, которые занимают только то пространство, которое фактически используется внутри виртуальной машины. При создании снимка (snapshot) виртуальной машины гипервизор фиксирует текущее состояние диска, а все последующие изменения записываются в отдельный файл-оверлей, не затрагивая исходный образ. Это позволяет быстро откатывать изменения или создавать множество копий виртуальных машин с минимальным расходом дискового пространства.

Базы данных

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

Языки программирования

В некоторых языках программирования и их реализациях COW используется для оптимизации работы с неизменяемыми или разделяемыми структурами данных. Например, в языке PHP строки реализованы с использованием COW: при присваивании одной строки другой они указывают на одни и те же данные в памяти, а копирование происходит только при изменении одной из строк. В языке Rust стандартные типы, такие как Cow<T>, позволяют абстрагироваться от того, является ли данные заимствованными или собственными; копирование происходит только при необходимости записи.

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

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

Недостатки

Примеры использования в российских разработках

В российских операционных системах, таких как «Эльбрус» (разработка МЦСТ) и «Астра Linux» (ГК «Астра»), механизм Copy-on-Write используется в соответствии с общими принципами ядра Linux. В частности, в «Астра Linux» при создании процессов через fork() применяется стандартная реализация COW. В системах виртуализации, разрабатываемых в России (например, «zVirt» от ГК «Астра»), также используются образы дисков на основе COW для эффективного управления ресурсами.

Источники

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

На главную BFOmetr →