LINUX.ORG.RU
ФорумAdmin

Падение windows server 2016 во время бэкапа.

 


1

3

Здравствуйте.Подскажите помогите.Есть сервер HP с intel xeon e5 2690 v4. с proxmox 7.4.3.на борту. Там развёрнута VM с ос windows server 2016 и при каждом бэкапе проксмокса, windows падает и идёт в ребут. Интернет читал, ничего не нашёл толкового. Мб у кого была такая трабла?

root@pve4:~# qm config 112 bootdisk: sata0 cores: 18 cpu: host ide2: none,media=cdrom memory: 65536 name: Terminalsrv net0: virtio=F6:50:7D:24:D2:D6,bridge=vmbr0,firewall=1 numa: 1 onboot: 1 ostype: win10 sata0: local-zfs:vm-112-disk-0,cache=writeback,size=300G,ssd=1 scsihw: virtio-scsi-pci smbios1: uuid=749ba510-eade-4198-b861-02da47b6c94d sockets: 2 vmgenid: 82e52528-a36e-4cd7-8e89-3580f5032578



Последнее исправление: sedrak (всего исправлений: 1)

что такое windows падает? bsod?
ну так настрой запрет перезагрузки в случае бсода системы - тогда уже сможешь сам спокойно stop-код и даже его аргументы, если повезёт, переписать на листик (или сфоткать), а потом поискать в гугле

d00fy ★★★
()

У меня было подобное (и опять, никак не гуглилось). И не только во время бэкапов, а иногда виндовые виртуалки падали случайным образом.

Вылечилось настроек следующими параметрами systcl ядра (для дебиана закинуть надо в файлик в /etc/sysctl.d/) Копирую вместе с коментариями, которые надеюсь, поясняют суть проблемы:

# NEXT SETTINGS ARE TO AVOID SWAPPING OF APPS DUE TO TOO LARGE FILE CACHES IN MEMORY (VM disks backup)
# Reducing these is relevant with high-memory systems (>16G) to reduce absolute amounts which has to be written to disk at once
# Reducing these as below, seems to fix an issue with Win2K3 VMs sometimes spontaneously blue-screen-ing due to "hardware error" (assumingly when the caches get flushed gets too long time)

# At the default value of vfs_cache_pressure=100 the kernel will attempt to reclaim dentries and inodes at a "fair" rate with respect to pagecache and swapcache 
# reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer to retain dentry and inode caches. When vfs_cache_pressure=0, the kernel will never reclaim 
# dentries and inodes due to memory pressure and this can easily lead to out-of-memory conditions. Increasing vfs_cache_pressure beyond 100 causes the kernel 
# to prefer to reclaim dentries and inodes. 
# From another resource: 
# Setting vfs_cache_pressure to low value makes sense because in most cases, the kernel needs to know the directory structure before it can use file 
# contents from the cache and flushing the directory cache too soon will make the file cache next to worthless. Consider going all the way down to 1 with 
# this setting if you have lots of files. Setting this to big value is sensible only if you have only a few big files that are constantly being re-read.
# V: INCREASE IT (it defaults to 100) to AVOID backuping huge VM disk files to kick qemu in swap! See last remark above.
# vm.vfs_cache_pressure = 300
vm.vfs_cache_pressure = 150

# dirty_ratio, dirty_background_ratio:
# Lowering them from standard values causes everything to be flushed to disk rather than storing much in RAM. It helps large memory systems, which would normally 
# flush a 45G-90G pagecache to disk, causing huge wait times for front-end applications, decreasing overall responsiveness and interactivity. 
# https://lonesysadmin.net/2013/12/22/better-linux-disk-caching-performance-vm-dirty_ratio/

# vm.dirty_ratio is percentage of system memory which when dirty, *the process doing writes* would block and write out dirty pages to the disks
# Contains, as a percentage of total available memory that contains free pages and reclaimable pages, the number of pages at which a process which is generating disk writes will itself start writing out dirty data.
# tell the kernel to use up to 4% (96G*0.02=~4G) of the RAM as cache for writes (defaults to 20%)
# Try to decrease to see whether a spontaneous shutdown (Hardware failure) of the VMs will cease

# vm.dirty_ratio is the absolute maximum amount of system memory that can be filled with dirty pages before everything must get committed to disk. When the 
#       system gets to this point all new I/O blocks until dirty pages have been written to disk. This is often the source of long I/O pauses, but is a 
#       safeguard against too much data being cached unsafely in memory.
# It is a percentage
# Defaults to 20
# Has to be small for a VM host with slow IO (classic HDDs) so it does not "stall" for long when flushing which VMs do not like!!
vm.dirty_ratio = 5

# vm.dirty_background_ratio is the percentage of system memory which when dirty *then system* can start writing data to the disks
# Contains, as a percentage of total available memory that contains free pages and reclaimable pages, the number of pages at which the background kernel flusher threads will start writing out dirty data.
# instruct kernel to use up to 1% of RAM (~=1G) before slowing down the process that's writing (default for dirty_background_ratio is 10).
# Try to decrease to see whether a spontaneous shutdown (Hardware failure) of the VMs will cease

# vm.dirty_background_ratio is the percentage of system memory that can be filled with “dirty” pages — memory pages that still need to be written to disk — 
#       before the pdflush/flush/kdmflush background processes kick in to write it to disk. My example is 10%, so if my virtual server has 32 GB of memory 
#       that’s 3.2 GB of data that can be sitting in RAM before something is done.
# It is a percentage
# Defaults to 10
# Has to be small for a VM host with slow IO (classic HDDs) so it does not "stall" for long when flushing which VMs do not like!!
vm.dirty_background_ratio = 1

# if you need settin even lower than 1% (server with very large mem), use the absolute value based sister 
# parameters: vm.dirty_background_bytes and vm.dirty_bytes which can be tuned exactly

По сути дело было в том, что очевидно доходило до критического предела vm.dirty_ratio (так как грязные страницы росли быстрее чем оно сумевало flush-ить их на диски) - тогда практически все IO подвисает пока процент грязных страниц не упадет под vm.dirty_ratio. Виндовым виртуалкам это не нравилось.

Так что попробуйте уменьшить (в зависимости от памяти на сервере) vm.dirty_ratio = 5 vm.dirty_background_ratio = 1

vm.dirty_background_ratio должно быть меньше чем vm.dirty_ratio как минимум раза в три. Это все в процентах от памяти

Идея в том, чтобы vm.dirty_background_ratio включался пораньше чтобы скидывать грязные страницы памяти на диск, и дело не доходило до vm.dirty_ratio А даже если и дошло бы, то «подвисание» будет намного короче (так как нужно скинуть намного меньшего объема) и виртуалки падать не будут. В моем случае, это помогло.

manul91
()
Последнее исправление: manul91 (всего исправлений: 1)
Ответ на: комментарий от DALDON

Знаю. Я сам так жил больше года, мониторя виндовых виртуалок скриптом и тупо поднимая их при падении.

Наткнулся на этом решении случайно, когда понадобилось вынуть половину памяти из сервака на несколько месяцев - и оказалось, что с уполовиненной памяти, на это время на нем не упала ни раз ни одна виртуалка.

Проблема еще и в том, что тупые винды давали самые разнообразные BSOD коды при падении. Когда «проблема» по сути сводилась к тому что «диски не отвечают за ожидаемое время».

Не утверждаю что это панацея, но у меня точно сработало. Там был парк винд на kvm с 2003 до 2012 версий, так что не знаю как насчет винд поновее.

Дефолтные сетинги кернела (дебиана, по меньшей мере) для vm.dirty_ratio и vm.dirty_background_ratio годятся для десктопов и большинства серверов, но это (железка с памяти 64G и выше, на которой крутятся древнючие винды) все таки редкая ситуация.

С тех пор всегда уменьшаю; vm.dirty_ratio это процент, но как абсолютное значение ИМХО лучше чтоб не превышало 1-2GB (для медленного HDD стораджа). А значение vm.dirty_background_ratio не менее чем в три раза меньше.

manul91
()
Последнее исправление: manul91 (всего исправлений: 6)
Ответ на: комментарий от DALDON

Чтоб память не засорялась ненужными кэшами, лучше всего запереть процесс бэкапа в ограниченную память, средствами cgroups2 (или то же самое череч systemd).

Бэкапу 1-2G более чем достаточно, и притом не будет засорять всю память кэшами при копировании соизмеримого количества данных.

manul91
()
Ответ на: комментарий от DALDON

Пока что это самое простое решение что я придумал, именно так и делаю бэкап, но есть виртуалки которые должны работать 24/7 и не падать. Но тут пока все стабильно, проблемы не возникало. Но есть правда в кластере на одной виртуалке виндовой проблема, при бэкапе сеть отваливается, любые сетевые подключения, но тут может быть связано с virtio, потому что раньше использовалось обычный intel, может конечно совпадение, но с переходом начались глюки с падением сетей.

sedrak
() автор топика
30 декабря 2023 г.
Ответ на: комментарий от DALDON

Максимальную память бэкап процесса/скрипта проще всего организовать если запускать его сервисом средствами systemd (по таймеру), см. MemoryMax, MemoryHigh параметры юнитов https://serverfault.com/questions/1108857/what-is-the-maximum-value-for-system-d-memorymax

Если запускать ручно прямо с консоли, от не-рута, можно примерно так:

systemd-run --user --scope -p MemoryMax=5G -p MemorySwapMax=0 executable-to-run-memorylimited

ionice -c 3 дополнительно еще ограничит приоритет IO процесса до idle (только когда другие процессы не пользуют IO):

systemd-run --user --scope -p MemoryMax=5G -p MemorySwapMax=0 ionice -c 3 executable-to-run-memorylimited-and-iolimited

Если systemd не пользовать, можно прямо заюзать файловую систему cgroups v2 скриптом.

Вот кустарный скрипт, который запускает любой другой скрипт ограниченным в памяти (недостаток что нужно запускать только в контексте рута)

# cat run-memory-limited
#!/bin/sh

executableFileExistOrDie() {
        [ -x "${1}" ] || { echo "Could not find command ${1}! Exit."; exit 1; }
}

showhelp() {
        echo ${1}
        echo
        echo "Usage:"
        echo "${0} [mem-limit] [command args]"
        echo
        echo "Example:"
        echo "${0} 500M cp file1 dest1/"
        echo
}


# veryfy args and executables

ARGNUM=$#

[ ${ARGNUM} -lt 2 ] && { showhelp "Need at least 2 arguments, currently ${ARGNUM}!!"; exit 1; }
[ $(id -u) = 0 ] || { showhelp "This script must be run as root !!!"; exit 1; }


MKTEMP="/usr/bin/mktemp" && executableFileExistOrDie "${MKTEMP}"

MKDIR="/usr/bin/mkdir" && executableFileExistOrDie "${MKDIR}"

RMDIR="/usr/bin/rmdir" && executableFileExistOrDie "${RMDIR}"

MOUNT="/usr/bin/mount" && executableFileExistOrDie "${MOUNT}"

UMOUNT="/usr/bin/umount" && executableFileExistOrDie "${UMOUNT}"

CAT="/usr/bin/cat" && executableFileExistOrDie "${CAT}"

WC="/usr/bin/wc" && executableFileExistOrDie "${WC}"

TR="/usr/bin/tr" && executableFileExistOrDie "${TR}"

ECHO="/usr/bin/echo" && executableFileExistOrDie "${ECHO}"

BASENAME="/usr/bin/basename" && executableFileExistOrDie "${BASENAME}"

CGROUPDIR="/tmp/memgroup"
CGROUPSUBDIR="memory-limited-temp"
SCRIPTNAME=`${BASENAME} "${0}"`
CEXITCODE=0

# process args

MEM="$1"
shift
CMND="$@"

### CREATE SPECIAL MEM-LIMITED CGROUP AND RUN INSIDE; THIS IS TO ENSURE THE PROCESS WILL NOT CONSUME TOO MUCH BUFFER MEM AND WILL NOT SWAP-OUT 
THISPROCESS=$$
${MKDIR} -p ${CGROUPDIR}
${MOUNT} -t cgroup2 none ${CGROUPDIR}
MEMORY_LIMITED_DIR="$(${MKTEMP} -d ${CGROUPDIR}/${CGROUPSUBDIR}.XXXXXXXXXXXXX)"
#ensure memory is enabled for subtrees
echo "+memory" > ${CGROUPDIR}/cgroup.subtree_control
#enable mem max
echo ${MEM} > ${MEMORY_LIMITED_DIR}/memory.max
echo ${THISPROCESS} > ${MEMORY_LIMITED_DIR}/cgroup.procs
### END OF CGROUP SELF-ASSIGNMENT


${ECHO} -e "Jail cgroup dir:\t ${MEMORY_LIMITED_DIR}"
${ECHO} -e "Memory jailed to:\t ${MEM}"
${ECHO} -e "Wrapper proc id:\t ${THISPROCESS}"
${ECHO} -e "Wrapper proc name:\t ${SCRIPTNAME}"
${ECHO} -e "Command to execute:\t ${CMND}"


### EXECUTE COMMAND CGROUP MEMORY-JAILED
echo
echo "Executing command ""'""${CMND}""'"" ...."
${CMND}
CEXITCODE=$?
[ ${CEXITCODE} -eq 0 ] || { echo "Command ""'""${CMND}""'"" failed with exit code ${CEXITCODE} !"; }
[ ${CEXITCODE} -ne 0 ] || { echo "Command ""'""${CMND}""'"" executed and exited with code 0."; }


### WAIT TO FINISH AND CLEANUP CGROUP MEMORYJAIL
echo
echo "Waiting for all possibly async raised child jobs/processes to finish..."
wait

# move back in the main process pool, therefore leaving ${MEMORY_LIMITED_DIR}/cgroup.procs eventually empty, except perhaps the child async tasks/processes
echo ${THISPROCESS} > ${CGROUPDIR}/cgroup.procs

WAITCTR=0
while :
do
        PROCNUMLEFT=`${CAT} ${MEMORY_LIMITED_DIR}/cgroup.procs | ${WC} -l`
        if [ ${PROCNUMLEFT} -gt 0 ]
        then
                # is there still something in tasks? Ideally, we may need to wait until this becomes empty - or explicitly move all of existing stuff in the main task pool?
                ${ECHO} -n "${SCRIPTNAME} : `date`: ${PROCNUMLEFT} procs ids left in ${MEMORY_LIMITED_DIR}/cgroup.procs "
                ${CAT} ${MEMORY_LIMITED_DIR}/cgroup.procs | ${TR} '\n' ','
                ${ECHO}  ". Waited ${WAITCTR} sec total..."
                sleep 10
                WAITCTR=$((${WAITCTR} + 10))
        else
                break;
        fi
done

echo "All possibly async raised child jobs/processes finished."

${RMDIR} ${MEMORY_LIMITED_DIR}
${UMOUNT} ${CGROUPDIR}
${RMDIR} ${CGROUPDIR}

echo "Syncing..."
sync
echo "Done."

exit $CEXITCODE

Пользоваться так:

# run-memory-limited 5G executable-to-run-memorylimited

Чтобы не только память не засорялась (макс. 5G), а также и IO бэкапа тоже не мешало/замедляло виртуалок, можно запускать примерно так через ionice (хотя если vm-backup-script.sh рождает асинхронные процессы не уверен что ionice idle распространится и на них, лучше проверить, можно понадобится вызывать их всегда с ionice -c 3 експлицитно) :

# run-memory-limited 5G ionice -c 3 vm-backup-script.sh
manul91
()
Последнее исправление: manul91 (всего исправлений: 2)

Не вспомню что там было конкретно, но суть в том что винде не нравится то что происходит с файловой системой на момент бэкапа. В проксе есть такая опция ‘freeze-fs-on-backup’, по умолчанию включена. Для серваков которые перезагружались в момент бэкапа у себя эту опцию выключили.

В 8-ой версии это можно сделать в гуйне, а в 7-ой только в конфиг файле виртуалки.

Toten_Kopf
()
Ответ на: комментарий от manul91

Смотрите, какая интересная петрушка то выходит… Пристегните ремни:

И так, я пока до конца не разобрался, но..!

Похоже, ж кеши то забивает ни vzdump. А забивает их… Процессы zfs? Если я всё правильно понимаю, то: vzdump, подключается к процессу qemu и через него, начинает «высасывать образ». А qemu в свою очередь пинает процессы zfs (в моём случае).

Как я это понял:

Я значит воспользовался Вашими советами. Виртуальные машины не зависли (делал десятки), но вот какая интересная штука: linux машина, почти зависла, когда я для неё запустил vzdump. - la внутри неё поднялся до огромных размеров, и пошли очень большие задержки в вводе-выводе. Что бы окончательно продуктив не положить, остановил backup, в конфигурационном файле vzdump, ограничил скорость, и стало всё ок. При этом..! Внимание: другие машины, которые в общем точно так же работали на этих дисках, la не поднимался. - Таким образом, я пришел к выводу, что vzdump всё своё чтение, если мы делаем копирование в режиме снепшшота, выполняет путем присасывания к процессу qemu конкретной машины… Я так понимаю, что в таком случае, фиг чего поделаешь?

Я так понимаю, сейчас Вы уже не работаете с proxmox? - Вы смотрели, что именно vzdump кеши забивает? :)

DALDON ★★★★★
()
Последнее исправление: DALDON (всего исправлений: 1)
Ответ на: комментарий от DALDON

Я так понимаю, сейчас Вы уже не работаете с proxmox? - Вы смотрели, что именно vzdump кеши забивает? :)

Proxmox-ом никогда не пользовался. Zfs (в продакшане) - тоже.

В случае когда были проблемы (на котором ссылался выше), бэкапы делались через LVM снэпшотов.

Документация vzdump ( https://pve.proxmox.com/pve-docs/vzdump.1.html ) ссылается на technical overview of the Proxmox VE live backup for QemuServer ( https://git.proxmox.com/?p=pve-qemu.git;a=blob_plain;f=backup.txt ) где написано следующее:

==Disadvantages==

* we need to define a new archive format

Note: Most existing archive formats are optimized to store small files
including file attributes. We simply do not need that for VM archives.

* archive contains data 'out of order'

If you want to access image data in sequential order, you need to
re-order archive data. It would be possible to to that on the fly,
using temporary files.

Fortunately, a normal restore/extract works perfectly with 'out of
order' data, because the target files are seekable.

* slow backup storage can slow down VM during backup

It is important to note that we only do sequential writes to the
backup storage. Furthermore one can compress the backup stream. IMHO,
it is better to slow down the VM a bit. All other solutions creates
large amounts of temporary data during backup.
  • slow backup storage can slow down VM during backup

Так что ваша проблема в случае vzdump, вроде описана и известна. Либо нужно заменить backup storage на «быстрый», либо поменять стратегию для бэкапов.

И да, из того что там написано ясно, что vzdump как раз «присасывается» к процессу qemu виртуалки и тормозит его.

В случае с LVM такого нету. Снэпшот происходит практически мгновенно, потом совершенно независимо бэкапится. После того как бэкап закончен, ненужный уже снапшот удаляется. Цена этому - замедление только IO write performance виртуалки пока есть snapshot - но оно фиксированно (грубо вдвое).

vzdump - не очень продуманное решение с точки зрения scalability (цена за итоговую «экономию» в IO во время бэкапа - возможность целостного тормоза виртуалок, вплоть до «остановки» при неблагоприятных условий).

manul91
()
Последнее исправление: manul91 (всего исправлений: 2)
Ответ на: комментарий от manul91

Добрый день! Вы один из тех крайне не многих людей, с которыми очень, очень классно общаться. Всё классно описали и нагуглили. Именно всё это же самое я и нагуглил ранее. - Только, вот какая штука, что ещё из не совсем очевидного, последствия присасывания, через vzdump: в случае присасыввания, никакие ionice я так понимаю, в принципе не работают! Оно и очевидно. Посколько, сам процесс qemu и сосет данные, по сути. Таким образом, происходит вот какая не приятная штука то: допустим, у меня жесткий диск, в моём случае raid10. Сеть 1гбит, я начинаю присасываться, вычитывать со скоростью 100 мегабайт в секунду… Казалось бы, не страшно, но, тут виртуальная машина хочет записать блок 8, блок 100 и блок 875. - Что будет происходит? - Система начинает разрываться, между чтением и записью! - Мы ведь не забыли, что у нас всё идет через kvm… И так, остановится чтение потока. Головки диска побегут по блокам 8,100,875 - побегут скорее их класть в бекап. Потом, откроется шлагбаум для записи этих блоков на диск, потом, диски снова попытаются перейти в режим потокового чтения… - Отсюда я и вижу, в момент бекапа дичайший la, который обусловлен задержкой ввода-вывода. Как бы это не парадкосально, но, машины у меня падают, в первую очередь из-за большого кол-ва чтения, а не из-за медленной записи в гигабитной сети (а пишу я на nfs в режиме async, если что). Похоже, у меня режим async ещё забивает - надо бы посмотреть сколько грязных страниц у меня появляется во время бекапа. Весьма любопытно.

И так: основное решение вопроса лежало в том, что я снизил скорость работы vzdump. Вот так вот просто. Я не читаю настолько активно, и диски успевают и почитать, и пописать… - Такой вот парадокс. И машины не падают.

Совершенно верно сказали, что стоит пересмотреть на стратегию бекапа. Тут же ещё какой момент? А момент такой, что, один диск в kvm, это один процесс чтения. А zfs, в зеркале, при таком раскладе всегда будет читать только с одного диска. Вот оно всё в купе и собирается, и дает негативный результат.

Спасибо огромное, Вы очень круто всё пишите. Ваши советы по ограничению памяти через systemd, так же буду рассматривать. И при возможности применю.

P.S. - посколько от zfs отказываться не хочется, сейчас смотрю что в этом плане у proxmox backup server. Но, и повторюсь, что снижение скорости vzdump избавило от проблем. Но, там да, другие минусы никуда не делись - а именно, это отсутствие инкремент бекапов и т.д.

DALDON ★★★★★
()
Последнее исправление: DALDON (всего исправлений: 1)