Skip to content

Commit

Permalink
FB8-67: Publish git hash in db log and via global status (facebook#991)
Browse files Browse the repository at this point in the history
Summary:
Jira ticket: https://jira.percona.com/browse/FB8-67

Reference commit: facebook@e4f22e0
Reference commit: facebook@f00855b
Reference commit: facebook@92bec02
Reference commit: facebook@408ea32ed2

Rocksdb hash and date is set to "none" until rocksdb is added.
Pull Request resolved: facebook#991

Reviewed By: lth

Differential Revision: D14603932

Pulled By: lth
  • Loading branch information
dutow authored and inikep committed Sep 7, 2020
1 parent fac1220 commit 93836a3
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 2 deletions.
214 changes: 214 additions & 0 deletions cmake/githash.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
#!/usr/bin/perl -w

#
# Copyright (c) 2016 Facebook, Inc.
# All rights reserved
#

#
# Git hash/date header file generator
#

use strict;

use Cwd;
use File::Copy qw(copy);
use Getopt::Long qw(GetOptions);
use Pod::Usage qw(pod2usage);

sub check_all_or_none {
my $bitmask_a = 0;
$bitmask_a = $bitmask_a | 1 if shift ne "";
$bitmask_a = $bitmask_a | 2 if shift ne "";

my $bitmask_b = 0;
$bitmask_b = $bitmask_b | 1 if shift ne "";
$bitmask_b = $bitmask_b | 2 if shift ne "";

pod2usage("You must specify both or none of the mysql git hash and date")
unless ($bitmask_a == 0 || $bitmask_a == 3);

pod2usage("You must specify both or none of the rocksdb git hash and date")
unless ($bitmask_b == 0 || $bitmask_b == 3);
}

# Function to retrieve the git hash and date from a repository
sub git_hash_and_date {
my $subdir = shift;
my $orgdir = Cwd::getcwd;

# Switch directories to the specified one
chdir($subdir) or die "Can't change directory to '$subdir'";

# Get the hash and date from the most recent revision in the repository
my $git_cmd = "git log -1 --format=\"%H;%cI\"";
open (my $log, "$git_cmd |") or die "Can't run $git_cmd";

my $githash = "";
my $gitdate = "";

# Loop through all the lines - we should only have one line
while (<$log>) {
# Search for a line that has a hash, a semicolon and the date
if (/^([0-9a-f]{7,40});(.*)\n/) {
die "Unexpected multiple matching log lines" unless !length($githash);
$githash = $1;
$gitdate = $2;
}
}

# Make sure we got something
die "No matching log lines" unless length($githash);

# Close the input and switch back to the original subdirectory
close($log);
chdir($orgdir);

# Return the found hash and date
return ($githash, $gitdate);
}

# main function
sub main {
my $root = "";
my $infile = "";
my $mysql_git_hash = "";
my $mysql_git_date = "";
my $rocksdb_git_hash = "";
my $rocksdb_git_date = "";
my $help = 0;

# Get the parameters
GetOptions(
'help|?' => \$help,
'git_root=s' => \$root,
'file=s' => \$infile,
'mysql_githash=s' => \$mysql_git_hash,
'mysql_gitdate=s' => \$mysql_git_date,
'rocksdb_githash=s' => \$rocksdb_git_hash,
'rocksdb_gitdate=s' => \$rocksdb_git_date
) or pod2usage();

# Validate the parameters
pod2usage(-verbose => 1) if $help;
pod2usage("missing required parameter --git_root") if $root eq "";
pos2usage("missing required parameter --file") if $infile eq "";
check_all_or_none($mysql_git_hash, $mysql_git_date,
$rocksdb_git_hash, $rocksdb_git_date);

my $rocksdb = "$root/rocksdb";
my $outfile = "$infile.tmp";

if ($mysql_git_hash eq "") {
# retrieve the git hash and date for the main repository
($mysql_git_hash, $mysql_git_date) = git_hash_and_date $root;
}
if ($rocksdb_git_hash eq "") {
if (-d $rocksdb) {
# retrieve the git hash and date for the rocksdb submodule
($rocksdb_git_hash, $rocksdb_git_date) = git_hash_and_date $rocksdb;
} else {
$rocksdb_git_hash="none";
$rocksdb_git_date="none";
}
}

# Open the user's file for reading and a temporary file for writing
open(my $in, "<", $infile) or die "Could not open '$infile'";
open(my $out, ">", $outfile) or die "Could not create '$outfile'";

# For each line, see if we can replace anything
while (<$in>) {
s/\@MYSQL_GIT_HASH\@/$mysql_git_hash/g;
s/\@MYSQL_GIT_DATE\@/$mysql_git_date/g;
s/\@ROCKSDB_GIT_HASH\@/$rocksdb_git_hash/g;
s/\@ROCKSDB_GIT_DATE\@/$rocksdb_git_date/g;
print $out $_;
}

# Close both files
close $in;
close $out;

# Copy the temporary file to the original and then delete it
copy $outfile, $infile or
die "Unable to copy temp file ($outfile) on top of original ($infile)";
unlink $outfile;
}

main(@ARGV);

=head1 NAME
githash.pl - Generate the mysql_githash.h file for MySQL
=head1 SYNOPSIS
githash.pl [options]
Options:
--help Brief help message
--git_root=<path> Path to the root of the MySQL git repository
--file=<file> File to update with the git hashes and dates
--mysql_githash=<hash_str> Optional git hash to use for MySQL
--mysql_gitdate=<date_str> Optional git date to use for MySQL
--rocksdb_githash=<hash_str> Optional git hash to use for RocksDB
--rocksdb_gitdate=<date_str> Optional git date to use for RocksDB
=head1 OPTIONS
=over 4
=item B<--help>
Print a brief help message list all the options and exits
=item B<--git_root>
Supplies the path to the root git repository. If the optional hashes and
dates are not supplied this script will call 'git log' in this location to get
the hashes and dates.
=item B<--file>
Specifies the file to update. This file will be scanned for the following
markers, which will be replaced by the corresponding hash or date:
@MYSQL_GIT_HASH@
@MYSQL_GIT_DATE@
@ROCKSDB_GIT_HASH@
@ROCKSDB_GIT_DATE@
=item B<--mysql_githash>
Optional git hash for the MySQL repository. If this is not specified the
script will use "git log" to query the repository. If one of the hashes or
dates is supplied, all of them must be supplied.
=item B<--mysql_gitdate>
Optional git date for the MySQL repository. If this is not specified the
script will use "git log" to query the repository. If one of the hashes or
dates is supplied, all of them must be supplied.
=item B<--rocksdb_githash>
Optional git hash for the RocksDB repository. If this is not specified the
script will use "git log" to query the repository. If one of the hashes or
dates is supplied, all of them must be supplied.
=item B<--rocksdb_gitdate>
Optional git date for the RocksDB repository. If this is not specified the
script will use "git log" to query the repository. If one of the hashes or
dates is supplied, all of them must be supplied.
=back
=head1 DESCRIPTION
B<This program> will take the git hashes and dates (either supplied via
parameters or retrieved from 'git log') and update the specified file with the
values.
=cut
4 changes: 2 additions & 2 deletions share/messages_to_clients.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9413,8 +9413,8 @@ ER_PLACEHOLDER_50021
ER_PLACEHOLDER_50022
eng "Placeholder"

ER_PLACEHOLDER_50023
eng "Placeholder"
ER_GIT_HASH
eng "%s git hash: %s - %s"

ER_PLACEHOLDER_50024
eng "Placeholder"
Expand Down
33 changes: 33 additions & 0 deletions sql/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ SET(GEN_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/sql_hints.yy.h
${CMAKE_CURRENT_BINARY_DIR}/sql_hints.yy.cc
${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h
${CMAKE_CURRENT_BINARY_DIR}/mysql_githash.h
)
SET(GEN_DIGEST_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/lex_token.h
Expand Down Expand Up @@ -1192,3 +1193,35 @@ ADD_CUSTOM_TARGET(distclean
ADD_CUSTOM_TARGET(show-dist-name
COMMAND ${CMAKE_COMMAND} -E echo "${CPACK_PACKAGE_FILE_NAME}"
)

# If the repository was modified (via push or pull) or if the
# mysql_githash.h.in changed rebuild the mysql_githash.h file
SET(GITHASH_HEADER_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/mysql_githash.h.in)
SET(GITHASH_HEADER ${CMAKE_CURRENT_BINARY_DIR}/mysql_githash.h)


SET(GITHASH_DEPENDS ${GITHASH_HEADER_SOURCE})
SET(GITHASH_PERL_OPTS --git_root=${CMAKE_SOURCE_DIR} --file=${GITHASH_HEADER})

IF(DEFINED MYSQL_GITHASH)
# If the hashes and dates are passed in add them to the parameters for
# the perl script
SET(GITHASH_PERL_OPTS ${GITHASH_PERL_OPTS}
--mysql_githash=${MYSQL_GITHASH}
--mysql_gitdate=${MYSQL_GITDATE}
--rocksdb_githash=${ROCKSDB_GITHASH}
--rocksdb_gitdate=${ROCKSDB_GITDATE})
ELSE()
# Otherwise we want to add the .git/logs/HEAD file to the list of
# dependencies
SET(GITHASH_DEPENDS ${GITHASH_DEPENDS} ${CMAKE_SOURCE_DIR}/.git/logs/HEAD)
ENDIF()

SET(GITHASH_PERL ${CMAKE_SOURCE_DIR}/cmake/githash.pl)
ADD_CUSTOM_COMMAND(OUTPUT ${GITHASH_HEADER}
COMMAND ${CMAKE_COMMAND} -E copy ${GITHASH_HEADER_SOURCE} ${GITHASH_HEADER}
COMMAND ${CMAKE_COMMAND} -E echo ${GITHASH_PERL} ${GITHASH_PERL_OPTS}
COMMAND perl ${GITHASH_PERL} ${GITHASH_PERL_OPTS}
DEPENDS ${GITHASH_DEPENDS}
VERBATIM
)
31 changes: 31 additions & 0 deletions sql/mysql_githash.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copyright (c) 2016, Facebook, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

/*
Do not hand edit this file. It is generated as part of the build
process and contains git hashes and dates for MySQL and RocksDB
*/
#ifndef MYSQL_GITHASH_H
#define MYSQL_GITHASH_H

#define MYSQL_GIT_HASH "@MYSQL_GIT_HASH@"
#define MYSQL_GIT_DATE "@MYSQL_GIT_DATE@"

#define ROCKSDB_GIT_HASH "@ROCKSDB_GIT_HASH@"
#define ROCKSDB_GIT_DATE "@ROCKSDB_GIT_DATE@"

#endif
19 changes: 19 additions & 0 deletions sql/mysqld.cc
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ The documentation is based on the source files such as:
#ifdef _WIN32
#include "sql/restart_monitor_win.h"
#endif
#include "sql/mysql_githash.h"
#include "sql/rpl_filter.h"
#include "sql/rpl_gtid.h"
#include "sql/rpl_gtid_persist.h" // Gtid_table_persistor
Expand Down Expand Up @@ -989,6 +990,12 @@ bool temptable_use_mmap;
static char compiled_default_collation_name[] = MYSQL_DEFAULT_COLLATION_NAME;
static bool binlog_format_used = false;

/* MySQL git hashes and dates */
static char git_hash[] = MYSQL_GIT_HASH;
static char git_date[] = MYSQL_GIT_DATE;
static char rocksdb_git_hash[] = ROCKSDB_GIT_HASH;
static char rocksdb_git_date[] = ROCKSDB_GIT_DATE;

LEX_STRING opt_init_connect, opt_init_slave;

/* Global variables */
Expand Down Expand Up @@ -7326,6 +7333,12 @@ int mysqld_main(int argc, char **argv)

create_compress_gtid_table_thread();

// NO_LINT_DEBUG
sql_print_information(ER_DEFAULT(ER_GIT_HASH), "MySQL", git_hash, git_date);
// NO_LINT_DEBUG
sql_print_information(ER_DEFAULT(ER_GIT_HASH), "RocksDB", rocksdb_git_hash,
rocksdb_git_date);

LogEvent()
.type(LOG_TYPE_ERROR)
.subsys(LOG_SUBSYSTEM_TAG)
Expand Down Expand Up @@ -9086,6 +9099,12 @@ SHOW_VAR status_vars[] = {
SHOW_TIMER_STATUS, SHOW_SCOPE_ALL},
{"Flush_commands", (char *)&refresh_version, SHOW_LONG_NOFLUSH,
SHOW_SCOPE_GLOBAL},
{"Git_hash", (char *)git_hash, SHOW_CHAR, SHOW_SCOPE_GLOBAL},
{"Git_date", (char *)git_date, SHOW_CHAR, SHOW_SCOPE_GLOBAL},
{"Rocksdb_git_hash", (char *)rocksdb_git_hash, SHOW_CHAR,
SHOW_SCOPE_GLOBAL},
{"Rocksdb_git_date", (char *)rocksdb_git_date, SHOW_CHAR,
SHOW_SCOPE_GLOBAL},
{"Handler_commit", (char *)offsetof(System_status_var, ha_commit_count),
SHOW_LONGLONG_STATUS, SHOW_SCOPE_ALL},
{"Handler_delete", (char *)offsetof(System_status_var, ha_delete_count),
Expand Down

0 comments on commit 93836a3

Please sign in to comment.