Eu finalmente encontrei um truque .
A configuração : digamos que nossa unidade original seja /dev/sda
(PV é /dev/sda1
) e nossas duas novas unidades sejam /dev/sdb
e /dev/sdc
. Todas as unidades são 100 MB grandes.
A ideia : como todos os nossos dados podem caber na metade de sdb
e sdc
, podemos colocar temporariamente nossos dados lá e, enquanto isso, criar um espelho listrado de nosso LV entre as outras três metades das unidades. Em seguida, elimine o lado original do espelho (temporário) e estenda nosso LV listrado até o tamanho real.
Esta maravilhosa obra de arte deve explicar melhor:
original state:
sda sdb sdc
_______ _______ _______
| | | | | |
| | | | | |
|lv_orig| | empty | | empty |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
|_______| |_______| |_______|
partition sdb & sdc, pvmove, then partition sda:
sda sdb sdc
_______ _______ _______
| | | | | |
| sda1 | | sdb1 | | sdc1 |
| empty | | empty | | empty |
|_______| |_______| |_______|
| | | | | |
| sda2 | |lv_orig| |lv_orig| <= linear on 2 drives
| empty | |half 1 | |half 2 |
|_______| |_______| |_______|
add sda{1,2,3} to vg, mirror the LV on this in striped mode:
sda sdb sdc
_______ _______ _______
|lv_orig| |lv_orig| |lv_orig|
|mirror | |mirror | |mirror | <= striped!
|stripe1| |stripe2| |stripe3|
|_______| |_______| |_______|
| | | | | |
| sda2 | |lv_orig| |lv_orig|
| empty | |half 1 | |half 2 |
|_______| |_______| |_______|
get rid of the sd{b,c}2 side of the mirror:
sda sdb sdc
_______ _______ _______
| | | | | |
|lv_orig| |lv_orig| |lv_orig| <= still striped!
|stripe1| |stripe2| |stripe3|
|_______| |_______| |_______|
| | | | | |
| sda2 | | sdb2 | | sdc2 |
| empty | | empty | | empty |
|_______| |_______| |_______|
delete sd{a,b,c}2 partitions to extend sd{a,b,c}1 on the whole disk,
finally, extend the lv:
sda sdb sdc
_______ _______ _______
| | | | | |
| sda1 | | sdb1 | | sdc1 |
| | | | | |
|lv_orig| |lv_orig| |lv_orig| <= definitely striped!
| | | | | |
|bigger&| |bigger&| |bigger&|
|striped| |striped| |striped|
|_______| |_______| |_______|
Veja como proceder:
Disclaimer: Eu escrevi isso principalmente com base em memórias, por favor, verifique os comandos (e edite o post, se necessário!)
- crie as partições
sdb1
esdb2
, respectivamente 42 e 58 MB, - mesma coisa para
sdc
, -
pvcreate /dev/sd{b,c}{1,2}
, -
vgextend vg_orig /dev/sdb2 /dev/sdc2
, -
pvmove /dev/sda1
moverá todos os dados do LV parasdb2
esdc2
, -
vgreduce vg_orig /dev/sda1
epvremove /dev/sda1
farão com que o LVM pare completamente de usarsda
- crie uma partição de 42 MB
/dev/sda1
(apagando a anterior, se necessário) epvcreate /dev/sda1
,vgextend vg_orig dev/sd{a,b,c}1
, -
lvconvert --type mirror --mirrors 1 --stripes 3 vg_orig/lv_orig /dev/sd{a,b,c}1
criará um espelho separado do nosso volume LV original (o que estamos procurando!), você pode verificar os detalhes comlvdisplay -am
, - o comando anterior pode falhar se o número total de extensões no LV não for um múltiplo de 3, nesse caso, você pode simplesmente adicionar 1 ou 2 ao LV da seguinte forma:
lvextend -l +1 vg_orig/lv_orig
, - com este comando, nos livraremos da cópia espelhada temporária dos dados que temos em
sdb2
esdc2
:lvconvert --type mirror --mirrors 0 vg_orig/lv_orig /dev/sd{b,c}2
, - remova as partições sdX2 das quais não precisamos mais:
vgreduce vg_orig /dev/sd{b,c}2
,pvremove /dev/sd{b,c}2
, - agora temos uma versão distribuída de nossos dados originais, ainda precisamos aumentar as partições de
sd{a,b,c}1
, exclua as partiçõessdb2
esdc2
e recrie assda1
,sdb1
esdc1
, partições para que elas comecem no mesmo número de setor, mas terminem em um número de setor maior (não tenha medo :)), -
partprobe /dev/sd{a,b,c}1
para atualizar a tabela de partições do kernel, -
pvresize /dev/sd{a,b,c}1
para fazer o LVM perceber que os PVs são maiores, -
lvextend -l 100%VG vg_orig/lv_orig
para tornar o LV maior agora, -
resize2fs vg_orig/lv_orig
se você tiver um sistema de arquivos ext que deseja expandir on-line.
Aqui está!
É bastante confuso que uma ferramenta como o LVM, supostamente feita para este tipo de operação, não seja capaz de fazer essa tarefa facilmente em um único (ou dois) comando ...