web-dev-qa-db-ja.com

論理ボリュームの未使用バイトを印刷する

物理ボリュームが次のようにサイズ変更されたと想像してください。

pvresize /dev/sda2 

そして、論理ボリュームは次のようにサイズ変更されました。

lvresize -l +100%FREE system/home

しかし、このコマンドは実行されませんでした。

resize2fs /dev/mapper/system-home

最後のコマンドを忘れたため、未使用のスペースがあります。

未使用バイトの計算方法は?

背景:サーバー上でファイルシステムのサイズ変更が忘れられたかどうかをチェックするチェックスクリプトを書きたいと思います。

ところで:私はシェルスクリプトを信用していません。

1
guettli

ブロックデバイス全体のデフォルトサイズとオンライン拡張により、サイズチェックが不要になります。すべてのファイルシステムでresize2fsを実行します。

(サイズが必要なユースケースがある場合は、質問を編集してください。)

スクリプトまたはシェルエイリアスにlvresize --resizefsを追加して、ファイルシステムを再び忘れないようにします。


理想的には、スペースの不足がキャパシティプランニングレポートに表示され続けます。うまくいけば、ほとんどいっぱいになることについてのアラートをトリガーするほどいっぱいにならないでしょう。

6
John Mahowald

ステップ1:ファイルシステムの境界を特定する

dumpe2fs -h /dev/mapper/system-home | grep -E "^Block count|^Block size"

以下の例のように、これら2つの数値を使用してファイルシステムの合計サイズを取得します。

Block count:              98304
Block size:               1024    (which is 1k)
FS size = 98304 = **96MB**

ステップ2:ブロックデバイスの境界を特定する

a)論理ボリュームに関連付けられているdmを識別しますreadlink -f /dev/mapper/system-homeこれは/ dev/dm-XXを提供します

b)/dev/dm-XX境界を特定しますcat /sys/block/dm-XX/sizeこれは(512バイト)ブロック単位の合計サイズを示します。サイズが300000ブロックの場合、ブロックデバイスのサイズは150MBより少し小さくなります

150-96は〜54MB割り当て可能なファイルシステムの空き容量を増やします

4
averon

関係するすべてのブロックデバイスを検索し、それに応じてサイズ変更コマンドを出力するスクリプトを使用して、サイズ変更の問題を解決します。

https://github.com/mircea-vutcovici/scripts/blob/master/vol_resize.sh

同様の方法で、ブロックデバイスサイズとファイルシステムサイズを表示するコマンドを実行するように変更できます。スクリプトを見るだけで、答えがもう少し複雑であることがわかります。

例えば。次のようなレイアウトを想像してみてください。

  • LUNのマルチパス
  • パーティションテーブル
  • lvm
  • dmcrypt
  • zfs
  • zfs zvol

サイズを見つける方法:

  • ブロックデバイス:_blockdev --getsz sdX_、_grep . /sys/block/*/size_
  • lvm:pvs
  • ext2、3、4:dumpe2fs /dev/sdX|egrep '^Block (count|size):'
  • zfs:_zpool status_、_zpool list_、_zfs list_
  • btrfs:
  • xfs:_xfs_info_
  • デバイスマッパー:_dmsetup table_
  • マウントされたファイルシステム:df
2

他の人はあなたの質問に答えるために使用できるツールをリストしました、しかし私はあなたが使用できる実際の実用的な実装を作りたかったです。だから、私はあなたが求めていることを正確に行うためにbashスクリプトを書きました:FSによってまだ吸収されていないLVの終わりにある空き領域の量を報告します(誰かがFS自体)を成長させます。

ファイルシステムのサイズの決定はそのファイルシステムのツールに依存するため、LVMディスクに使用しているファイルシステムに合わせてファイルシステムをパーソナライズする必要があることに注意してください。私は個人的にXFSとEXT4の両方を使用しているので、以下のスクリプトは両方を実装しています。具体的には、EXT4にはtune2fsを使用し、XFSにはxfs_infoを使用する必要がありました。

lvfree.sh

#!/bin/bash

# Header
printf '%-20s %-7s %8s %8s %8s\n' Mountpoint FS_Type LV_Size FS_Size LV_Free

lsblk -nlbo TYPE,FSTYPE,MOUNTPOINT,PATH,SIZE | grep -E '^lvm +(ext4|xfs)' | while read TYPE FSTYPE MOUNTPOINT PAATH SIZE; do
  if [[ $FSTYPE == 'ext4' ]] ; then
    FSSIZE=$(tune2fs -l $PAATH | grep -E '(Block count|Block size)' | awk 'BEGIN{x=1}{x=x*$NF}END{print x}') 
  Elif [[ $FSTYPE == 'xfs' ]] ; then
    FSSIZE=$(xfs_info $MOUNTPOINT | grep ^data | /bin/tr = ' ' | awk '{print $3*$5}')
  fi
  LVFREE=$((SIZE - FSSIZE))
  printf '%-20s %-7s %8d %8d %8d\n' $MOUNTPOINT $FSTYPE $((SIZE/1024/1024)) $((FSSIZE/1024/1024)) $((LVFREE/1024/1024))
done

それをテストする

まず、いくつかのLVを拡張しますが、FSを拡張するのを忘れます

[root@xps joshua]# lvextend -L +1G /dev/vg1/home
 Size of logical volume vg1/home changed from 90.00 GiB (23040 extents) to 91.00 GiB (23296 extents).
 Logical volume vg1/home successfully resized.

[root@xps ~]# lvextend -L +256M /dev/vg1/usr
 Size of logical volume vg1/usr changed from 25.00 GiB (6400 extents) to 25.25 GiB (6464 extents).
 Logical volume vg1/usr successfully resized.

スクリプトを実行して、LVの空き領域を確認します

[root@xps ~]# ./lvfree.sh 
Mountpoint           FS_Type  LV_Size  FS_Size  LV_Free
/                    ext4        5120     5120        0
/var                 ext4       24576    24576        0
/var/log             ext4       20480    20480        0
/usr                 ext4       25856    25600      256
/home                xfs        93184    92160     1024
/tmp                 ext4       10240    10240        0
/opt                 ext4        5120     5120        0

今、私はXFSおよびEXT4ファイルシステムを拡張することを覚えています。

[root@xps ~]# xfs_growfs /home
meta-data=/dev/mapper/vg1-home   isize=256    agcount=8, agsize=3276800 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0, sparse=0, rmapbt=0
         =                       reflink=0
data     =                       bsize=4096   blocks=23592960, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=65536  ascii-ci=0, ftype=0
log      =internal log           bsize=4096   blocks=6400, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 23592960 to 23855104

[root@xps ~]# resize2fs /dev/mapper/vg1-usr 
resize2fs 1.45.3 (14-Jul-2019)
Filesystem at /dev/mapper/vg1-usr is mounted on /usr; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 2
The filesystem on /dev/mapper/vg1-usr is now 6619136 (4k) blocks long.

そして最後に、新しいスクリプトを実行して、新しいスペースがファイルシステムに組み込まれていることを確認します。

[root@xps ~]# ./lvfree.sh 
Mountpoint           FS_Type  LV_Size  FS_Size  LV_Free
/                    ext4        5120     5120        0
/var                 ext4       24576    24576        0
/var/log             ext4       20480    20480        0
/usr                 ext4       25856    25856        0
/home                xfs        93184    93184        0
/tmp                 ext4       10240    10240        0
/opt                 ext4        5120     5120        0

脚注:私のスクリプトのPAATHはタイプミスではありません。変数名PATHはシェルスクリプトで予約された意味を持っているため、使用する必要はありませんでした。

1
Joshua Huber

簡単に言うと、 bash 機能を使用します。

crtdev=/dev/sda9
crtdev=/dev/Vol-1/Root
  1. デバイスサイズ(実数):

    { read devsz;read devss;}< <(blockdev --getsz --getss $crtdev)
    devsize=$((devsz*devss))
    

    注:lsblkを使用して、サイズのあるデバイスを一覧表示できます。

    lsblk -no KNAME,NAME,SIZE
    

    これはスクリプトで役立つ可能性があります...さらに参照してください!

  2. ファイルシステムのサイズ(現在)

    1. ext2|ext3|ext4の場合:

      while IFS=$':\t\r\n' read fld val;do
          case $fld in
               Block\ size)  fsbs=$val;;
               Block\ count) fssz=$val;;
           esac
      done < <(dumpe2fs 2>&1 -h $crtdev)
      fssize=$((fssz*fsbs))
      
    2. xfsの場合:

      XFS情報はマウントされたデバイスでは実行されません。代わりにmont-pointを使用する必要があります。

      mntpnt=/mnt
      while IFS=$' =,\t\r\n' read -a lne;do
          [ "$lne" = "data" ] &&
              fsbs=${lne[2]} fssz=${lne[4]}
      done < <( xfs_info $mntpnt )
      fssize=$((fssz*fsbs))
      
    3. ntfsの場合:

      これは簡単ではないようです...過去にntfsresizeを使用したことがある場合でも、あまり使用しないためです。そこに何かがある:

      read fsinfo < <(file -bs $1)
      fssz=${fsinfo#*, sectors } fssz=${fssz%%,*}
      fssize=$(( 512 * ( fssz + 1 ) ))
      

      注:私はこれが嫌いです:+ 1を説明できず、代わりに+ 8を使用したテスト作業の一部が...

そしてついに

printf "Dev: %d - FS: %d = Unused: %d\n" $devsize $fssize $(( devsize - fssize ))

すべてのデバイスをスキャンするためにlsblkを使用するスクリプト:

このスクリプトは引数なしで実行され、diffがnull以外のデバイスごとに1行を出力します。任意の(ダミー)引数を指定して実行すると、xfsまたはext[234]デバイスごとに1行が出力されます。

このように bash 効率的なbashismを使用し、フォークをlshwdumpe2fs、および/またはxfs_infoに制限します。ただ、このスクリプトは非常に小さなリソースフットプリントを提示します。

!! rootまたはSudoとして実行されます!!

#!/bin/bash
shopt -s extglob
declare -A KNAMES='()' # Prevent double check
infolog() {
    # Entering this with $kname, $size, $fs, $name, $fsbs and $fssz.
    fssize=$((fssz*fsbs))
    (( $# | size-fssize ))&& # Only if diffsize > 0 or if argument was submited
        printf "%-25s %-6s %15u %15u %14u\n" \
               ${NAME##*/} $FSTYPE $SIZE $fssize $((SIZE-fssize))
}
while read line; do  eval "$line"
    [ "${KNAMES[${KNAME##*/}]}" ] || case $FSTYPE in 
        ext* ) while IFS=$':\t\r\n' read fld val;do
                case $fld in
                    Block\ size)  fsbs=$val;;
                    Block\ count) fssz=$val;;
                esac
            done < <(dumpe2fs 2>&1 -h $KNAME)
            infolog $@ ;;
        xfs ) check=$KNAME
            [ "$MOUNTPOINT" ] && check="$MOUNTPOINT"
            while IFS=$' =,\t\r\n' read -a lne;do
                [ "$lne" = "data" ] &&
                    fsbs=${lne[2]} fssz=${lne[4]}
            done < <( xfs_info "$check" )
            infolog $@ ;;
        ntfs )
            read fsinfo < <(file -Lbs $KNAME)
            fssz=${fsinfo#*, sectors } fssz=${fssz%%,*}
            (( fssz += 1, fsbs=512 ))
            infolog $@ ;;
    esac
    KNAMES[${KNAME##*/}]="done"
done < <(lsblk -bnpPo KNAME,NAME,MOUNTPOINT,FSTYPE,SIZE)

(これは、SOのスクロールバーを防ぐために少し縮小されています;)

サンプル実行(引数なし):

./unused_bytes_by_dev.sh
Vol--I-XDATAS             xfs        48318382080     42949672960     5368709120
sdd1                      ext4        1010774016       175472640      835301376

1つの引数で:

./unused_bytes_by_dev.sh dummy
md0                       ext4         246349824       246349824              0
Vol--I-ROOT               ext4        1610612736      1610612736              0
Vol--V-USR                ext4       31138512896     31138512896              0
Vol--I-VAR                ext4       22548578304     22548578304              0
Vol--I-HOME               ext4       34359738368     34359738368              0
Vol--I-XDATAS             xfs        48318382080     42949672960     5368709120
Vol--I-Win                ntfs       42949672960     42949672960              0
sdd1                      ext4        1010774016       175472640      835301376
1
F. Hauri

dfは、FSから見た合計サイズを、-k —KB単位で示します。

Sudo blockdev --getsize64は、純粋なブロックデバイスサイズをバイト単位で提供します。

バイトをKBに変換し、これら2つの間に有意差があるかどうかを比較するのは非常に簡単です。

0
poige