From e4f22e08efe45e660197daa988daa03f32639725 Mon Sep 17 00:00:00 2001 From: Jay Edgar Date: Wed, 6 Apr 2016 12:48:20 -0700 Subject: [PATCH] Publish git hash in db log and via global status Summary: Include the git hash for the MyRocks repository and RocksDB submodule in the compilation and log this information to the mysqld.err log as well as make it available via SHOW GLOBAL STATUS. Test Plan: MTR Reviewers: yoshinorim, MarkCallaghan, jtolmer, hermanlee4 Reviewed By: hermanlee4 Subscribers: webscalesql-eng Differential Revision: https://reviews.facebook.net/D56355 --- cmake/githash.pl | 119 ++++++++++++++++++++++ mysql-test/suite/rocksdb/r/rocksdb.result | 6 ++ sql/CMakeLists.txt | 12 +++ sql/mysql_githash.h.in | 28 +++++ sql/mysqld.cc | 16 +++ 5 files changed, 181 insertions(+) create mode 100755 cmake/githash.pl create mode 100644 sql/mysql_githash.h.in diff --git a/cmake/githash.pl b/cmake/githash.pl new file mode 100755 index 000000000000..f30e2534ad34 --- /dev/null +++ b/cmake/githash.pl @@ -0,0 +1,119 @@ +#!/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); + +# Simple command line processing that expects just two items +# 1) a subdirectory +# 2) a file name +sub process_cmd_line { + my $root = ""; + my $infile = ""; + + # Loop through the command line arguments + foreach (@_) { + if (!length($root)) { + # If we don't already have the root directory, get it + $root = $_; + } + elsif (!length($infile)) { + # If we don't already have the file name, get it + $infile = $_; + } + else { + die "Too many parameters - $_"; + } + } + + # Check to make sure we got what we expected + die "Too few parameters, expect githash.pl " + unless length($infile); + + # Return the parameters to the caller + return ($root, $infile); +} + +# 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;%cd\""; + 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 { + # expect two parameters - + # 1) the root of the git repository + # 2) the file to update with the git hash and date + (my $root, my $infile) = process_cmd_line(@_); + my $rocksdb = "$root/rocksdb"; + my $outfile = "$infile.tmp"; + + # retrieve the git hash and date for the main repository + my ($mysql_git_hash, $mysql_git_date) = git_hash_and_date $root; + # retrieve the git hash and date for the rocksdb submodule + my ($rocksdb_git_hash, $rocksdb_git_date) = git_hash_and_date $rocksdb; + + # 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 on top of original"; + unlink $outfile; +} + +main(@ARGV); diff --git a/mysql-test/suite/rocksdb/r/rocksdb.result b/mysql-test/suite/rocksdb/r/rocksdb.result index 58b9c53bc269..b6c48948cb87 100644 --- a/mysql-test/suite/rocksdb/r/rocksdb.result +++ b/mysql-test/suite/rocksdb/r/rocksdb.result @@ -1389,6 +1389,8 @@ drop table t0, t1; # show status like 'rocksdb%'; Variable_name Value +Rocksdb_git_date # +Rocksdb_git_hash # rocksdb_rows_deleted # rocksdb_rows_inserted # rocksdb_rows_read # @@ -1458,6 +1460,8 @@ rocksdb_write_timedout # rocksdb_write_wal # select VARIABLE_NAME from INFORMATION_SCHEMA.global_status where VARIABLE_NAME LIKE 'rocksdb%'; VARIABLE_NAME +ROCKSDB_GIT_DATE +ROCKSDB_GIT_HASH ROCKSDB_ROWS_DELETED ROCKSDB_ROWS_INSERTED ROCKSDB_ROWS_READ @@ -1529,6 +1533,8 @@ ROCKSDB_WRITE_WAL # but they are shown as both session and global, like InnoDB's status vars. select VARIABLE_NAME from INFORMATION_SCHEMA.session_status where VARIABLE_NAME LIKE 'rocksdb%'; VARIABLE_NAME +ROCKSDB_GIT_DATE +ROCKSDB_GIT_HASH ROCKSDB_ROWS_DELETED ROCKSDB_ROWS_INSERTED ROCKSDB_ROWS_READ diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index ac79a64b03cb..542be9d7b558 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -27,6 +27,7 @@ SET(GEN_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.cc ${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.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 @@ -507,3 +508,14 @@ 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_PERL ${CMAKE_SOURCE_DIR}/cmake/githash.pl) +ADD_CUSTOM_COMMAND(OUTPUT ${GITHASH_HEADER} + COMMAND ${CMAKE_COMMAND} -E copy ${GITHASH_HEADER_SOURCE} ${GITHASH_HEADER} + COMMAND perl ${GITHASH_PERL} ${CMAKE_SOURCE_DIR} ${GITHASH_HEADER} + DEPENDS ${CMAKE_SOURCE_DIR}/.git/logs/HEAD ${GITHASH_HEADER_SOURCE} + VERBATIM +) diff --git a/sql/mysql_githash.h.in b/sql/mysql_githash.h.in new file mode 100644 index 000000000000..a7f152dc3194 --- /dev/null +++ b/sql/mysql_githash.h.in @@ -0,0 +1,28 @@ +/* + 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 +*/ +#pragma once + +#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@" diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e89a50ce9e47..1a3b79f53937 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -85,6 +85,7 @@ #include #include #include "mysql_com_server.h" +#include "mysql_githash.h" #include "keycaches.h" #include "../storage/myisam/ha_myisam.h" @@ -401,6 +402,12 @@ char *default_tmp_storage_engine; static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME; static bool binlog_format_used= false; +/* MySQL and RocksDB 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; static mysql_cond_t COND_thread_cache, COND_flush_thread_cache; @@ -7024,6 +7031,11 @@ int mysqld_main(int argc, char **argv) : mysqld_unix_port), mysqld_port, MYSQL_COMPILATION_COMMENT); + // NO_LINT_DEBUG + sql_print_information("MySQL git hash: %s (%s)", git_hash, git_date); + // NO_LINT_DEBUG + sql_print_information("RocksDB git hash: %s (%s)", rocksdb_git_hash, + rocksdb_git_date); #if defined(_WIN32) && !defined(EMBEDDED_LIBRARY) Service.SetRunning(); #endif @@ -9494,6 +9506,8 @@ SHOW_VAR status_vars[]= { {"Exec_seconds", (char*) offsetof(STATUS_VAR, exec_time), SHOW_TIMER_STATUS}, {"Flashcache_enabled", (char*) &cachedev_enabled, SHOW_BOOL }, {"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH}, + {"Git_hash", (char*) git_hash, SHOW_CHAR }, + {"Git_date", (char*) git_date, SHOW_CHAR }, {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONGLONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONGLONG_STATUS}, {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONGLONG_STATUS}, @@ -9632,6 +9646,8 @@ SHOW_VAR status_vars[]= { {"Rpl_seconds_delete_rows", (char*) &repl_event_times[DELETE_ROWS_EVENT], SHOW_TIMER}, {"Rpl_seconds_incident", (char*) &repl_event_times[INCIDENT_EVENT], SHOW_TIMER}, #endif + {"Rocksdb_git_hash", (char*) rocksdb_git_hash, SHOW_CHAR }, + {"Rocksdb_git_date", (char*) rocksdb_git_date, SHOW_CHAR }, {"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONGLONG_STATUS}, {"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONGLONG_STATUS}, {"Select_range", (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONGLONG_STATUS},