Object versioning in swift is implemented by setting a flag on the container
to tell swift to version all objects in the container. The value of the flag is
the URL-encoded container name where the versions are stored (commonly referred
to as the “archive container”). The flag itself is one of two headers, which
determines how object DELETE
requests are handled:
X-History-Location
On
DELETE
, copy the current version of the object to the archive container, write a zero-byte “delete marker” object that notes when the delete took place, and delete the object from the versioned container. The object will no longer appear in container listings for the versioned container and future requests there will return404 Not Found
. However, the content will still be recoverable from the archive container.
X-Versions-Location
On
DELETE
, only remove the current version of the object. If any previous versions exist in the archive container, the most recent one is copied over the current version, and the copy in the archive container is deleted. As a result, if you have 5 total versions of the object, you must delete the object 5 times for that object name to start responding with404 Not Found
.
Either header may be used for the various containers within an account, but
only one may be set for any given container. Attempting to set both
simulataneously will result in a 400 Bad Request
response.
Note
It is recommended to use a different archive container for each container that is being versioned.
Note
Enabling versioning on an archive container is not recommended.
When data is PUT
into a versioned container (a container with the
versioning flag turned on), the existing data in the file is redirected to a
new object in the archive container and the data in the PUT
request is
saved as the data for the versioned object. The new object name (for the
previous version) is <archive_container>/<length><object_name>/<timestamp>
,
where length
is the 3-character zero-padded hexadecimal length of the
<object_name>
and <timestamp>
is the timestamp of when the previous
version was created.
A GET
to a versioned object will return the current version of the object
without having to do any request redirects or metadata lookups.
A POST
to a versioned object will update the object metadata as normal,
but will not create a new version of the object. In other words, new versions
are only created when the content of the object changes.
A DELETE
to a versioned object will be handled in one of two ways,
as described above.
To restore a previous version of an object, find the desired version in the
archive container then issue a COPY
with a Destination
header
indicating the original location. This will archive the current version similar
to a PUT
over the versioned object. If the client additionally wishes to
permanently delete what was the current version, it must find the newly-created
archive in the archive container and issue a separate DELETE
to it.
This middleware was written as an effort to refactor parts of the proxy server,
so this functionality was already available in previous releases and every
attempt was made to maintain backwards compatibility. To allow operators to
perform a seamless upgrade, it is not required to add the middleware to the
proxy pipeline and the flag allow_versions
in the container server
configuration files are still valid, but only when using
X-Versions-Location
. In future releases, allow_versions
will be
deprecated in favor of adding this middleware to the pipeline to enable or
disable the feature.
In case the middleware is added to the proxy pipeline, you must also
set allow_versioned_writes
to True
in the middleware options
to enable the information about this middleware to be returned in a /info
request.
Note
You need to add the middleware to the proxy pipeline and set
allow_versioned_writes = True
to useX-History-Location
. Settingallow_versions = True
in the container server is not sufficient to enable the use ofX-History-Location
.
If allow_versioned_writes
is set in the filter configuration, you can leave
the allow_versions
flag in the container server configuration files
untouched. If you decide to disable or remove the allow_versions
flag, you
must re-set any existing containers that had the X-Versions-Location
flag
configured so that it can now be tracked by the versioned_writes middleware.
Clients should not use the X-History-Location
header until all proxies in
the cluster have been upgraded to a version of Swift that supports it.
Attempting to use X-History-Location
during a rolling upgrade may result
in some requests being served by proxies running old code, leading to data
loss.
curl
with X-Versions-Location
¶First, create a container with the X-Versions-Location
header or add the
header to an existing container. Also make sure the container referenced by
the X-Versions-Location
exists. In this example, the name of that
container is “versions”:
curl -i -XPUT -H "X-Auth-Token: <token>" -H "X-Versions-Location: versions" http://<storage_url>/container
curl -i -XPUT -H "X-Auth-Token: <token>" http://<storage_url>/versions
Create an object (the first version):
curl -i -XPUT --data-binary 1 -H "X-Auth-Token: <token>" http://<storage_url>/container/myobject
Now create a new version of that object:
curl -i -XPUT --data-binary 2 -H "X-Auth-Token: <token>" http://<storage_url>/container/myobject
See a listing of the older versions of the object:
curl -i -H "X-Auth-Token: <token>" http://<storage_url>/versions?prefix=008myobject/
Now delete the current version of the object and see that the older version is gone from ‘versions’ container and back in ‘container’ container:
curl -i -XDELETE -H "X-Auth-Token: <token>" http://<storage_url>/container/myobject
curl -i -H "X-Auth-Token: <token>" http://<storage_url>/versions?prefix=008myobject/
curl -i -XGET -H "X-Auth-Token: <token>" http://<storage_url>/container/myobject
curl
with X-History-Location
¶As above, create a container with the X-History-Location
header and ensure
that the container referenced by the X-History-Location
exists. In this
example, the name of that container is “versions”:
curl -i -XPUT -H "X-Auth-Token: <token>" -H "X-History-Location: versions" http://<storage_url>/container
curl -i -XPUT -H "X-Auth-Token: <token>" http://<storage_url>/versions
Create an object (the first version):
curl -i -XPUT --data-binary 1 -H "X-Auth-Token: <token>" http://<storage_url>/container/myobject
Now create a new version of that object:
curl -i -XPUT --data-binary 2 -H "X-Auth-Token: <token>" http://<storage_url>/container/myobject
Now delete the current version of the object. Subsequent requests will 404:
curl -i -XDELETE -H "X-Auth-Token: <token>" http://<storage_url>/container/myobject
curl -i -H "X-Auth-Token: <token>" http://<storage_url>/container/myobject
A listing of the older versions of the object will include both the first and second versions of the object, as well as a “delete marker” object:
curl -i -H "X-Auth-Token: <token>" http://<storage_url>/versions?prefix=008myobject/
To restore a previous version, simply COPY
it from the archive container:
curl -i -XCOPY -H "X-Auth-Token: <token>" http://<storage_url>/versions/008myobject/<timestamp> -H "Destination: container/myobject"
Note that the archive container still has all previous versions of the object, including the source for the restore:
curl -i -H "X-Auth-Token: <token>" http://<storage_url>/versions?prefix=008myobject/
To permanently delete a previous version, DELETE
it from the archive
container:
curl -i -XDELETE -H "X-Auth-Token: <token>" http://<storage_url>/versions/008myobject/<timestamp>
If you want to disable all functionality, set allow_versioned_writes
to
False
in the middleware options.
Disable versioning from a container (x is any value except empty):
curl -i -XPOST -H "X-Auth-Token: <token>" -H "X-Remove-Versions-Location: x" http://<storage_url>/container
Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.