多版本用于防止对象意外删除或者覆盖。当一个bucket开启多版本后:
- 删除对象并不会真正的删除对象,而是创建一个带有Delete Marker标志的新版本的对象
- 上传对象并不是覆盖原有的对象,而是添加一个新版本的对象
Bucket versioning的设置
bucket默认不开启versioning配置。如果需要开启,需要显示的的开启多版本。
<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Status>Enabled</Status>
</VersioningConfiguration>
一个bucket一旦开启了多版本,就不能停止或者Disable的状态,只能处于两种状态
- Enabled:开启
- Suspended:开启后挂起
对象的版本 Version ID
开启多版本后,每个对象都有一个版本号:
- 在没有开启versioning时,对象的默认版本号是“null”
- 当开启多版本后,系统为上传的对象自动产生一个唯一的版本号
current object:在多版本对象中, 最新的对象被称为current对象。在get或者list(不带版本的)操作中,如果current object是带Delete Marker的对象,则该对象不可见,get操作返回不存在,list操作不会列出该对象。否则该对象对外都可见。
Bucket Versioning的操作行为
Enable状态
Put Object
当开启多版本后,每个对象上传操作,都会自动产生一个带新版本号的对象。
Delete Object
如果当前对象是一个带版本号的对象,则添加一个新的版本号的Delete Marker对象;如果当前对象为Delete Marker Object,会返回该对象不存在的错误。
Delete Object with VersionID
如果是删除指定已存在的版本的Object,则该版本的Object会实际删除;如果删除的版本是Delete Marker标记的对象,则该Delete Marker对象被删除,其效果等同于没有Delete Marker Object的效果:最新版本的对象都可见。
Suspended状态
Put Object
会上传一个版本为“null”的新对象;如果已经存在版本“null”的对象,则会产生覆盖操作。
Delete Object
删除操作只会对版本为“null”的对象起作用:1)如果有版本为“null”的对象,则删除该对象,包括数据都会删除。2)无论之前有没有null对象,都会添加一个一个Delete Marker 对象,版本号为“null”
Delete Object with VersionID
如果是删除指定已存在的版本的Object,则该object会实际删除。如果删除指定版本为“null”的Delete Marker Object,则最近版本的对象可见。
实例
下面的示例以流行的对Minio对象存储系统来演示。
.创建一个bucket:testversion,没有开启多版本,上传一个文件,默认的版本为“null”
2.开启多版本
如图1所示,再次上传对象 test1.sh,会产生一个版本号为“7ee1f226-87ee-4478-a234-a5ee437c674a”的对象。
图1:put Object
如图2所示,删除对象 test1.sh,会产生一个版本号为“75234567-fdf5-4011-ab9d-52b45d7f077e”的对象,并且添加了Delete Marker标志。
图2:多版本下,删除对象
这时刻,如果ls 操作不加 --versions操作,就看不到对象。ls操作只列出current object,当前的current object为Delete Marker标记的对象,就返回不存在。
图3:多个Delete Marker的情况
我们可以看到图3的情况:在版本v4上传了新版本的test1.sh对象,在版本v5上删除。然后上传了版本v6和v7两个新的版本。
3.Suspended状态
图4:suspend,put object
图4为在suspended状态下,put object的情况:如果有null版本的对象,会覆盖null版本的对象。
图5: suspend,delete object
如图5所示:在suspend状态下,删除对象,原本的null对象会删除,数据也会删除。重新添加一个版本为“null”的添加Delete Marker标志的对象,并且该对象的size为0
Versioning总结
Put操作,Enable状态会增加一个新版本的对象。Suspended状态会增加一个“null”版本的对象,如果已经存储一个“null”版本的对象(包括null 版本的Delete Marker对象),会发生覆盖操作。
删除操作如果不加版本号,对于Enable 和Suspended两种状态,删除都是加 Delete Marker标志,不同的是,在Enable状态会申请一个最新的版本号。处于Suspended状态,只会对“null” 对象其作用。Delete Marker标志加在“null”对象上。
对于List操作,如果加了参数–version,会列出所以的版本的对象。如果不加–version参数,只会列出current 版本的对象,如果current版本的对象为Delete Marker,则会返回对象不存在,否则返回最新版本的对象。