jfcoz / postgresqltuner

Simple script to analyse your PostgreSQL database configuration, and give tuning advice
https://postgresqltuner.pl
GNU General Public License v3.0
2.61k stars 190 forks source link

Hardware loop broken running on Debian 9.8 #37

Closed PitoneMaledetto closed 5 years ago

PitoneMaledetto commented 5 years ago

The script fails to recognize server type as VMWare VM.

Expected Behavior

[INFO] Running in VMware hypervisor

Current Behavior

Use of uninitialized value $line in pattern match (m//) at ./postgresqltuner.pl line 302. Use of uninitialized value $line in pattern match (m//) at ./postgresqltuner.pl line 305. Use of uninitialized value $line in pattern match (m//) at ./postgresqltuner.pl line 308. Use of uninitialized value $line in pattern match (m//) at ./postgresqltuner.pl line 311. Use of uninitialized value $line in pattern match (m//) at ./postgresqltuner.pl line 314. [INFO] Running on physical machine

Possible Solution

n.a.

Steps to Reproduce (for bugs)

run the script on the same version of Debian as per "Your Environment"

Context

I already know that I have to change the scheduler because I am running PostgreSQL on a virtual server. Other users running postgresqltuner.pl for the first time might overlook the above important scheduler setting change.

Your Environment

DanielElgh commented 5 years ago

This happens because non-root users are restricted from running dmesg in the disto you are using. os_cmd() returns undef in this case which causes Perl to throw the uninitialized warnings. The script will later act as if the server is a physical machine, even though it might be a virtual server. This can easily be fixed in numerous ways. An example could be to fall back on systemd-detect-virt in case dmsg terminates with a non-zero exit code.

You can work around the issue until the code is fixed by allowing non-root users to run dmesg. This can be achieved by updating the kernel parameter kernel.dmesg_restrict to 0. I.e. sudo sysctl kernel.dmesg_restrict=0.

PitoneMaledetto commented 5 years ago

Hi DanielElgh, indeed at line 300: my @dmesg=os_cmd("systemd-detect-virt");

then: ===== OS information ===== [INFO] OS: linux Version: 3.16.0 Arch: x86_64-linux-gnu-thread-multi [INFO] OS total memory: 23.55 GB [OK] vm.overcommit_memory is good : no memory overcommitment [INFO] Running in VMware hypervisor [INFO] Currently used I/O scheduler(s) : cfq [BAD] CFQ scheduler is bad on virtual machines (hypervisor and/or storage is already dooing I/O scheduling)

Thank you for your help. It begs the question: why not using systemd-detect-virt as default since a non-privileged user can't access dmesg?

jfcoz commented 5 years ago

@DanielElgh , thanks for your PR !

@PitoneMaledetto , dmesg was an option, as systemd-detect-virt was not on all systems.