save MinIO version with each version (8-bytes extra) (#15170)

store MinIO version along with each version in 'xl.meta'
for future purposes, can be used as ways to add specific
code for bug fixes if any.
This commit is contained in:
Harshavardhana 2022-06-27 03:59:41 -07:00 committed by GitHub
parent 7b9b7cef11
commit 6722f58668
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 92 additions and 25 deletions

View File

@ -102,6 +102,11 @@ func init() {
PersistOnFailure: false,
}
t, _ := minioVersionToReleaseTime(Version)
if !t.IsZero() {
globalVersionUnix = uint64(t.Unix())
}
globalIsCICD = env.Get("MINIO_CI_CD", "") != "" || env.Get("CI", "") != ""
containers := IsKubernetes() || IsDocker() || IsBOSH() || IsDCOS() || IsPCFTile()

View File

@ -326,6 +326,7 @@ func (er erasureObjects) newMultipartUpload(ctx context.Context, bucket string,
partsMetadata := make([]FileInfo, len(onlineDisks))
fi := newFileInfo(pathJoin(bucket, object), dataDrives, parityDrives)
fi.WrittenByVersion = globalVersionUnix
fi.VersionID = opts.VersionID
if opts.Versioned && fi.VersionID == "" {
fi.VersionID = mustGetUUID()

View File

@ -944,6 +944,7 @@ func (er erasureObjects) putObject(ctx context.Context, bucket string, object st
partsMetadata := make([]FileInfo, len(storageDisks))
fi := newFileInfo(pathJoin(bucket, object), dataDrives, parityDrives)
fi.WrittenByVersion = globalVersionUnix
fi.VersionID = opts.VersionID
if opts.Versioned && fi.VersionID == "" {
fi.VersionID = mustGetUUID()

View File

@ -941,6 +941,7 @@ func (es *erasureSingle) putObject(ctx context.Context, bucket string, object st
partsMetadata := make([]FileInfo, len(storageDisks))
fi := newFileInfo(pathJoin(bucket, object), dataDrives, parityDrives)
fi.WrittenByVersion = globalVersionUnix
fi.VersionID = opts.VersionID
if opts.Versioned && fi.VersionID == "" {
fi.VersionID = mustGetUUID()
@ -2070,6 +2071,7 @@ func (es *erasureSingle) newMultipartUpload(ctx context.Context, bucket string,
partsMetadata := make([]FileInfo, len(onlineDisks))
fi := newFileInfo(pathJoin(bucket, object), dataDrives, parityDrives)
fi.WrittenByVersion = globalVersionUnix
fi.VersionID = opts.VersionID
if opts.Versioned && fi.VersionID == "" {
fi.VersionID = mustGetUUID()

View File

@ -373,6 +373,9 @@ var (
globalObjectPerfBucket = "minio-perf-test-tmp-bucket"
globalObjectPerfUserMetadata = "X-Amz-Meta-Minio-Object-Perf" // Clients can set this to bypass S3 API service freeze. Used by object pref tests.
// MinIO version unix timestamp
globalVersionUnix uint64
// Add new variable global values here.
)

View File

@ -176,6 +176,10 @@ type FileInfo struct {
// File mode bits.
Mode uint32 `msg:"m"`
// WrittenByVersion is the unix time stamp of the MinIO
// version that created this version of the object.
WrittenByVersion uint64 `msg:"wv"`
// File metadata
Metadata map[string]string `msg:"meta"`

View File

@ -550,8 +550,8 @@ func (z *FileInfo) DecodeMsg(dc *msgp.Reader) (err error) {
err = msgp.WrapError(err)
return
}
if zb0001 != 26 {
err = msgp.ArrayError{Wanted: 26, Got: zb0001}
if zb0001 != 27 {
err = msgp.ArrayError{Wanted: 27, Got: zb0001}
return
}
z.Volume, err = dc.ReadString()
@ -629,6 +629,11 @@ func (z *FileInfo) DecodeMsg(dc *msgp.Reader) (err error) {
err = msgp.WrapError(err, "Mode")
return
}
z.WrittenByVersion, err = dc.ReadUint64()
if err != nil {
err = msgp.WrapError(err, "WrittenByVersion")
return
}
var zb0002 uint32
zb0002, err = dc.ReadMapHeader()
if err != nil {
@ -726,8 +731,8 @@ func (z *FileInfo) DecodeMsg(dc *msgp.Reader) (err error) {
// EncodeMsg implements msgp.Encodable
func (z *FileInfo) EncodeMsg(en *msgp.Writer) (err error) {
// array header, size 26
err = en.Append(0xdc, 0x0, 0x1a)
// array header, size 27
err = en.Append(0xdc, 0x0, 0x1b)
if err != nil {
return
}
@ -806,6 +811,11 @@ func (z *FileInfo) EncodeMsg(en *msgp.Writer) (err error) {
err = msgp.WrapError(err, "Mode")
return
}
err = en.WriteUint64(z.WrittenByVersion)
if err != nil {
err = msgp.WrapError(err, "WrittenByVersion")
return
}
err = en.WriteMapHeader(uint32(len(z.Metadata)))
if err != nil {
err = msgp.WrapError(err, "Metadata")
@ -886,8 +896,8 @@ func (z *FileInfo) EncodeMsg(en *msgp.Writer) (err error) {
// MarshalMsg implements msgp.Marshaler
func (z *FileInfo) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
// array header, size 26
o = append(o, 0xdc, 0x0, 0x1a)
// array header, size 27
o = append(o, 0xdc, 0x0, 0x1b)
o = msgp.AppendString(o, z.Volume)
o = msgp.AppendString(o, z.Name)
o = msgp.AppendString(o, z.VersionID)
@ -903,6 +913,7 @@ func (z *FileInfo) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.AppendTime(o, z.ModTime)
o = msgp.AppendInt64(o, z.Size)
o = msgp.AppendUint32(o, z.Mode)
o = msgp.AppendUint64(o, z.WrittenByVersion)
o = msgp.AppendMapHeader(o, uint32(len(z.Metadata)))
for za0001, za0002 := range z.Metadata {
o = msgp.AppendString(o, za0001)
@ -944,8 +955,8 @@ func (z *FileInfo) UnmarshalMsg(bts []byte) (o []byte, err error) {
err = msgp.WrapError(err)
return
}
if zb0001 != 26 {
err = msgp.ArrayError{Wanted: 26, Got: zb0001}
if zb0001 != 27 {
err = msgp.ArrayError{Wanted: 27, Got: zb0001}
return
}
z.Volume, bts, err = msgp.ReadStringBytes(bts)
@ -1023,6 +1034,11 @@ func (z *FileInfo) UnmarshalMsg(bts []byte) (o []byte, err error) {
err = msgp.WrapError(err, "Mode")
return
}
z.WrittenByVersion, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "WrittenByVersion")
return
}
var zb0002 uint32
zb0002, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
@ -1121,7 +1137,7 @@ func (z *FileInfo) UnmarshalMsg(bts []byte) (o []byte, err error) {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *FileInfo) Msgsize() (s int) {
s = 3 + msgp.StringPrefixSize + len(z.Volume) + msgp.StringPrefixSize + len(z.Name) + msgp.StringPrefixSize + len(z.VersionID) + msgp.BoolSize + msgp.BoolSize + msgp.StringPrefixSize + len(z.TransitionStatus) + msgp.StringPrefixSize + len(z.TransitionedObjName) + msgp.StringPrefixSize + len(z.TransitionTier) + msgp.StringPrefixSize + len(z.TransitionVersionID) + msgp.BoolSize + msgp.StringPrefixSize + len(z.DataDir) + msgp.BoolSize + msgp.TimeSize + msgp.Int64Size + msgp.Uint32Size + msgp.MapHeaderSize
s = 3 + msgp.StringPrefixSize + len(z.Volume) + msgp.StringPrefixSize + len(z.Name) + msgp.StringPrefixSize + len(z.VersionID) + msgp.BoolSize + msgp.BoolSize + msgp.StringPrefixSize + len(z.TransitionStatus) + msgp.StringPrefixSize + len(z.TransitionedObjName) + msgp.StringPrefixSize + len(z.TransitionTier) + msgp.StringPrefixSize + len(z.TransitionVersionID) + msgp.BoolSize + msgp.StringPrefixSize + len(z.DataDir) + msgp.BoolSize + msgp.TimeSize + msgp.Int64Size + msgp.Uint32Size + msgp.Uint64Size + msgp.MapHeaderSize
if z.Metadata != nil {
for za0001, za0002 := range z.Metadata {
_ = za0002

View File

@ -1,4 +1,4 @@
// Copyright (c) 2015-2021 MinIO, Inc.
// Copyright (c) 2015-2022 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
@ -18,7 +18,7 @@
package cmd
const (
storageRESTVersion = "v45" // Added ReadXL API
storageRESTVersion = "v46" // Added MinIO version to FileInfo
storageRESTVersionPrefix = SlashSeparator + storageRESTVersion
storageRESTPrefix = minioReservedBucketPath + "/storage"
)

View File

@ -178,10 +178,11 @@ type xlMetaV2Object struct {
// on what Type field carries, it is imperative for the caller
// to verify which journal type first before accessing rest of the fields.
type xlMetaV2Version struct {
Type VersionType `json:"Type" msg:"Type"`
ObjectV1 *xlMetaV1Object `json:"V1Obj,omitempty" msg:"V1Obj,omitempty"`
ObjectV2 *xlMetaV2Object `json:"V2Obj,omitempty" msg:"V2Obj,omitempty"`
DeleteMarker *xlMetaV2DeleteMarker `json:"DelObj,omitempty" msg:"DelObj,omitempty"`
Type VersionType `json:"Type" msg:"Type"`
ObjectV1 *xlMetaV1Object `json:"V1Obj,omitempty" msg:"V1Obj,omitempty"`
ObjectV2 *xlMetaV2Object `json:"V2Obj,omitempty" msg:"V2Obj,omitempty"`
DeleteMarker *xlMetaV2DeleteMarker `json:"DelObj,omitempty" msg:"DelObj,omitempty"`
WrittenByVersion uint64 `msg:"v"` // Tracks written by MinIO version
}
// xlFlags contains flags on the object.
@ -409,16 +410,22 @@ func (j xlMetaV2Version) getVersionID() [16]byte {
}
// ToFileInfo returns FileInfo of the underlying type.
func (j *xlMetaV2Version) ToFileInfo(volume, path string) (FileInfo, error) {
func (j *xlMetaV2Version) ToFileInfo(volume, path string) (fi FileInfo, err error) {
if j == nil {
return fi, errFileNotFound
}
switch j.Type {
case ObjectType:
return j.ObjectV2.ToFileInfo(volume, path)
fi, err = j.ObjectV2.ToFileInfo(volume, path)
case DeleteType:
return j.DeleteMarker.ToFileInfo(volume, path)
fi, err = j.DeleteMarker.ToFileInfo(volume, path)
case LegacyType:
return j.ObjectV1.ToFileInfo(volume, path)
fi, err = j.ObjectV1.ToFileInfo(volume, path)
default:
return fi, errFileNotFound
}
return FileInfo{}, errFileNotFound
fi.WrittenByVersion = j.WrittenByVersion
return fi, err
}
const (
@ -1424,7 +1431,9 @@ func (x *xlMetaV2) AddVersion(fi FileInfo) error {
}
}
ventry := xlMetaV2Version{}
ventry := xlMetaV2Version{
WrittenByVersion: fi.WrittenByVersion,
}
if fi.Deleted {
ventry.Type = DeleteType

View File

@ -1774,6 +1774,12 @@ func (z *xlMetaV2Version) DecodeMsg(dc *msgp.Reader) (err error) {
return
}
}
case "v":
z.WrittenByVersion, err = dc.ReadUint64()
if err != nil {
err = msgp.WrapError(err, "WrittenByVersion")
return
}
default:
err = dc.Skip()
if err != nil {
@ -1788,8 +1794,8 @@ func (z *xlMetaV2Version) DecodeMsg(dc *msgp.Reader) (err error) {
// EncodeMsg implements msgp.Encodable
func (z *xlMetaV2Version) EncodeMsg(en *msgp.Writer) (err error) {
// omitempty: check for empty values
zb0001Len := uint32(4)
var zb0001Mask uint8 /* 4 bits */
zb0001Len := uint32(5)
var zb0001Mask uint8 /* 5 bits */
if z.ObjectV1 == nil {
zb0001Len--
zb0001Mask |= 0x2
@ -1877,6 +1883,16 @@ func (z *xlMetaV2Version) EncodeMsg(en *msgp.Writer) (err error) {
}
}
}
// write "v"
err = en.Append(0xa1, 0x76)
if err != nil {
return
}
err = en.WriteUint64(z.WrittenByVersion)
if err != nil {
err = msgp.WrapError(err, "WrittenByVersion")
return
}
return
}
@ -1884,8 +1900,8 @@ func (z *xlMetaV2Version) EncodeMsg(en *msgp.Writer) (err error) {
func (z *xlMetaV2Version) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
zb0001Len := uint32(4)
var zb0001Mask uint8 /* 4 bits */
zb0001Len := uint32(5)
var zb0001Mask uint8 /* 5 bits */
if z.ObjectV1 == nil {
zb0001Len--
zb0001Mask |= 0x2
@ -1945,6 +1961,9 @@ func (z *xlMetaV2Version) MarshalMsg(b []byte) (o []byte, err error) {
}
}
}
// string "v"
o = append(o, 0xa1, 0x76)
o = msgp.AppendUint64(o, z.WrittenByVersion)
return
}
@ -2027,6 +2046,12 @@ func (z *xlMetaV2Version) UnmarshalMsg(bts []byte) (o []byte, err error) {
return
}
}
case "v":
z.WrittenByVersion, bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
err = msgp.WrapError(err, "WrittenByVersion")
return
}
default:
bts, err = msgp.Skip(bts)
if err != nil {
@ -2059,6 +2084,7 @@ func (z *xlMetaV2Version) Msgsize() (s int) {
} else {
s += z.DeleteMarker.Msgsize()
}
s += 2 + msgp.Uint64Size
return
}