RAID reshaping is changing attributes of a RAID LV while keeping
the same RAID level. This includes changing RAID layout, stripe
size, or number of stripes.
When changing the RAID layout or stripe size, no new SubLVs
(MetaLVs or DataLVs) need to be allocated, but DataLVs are
extended by a small amount (typically 1 extent). The extra space
allows blocks in a stripe to be updated safely, and not be
corrupted in case of a crash. If a crash occurs, reshaping can
just be restarted.
(If blocks in a stripe were updated in place, a crash could leave
them partially updated and corrupted. Instead, an existing
stripe is quiesced, read, changed in layout, and the new stripe
written to free space. Once that is done, the new stripe is
unquiesced and used.)
Examples
(Command output shown in examples may change.)
Converting raid6_n_6 to raid6_nr with rotating data/parity.
This conversion naturally follows a previous conversion from
striped/raid0 to raid6_n_6 (shown above). It completes the
transition to a more traditional RAID6.
# lvs -o lv_name,segtype,sync_percent,data_copies
LV Type Cpy%Sync #Cpy
lv raid6_n_6 100.00 3
[lv_rimage_0] linear
[lv_rimage_1] linear
[lv_rimage_2] linear
[lv_rimage_3] linear
[lv_rimage_4] linear
[lv_rimage_5] linear
[lv_rmeta_0] linear
[lv_rmeta_1] linear
[lv_rmeta_2] linear
[lv_rmeta_3] linear
[lv_rmeta_4] linear
[lv_rmeta_5] linear
# lvconvert --type raid6_nr vg/lv
# lvs -a -o lv_name,segtype,sync_percent,data_copies
LV Type Cpy%Sync #Cpy
lv raid6_nr 100.00 3
[lv_rimage_0] linear
[lv_rimage_0] linear
[lv_rimage_1] linear
[lv_rimage_1] linear
[lv_rimage_2] linear
[lv_rimage_2] linear
[lv_rimage_3] linear
[lv_rimage_3] linear
[lv_rimage_4] linear
[lv_rimage_5] linear
[lv_rmeta_0] linear
[lv_rmeta_1] linear
[lv_rmeta_2] linear
[lv_rmeta_3] linear
[lv_rmeta_4] linear
[lv_rmeta_5] linear
The DataLVs are larger (additional segment in each) which
provides space for out-of-place reshaping. The result is:
# lvs -a -o lv_name,segtype,seg_pe_ranges,dataoffset
LV Type PE Ranges DOff
lv raid6_nr lv_rimage_0:0-32 \
lv_rimage_1:0-32 \
lv_rimage_2:0-32 \
lv_rimage_3:0-32
[lv_rimage_0] linear /dev/sda:0-31 2048
[lv_rimage_0] linear /dev/sda:33-33
[lv_rimage_1] linear /dev/sdaa:0-31 2048
[lv_rimage_1] linear /dev/sdaa:33-33
[lv_rimage_2] linear /dev/sdab:1-33 2048
[lv_rimage_3] linear /dev/sdac:1-33 2048
[lv_rmeta_0] linear /dev/sda:32-32
[lv_rmeta_1] linear /dev/sdaa:32-32
[lv_rmeta_2] linear /dev/sdab:0-0
[lv_rmeta_3] linear /dev/sdac:0-0
All segments with PE ranges '33-33' provide the out-of-place
reshape space. The dataoffset column shows that the data was
moved from initial offset 0 to 2048 sectors on each component
DataLV.
For performance reasons the raid6_nr RaidLV can be restriped.
Convert it from 3-way striped to 5-way-striped.
# lvconvert --stripes 5 vg/lv
Using default stripesize 64.00 KiB.
WARNING: Adding stripes to active logical volume vg/lv will \
grow it from 99 to 165 extents!
Run "lvresize -l99 vg/lv" to shrink it or use the additional \
capacity.
Logical volume vg/lv successfully converted.
# lvs vg/lv
LV VG Attr LSize Cpy%Sync
lv vg rwi-a-r-s- 652.00m 52.94
# lvs -a -o lv_name,attr,segtype,seg_pe_ranges,dataoffset vg
LV Attr Type PE Ranges DOff
lv rwi-a-r--- raid6_nr lv_rimage_0:0-33 \
lv_rimage_1:0-33 \
lv_rimage_2:0-33 ... \
lv_rimage_5:0-33 \
lv_rimage_6:0-33 0
[lv_rimage_0] iwi-aor--- linear /dev/sda:0-32 0
[lv_rimage_0] iwi-aor--- linear /dev/sda:34-34
[lv_rimage_1] iwi-aor--- linear /dev/sdaa:0-32 0
[lv_rimage_1] iwi-aor--- linear /dev/sdaa:34-34
[lv_rimage_2] iwi-aor--- linear /dev/sdab:0-32 0
[lv_rimage_2] iwi-aor--- linear /dev/sdab:34-34
[lv_rimage_3] iwi-aor--- linear /dev/sdac:1-34 0
[lv_rimage_4] iwi-aor--- linear /dev/sdad:1-34 0
[lv_rimage_5] iwi-aor--- linear /dev/sdae:1-34 0
[lv_rimage_6] iwi-aor--- linear /dev/sdaf:1-34 0
[lv_rmeta_0] ewi-aor--- linear /dev/sda:33-33
[lv_rmeta_1] ewi-aor--- linear /dev/sdaa:33-33
[lv_rmeta_2] ewi-aor--- linear /dev/sdab:33-33
[lv_rmeta_3] ewi-aor--- linear /dev/sdac:0-0
[lv_rmeta_4] ewi-aor--- linear /dev/sdad:0-0
[lv_rmeta_5] ewi-aor--- linear /dev/sdae:0-0
[lv_rmeta_6] ewi-aor--- linear /dev/sdaf:0-0
Stripes also can be removed from raid5 and 6. Convert the 5-way
striped raid6_nr LV to 4-way-striped. The force option needs to
be used, because removing stripes (i.e. image SubLVs) from a
RaidLV will shrink its size.
# lvconvert --stripes 4 vg/lv
Using default stripesize 64.00 KiB.
WARNING: Removing stripes from active logical volume vg/lv will \
shrink it from 660.00 MiB to 528.00 MiB!
THIS MAY DESTROY (PARTS OF) YOUR DATA!
If that leaves the logical volume larger than 206 extents due \
to stripe rounding,
you may want to grow the content afterwards (filesystem etc.)
WARNING: to remove freed stripes after the conversion has finished,\
you have to run "lvconvert --stripes 4 vg/lv"
Logical volume vg/lv successfully converted.
# lvs -a -o lv_name,attr,segtype,seg_pe_ranges,dataoffset vg
LV Attr Type PE Ranges DOff
lv rwi-a-r-s- raid6_nr lv_rimage_0:0-33 \
lv_rimage_1:0-33 \
lv_rimage_2:0-33 ... \
lv_rimage_5:0-33 \
lv_rimage_6:0-33 0
[lv_rimage_0] Iwi-aor--- linear /dev/sda:0-32 0
[lv_rimage_0] Iwi-aor--- linear /dev/sda:34-34
[lv_rimage_1] Iwi-aor--- linear /dev/sdaa:0-32 0
[lv_rimage_1] Iwi-aor--- linear /dev/sdaa:34-34
[lv_rimage_2] Iwi-aor--- linear /dev/sdab:0-32 0
[lv_rimage_2] Iwi-aor--- linear /dev/sdab:34-34
[lv_rimage_3] Iwi-aor--- linear /dev/sdac:1-34 0
[lv_rimage_4] Iwi-aor--- linear /dev/sdad:1-34 0
[lv_rimage_5] Iwi-aor--- linear /dev/sdae:1-34 0
[lv_rimage_6] Iwi-aor-R- linear /dev/sdaf:1-34 0
[lv_rmeta_0] ewi-aor--- linear /dev/sda:33-33
[lv_rmeta_1] ewi-aor--- linear /dev/sdaa:33-33
[lv_rmeta_2] ewi-aor--- linear /dev/sdab:33-33
[lv_rmeta_3] ewi-aor--- linear /dev/sdac:0-0
[lv_rmeta_4] ewi-aor--- linear /dev/sdad:0-0
[lv_rmeta_5] ewi-aor--- linear /dev/sdae:0-0
[lv_rmeta_6] ewi-aor-R- linear /dev/sdaf:0-0
The 's' in column 9 of the attribute field shows the RaidLV is
still reshaping. The 'R' in the same column of the attribute
field shows the freed image Sub LVs which will need removing once
the reshaping finished.
# lvs -o lv_name,attr,segtype,seg_pe_ranges,dataoffset vg
LV Attr Type PE Ranges DOff
lv rwi-a-r-R- raid6_nr lv_rimage_0:0-33 \
lv_rimage_1:0-33 \
lv_rimage_2:0-33 ... \
lv_rimage_5:0-33 \
lv_rimage_6:0-33 8192
Now that the reshape is finished the 'R' attribute on the RaidLV
shows images can be removed.
# lvs -o lv_name,attr,segtype,seg_pe_ranges,dataoffset vg
LV Attr Type PE Ranges DOff
lv rwi-a-r-R- raid6_nr lv_rimage_0:0-33 \
lv_rimage_1:0-33 \
lv_rimage_2:0-33 ... \
lv_rimage_5:0-33 \
lv_rimage_6:0-33 8192
This is achieved by repeating the command ("lvconvert --stripes 4
vg/lv" would be sufficient).
# lvconvert --stripes 4 vg/lv
Using default stripesize 64.00 KiB.
Logical volume vg/lv successfully converted.
# lvs -a -o lv_name,attr,segtype,seg_pe_ranges,dataoffset vg
LV Attr Type PE Ranges DOff
lv rwi-a-r--- raid6_nr lv_rimage_0:0-33 \
lv_rimage_1:0-33 \
lv_rimage_2:0-33 ... \
lv_rimage_5:0-33 8192
[lv_rimage_0] iwi-aor--- linear /dev/sda:0-32 8192
[lv_rimage_0] iwi-aor--- linear /dev/sda:34-34
[lv_rimage_1] iwi-aor--- linear /dev/sdaa:0-32 8192
[lv_rimage_1] iwi-aor--- linear /dev/sdaa:34-34
[lv_rimage_2] iwi-aor--- linear /dev/sdab:0-32 8192
[lv_rimage_2] iwi-aor--- linear /dev/sdab:34-34
[lv_rimage_3] iwi-aor--- linear /dev/sdac:1-34 8192
[lv_rimage_4] iwi-aor--- linear /dev/sdad:1-34 8192
[lv_rimage_5] iwi-aor--- linear /dev/sdae:1-34 8192
[lv_rmeta_0] ewi-aor--- linear /dev/sda:33-33
[lv_rmeta_1] ewi-aor--- linear /dev/sdaa:33-33
[lv_rmeta_2] ewi-aor--- linear /dev/sdab:33-33
[lv_rmeta_3] ewi-aor--- linear /dev/sdac:0-0
[lv_rmeta_4] ewi-aor--- linear /dev/sdad:0-0
[lv_rmeta_5] ewi-aor--- linear /dev/sdae:0-0
# lvs -a -o lv_name,attr,segtype,reshapelen vg
LV Attr Type RSize
lv rwi-a-r--- raid6_nr 24.00m
[lv_rimage_0] iwi-aor--- linear 4.00m
[lv_rimage_0] iwi-aor--- linear
[lv_rimage_1] iwi-aor--- linear 4.00m
[lv_rimage_1] iwi-aor--- linear
[lv_rimage_2] iwi-aor--- linear 4.00m
[lv_rimage_2] iwi-aor--- linear
[lv_rimage_3] iwi-aor--- linear 4.00m
[lv_rimage_4] iwi-aor--- linear 4.00m
[lv_rimage_5] iwi-aor--- linear 4.00m
[lv_rmeta_0] ewi-aor--- linear
[lv_rmeta_1] ewi-aor--- linear
[lv_rmeta_2] ewi-aor--- linear
[lv_rmeta_3] ewi-aor--- linear
[lv_rmeta_4] ewi-aor--- linear
[lv_rmeta_5] ewi-aor--- linear
Future developments might include automatic removal of the freed
images.
If the reshape space shall be removed any lvconvert command not
changing the layout can be used:
# lvconvert --stripes 4 vg/lv
Using default stripesize 64.00 KiB.
No change in RAID LV vg/lv layout, freeing reshape space.
Logical volume vg/lv successfully converted.
# lvs -a -o lv_name,attr,segtype,reshapelen vg
LV Attr Type RSize
lv rwi-a-r--- raid6_nr 0
[lv_rimage_0] iwi-aor--- linear 0
[lv_rimage_0] iwi-aor--- linear
[lv_rimage_1] iwi-aor--- linear 0
[lv_rimage_1] iwi-aor--- linear
[lv_rimage_2] iwi-aor--- linear 0
[lv_rimage_2] iwi-aor--- linear
[lv_rimage_3] iwi-aor--- linear 0
[lv_rimage_4] iwi-aor--- linear 0
[lv_rimage_5] iwi-aor--- linear 0
[lv_rmeta_0] ewi-aor--- linear
[lv_rmeta_1] ewi-aor--- linear
[lv_rmeta_2] ewi-aor--- linear
[lv_rmeta_3] ewi-aor--- linear
[lv_rmeta_4] ewi-aor--- linear
[lv_rmeta_5] ewi-aor--- linear
In case the RaidLV should be converted to striped:
# lvconvert --type striped vg/lv
Unable to convert LV vg/lv from raid6_nr to striped.
Converting vg/lv from raid6_nr is directly possible to the \
following layouts:
raid6_nc
raid6_zr
raid6_la_6
raid6_ls_6
raid6_ra_6
raid6_rs_6
raid6_n_6
A direct conversion isn't possible thus the command informed
about the possible ones. raid6_n_6 is suitable to convert to
striped so convert to it first (this is a reshape changing the
raid6 layout from raid6_nr to raid6_n_6).
# lvconvert --type raid6_n_6
Using default stripesize 64.00 KiB.
Converting raid6_nr LV vg/lv to raid6_n_6.
Are you sure you want to convert raid6_nr LV vg/lv? [y/n]: y
Logical volume vg/lv successfully converted.
Wait for the reshape to finish.
# lvconvert --type striped vg/lv
Logical volume vg/lv successfully converted.
# lvs -o lv_name,attr,segtype,seg_pe_ranges,dataoffset vg
LV Attr Type PE Ranges DOff
lv -wi-a----- striped /dev/sda:2-32 \
/dev/sdaa:2-32 \
/dev/sdab:2-32 \
/dev/sdac:3-33
lv -wi-a----- striped /dev/sda:34-35 \
/dev/sdaa:34-35 \
/dev/sdab:34-35 \
/dev/sdac:34-35
From striped we can convert to raid10
# lvconvert --type raid10 vg/lv
Using default stripesize 64.00 KiB.
Logical volume vg/lv successfully converted.
# lvs -o lv_name,attr,segtype,seg_pe_ranges,dataoffset vg
LV Attr Type PE Ranges DOff
lv rwi-a-r--- raid10 lv_rimage_0:0-32 \
lv_rimage_4:0-32 \
lv_rimage_1:0-32 ... \
lv_rimage_3:0-32 \
lv_rimage_7:0-32 0
# lvs -a -o lv_name,attr,segtype,seg_pe_ranges,dataoffset vg
WARNING: Cannot find matching striped segment for vg/lv_rimage_3.
LV Attr Type PE Ranges DOff
lv rwi-a-r--- raid10 lv_rimage_0:0-32 \
lv_rimage_4:0-32 \
lv_rimage_1:0-32 ... \
lv_rimage_3:0-32 \
lv_rimage_7:0-32 0
[lv_rimage_0] iwi-aor--- linear /dev/sda:2-32 0
[lv_rimage_0] iwi-aor--- linear /dev/sda:34-35
[lv_rimage_1] iwi-aor--- linear /dev/sdaa:2-32 0
[lv_rimage_1] iwi-aor--- linear /dev/sdaa:34-35
[lv_rimage_2] iwi-aor--- linear /dev/sdab:2-32 0
[lv_rimage_2] iwi-aor--- linear /dev/sdab:34-35
[lv_rimage_3] iwi-XXr--- linear /dev/sdac:3-35 0
[lv_rimage_4] iwi-aor--- linear /dev/sdad:1-33 0
[lv_rimage_5] iwi-aor--- linear /dev/sdae:1-33 0
[lv_rimage_6] iwi-aor--- linear /dev/sdaf:1-33 0
[lv_rimage_7] iwi-aor--- linear /dev/sdag:1-33 0
[lv_rmeta_0] ewi-aor--- linear /dev/sda:0-0
[lv_rmeta_1] ewi-aor--- linear /dev/sdaa:0-0
[lv_rmeta_2] ewi-aor--- linear /dev/sdab:0-0
[lv_rmeta_3] ewi-aor--- linear /dev/sdac:0-0
[lv_rmeta_4] ewi-aor--- linear /dev/sdad:0-0
[lv_rmeta_5] ewi-aor--- linear /dev/sdae:0-0
[lv_rmeta_6] ewi-aor--- linear /dev/sdaf:0-0
[lv_rmeta_7] ewi-aor--- linear /dev/sdag:0-0
raid10 allows to add stripes but can't remove them.
A more elaborate example to convert from linear to striped with
interim conversions to raid1 then raid5 followed by restripe (4
steps).
We start with the linear LV.
# lvs -a -o name,size,segtype,syncpercent,datastripes,\
stripesize,reshapelenle,devices vg
LV LSize Type Cpy%Sync #DStr Stripe RSize Devices
lv 128.00m linear 1 0 /dev/sda(0)
Then convert it to a 2-way raid1.
# lvconvert --mirrors 1 vg/lv
Logical volume vg/lv successfully converted.
# lvs -a -o name,size,segtype,datastripes,\
stripesize,reshapelenle,devices vg
LV LSize Type #DStr Stripe RSize Devices
lv 128.00m raid1 2 0 lv_rimage_0(0),\
lv_rimage_1(0)
[lv_rimage_0] 128.00m linear 1 0 /dev/sda(0)
[lv_rimage_1] 128.00m linear 1 0 /dev/sdhx(1)
[lv_rmeta_0] 4.00m linear 1 0 /dev/sda(32)
[lv_rmeta_1] 4.00m linear 1 0 /dev/sdhx(0)
Once the raid1 LV is fully synchronized we convert it to raid5_n
(only 2-way raid1 LVs can be converted to raid5). We select
raid5_n here because it has dedicated parity SubLVs at the end
and can be converted to striped directly without any additional
conversion.
# lvconvert --type raid5_n vg/lv
Using default stripesize 64.00 KiB.
Logical volume vg/lv successfully converted.
# lvs -a -o name,size,segtype,syncpercent,datastripes,\
stripesize,reshapelenle,devices vg
LV LSize Type #DStr Stripe RSize Devices
lv 128.00m raid5_n 1 64.00k 0 lv_rimage_0(0),\
lv_rimage_1(0)
[lv_rimage_0] 128.00m linear 1 0 0 /dev/sda(0)
[lv_rimage_1] 128.00m linear 1 0 0 /dev/sdhx(1)
[lv_rmeta_0] 4.00m linear 1 0 /dev/sda(32)
[lv_rmeta_1] 4.00m linear 1 0 /dev/sdhx(0)
Now we'll change the number of data stripes from 1 to 5 and
request 128K stripe size in one command. This will grow the size
of the LV by a factor of 5 (we add 4 data stripes to the one
given). That additional space can be used by e.g. growing any
contained filesystem or the LV can be reduced in size after the
reshaping conversion has finished.
# lvconvert --stripesize 128k --stripes 5 vg/lv
Converting stripesize 64.00 KiB of raid5_n LV vg/lv to 128.00 KiB.
WARNING: Adding stripes to active logical volume vg/lv will grow \
it from 32 to 160 extents!
Run "lvresize -l32 vg/lv" to shrink it or use the additional capacity.
Logical volume vg/lv successfully converted.
# lvs -a -o name,size,segtype,datastripes,\
stripesize,reshapelenle,devices
LV LSize Type #DStr Stripe RSize Devices
lv 640.00m raid5_n 5 128.00k 6 lv_rimage_0(0),\
lv_rimage_1(0),\
lv_rimage_2(0),\
lv_rimage_3(0),\
lv_rimage_4(0),\
lv_rimage_5(0)
[lv_rimage_0] 132.00m linear 1 0 1 /dev/sda(33)
[lv_rimage_0] 132.00m linear 1 0 /dev/sda(0)
[lv_rimage_1] 132.00m linear 1 0 1 /dev/sdhx(33)
[lv_rimage_1] 132.00m linear 1 0 /dev/sdhx(1)
[lv_rimage_2] 132.00m linear 1 0 1 /dev/sdhw(33)
[lv_rimage_2] 132.00m linear 1 0 /dev/sdhw(1)
[lv_rimage_3] 132.00m linear 1 0 1 /dev/sdhv(33)
[lv_rimage_3] 132.00m linear 1 0 /dev/sdhv(1)
[lv_rimage_4] 132.00m linear 1 0 1 /dev/sdhu(33)
[lv_rimage_4] 132.00m linear 1 0 /dev/sdhu(1)
[lv_rimage_5] 132.00m linear 1 0 1 /dev/sdht(33)
[lv_rimage_5] 132.00m linear 1 0 /dev/sdht(1)
[lv_rmeta_0] 4.00m linear 1 0 /dev/sda(32)
[lv_rmeta_1] 4.00m linear 1 0 /dev/sdhx(0)
[lv_rmeta_2] 4.00m linear 1 0 /dev/sdhw(0)
[lv_rmeta_3] 4.00m linear 1 0 /dev/sdhv(0)
[lv_rmeta_4] 4.00m linear 1 0 /dev/sdhu(0)
[lv_rmeta_5] 4.00m linear 1 0 /dev/sdht(0)
Once the conversion has finished we can can convert to striped.
# lvconvert --type striped vg/lv
Logical volume vg/lv successfully converted.
# lvs -a -o name,size,segtype,datastripes,\
stripesize,reshapelenle,devices vg
LV LSize Type #DStr Stripe RSize Devices
lv 640.00m striped 5 128.00k /dev/sda(33),\
/dev/sdhx(33),\
/dev/sdhw(33),\
/dev/sdhv(33),\
/dev/sdhu(33)
lv 640.00m striped 5 128.00k /dev/sda(0),\
/dev/sdhx(1),\
/dev/sdhw(1),\
/dev/sdhv(1),\
/dev/sdhu(1)
Reversing these steps will convert a given striped LV to linear.
Mind the facts that stripes are removed thus the capacity of the
RaidLV will shrink and that changing the RaidLV layout will
influence its performance.
"lvconvert --stripes 1 vg/lv" for converting to 1 stripe will
inform upfront about the reduced size to allow for resizing the
content or growing the RaidLV before actually converting to 1
stripe. The --force
option is needed to allow stripe removing
conversions to prevent data loss.
Of course any interim step can be the intended last one (e.g.
striped → raid1).