skip to Main Content

Since our previous technician passed away, I am adjusting a few pieces of his code as it doesn’t work correctly with for example MySQL 8.0

The piece of perl code is:

@temp = `/usr/sbin/vzctl exec $server 'mysql -V 2>/dev/null'`;
chomp(@temp);
@temp = split /s+/,$temp[0];
$mysql = $temp[4];
$mysql =~ s/,//;

It works without issues for MySQL 5.5 / 5.6 / 5.7 and with all MariaDB versions.

Two examples of correct output:

MySQL:  5.5.33
MySQL: 10.3.18-MariaDB

However with MySQL 8.0 there is a problem. I checked it with the mysql -V command and it outputs the information differently.

Normal output (for all MySQL/MariaDB versions):

mysql  Ver 14.14 Distrib 5.6.46, for Linux (x86_64) using  EditLine wrapper

But with MySQL 8.0 it’s like this:

mysql  Ver 8.0.18 for Linux on x86_64 (MySQL Community Server - GPL)

As a result of the above it displays: Linux (instead of the version). So far I can understand this, as the “$temp[4]” is the word Linux in mysql -v.

Is there a workaround for this? I tried a few things, but I lack knowledge with perl to be honest and so far I am not making any progress. For some reason I cannot get the version being displayed correctly with MySQL 8.0.

I also tried fooling around with dpkg -l ‘mysql-server’, however that would need more modifications to work also with other distributions, like CentOS.

So maybe someone has an idea on how to solve this for MySQL 8.0? And maybe I can learn something as well from it for future usage. Thanks in advance.

2

Answers


  1. You want the server version?

    use DBI qw( );
    
    my $dsn = "DBI:mysql:database=$database;host=$hostname;port=$port";
    my $dbh = DBI->connect($dsn, $user, $password);
    say $dbh->{mysql_serverversion};
    

    It also appears to be the last (if only) version in the information line, so you could use the following:

    my ($info) = `/usr/sbin/vzctl exec $server 'mysql -V 2>/dev/null'`;
    my $version = $info =~ ( /bd+.[d.]+/g )[-1];
    
    Login or Signup to reply.
  2. There are probably ways you can get this directly from the MySQL server. But this seems to do what you want and isn’t too different from your existing code.

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    while (<DATA>) {
      my @temp = split /s+/, $_;
    
      my $mysql;
    
      # If the fifth column contains a character that isn't a
      # digit, a dot or a comma...
      if ($temp[4] =~ /[^d.,]/) {
        # then look in column 3
        $mysql = $temp[2];
      } else {
        # else look in column 5
        $mysql = $temp[4];
      }
    
      $mysql =~ s/,//;
    
      print "$mysqln";
    }
    
    __DATA__
    mysql  Ver 14.14 Distrib 5.6.46, for Linux (x86_64) using  EditLine wrapper
    mysql  Ver 8.0.18 for Linux on x86_64 (MySQL Community Server - GPL)
    

    Update: Following the comment below, I’d suggest updating the if/else clause to be this:

    # If column 5 start with what looks like a version number...
    if ($temp[4] =~ /^d+.d+/) {
      # then look in column 5
      $mysql = $temp[4];
    } else {
      # else look in column 3
      $mysql = $temp[2];
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search